Decklog To Tabletop simulator script

Download TCG card from Decklog and import to Tabletop simulator as deck item

目前为 2021-01-28 提交的版本。查看 最新版本

  1. // ==UserScript==
  2. // @name Decklog To Tabletop simulator script
  3. // @namespace http://tampermonkey.net/
  4. // @version 2.0
  5. // @description Download TCG card from Decklog and import to Tabletop simulator as deck item
  6. // @author Royal
  7. // @match https://decklog.bushiroad.com/view/*
  8. // @grant GM_download
  9. // @grant GM_setClipboard
  10. // @grant GM_xmlhttpRequest
  11. // @require http://code.jquery.com/jquery-3.4.1.min.js
  12. // @require https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.14.7/umd/popper.min.js
  13. // @require https://cdn.bootcdn.net/ajax/libs/twitter-bootstrap/4.5.3/js/bootstrap.min.js
  14. // ==/UserScript==
  15.  
  16.  
  17. (function(){var c;c=jQuery;c.bootstrapGrowl=function(f,a){var b,e,d;a=c.extend({},c.bootstrapGrowl.default_options,a);b=c("<div>");b.attr("class","bootstrap-growl alert");a.type&&b.addClass("alert-"+a.type);a.allow_dismiss&&(b.addClass("alert-dismissible"),b.append('<button class="close" data-dismiss="alert" type="button"><span aria-hidden="true">&#215;</span><span class="sr-only">Close</span></button>'));b.append(f);a.top_offset&&(a.offset={from:"top",amount:a.top_offset});d=a.offset.amount;c(".bootstrap-growl").each(function(){return d= Math.max(d,parseInt(c(this).css(a.offset.from))+c(this).outerHeight()+a.stackup_spacing)});e={position:"body"===a.ele?"fixed":"absolute",margin:0,"z-index":"9999",display:"none"};e[a.offset.from]=d+"px";b.css(e);"auto"!==a.width&&b.css("width",a.width+"px");c(a.ele).append(b);switch(a.align){case "center":b.css({left:"50%","margin-left":"-"+b.outerWidth()/2+"px"});break;case "left":b.css("left","20px");break;default:b.css("right","20px")}b.fadeIn();0<a.delay&&b.delay(a.delay).fadeOut(function(){return c(this).alert("close")}); return b};c.bootstrapGrowl.default_options={ele:"body",type:"info",offset:{from:"top",amount:20},align:"right",width:250,delay:4E3,allow_dismiss:!0,stackup_spacing:10}}).call(this);
  18.  
  19. //declare all globle var
  20. var scrUIdata = "";
  21. var urllisttostring = "";
  22. var cardidtostring = "";
  23. var cardtitletostring = "";
  24. var carddesctostring = "";
  25. var allfinish = false;
  26. var totalnum = "";
  27. var lua_base = "";
  28. var carddata = "";
  29. var cardback = "";
  30. var cardid = "";
  31. var craddescarray = [];
  32. var cardidarray = [];
  33. var target = document.querySelector("#loader-bg");
  34. var runcheck = true;
  35. // create an observer instance
  36. var observer = new MutationObserver(function (mutations) {
  37. mutations.forEach(async function (mutation) {
  38. //alert("mutation");
  39. await doruncheck();
  40. });
  41. });
  42.  
  43. // configuration of the observer:
  44. var config = { attributes: true };
  45. var target2 = document.querySelector(".body-page-view");
  46. // create an observer instance
  47. var observer2 = new MutationObserver(function (mutations) {
  48. mutations.forEach(function (mutation) {
  49. setTimeout(function () {
  50. //Code to run After timeout elapses
  51. remove_landscape_card();
  52. }, 500); //Two seconds will elapse and Code will execute.
  53. });
  54. });
  55.  
  56. // configuration of the observer:
  57. var config2 = { attributes: true, childList: true, characterData: true };
  58. var sqlcardid = "";
  59. var deckname = "";
  60. var deckdesc = "";
  61.  
  62. //finish declare
  63.  
  64. (function () {
  65. "use strict";
  66.  
  67. // Your code here...
  68. $(document).ready(function () {
  69. //When document has loaded
  70. console.log("start");
  71.  
  72. observer.observe(target, config);
  73. observer2.observe(target2, config2);
  74. });
  75. })();
  76.  
  77. async function doruncheck() {
  78. if (runcheck == true) {
  79. //check for page finish
  80. var stats = $("#loader-bg").attr("style");
  81. //console.log(stats);
  82. if (stats.includes("none") == true) {
  83. await startpage();
  84. runcheck = false;
  85. }
  86. } else {
  87. //console.log("no check");
  88. }
  89. }
  90.  
  91. function startpage() {
  92. runcheck = false;
  93. //build UI
  94. get_UI();
  95. setTimeout(function () {
  96. $(".deckview").append(scrUIdata);
  97. $("#collapseOne").addClass("collapse");
  98. set_UI_button();
  99. //show_debug();
  100. }, 2000);
  101. }
  102.  
  103. async function get_UI() {
  104. await GM_xmlhttpRequest({
  105. method: "GET",
  106. url:
  107. "https://raw.githubusercontent.com/RoyalShooter/Decklog-To-Tabletop-simulator-script/main/UI_code/UIhtml_public",
  108. headers: {
  109. "User-agent": "Mozilla/4.0 (compatible) Greasemonkey",
  110. Accept: "application/atom+xml,application/xml,text/xml",
  111. },
  112. onload: function (responseDetails) {
  113. scrUIdata = responseDetails.responseText || "<h1>Error on loding UI</h1>";
  114. //console.log(scrUIdata);
  115. },
  116. });
  117. }
  118. //start hooking all button control
  119. function set_UI_button() {
  120. $("#scr_download_lua").click(download_TTS_Lua_code);
  121. $("#scr_download_as_image").click(download_Image);
  122. }
  123.  
  124. function show_debug() {
  125. $("#collapseOne").append(
  126. '<button type="button" id="Testbbt">Testbbt</button>'
  127. );
  128. $("#Testbbt").click(Testbbt);
  129. }
  130. //finish set button
  131. function download_Image(zEvent) {
  132. alert("Downloading as TTS card set");
  133. $(".deckview")
  134. .find(".card-item")
  135. .each(function (index) {
  136. //console.log(index + ": " + $(this).find("img").attr("title"));
  137. var name = $(this).find("img").attr("title").replace("/", "-");
  138. var dl_url = $(this).find("img").attr("src");
  139. var num =
  140. "0" +
  141. $(this).find(".card-controller-inner").find(".num").first().text() +
  142. "x";
  143. var path = "Decklog_TTS/"; // use a special folder for all the images
  144. var arg = {
  145. url: dl_url,
  146. name: path + num + " " + name + ".png",
  147. };
  148. var result = GM_download(arg);
  149. //console.log(result);
  150. });
  151. //download card back
  152. var arg = {
  153. url: "https://www.tcgcard.tw/wp-content/uploads/2020/05/ws_cardback.png",
  154. name: "Decklog_TTS/00 back.png",
  155. };
  156. var result = GM_download(arg);
  157. //console.log(result);
  158. }
  159.  
  160. async function download_TTS_Lua_code(zEvent) {
  161. $("#scr_loding").removeClass("d-none");
  162. // alert ("Test");
  163. var urllist = [];
  164. var cardidlist = [];
  165. var cardtitlelist = [];
  166. var carddesc = [];
  167. totalnum = $(".graph-sum-value").text();
  168. deckname = $("h2").text().replace("デッキ名「", "").replace("」のデッキ", "");
  169. var deckid = $(location).attr("href");
  170. console.log(deckid);
  171. var deckseries = $(".col-lg-6").find("span").first().text();
  172. deckdesc = deckseries + " \\n" + deckid;
  173.  
  174. $(".deckview")
  175. .find(".card-item")
  176. .each(function (index) {
  177. //console.log( index + ": " + $(this).find("img").attr("title"));
  178.  
  179. var num = $(this)
  180. .find(".card-controller-inner")
  181. .find(".num")
  182. .first()
  183. .text();
  184. var i;
  185. for (i = 0; i < num; i++) {
  186. var dl_url = $(this).find("img").attr("src");
  187. urllist.push(dl_url);
  188. var name = $(this).find("img").attr("title");
  189. var spname = name.split(" : ");
  190. cardidlist.push(spname[0]);
  191. cardtitlelist.push(spname[1]);
  192. }
  193. });
  194. //console.log("'" + urllist.join("','") + "'");
  195. //console.log("'" + cardidlist.join("','") + "'");
  196. //console.log("'" + cardtitlelist.join("','") + "'");
  197. //console.log("'" + carddesc.join("','") + "'");
  198. //GM_setClipboard("'" + urllist.join("','") + "'");
  199. urllisttostring = "'" + urllist.join("','") + "'";
  200. cardidtostring = "'" + cardidlist.join("','") + "'";
  201. cardtitletostring = "'" + cardtitlelist.join("','") + "'";
  202.  
  203.  
  204.  
  205. var download_desc = $("#scr_progress_bar_show").hasClass("d-none")
  206. if (download_desc == false){
  207. //alert("do download "+download_desc)
  208. }else{
  209. //alert("do nothing "+download_desc)
  210. }
  211. carddesctostring = "'" + craddescarray.join("','") + "'" || "";
  212. combine();
  213. $("#scr_loding").addClass("d-none");
  214. }
  215.  
  216. function remove_landscape_card(zEvent) {
  217. //alert ("Test");
  218. const img = new Image();
  219. $(".deckview")
  220. .find(".card-item")
  221. .each(function (index) {
  222. //console.log( index + ": " + $(this).find("img"));
  223. const img = new Image();
  224. //img.onload = function() {
  225. // console.log( index + ": " + this.width + 'x' + this.height);
  226. //}
  227. img.src = $(this).find("img").attr("src");
  228. //console.log( index + ": " + img.width + 'x' + img.height);
  229.  
  230. if (img.width > img.height) {
  231. $("#scr_loding").removeClass("d-none");
  232. var name = $(this).find("img").attr("title");
  233. var spname = name.split(" : ");
  234. var yyturl1 =
  235. "https://yuyu-tei.jp/game_ws/sell/sell_price.php?name=" + spname[0];
  236.  
  237. let getimg = new Promise((resolve, reject) => {
  238. GM_xmlhttpRequest({
  239. method: "GET",
  240. url: yyturl1,
  241. headers: {
  242. "User-agent": "Mozilla/4.0 (compatible) Greasemonkey",
  243. Accept: "application/atom+xml,application/xml,text/xml",
  244. },
  245. onload: function (responseDetails) {
  246. //console.log('Request for Atom feed returned ' + responseDetails.status + ' ' + responseDetails.statusText + '\n\n' +'Feed data:\n' + responseDetails.responseText);
  247. //console.log(responseDetails.responseText)
  248. var yyturl2 =
  249. "https://yuyu-tei.jp" +
  250. $(responseDetails.responseText)
  251. .find(".card_list_box")
  252. .find("a")
  253. .attr("href");
  254.  
  255. GM_xmlhttpRequest({
  256. method: "GET",
  257. url: yyturl2,
  258. headers: {
  259. "User-agent": "Mozilla/4.0 (compatible) Greasemonkey",
  260. Accept: "application/atom+xml,application/xml,text/xml",
  261. },
  262. onload: function (responseDetails) {
  263. //console.log('Request for Atom feed returned ' + responseDetails.status + ' ' + responseDetails.statusText + '\n\n' +'Feed data:\n' + responseDetails.responseText);
  264. //console.log(responseDetails.responseText)
  265. var data = responseDetails.responseText;
  266. var newimg = $(data)
  267. .find(".image_box")
  268. .find("img")
  269. .first()
  270. .attr("src");
  271. //console.log(newimg);
  272. if (newimg != "") {
  273. resolve(newimg);
  274. } else {
  275. reject("img no found");
  276. }
  277. },
  278. });
  279. },
  280. });
  281. });
  282.  
  283. getimg.then((successdata) => {
  284. console.log("replace image = "+$(this).find("img").attr("src", successdata));
  285. $("#scr_loding").addClass("d-none");
  286. });
  287. }
  288.  
  289. //alert(name);
  290. });
  291. }
  292.  
  293. function get_card_id_list() {
  294. //alert("get_card_id_list");
  295. var urllist = [];
  296. var cardidlist = [];
  297. var cardidtop = [];
  298. var cardidback = [];
  299. var cardidtemparray = [];
  300. var cardidtemp = "";
  301. var cardtitlelist = [];
  302. var carddesc = [];
  303. totalnum = $(".graph-sum-value").text();
  304.  
  305. $(".deckview")
  306. .find(".card-item")
  307. .each(function (index) {
  308. //console.log( index + ": " + $(this).find("img").attr("title"));
  309.  
  310. var num = $(this)
  311. .find(".card-controller-inner")
  312. .find(".num")
  313. .first()
  314. .text();
  315. var i;
  316. for (i = 0; i < num; i++) {
  317. var dl_url = $(this).find("img").attr("src");
  318. urllist.push(dl_url);
  319. var name = $(this).find("img").attr("title");
  320. var spname = name.split(" : ");
  321. cardidtemparray = spname[0].split("-");
  322. cardidtop = cardidtemparray[0];
  323. cardidback = cardidtemparray[1].substring(0, 3);
  324. //console.log(cardidback);
  325. cardidtemp = cardidtop + "-" + cardidback;
  326. cardidlist.push(cardidtemp);
  327. cardidarray = cardidlist;
  328. }
  329. });
  330. //pass "cardidarray[]" to globle var
  331. }
  332.  
  333. function download_card_id_list(zEvent) {
  334. get_card_id_list();
  335. //console.log('"' + cardidarray.join('","') + '"');
  336. sqlcardid = "cardid = [" + '"' + cardidarray.join('","') + '"' + "]";
  337. var totext = sqlcardid;
  338. GM_setClipboard(totext);
  339. alert("Card ID list complete, Please paste into handler.");
  340. }
  341.  
  342. function card_desc_download_enable(zEvent) {
  343. //console.log("card_desc_download_enable");
  344. $("#scr_progress_bar_show").toggleClass("d-none");
  345. }
  346.  
  347. function scr_cardback_input_show(zEvent) {
  348. $("#scr_progress_bar_show").toggleClass("d-none");
  349. }
  350.  
  351. let get_lua_code = new Promise((resolve, reject) => {
  352. GM_xmlhttpRequest({
  353. method: "GET",
  354. url:
  355. "https://raw.githubusercontent.com/RoyalShooter/Decklog-To-Tabletop-simulator-script/main/base2",
  356. headers: {
  357. "User-agent": "Mozilla/4.0 (compatible) Greasemonkey",
  358. Accept: "application/atom+xml,application/xml,text/xml",
  359. },
  360. onload: function (responseDetails) {
  361. //console.log('Request for Atom feed returned ' + responseDetails.status + ' ' + responseDetails.statusText + '\n\n' +'Feed data:\n' + responseDetails.responseText);
  362. //console.log(responseDetails.responseText)
  363. lua_base = responseDetails.responseText;
  364. //GM_setClipboard (lua_base);
  365. if (lua_base != "") {
  366. resolve(lua_base);
  367. } else {
  368. reject("err on base lua");
  369. }
  370. },
  371. });
  372. });
  373.  
  374. function combine() {
  375. cardback =
  376. "https://www.tcgcard.tw/wp-content/uploads/2020/05/ws_cardback.png";
  377. get_lua_code.then((successdata) => {
  378. lua_base = successdata;
  379. });
  380. var lua_top =
  381. "local testurl = {" +
  382. urllisttostring +
  383. "} \n local cardid = {" +
  384. cardidtostring +
  385. "} \n local cardname = {" +
  386. cardtitletostring +
  387. "} \n local carddesc = {" +
  388. carddesctostring +
  389. "} \n local totalnum = '" +
  390. totalnum +
  391. "' \n local deckname = '" +
  392. deckname +
  393. "' \n local deckdesc = '" +
  394. deckdesc +
  395. "' \n local cardBack = '" +
  396. cardback +
  397. "'\n";
  398.  
  399. var lua = lua_top + "\n" + lua_base;
  400. GM_setClipboard(lua);
  401. //alert("Lua code finished, please paste lua in the scripting tab");
  402. $.bootstrapGrowl("Lua code finished, please paste lua in the scripting tab", {
  403. type: 'success', // (null, 'info', 'danger', 'success')
  404. allow_dismiss: true, // If true then will display a cross to close the popup.
  405. stackup_spacing: 10 // spacing between consecutively stacked growls.
  406. });
  407. }
  408.  
  409. function Testbbt(zEvent) {
  410. alert("Test2");
  411. //get_card_data("BFR/S78-042");
  412. var download_desc = $("#scr_progress_bar_show").hasClass("d-none")
  413. if (download_desc == false){
  414. //alert("do download "+download_desc)
  415. }else{
  416. //alert("do nothing "+download_desc)
  417. }
  418.  
  419. }
  420.  
  421. // TTS somehow can't read special charater, dev said this will be fix in upcomming update, for now this funtion will increase readability
  422. function fix_charater(data){
  423. return new Promise((resolve, reject) => {
  424. var text = data ;
  425. text = text.replace("【", "<")
  426. text = text.replace("】", ">")
  427. text = text.replace("(", "(")
  428. text = text.replace(")", ")")
  429. text = text.replace(":", ":")
  430. text = text.replace("。", ".")
  431. text = text.replace(",", ",")
  432. text = text.replace("《", "<")
  433. text = text.replace("》", ">")
  434. text = text.replace("「", "<")
  435. text = text.replace("」", ">")
  436. text = text.replace("【", "<")
  437. text = text.replace("】", ">")
  438. text = text.replace("【", "<")
  439. text = text.replace("】", ">")
  440. text = text.replace("《", "<")
  441. text = text.replace("》", ">")
  442. text = text.replace("「", "<")
  443. text = text.replace("」", "<")
  444. text = text.replace("[", "[")
  445. text = text.replace("]", "]")
  446. text = text.replace("『", "[")
  447. text = text.replace("』", "]")
  448. text = text.replace("+", "+")
  449. text = text.replace("。", ".")
  450. text = text.replace("、", ",")
  451. text = text.replace("。", ".")
  452. //console.log(text)
  453. resolve(text)
  454. });
  455. }