pad.skyozora.com-Multiplay-Helper

show stamina and fast add stage

当前为 2017-09-29 提交的版本,查看 最新版本

  1. // ==UserScript==
  2. // @name pad.skyozora.com-Multiplay-Helper
  3. // @name:zh-CN 智龙迷城战友系统及资讯网协力页面辅助器
  4. // @namespace http://www.mapaler.com/
  5. // @description show stamina and fast add stage
  6. // @description:zh-CN 智龙迷城战友系统及资讯网,协力页面,显示体力,登陆页面可快速添加今日地图
  7. // @include http://pad.skyozora.com/multiplay/register/
  8. // @include http://pad.skyozora.com/multiplay/
  9. // @resource style https://raw.githubusercontent.com/Mapaler/pad.skyozora.com-Multiplay-Helper/master/style.css?v4
  10. // @version 1.0.0
  11. // @copyright 2017+, Mapaler <mapaler@163.com>
  12. // @grant GM_getResourceText
  13. // ==/UserScript==
  14.  
  15.  
  16. //仿GM_xmlhttpRequest函数v1.3
  17. if (typeof(GM_xmlhttpRequest) == "undefined")
  18. {
  19. var GM_xmlhttpRequest = function(GM_param) {
  20.  
  21. var xhr = new XMLHttpRequest(); //创建XMLHttpRequest对象
  22. xhr.open(GM_param.method, GM_param.url, true);
  23. if (GM_param.responseType) xhr.responseType = GM_param.responseType;
  24. if (GM_param.overrideMimeType) xhr.overrideMimeType(GM_param.overrideMimeType);
  25. xhr.onreadystatechange = function() //设置回调函数
  26. {
  27. if (xhr.readyState === xhr.DONE) {
  28. if (xhr.status === 200 && GM_param.onload)
  29. GM_param.onload(xhr);
  30. if (xhr.status !== 200 && GM_param.onerror)
  31. GM_param.onerror(xhr);
  32. }
  33. }
  34.  
  35. for (var header in GM_param.headers) {
  36. xhr.setRequestHeader(header, GM_param.headers[header]);
  37. }
  38.  
  39. xhr.send(GM_param.data ? GM_param.data : null);
  40. }
  41. }
  42. //仿GM_getValue函数v1.0
  43. if(typeof(GM_getValue) == "undefined")
  44. {
  45. var GM_getValue = function(name, type){
  46. var value = localStorage.getItem(name);
  47. if (value == undefined) return value;
  48. if ((/^(?:true|false)$/i.test(value) && type == undefined) || type == "boolean")
  49. {
  50. if (/^true$/i.test(value))
  51. return true;
  52. else if (/^false$/i.test(value))
  53. return false;
  54. else
  55. return Boolean(value);
  56. }
  57. else if((/^\-?[\d\.]+$/i.test(value) && type == undefined) || type == "number")
  58. return Number(value);
  59. else
  60. return value;
  61. }
  62. }
  63. //仿GM_setValue函数v1.0
  64. if(typeof(GM_setValue) == "undefined")
  65. {
  66. var GM_setValue = function(name, value){
  67. localStorage.setItem(name, value);
  68. }
  69. }
  70. //仿GM_deleteValue函数v1.0
  71. if(typeof(GM_deleteValue) == "undefined")
  72. {
  73. var GM_deleteValue = function(name){
  74. localStorage.removeItem(name);
  75. }
  76. }
  77. //仿GM_listValues函数v1.0
  78. if(typeof(GM_listValues) == "undefined")
  79. {
  80. var GM_listValues = function(){
  81. var keys = [];
  82. for (var ki=0, kilen=localStorage.length; ki<kilen; ki++)
  83. {
  84. keys.push(localStorage.key(ki));
  85. }
  86. return keys;
  87. }
  88. }
  89. //创建带Label的Input类
  90. var LabelInput = function(text, classname, name, type, value, title = "", beforeText = true) {
  91. var label = document.createElement("label");
  92. if (text != undefined) label.appendChild(document.createTextNode(text));
  93. label.className = classname;
  94. if (typeof(title) != "undefined")
  95. label.title = title;
  96.  
  97. var ipt = document.createElement("input");
  98. ipt.name = name;
  99. ipt.id = ipt.name;
  100. ipt.type = type;
  101. ipt.value = value;
  102.  
  103. label.input = ipt;
  104. if (beforeText)
  105. label.insertBefore(ipt, label.firstChild);
  106. else
  107. label.appendChild(ipt);
  108. return label;
  109. };
  110. function log(str) //在信息框显示内容的
  111. {
  112. var infoBox = document.querySelector("#info-box");
  113. for (var ci = infoBox.childNodes.length-1;ci>=0;ci--) //清空主图列表
  114. {
  115. infoBox.childNodes[ci].remove();
  116. }
  117. infoBox.appendChild(document.createTextNode(str));
  118. }
  119.  
  120.  
  121. var config={
  122. version:1, //储存当前设置结构版本
  123. updateDate:0, //储存今日开放地图上次更新时间
  124. todayStage:[], //储存当前开放的地图
  125. starStage:[], //储存收藏的地图
  126. message:[],
  127. };
  128. var stageList=[]; //储存全部地图的数据
  129.  
  130. var stageTestReg = "^/?s(?:tage)?/"; //用来测试href是不是地下城的
  131.  
  132. if(typeof(GM_getResourceText) != "undefined") //用了GM插件
  133. {
  134. var styleDom = document.createElement("style");
  135. styleDom.type = "text/css";
  136. styleDom.appendChild(document.createTextNode(GM_getResourceText('style')));
  137. document.head.appendChild(styleDom);
  138. }
  139.  
  140. if (GM_getValue("helper-config")==undefined)
  141. {
  142. saveConfig();
  143. alert("?欢迎使用!\n请先导入地下城列表数据\n然后检查今日开放地下城。");
  144. console.log("配置不存在,储存默认配置");
  145. }else
  146. {
  147. loadConfig(GM_getValue("helper-config"),GM_getValue("helper-stage-list"));
  148. //console.log("配置存在",config);
  149.  
  150. var now = new Date();var last = new Date(config.updateDate);
  151. if (now > last && now.getDate() != last.getDate())
  152. {
  153. console.log("今天的开放地图还没检查");
  154. alert("?又是新的一天了!\n请检查今天开放的地下城。");
  155. config.todayStage.length = 0; //清空昨天的
  156. }else
  157. {
  158. console.log("已经是今天的开放地图");
  159. }
  160. }
  161. function loadConfig(configStr,stageListStr,reset = false)
  162. {
  163. var bk = [true,true];
  164. var saConfig = JSON.parse(configStr);
  165. var saStageList = JSON.parse(stageListStr);
  166.  
  167. if (typeof(saConfig) == "object")
  168. {
  169. if (reset)
  170. {
  171. config = saConfig;
  172. }
  173. else
  174. config = Object.assign(config, saConfig);
  175. }
  176. else
  177. {
  178. console.error("配置损坏,使用默认配置");
  179. bk[0] = false;
  180. }
  181. if (typeof(saStageList) == "object")
  182. stageList = saStageList;
  183. else
  184. {
  185. console.error("完整地下城数据丢失,使用空配置");
  186. bk[1] = false;
  187. }
  188. return bk;
  189. }
  190. function saveConfig(type)
  191. {
  192. if (type == undefined) type == 255;
  193. if (1 == (type & 1))
  194. {
  195. var configStr = JSON.stringify(config);
  196. GM_setValue("helper-config", configStr);
  197. }
  198. if (2 == (type & 2))
  199. {
  200. var stageListStr = JSON.stringify(stageList);
  201. GM_setValue("helper-stage-list", stageListStr);
  202. }
  203. }
  204.  
  205.  
  206. if(location.pathname == "/multiplay/register/") //注册页面
  207. {
  208. registerPage();
  209. }else if(location.pathname == "/multiplay/") //列表页面
  210. {
  211. multiplayPage();
  212. }
  213.  
  214. function registerPage()
  215. {
  216. var form = document.querySelector("#wrapper>table:nth-of-type(3) form"); //主要版面的表单
  217. form.querySelector("p:nth-last-of-type(1)").remove() //去除最后面那个无用的东西
  218. //new Date().getDate()
  219. var box = document.createElement("div");form.parentElement.appendChild(box);
  220. box.id = box.className = "mlt-helper";
  221.  
  222.  
  223. function typeClick(){refreshStageList1(this.value)};
  224.  
  225. var stgBox = document.createElement("div");box.appendChild(stgBox);
  226. stgBox.className = "main-stg-box";
  227.  
  228. var stg1Box = document.createElement("div");stgBox.appendChild(stg1Box);
  229. stg1Box.className = "stg-box stg-box-1";
  230. var stg1Ul = document.createElement("ul");stg1Box.appendChild(stg1Ul);
  231. var stg1UlLi1 = document.createElement("li");stg1Ul.appendChild(stg1UlLi1);
  232. var stgType1 = new LabelInput("今日地下城", "stg-type","stg-type","radio","0","今天开放的降临地下城与活动地下城");
  233. stgType1.input.checked = true;
  234. stgType1.input.onclick = typeClick;
  235. stg1UlLi1.appendChild(stgType1);
  236. var stg1UlLi2 = document.createElement("li");stg1Ul.appendChild(stg1UlLi2);
  237. var stgType2 = new LabelInput("我的收藏", "stg-type","stg-type","radio","1","我收藏的地下城");
  238. stgType2.input.onclick = typeClick;
  239. stg1UlLi2.appendChild(stgType2);
  240.  
  241. var stg2Box = document.createElement("div");stgBox.appendChild(stg2Box);
  242. stg2Box.className = "stg-box stg-box-2";
  243. var stg2Ul = document.createElement("ul");stg2Box.appendChild(stg2Ul);
  244.  
  245. //征求文本信息
  246. var req = form.querySelector("[name=req]");
  247. var msgBox = document.createElement("select");stgBox.appendChild(msgBox);
  248. msgBox.size = 5;
  249. msgBox.className = "stg-box msg-box";
  250. msgBox.onclick = function(){
  251. if (config.message[this.value] !== undefined)
  252. req.value += config.message[this.value];
  253. }
  254.  
  255. function refreshMessageList()
  256. {
  257. while(msgBox.options.length>0) //清空原来的短语列表
  258. {
  259. msgBox.remove(0);
  260. }
  261. config.message.forEach(function(item,index){
  262. var opt = new Option(item, index);
  263. msgBox.add(opt);
  264. })
  265. }
  266. var msgBoxCtl = document.createElement("div");stgBox.appendChild(msgBoxCtl);
  267. msgBoxCtl.className = "msg-box-control";
  268. var msgAdd = document.createElement("input");msgBoxCtl.appendChild(msgAdd);
  269. msgAdd.type = "button";
  270. msgAdd.id = msgAdd.className = "message-add";
  271. msgAdd.value = "+";
  272. msgAdd.onclick = function(){
  273. var str = prompt("请输入需要保存的短语");
  274. if (str == null) return;
  275. config.message.push(str);
  276. saveConfig(1);
  277. refreshMessageList();
  278. };
  279. var msgAdd = document.createElement("input");msgBoxCtl.appendChild(msgAdd);
  280. msgAdd.type = "button";
  281. msgAdd.id = msgAdd.className = "message-remove";
  282. msgAdd.value = "-";
  283. msgAdd.onclick = function(){
  284. config.message.splice(msgBox.selectedIndex,1);
  285. saveConfig(1);
  286. refreshMessageList();
  287. };
  288.  
  289.  
  290. //刷新地下城列表类型
  291. function refreshStageList1(type)
  292. {
  293. if (type == undefined)type = 0;
  294. for (var ci = stg2Ul.childNodes.length-1;ci>=0;ci--) //清空主图列表
  295. {
  296. stg2Ul.childNodes[ci].remove();
  297. }
  298. var stages; //需要处理的数组
  299. if (type == 0)
  300. {
  301. stages = config.todayStage
  302. }else if (type == 1)
  303. {
  304. stages = config.starStage
  305. }else
  306. {
  307. console.error("未知的地下城类型");
  308. return;
  309. }
  310.  
  311. stages.forEach(function(stgName)
  312. {
  313. var _stgName = stgName;
  314. var li = document.createElement("li");stg2Ul.appendChild(li);
  315. var stgLbl = new LabelInput(null, "stg-list","stg-list","radio",_stgName,"地下城大关卡:" + _stgName);
  316. li.appendChild(stgLbl);
  317. stgLbl.input.onclick = refreshStageList2;
  318.  
  319. var icon = document.createElement("div"); stgLbl.appendChild(icon);
  320. icon.className = "stage-icon";
  321. var thisStage = stageList.filter(function(stg){return stg.name == _stgName;})[0]
  322. if (thisStage) icon.style.backgroundImage = "url(" + thisStage.iconUrl + ")";
  323. var detail = document.createElement("div"); stgLbl.appendChild(detail);
  324. detail.className = "stage-detail";
  325. detail.appendChild(document.createTextNode(_stgName));
  326. })
  327. }
  328. function refreshStageList2()
  329. {
  330. if (!this.checked) return; //如果并不是自身被选中,那么就没反应
  331. var _stgName = this.value;
  332. var thisStage = stageList.filter(function(stg){return stg.name == _stgName;})[0]
  333. if (thisStage == undefined)
  334. {
  335. alert("?数据库里没有这个地下城");
  336. return;
  337. }
  338. /*
  339. //添加脚本的地下城类型
  340. function checkOptionValue(select,value)
  341. {
  342. var otps = select.options;
  343. for (var oi=0,oi_l = otps.length;oi<oi_l;oi++)
  344. {
  345. if (otps[oi].value == value)
  346. {
  347. return oi;
  348. }
  349. }
  350. return -1;
  351. }
  352. var newTypeName = "脚本选中>>";
  353. var typeIdx = checkOptionValue(stage0,newTypeName);
  354. if (typeIdx>=0)
  355. {
  356. stage0.selectedIndex = typeIdx;
  357. }else
  358. {
  359. var opt = new Option(newTypeName, newTypeName);
  360. stage0.add(opt);
  361. stage0.selectedIndex = stage0.options.length - 1;
  362. }
  363. */
  364. stage0.selectedIndex = stage0.options.length - 1; //选中“上次登录的关卡”
  365.  
  366. while(stage1.options.length>0) //清空原来的主地下城列表
  367. {
  368. stage1.remove(0);
  369. }
  370. while(stage2.options.length>0) //清空原来的子地下城列表
  371. {
  372. stage2.remove(0);
  373. }
  374.  
  375. var opt = new Option(thisStage.name, thisStage.name);
  376. stage1.add(opt);
  377. stage1.selectedIndex = stage1.options.length - 1;
  378.  
  379. thisStage.subStage.forEach(function(stg){
  380. var opt = new Option(stg.name, stg.name);
  381. stage2.add(opt);
  382. })
  383. stage2.selectedIndex = 0;
  384. }
  385.  
  386. function addStarStage(name)
  387. {
  388. if (config.starStage.indexOf(name)<0)
  389. {
  390. if (!stageList.some(function(item){ //查找以前有没有这个地图
  391. return item.name == name;
  392. }))
  393. alert("?数据库里没有这个地下城");
  394. else{
  395. config.starStage.push(name);
  396. saveConfig(1);
  397. stgType2.input.click(); //点击刷新
  398. //alert("?“"+ name +"”收藏成功");
  399. }
  400. }else
  401. {
  402. alert("?“"+ name +"”已经收藏过了");
  403. }
  404. }
  405. function removeStarStage(name)
  406. {
  407. if (name == undefined)
  408. {
  409. config.starStage.length = 0; //如果没有输入,直接清空
  410. saveConfig(1);
  411. stgType2.input.click(); //点击刷新
  412. //alert("收藏清空了");
  413. return;
  414. }
  415. var index = config.starStage.indexOf(name);
  416. if (index<0)
  417. {
  418. alert("?你并没有收藏过“"+ name +"”");
  419. }else
  420. {
  421. config.starStage.splice(index,1)
  422. saveConfig(1);
  423. stgType2.input.click(); //点击刷新
  424. //alert("“"+ name +"”被删掉了");
  425. }
  426. }
  427. var btnBox1 = document.createElement("div");box.appendChild(btnBox1);
  428. var btnAddStg = document.createElement("input");btnBox1.appendChild(btnAddStg);
  429. btnAddStg.type = "button";
  430. btnAddStg.id = btnAddStg.className = "add-stage-string";
  431. btnAddStg.value = "输入地下城收藏";
  432. btnAddStg.onclick = function(){
  433. addStarStage(prompt("请输入地下城名称"));
  434. };
  435. var btnRemoveStg = document.createElement("input");btnBox1.appendChild(btnRemoveStg);
  436. btnRemoveStg.type = "button";
  437. btnRemoveStg.id = btnRemoveStg.className = "remove-stage";
  438. btnRemoveStg.value = "删除选中地下城收藏";
  439. btnRemoveStg.onclick = function(){
  440. var radios = document.getElementsByName("stg-list");
  441. for (var ri=0;ri<radios.length;ri++)
  442. {
  443. if (radios[ri].checked)
  444. {
  445. removeStarStage(radios[ri].value);
  446. }
  447. }
  448. };
  449. var btnRemoveAllStg = document.createElement("input");btnBox1.appendChild(btnRemoveAllStg);
  450. btnRemoveAllStg.type = "button";
  451. btnRemoveAllStg.id = btnRemoveAllStg.className = "remove-stage";
  452. btnRemoveAllStg.value = "清空地下城收藏";
  453. btnRemoveAllStg.onclick = function(){
  454. removeStarStage();
  455. };
  456.  
  457. var btnBox2 = document.createElement("div");box.appendChild(btnBox2);
  458. var chkUpt = document.createElement("input");btnBox2.appendChild(chkUpt);
  459. chkUpt.type = "button";
  460. chkUpt.id = chkUpt.className = "checkUpdate";
  461. chkUpt.value = "检查今日开放地下城";
  462. chkUpt.onclick = function(){
  463. checkTodayUpdate(function(){
  464. saveConfig(1);
  465. refreshStageList1(0);
  466. })
  467. }
  468.  
  469. var chkStgLst = document.createElement("input");btnBox2.appendChild(chkStgLst);
  470. chkStgLst.type = "button";
  471. chkStgLst.id = chkUpt.className = "check-stage-list";
  472. chkStgLst.value = "获取完整地下城数据";
  473. chkStgLst.onclick = function(){
  474. checkAllStageList();
  475. }
  476.  
  477. var ioCfg = document.createElement("input");btnBox2.appendChild(ioCfg);
  478. ioCfg.type = "button";
  479. ioCfg.id = chkUpt.className = "input-output-config";
  480. ioCfg.value = "导入/导出设置&地下城列表";
  481. ioCfg.onclick = function(){
  482. var dlg = ioConfigDialog();
  483. document.body.appendChild(dlg);
  484. dlg.classList.remove("display-none");
  485. dlg.configText.value = JSON.stringify(config);
  486. dlg.stageListText.value = JSON.stringify(stageList);
  487. };
  488.  
  489. //收藏按钮
  490. var stage0 = form.querySelector("[name=column1]");
  491. var stage1 = form.querySelector("#stage");
  492. var stage2 = form.querySelector("#stage2"); stage2.onchange = null;
  493. var starStg = document.createElement("input");form.insertBefore(starStg,stage2.nextSibling);
  494. starStg.type = "button";
  495. starStg.id = starStg.className = "star-stage";
  496. starStg.value = "⭐️";
  497. starStg.onclick = function(){
  498. addStarStage(stage1.value);
  499. };
  500.  
  501. var infoBox = document.createElement("div");box.appendChild(infoBox);
  502. infoBox.id = infoBox.className = "info-box";
  503. refreshStageList1(0); //先刷新地下城吧
  504. refreshMessageList(); //刷新文本列表
  505. }
  506. function checkTodayUpdate(callback)
  507. {
  508. log("开始检查今日地下城");
  509. GM_xmlhttpRequest({
  510. method: "GET",
  511. url: location.origin, //主页
  512. onload: dealMainPage,
  513. onerror: function(response) {
  514. log("获取主页地下城活动失败");
  515. console.error("获取主页地下城活动失败",response);
  516. }
  517. });
  518.  
  519. function dealMainPage(response)
  520. {
  521. var PageDOM = new DOMParser().parseFromString(response.responseText, "text/html");
  522. config.todayStage.length = 0; //先清空
  523. //紧急活动地下城表格
  524. var JinJiEvent = PageDOM.querySelector("#container>.item:nth-of-type(1)>table:nth-of-type(2)");
  525. //今天的降临
  526. var JiangLin = JinJiEvent.rows[2].cells[1].getElementsByTagName("a");
  527. for (var ai=0;ai<JiangLin.length;ai++)
  528. {
  529. var link = JiangLin[ai];
  530. if (new RegExp(stageTestReg,"igm").test(link.getAttribute("href")))
  531. {
  532. config.todayStage.push(link.title);
  533. }
  534. }
  535. //今天的紧急
  536. for (var ri=1;ri<JinJiEvent.rows[2].cells[0].rowSpan;ri++)
  537. {
  538. var link = JinJiEvent.rows[2+ri].cells[0].querySelector("a");
  539. if (new RegExp(stageTestReg,"igm").test(link.getAttribute("href")))
  540. {
  541. config.todayStage.push(link.title);
  542. }
  543. }
  544. //长期活动地下城表格
  545. var ChangQiEvent = PageDOM.querySelector("#container>.item:nth-of-type(2)>table:nth-of-type(2)");
  546. for (var ri=1;ri<ChangQiEvent.rows.length;ri++)
  547. {
  548. var imgs = ChangQiEvent.rows[ri].getElementsByTagName("img");
  549. var typeStr = ""; //储存地下城类型说明
  550. var typeSpan = ChangQiEvent.rows[ri].cells[2].querySelector("span");
  551. if (typeSpan != undefined)
  552. {
  553. typeStr = typeSpan.textContent;
  554. }
  555. var endTime = "";
  556. var endTimeTd = ChangQiEvent.rows[ri].cells[3];
  557. if (endTimeTd != undefined)
  558. {
  559. endTime = endTimeTd.childNodes[1].nodeValue;
  560. }
  561. for (var ii=0;ii<imgs.length;ii++)
  562. {
  563. var link = imgs[ii].parentElement;
  564. if (new RegExp(stageTestReg,"igm").test(link.getAttribute("href")) //是场景
  565. && !/coin\.png/igm.test(imgs[ii].getAttribute("src")) //不是金币地下城
  566. && !/一次通關限定/igm.test(typeStr) //不是一次通关限定
  567. && !/每天一場/igm.test(typeStr) //不是每天一场限定
  568. && !/後開始/igm.test(endTime) //不是还没有开始的
  569. )
  570. {
  571. config.todayStage.push(link.title);
  572. }
  573. }
  574. }
  575. config.updateDate = new Date().getTime();
  576. log("今日有" + config.todayStage.length + "个地下城");
  577. //console.log("今日地下城获取完毕",config);
  578. callback();
  579. }
  580. }
  581. //关卡大家都有的部分,类
  582. function minStage(name,iconUrl)
  583. {
  584. this.name = name;
  585. this.iconUrl = iconUrl;
  586. }
  587. //单个难度地下城关卡,类
  588. function Stage(name,iconUrl,stamina,battles)
  589. {
  590. var obj = new minStage(name,iconUrl);
  591. obj.stamina = stamina; //体力
  592. obj.battles = battles; //层数
  593. return obj;
  594. }
  595. //多个难度的地下城关卡,类
  596. function mainStage(name,iconUrl)
  597. {
  598. var obj = new minStage(name,iconUrl);
  599. obj.name = name;
  600. obj.iconUrl = iconUrl;
  601. obj.subStage = [];
  602. obj.checkSubStage = function(callback)
  603. {
  604. GM_xmlhttpRequest({
  605. method: "GET",
  606. url: "stage/" + this.name,
  607. onload: function(response){ //获取成功
  608. var PageDOM = new DOMParser().parseFromString(response.responseText, "text/html");
  609. var subStageList = PageDOM.querySelector("#wrapper>table:nth-of-type(3) ul"); //子关卡的列表ul
  610. var subStage = subStageList.getElementsByTagName("li"); //所有的li
  611.  
  612. obj.subStage.length = 0; //去掉所有的旧数据
  613. for (var si=0;si<subStage.length;si++)
  614. {
  615. var link = subStage[si].querySelector("div a"); //图标链接
  616. var iconUrl = link.querySelector("img").getAttribute("data-original");
  617. var detailTd = subStage[si].querySelector("div:nth-of-type(2)"); //介绍格
  618. if (detailTd == undefined)
  619. { //目前不知道到底是谁错了
  620. console.error("没有介绍格",subStage[si]);
  621. }
  622. var name = detailTd.querySelector("a").textContent.replace(/\s*關卡資料.*$/igm,"");
  623. var stamina = 0;var battles = 0;
  624. for (var ci=0;ci<detailTd.childNodes.length;ci++)
  625. {
  626. var cld = detailTd.childNodes[ci];
  627. if (cld.nodeName == "SPAN" && /體力/igm.test(cld.previousSibling.nodeValue))
  628. var stamina = parseInt(cld.textContent);
  629. if (cld.nodeName == "SPAN" && /層數/igm.test(cld.previousSibling.nodeValue))
  630. var battles = parseInt(cld.textContent);
  631. }
  632. var stage = new Stage(name,iconUrl,stamina,battles);
  633. obj.subStage.push(stage);
  634. }
  635. callback();
  636. },
  637. onerror: function(response) {
  638. log("获取 " + obj.name + " 详情失败");
  639. console.error("获取 " + obj.name + " 详情失败",response);
  640. },
  641. });
  642. }
  643. return obj;
  644. }
  645. function checkAllStageList(resetAll = false)
  646. {
  647. GM_xmlhttpRequest({
  648. method: "GET",
  649. url: "stage",
  650. onload: dealStageList,
  651. onerror: function(response) {
  652. log("获取全部地下城列表失败");
  653. console.error("获取全部地下城列表失败",response);
  654. },
  655. });
  656.  
  657. function dealStageList(response)
  658. {
  659. var PageDOM = new DOMParser().parseFromString(response.responseText, "text/html");
  660. if (resetAll) stageList.length = 0; //先清空
  661. //所有地下城表格
  662. var stageTd = PageDOM.querySelector("#wrapper>table:nth-of-type(3) td");
  663. var stages = stageTd.getElementsByClassName("tooltip"); //获取所有的链接
  664.  
  665.  
  666. //检查是否已经存在,否则添加新的
  667. function checkExistAdd(newStage,resetAll = false)
  668. {
  669. var oldStage = stageList.filter(function(item){ //查找以前有没有这个地图
  670. return item.name == link.title;
  671. })[0];
  672. if (!resetAll && oldStage != undefined)
  673. {
  674. oldStage.name = newStage.name;
  675. oldStage.iconUrl = newStage.iconUrl;
  676. }else
  677. { //没有就添加新的
  678. newStages.push(newStage);
  679. }
  680. }
  681.  
  682. var newStages = [];
  683. //所有地下城
  684. for (var si=1,si_l=stages.length;si<si_l;si++)
  685. {
  686. var link = stages[si];
  687. if (new RegExp(stageTestReg,"igm").test(link.getAttribute("href")))
  688. {
  689. imgUrl = link.querySelector("img").getAttribute("data-original");
  690. checkExistAdd(new mainStage(link.title,imgUrl),resetAll);
  691. }
  692. }
  693. //▼添加暂时没有的特殊图
  694. //checkExistAdd(new mainStage("闇の戦武龍","http://i1296.photobucket.com/albums/ag18/skyozora/pets_icon/3839_zpsinupxf0j.png"),resetAll);
  695. //▲添加暂时没有的特殊图
  696.  
  697. //var stageArr = stageList.slice(398,400); //debug用
  698. getStageDetail(newStages,newStages.length,function(){
  699. stageList = stageList.concat(newStages);
  700. log("所有地下城获取完毕");
  701. //console.log("所有地下城获取完毕",config);
  702. saveConfig(2);
  703. });
  704. }
  705. function getStageDetail(stgArr,max,callback)
  706. {
  707. if (stgArr.length < 1)
  708. {
  709. callback();
  710. return;
  711. }
  712. var newStgArr = stgArr.concat();
  713. var thisStg = newStgArr.shift(); //删除新数组的第一个元素
  714.  
  715. thisStg.checkSubStage(function(){
  716. log("已获取" + (max-newStgArr.length) + "/" + max);
  717. console.log("已获取" + (max-newStgArr.length) + "/" + max);
  718. getStageDetail(newStgArr,max,callback);
  719. });
  720. }
  721. }
  722.  
  723. /*
  724. * 协力列表页面
  725. *
  726. */
  727. function multiplayPage()
  728. {
  729. var table = document.querySelector("#wrapper>table:nth-of-type(3) table"); //协力请求表格
  730. for (var ri=table.rows.length-1;ri>0;ri--)
  731. {
  732. if (table.rows[ri].cells.length<2)
  733. {
  734. table.rows[ri].remove(); //去除广告
  735. }
  736. }
  737. table.rows[0].cells[0].colSpan += 1; //标题添加一格合并
  738. for (var ri=1;ri<table.rows.length;ri++)
  739. {
  740. var newCell = table.rows[ri].insertCell(2); //添加新格
  741. var stageNameCell = table.rows[ri].cells[1]; //获取名字的格
  742.  
  743. var link1 = stageNameCell.querySelector("a");
  744. var link2 = stageNameCell.querySelector("a:nth-of-type(2)");
  745. var stage1 = stageList.filter(function(item){
  746. return item.name == link1.textContent;
  747. })[0];
  748. if (stage1 == undefined) //如果发现没有数据的图,跳过
  749. {
  750. console.error("没有主关卡数据",link1.textContent)
  751. continue;
  752. }
  753. var stage2 = stage1.subStage.filter(function(item){
  754. return item.name == link2.textContent;
  755. })[0];
  756. if (stage2 == undefined) //如果发现没有数据的图,跳过
  757. {
  758. console.error("没有子关卡数据",link2.textContent)
  759. continue;
  760. }
  761. //newCell.appendChild(document.createTextNode(stage2.stamina + "体"));
  762. //newCell.appendChild(document.createElement("br"));
  763. newCell.appendChild(document.createTextNode("协力" + Math.round(stage2.stamina/2) + "体"));
  764. newCell.appendChild(document.createElement("br"));
  765. newCell.appendChild(document.createTextNode(stage2.battles + "层"));
  766. }
  767. }
  768.  
  769.  
  770. function ioConfigDialog()
  771. {
  772. var box = document.querySelector("#io-config-dialog");
  773. if (box != undefined) return box;
  774.  
  775. var box = document.createElement("div");
  776. box.id = box.className = "io-config-dialog";
  777. box.className = "display-none";
  778.  
  779. var txtBox = document.createElement("div");box.appendChild(txtBox);
  780. var divConfig = document.createElement("div");txtBox.appendChild(divConfig);
  781. divConfig.className = "text-box";
  782. var lblConfig = document.createElement("label");divConfig.appendChild(lblConfig);
  783. lblConfig.appendChild(document.createTextNode("设置:"));
  784. lblConfig.appendChild(document.createElement("br"));
  785. var txtConfig = document.createElement("textarea");lblConfig.appendChild(txtConfig);
  786. txtConfig.id = txtConfig.className = "text-config";
  787. txtConfig.value = "";
  788. box.configText = txtConfig;
  789.  
  790. var divStageList = document.createElement("div");txtBox.appendChild(divStageList);
  791. divStageList.className = "text-box";
  792. var lblStageList = document.createElement("label");divStageList.appendChild(lblStageList);
  793. lblStageList.appendChild(document.createTextNode("地下城列表:"));
  794. lblStageList.appendChild(document.createElement("br"));
  795. var txtStageList = document.createElement("textarea");lblStageList.appendChild(txtStageList);
  796. txtStageList.id = txtStageList.className = "text-stage-list";
  797. txtStageList.value = "";
  798. box.stageListText = txtStageList;
  799.  
  800. var btnBox = document.createElement("div");box.appendChild(btnBox);
  801. btnBox.className = "botton-box";
  802. var btnIpt = document.createElement("input");btnBox.appendChild(btnIpt);
  803. btnIpt.type = "button";
  804. btnIpt.id = btnIpt.className = "input-config";
  805. btnIpt.value = "导入设置";
  806. btnIpt.onclick = function(){
  807. var bk = loadConfig(txtConfig.value,txtStageList.value,true);
  808. if (bk[0] && bk[1])
  809. {
  810. saveConfig();
  811. alert("?导入成功");
  812. }else
  813. {
  814. if(!bk[0])alert("?该设置信息格式不正确");
  815. if(!bk[1])alert("?该地下城列表信息格式不正确");
  816. }
  817. }
  818.  
  819. var btnCls = document.createElement("input");btnBox.appendChild(btnCls);
  820. btnCls.type = "button";
  821. btnCls.id = btnCls.className = "close-dialog";
  822. btnCls.value = "关闭";
  823. btnCls.onclick = function(){box.classList.add("display-none");}
  824.  
  825. return box;
  826. }