您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
Generate additional statistical data in the dungeon and duel report pages
//----------------------------------------------------------------------------- // [WoD] Extra Statistics // Copyright (c) Fenghou, Tomy, DotIN13, ShakeSS // This script can generate additional statistical data in the dungeon and duel report pages. // When you entered the details or statistics page of reports, a new button will appear beside // the details button. At the details page, the new button is "Extra Stat", which will show // the statistics of the current level when you click it. At the statistics page, the new // button is "Entire Extra Stat", which will show the statistics of entire dungeon. //----------------------------------------------------------------------------- //----------------------------------------------------------------------------- // If you want to add a new Stat table, you should create a new sub class of CInfoList, // and use CStat::RegInfoList() to register your new info list. // A detailed example is CILItemDamage. //----------------------------------------------------------------------------- // 此版本的依赖项替换为gitee以保证国内访问 // ==UserScript== // @name WoD 战报额外统计信息与导出 // @namespace fenghou // @description Generate additional statistical data in the dungeon and duel report pages // @icon http://info.world-of-dungeons.org/wod/css/WOD.gif // @include http*://*.world-of-dungeons.*/wod/spiel/*dungeon/report.php* // @include http*://*.world-of-dungeons.*/wod/spiel/tournament/*duell.php* // @include http*://*.wannaexpresso.*/wod/spiel/*dungeon/report.php* // @include http*://*.wannaexpresso.*/wod/spiel/tournament/*duell.php* // @require https://code.jquery.com/jquery-3.3.1.min.js // @require https://cdn.jsdelivr.net/npm/[email protected]/Blob.min.js // @require https://cdn.jsdelivr.net/npm/[email protected]/dist/FileSaver.min.js // @require https://cdn.jsdelivr.net/npm/[email protected]/dist/jszip.js // @require https://cdn.jsdelivr.net/npm/[email protected]/dist/jquery.form.min.js // @require https://cdn.jsdelivr.net/npm/[email protected]/dayjs.min.js // @require https://cdn.jsdelivr.net/npm/[email protected]/plugin/customParseFormat.js // @require https://code.jquery.com/ui/1.13.2/jquery-ui.min.js // @modifier Christophero // @version 2023.03.14.1 // ==/UserScript== (function () { // COMMON FUNCTIONS /////////////////////////////////////////////////////////// // Choose contents of the corresponding language // Contents: {Name1 : [lang1, lang2, ...], Name2 : [lang1, lang2, ...], ...} // return: Local contents, or null // It will edit the input contents directly, so the returned object is not necessary function GetLocalContents(Contents) { function GetLanguageId() { var langText = null; var allMetas = document.getElementsByTagName("meta"); for (var i = 0; i < allMetas.length; ++i) { if (allMetas[i].httpEquiv == "Content-Language") { langText = allMetas[i].content; break; } } if (langText === null) return false; switch (langText) { case "en": return 0; case "cn": return 1; default: return null; } } var nLangId = GetLanguageId(); if (nLangId === null) return null; if (Contents instanceof Object) { for (var name in Contents) Contents[name] = Contents[name][nLangId]; return Contents; } else return null; } function CompareString(a, b) { a = a || ""; b = b || ""; return a.toLowerCase().localeCompare(b.toLowerCase(), "zh-CN-u-co-pinyin"); } function CreateElementHTML(Name, Content /* , [AttrName1, AttrValue1], [AttrName2, AttrValue2], ... */) { var HTML = '<' + Name; for (var i = 2; i < arguments.length; ++i) HTML += ' ' + arguments[i][0] + '="' + arguments[i][1] + '"'; HTML += (Content != null && Content !== "") ? ('>' + Content + '</' + Name + '>') : (' />'); return HTML; } function DbgMsg(Text) { if (DEBUG) alert(Text); } if (!Array.prototype.indexOf) { Array.prototype.indexOf = function (needle) { for (var i = 0; i < this.length; i++) { if (this[i] === needle) { return i; } } return -1; }; } initJQUIStyle(); /** * 初始化JqueryUI的样式表 */ function initJQUIStyle() { let $toolbarCss = $("<link>"); $("head").prepend($toolbarCss); $toolbarCss.attr({ rel: "stylesheet", type: "text/css", href: "https://code.jquery.com/ui/1.13.2/themes/humanity/jquery-ui.css", }); document.querySelector("style").textContent += ".ui-progressbar .ui-progressbar-value {transition: width 0.7s ease 0s;} " + "#progressbar .progress-label {position: absolute; left: 48%; font-weight: bold; text-shadow: 1px 1px 0 #fff; height: 31px; display: flex; justify-content: enter; align-items: center;}" + "@media (min-width:1px) { .ui-dialog { width: 95% !important; } } " + "@media (min-width: 768px) { .ui-dialog { max-width:900px !important; width:95% !important; } }"; } // COMMON STAT FUNCTIONS /////////////////////////////////////////////////////////// function getSum(numArr) { var nTotal = 0; for (var i = 0; i < numArr.length; i++) { nTotal = nTotal + Number(numArr[i]); } return nTotal; } function getAverage(numArr) { return getSum(numArr) / numArr.length; } // see http://www.johndcook.com/blog/2008/09/26/comparing-three-methods-of-computing-standard-deviation/ // for discussion on choice of algorithm function getVariance(numArr) { if (numArr.length <= 1) { return 0; } var nAvg = getAverage(numArr); var nTempSum = 0; for (var i = 0; i < numArr.length; i++) { nTempSum = nTempSum + Math.pow(Number(numArr[i]) - nAvg, 2); } return nTempSum / (numArr.length - 1); } // sample standard deviation function getSTD(numArr) { return Number(Math.sqrt(getVariance(numArr)).toFixed(2)); } function getMax(numArr) { return Math.max.apply(null, numArr); } function getMin(numArr) { return Math.min.apply(null, numArr); } // EXTERN FUNCTIONS /////////////////////////////////////////////////////////// /** * A utility function for defining JavaScript classes. * * This function expects a single object as its only argument. It defines * a new JavaScript class based on the data in that object and returns the * constructor function of the new class. This function handles the repetitive * tasks of defining classes: setting up the prototype object for correct * inheritance, copying methods from other types, and so on. * * The object passed as an argument should have some or all of the * following properties: * * name: The name of the class being defined. * If specified, this value will be stored in the classname * property of the prototype object. * * extend: The constructor of the class to be extended. If omitted, * the Object( ) constructor will be used. This value will * be stored in the superclass property of the prototype object. * * construct: The constructor function for the class. If omitted, a new * empty function will be used. This value becomes the return * value of the function, and is also stored in the constructor * property of the prototype object. * * methods: An object that specifies the instance methods (and other shared * properties) for the class. The properties of this object are * copied into the prototype object of the class. If omitted, * an empty object is used instead. Properties named * "classname", "superclass", and "constructor" are reserved * and should not be used in this object. * * statics: An object that specifies the static methods (and other static * properties) for the class. The properties of this object become * properties of the constructor function. If omitted, an empty * object is used instead. * * borrows: A constructor function or array of constructor functions. * The instance methods of each of the specified classes are copied * into the prototype object of this new class so that the * new class borrows the methods of each specified class. * Constructors are processed in the order they are specified, * so the methods of a class listed at the end of the array may * overwrite the methods of those specified earlier. Note that * borrowed methods are stored in the prototype object before * the properties of the methods object above. Therefore, * methods specified in the methods object can overwrite borrowed * methods. If this property is not specified, no methods are * borrowed. * * provides: A constructor function or array of constructor functions. * After the prototype object is fully initialized, this function * verifies that the prototype includes methods whose names and * number of arguments match the instance methods defined by each * of these classes. No methods are copied; this is simply an * assertion that this class "provides" the functionality of the * specified classes. If the assertion fails, this method will * throw an exception. If no exception is thrown, any * instance of the new class can also be considered (using "duck * typing") to be an instance of these other types. If this * property is not specified, no such verification is performed. **/ function DefineClass(data) { // Extract the fields we'll use from the argument object. // Set up default values. var classname = data.name; var superclass = data.extend || Object; var constructor = data.construct || function () {}; var methods = data.methods || {}; var statics = data.statics || {}; var borrows; var provides; // Borrows may be a single constructor or an array of them. if (!data.borrows) borrows = []; else if (data.borrows instanceof Array) borrows = data.borrows; else borrows = [data.borrows]; // Ditto for the provides property. if (!data.provides) provides = []; else if (data.provides instanceof Array) provides = data.provides; else provides = [data.provides]; // Create the object that will become the prototype for our class. var proto = new superclass(); // Delete any noninherited properties of this new prototype object. for (var p in proto) if (proto.hasOwnProperty(p)) delete proto[p]; // Borrow methods from "mixin" classes by copying to our prototype. for (var i = 0; i < borrows.length; i++) { var c = data.borrows[i]; borrows[i] = c; // Copy method properties from prototype of c to our prototype for (var p in c.prototype) { if (typeof c.prototype[p] != "function") continue; proto[p] = c.prototype[p]; } } // Copy instance methods to the prototype object // This may overwrite methods of the mixin classes for (var p in methods) proto[p] = methods[p]; // Set up the reserved "constructor", "superclass", and "classname" // properties of the prototype. proto.constructor = constructor; proto.superclass = superclass; // classname is set only if a name was actually specified. if (classname) proto.classname = classname; // Verify that our prototype provides all of the methods it is supposed to. for (var i = 0; i < provides.length; i++) { // for each class var c = provides[i]; for (var p in c.prototype) { // for each property if (typeof c.prototype[p] != "function") continue; // methods only if (p == "constructor" || p == "superclass") continue; // Check that we have a method with the same name and that // it has the same number of declared arguments. If so, move on if ( p in proto && typeof proto[p] == "function" && proto[p].length == c.prototype[p].length ) continue; // Otherwise, throw an exception throw new Error( "Class " + classname + " does not provide method " + c.classname + "." + p ); } } // Associate the prototype object with the constructor function constructor.prototype = proto; // Copy static properties to the constructor for (var p in statics) constructor[p] = statics[p]; // Finally, return the constructor function return constructor; } /** * Throughout, whitespace is defined as one of the characters * "\t" TAB \u0009 * "\n" LF \u000A * "\r" CR \u000D * " " SPC \u0020 * * This does not use Javascript's "\s" because that includes non-breaking * spaces (and also some other characters). */ /** * Determine whether a node's text content is entirely whitespace. * * @param nod A node implementing the |CharacterData| interface (i.e., * a |Text|, |Comment|, or |CDATASection| node * @return True if all of the text content of |nod| is whitespace, * otherwise false. */ function is_all_ws(nod) { // Use ECMA-262 Edition 3 String and RegExp features return !/[^\t\n\r ]/.test(nod.data); } /** * Determine if a node should be ignored by the iterator functions. * * @param nod An object implementing the DOM1 |Node| interface. * @return true if the node is: * 1) A |Text| node that is all whitespace * 2) A |Comment| node * and otherwise false. */ function is_ignorable(nod) { return ( nod.nodeType == Node.COMMENT_NODE || // A comment node (nod.nodeType == Node.TEXT_NODE && is_all_ws(nod)) ); // a text node, all ws } /** * Version of |previousSibling| that skips nodes that are entirely * whitespace or comments. (Normally |previousSibling| is a property * of all DOM nodes that gives the sibling node, the node that is * a child of the same parent, that occurs immediately before the * reference node.) * * @param sib The reference node. * @return Either: * 1) The closest previous sibling to |sib| that is not * ignorable according to |is_ignorable|, or * 2) null if no such node exists. */ function node_before(sib) { while ((sib = sib.previousSibling)) { if (!is_ignorable(sib)) return sib; } return null; } /** * Version of |nextSibling| that skips nodes that are entirely * whitespace or comments. * * @param sib The reference node. * @return Either: * 1) The closest next sibling to |sib| that is not * ignorable according to |is_ignorable|, or * 2) null if no such node exists. */ function node_after(sib) { while ((sib = sib.nextSibling)) { if (!is_ignorable(sib)) return sib; } return null; } /** * Version of |lastChild| that skips nodes that are entirely * whitespace or comments. (Normally |lastChild| is a property * of all DOM nodes that gives the last of the nodes contained * directly in the reference node.) * * @param par The reference node. * @return Either: * 1) The last child of |sib| that is not * ignorable according to |is_ignorable|, or * 2) null if no such node exists. */ function last_child(par) { var res = par.lastChild; while (res) { if (!is_ignorable(res)) return res; res = res.previousSibling; } return null; } /** * Version of |firstChild| that skips nodes that are entirely * whitespace and comments. * * @param par The reference node. * @return Either: * 1) The first child of |sib| that is not * ignorable according to |is_ignorable|, or * 2) null if no such node exists. */ function first_child(par) { var res = par.firstChild; while (res) { if (!is_ignorable(res)) return res; res = res.nextSibling; } return null; } /** * Version of |data| that doesn't include whitespace at the beginning * and end and normalizes all whitespace to a single space. (Normally * |data| is a property of text nodes that gives the text of the node.) * * @param txt The text node whose data should be returned * @return A string giving the contents of the text node with * whitespace collapsed. */ function data_of(txt) { var data = txt.data; // Use ECMA-262 Edition 3 String and RegExp features data = data.replace(/[\t\n\r ]+/g, " "); if (data.charAt(0) == " ") data = data.substring(1, data.length); if (data.charAt(data.length - 1) == " ") data = data.substring(0, data.length - 1); return data; } function split_id(id) { const segs = id.split("_"); let obj = { a: 0, b: 0, c: 0, d: 0 }; if (segs[1]) obj.a = parseInt(segs[1]); if (segs[2]) obj.a = parseInt(segs[1]); if (segs[3]) obj.a = parseInt(segs[1]); if (segs[4]) obj.a = parseInt(segs[1]); return obj; } function compare_id(id1, id2) { let obj1 = split_id(id1); let obj2 = split_id(id2); return obj1.a - obj2.a ? obj1.a - obj2.a : obj1.b - obj2.b ? obj1.b - obj2.b : obj1.c - obj2.c ? obj1.c - obj2.c : obj1.d - obj2.d; } // CLASSES //////////////////////////////////////////////////////////////////// // NextNode: the node next to the statistics node when it is created function CStat(NextNode, InfoDiv) { this._HTML = ''; this._reportInfoDiv = InfoDiv; this._gInfoList = []; this.iscurrentPage = true; this.nTotalPages = 0; this.nReadPages = 0; this.nReadRows = 0; this.nTotalRows = 0; this.setNode = function (newNode) { if (newNode.id == "stat_all") { this._Node = newNode; this._Node.innerHTML = ''; } else { if (this._Node) { var divs = newNode.parentNode.getElementsByTagName('div'); for (var i = 0; i < divs.length; i++) { if (divs[i].id == "stat_all") { newNode.parentNode.removeChild(divs[i]); break; } } } var NewSection = document.createElement("div"); NewSection.id = "stat_all"; NewSection.className = "stat_all tab"; if (newNode.parentNode) this._Node = newNode.parentNode.insertBefore(NewSection, newNode); else { this._Node = NewSection; newNode.appendChild(NewSection); } } this._HTML = ''; }; this.setNode(NextNode); this._reportInfoDiv.appendChild(document.createElement('table')); } CStat.prototype._Write = function (Text) { this._HTML += Text; }; CStat.prototype._Flush = function () { this._Node.innerHTML = this._HTML; }; CStat.prototype.RegInfoList = function (InfoList) { if (InfoList instanceof CInfoList) { this._gInfoList.push(InfoList); return true; } return false; }; CStat.prototype.SaveInfo = function (Info) { for (var i = 0; i < this._gInfoList.length; ++i) this._gInfoList[i].SaveInfo(Info); }; CStat.prototype.getTab = function (isExport, showhide) { function FactoryTabClick(Id) { return function () { CStat.OnTabClick(Id); }; } var tab = document.createElement('li'); tab.className = 'not_selected'; var title = Local.Text_Button_ShowAll; var id = 'showall'; if (showhide === true) { title = Local.Text_Button_ShowAll; id = 'showall'; } else { tab.id = 'tab_hideall'; title = Local.Text_Button_HideAll; id = 'hideall'; } tab.id = 'tab_' + id; var a = document.createElement('A'); a.id = 'show_all_a'; var name = document.createTextNode(title); a.appendChild(name); a.href = '#'; if (isExport) a.setAttribute("onclick", "st('" + id + "');"); else a.addEventListener("click", FactoryTabClick(id), false); tab.appendChild(a); return tab; }; CStat.prototype.Show = function (isExport) { this._Node.innerHTML = ''; var tabs = document.createElement("ul"); this._Node.appendChild(tabs); var bar = document.createElement('div'); bar.id = 'stat_bar'; bar.className = 'bar'; this._Node.appendChild(bar); var tabDivs = []; var isFirst = true; for (var i = 0; i < this._gInfoList.length; ++i) { var infoNode = this._gInfoList[i].Show(isExport); var tab = this._gInfoList[i].getTab(isExport); if (tab && infoNode) { tabs.appendChild(tab); this._Node.appendChild(infoNode); tabDivs.push(infoNode.id); if (isFirst) { tab.className = 'selected'; infoNode.style.display = ''; isFirst = false; } else { tab.className = 'not_selected'; infoNode.style.display = 'none'; } } } tabs.appendChild(this.getTab(isExport, true)); tabs.appendChild(this.getTab(isExport, false)); this._Node.setAttribute('tabs', tabDivs.join(',')); if (!isExport) { this._Node.appendChild(document.createElement('hr')); //this._Node.appendChild(this._reportInfoDiv); this.ShowProgress(); } if (!this.iscurrentPage) { this._reportInfoDiv.style.display = 'none'; this._Node.appendChild(this._reportInfoDiv); } //this._reportInfoDiv.parentNode.removeChild(this._reportInfoDiv); }; CStat.prototype.ShowProgress = function () { var widthP = 1; var currentP = 1; if (reportInfoDiv) { if (this.nReadPages < 1) currentP = 1; else currentP = this.nReadPages if (this.nTotalPages === 0 || this.nTotalRows === 0) widthP = 1; else widthP = parseInt(((currentP - 1) / this.nTotalPages + this.nReadRows / (this.nTotalRows * this.nTotalPages)) * 100); reportInfoDiv.style.width = widthP + '%'; } }; CStat.prototype._AddEvents = function () { function OnDelGMValues() { try { var ValueList = GM_listValues(); for (var name in ValueList) { GM_deleteValue(ValueList[name]); } alert(Local.Text_DefaultMsg); } catch (e) { alert("OnDelGMValues(): " + e); } } document.getElementById("stat_options_default").addEventListener("click", OnDelGMValues, false); }; CStat.OnTabClick = function (id) { var statdiv = document.getElementById('stat_all'); var tabs = statdiv.getAttribute('tabs').split(','); var showall = false; var lishowall = document.getElementById('tab_showall'); var lihideall = document.getElementById('tab_hideall'); lishowall.className = 'not_selected'; lihideall.className = 'not_selected'; for (var i = 0; i < tabs.length; i++) { var tabid = tabs[i]; var tab = document.getElementById(tabid); var li = document.getElementById('tab_' + tabid); li.className = 'not_selected'; if (id == 'showall') { lishowall.className = 'selected'; tab.style.display = ''; } else if (id == 'hideall') { lihideall.className = 'selected'; tab.style.display = 'none'; } else { if (tabid == id) { tab.style.display = ''; li.className = 'selected'; } else { tab.style.display = 'none'; li.className = 'not_selected'; } } } }; /////////////////////////////////////////////////////////////////////////////// function CTable(Title, Id, nColumns, isExport) { this._Title = Title; this._Id = Id; this._filterId = "filter_" + Id; this._nColumns = nColumns; this._HeadCellContents = new Array(nColumns); this._HeadCellLegends = new Array(nColumns); this._BodyCellContentTypes = new Array(nColumns); this._HeadCellContentFilters = []; this._BodyCellContents = []; this._HTML = ''; this._isExport = isExport; this._bShow = true; } CTable._ContentAttrs = { string: 'left', number: 'right', button: 'center' }; CTable.prototype.SetHeadCellContentFilters = function ( /* Content1, Content2, ... */) { for (var i = 0; i < arguments.length; ++i) if (arguments[i] != null) this._HeadCellContentFilters.push(arguments[i]); }; CTable.prototype.SetHeadCellContents = function ( /* Content1, Content2, ... */) { for (var i = 0; i < this._nColumns; ++i) this._HeadCellContents[i] = arguments[i] != null ? arguments[i] : ""; }; CTable.prototype.SetHeadCellLegends = function ( /* Content1, Content2, ... */) { for (var i = 0; i < this._nColumns; ++i) this._HeadCellLegends[i] = arguments[i] != null ? arguments[i] : ""; }; // Type: a string that is the property name of CTable::ContentAttrs CTable.prototype.SetBodyCellContentTypes = function ( /* Type1, Type2, ... */) { for (var i = 0; i < this._nColumns; ++i) this._BodyCellContentTypes[i] = arguments[i] != null ? CTable._ContentAttrs[arguments[i]] : ""; }; CTable.prototype.SetBodyCellContents = function ( /* Content1, Content2, ... */) { var Contents = new Array(this._nColumns); for (var i = 0; i < this._nColumns; ++i) Contents[i] = arguments[i] != null ? arguments[i] : ""; this._BodyCellContents.push(Contents); }; CTable.prototype.CreateHTML = function () { function Factory(Id) { return function () { CTable.OnClickTitle(Id); }; } function FactoryFilter(tableid, rowId) { return function () { CTable.OnChangeFilter(tableid, rowId); }; } function FactorySort(tableid, colId, numberId) { return function () { CTable.OnChangeOrder(tableid, colId, numberId); }; } function FactoryShowDetail(rowId, activeRows) { return function () { activeRows = activeRows.sort(compare_id) CTable.OnShowDetail(rowId, activeRows); }; } var tableid = "table_" + this._Id; var outputDiv = document.createElement('div'); outputDiv.id = this._Id; outputDiv.className = 'content'; var headerDiv = document.createElement('div'); outputDiv.appendChild(headerDiv); headerDiv.className = 'stat_header'; headerDiv.style.textAlign = 'center'; var spanTitle = document.createElement('span'); spanTitle.className = "stat_title clickable"; headerDiv.appendChild(spanTitle); spanTitle.innerHTML = this._Title; if (this._isExport) spanTitle.setAttribute('onclick', "ct('" + tableid + "');"); else spanTitle.addEventListener("click", Factory(tableid), false); var table = document.createElement("table"); table.className = "content_table"; table.style.margin = '0px auto'; table.id = tableid; if (!this._bShow) table.setAttribute('hide', 'hide'); outputDiv.appendChild(table); var trHeader = table.insertRow(0); trHeader.className = "content_table_header"; for (var i = 0; i < this._nColumns; ++i) { var th = document.createElement("th"); th.className = "content_table stat_order"; th.id = 'th_' + this._Id + i; th.setAttribute('order', '-1'); var thSpan = document.createElement("span"); thSpan.id = this._Id + "_col" + i; thSpan.innerHTML = this._HeadCellContents[i]; th.appendChild(thSpan); var legend = this._HeadCellLegends[i]; var infospan = document.createElement("span"); infospan.id = tableid + '_orderInfo_' + i; infospan.innerHTML = '<span></span><span></span>'; thSpan.appendChild(infospan); if (legend) { infospan.className = legend.className; if (i > 0) { thSpan.innerHTML = thSpan.innerHTML + '<br />'; thSpan.appendChild(legend); var legends = legend.getElementsByTagName('span'); for (var li = 0; li < legends.length; li++) { var l = legends[li]; l.className = "clickable"; if (this._isExport) l.setAttribute('onclick', "co('" + tableid + "'," + i + "," + li + ");"); else l.addEventListener("click", FactorySort(tableid, i, li), false); } } else { th.appendChild(legend); var checkboxs = legend.getElementsByTagName('input'); for (var ti = 0; ti < checkboxs.length; ti++) { var c = checkboxs[ti]; c.id = tableid + '_checkbox_' + i + '_' + ti; if (this._isExport) { c.setAttribute('onclick', "cf('" + tableid + "','" + this._filterId + "');"); c.setAttribute('checked', ''); } else c.addEventListener("click", FactoryFilter(tableid, this._filterId), false); } } } else { thSpan.className = "clickable"; if (this._isExport) thSpan.setAttribute('onclick', "co('" + tableid + "'," + i + ",0);"); else thSpan.addEventListener("click", FactorySort(tableid, i, 0), false); } trHeader.appendChild(th); } if (useFilter) { var trfilter = table.insertRow(-1); trfilter.id = this._filterId; trfilter.className = "content_table_filter_row"; for (var i = 0; i < this._nColumns - 1; ++i) { var cell = trfilter.insertCell(-1); if (this._HeadCellContentFilters != null) { if (this._HeadCellContentFilters[i] != null) { var filter = this._HeadCellContentFilters[i]; var comboboxid = this._filterId + "_combobox_" + i; var combobox = document.createElement("select"); cell.appendChild(combobox); combobox.id = comboboxid; if (this._isExport) combobox.setAttribute('onchange', "cf('" + tableid + "','" + this._filterId + "');"); else combobox.addEventListener("change", FactoryFilter(tableid, this._filterId), false); combobox.options.add(new Option(Local.Text_Table_AllData, i + '_' + 'all')); for (var j = 0; j < filter.length; j++) combobox.options.add(new Option(filter[j], i + '_' + j)); var comboboxOrg = combobox.cloneNode(true); comboboxOrg.id = 'org_' + comboboxid; comboboxOrg.style.display = 'none'; cell.appendChild(comboboxOrg); } else { var input = document.createElement("input"); var textid = this._filterId + "_textbox_" + i; input.type = "text"; input.size = 6; input.id = textid; cell.appendChild(input); } } } var searchButton = document.createElement("input"); searchButton.type = 'button'; searchButton.id = this._filterId + "_button"; searchButton.value = "查询"; searchButton.className = "button"; if (this._isExport) searchButton.setAttribute('onclick', "cf('" + tableid + "','" + this._filterId + "');"); else searchButton.addEventListener("click", FactoryFilter(tableid, this._filterId), false); var buttonCell = trfilter.insertCell(-1); buttonCell.appendChild(searchButton); buttonCell.style.textAlign = 'center'; } for (var i = 0; i < this._BodyCellContents.length; ++i) { var row = table.insertRow(-1); row.className = "row" + i % 2; row.setAttribute('oriorder', i); var rowId = []; var infoRowid = tableid + '_' + i; var infoNode; for (var j = 0; j < this._nColumns; ++j) { var rowspan = ""; var content = this._BodyCellContents[i][j]; if (content.show) { var cell = row.insertCell(-1); cell.className = "content_table"; cell.style.textAlign = this._BodyCellContentTypes[j]; if (content.rowspan > 1) { cell.rowSpan = content.rowspan; cell.style.verticalAlign = 'middle'; } var valueNode = content.value; cell.appendChild(valueNode); if (j == this._nColumns - 1) { if (this._isExport) valueNode.setAttribute("onclick", "sd('" + infoRowid + "',['" + content.activeRows.join("','") + "']);"); else valueNode.addEventListener("click", FactoryShowDetail(infoRowid, this._BodyCellContents[i][0].activeRows), false); infoNode = valueNode.getAttribute('data'); valueNode.removeAttribute('data'); } } rowId.push(j + "_" + this._BodyCellContents[i][j].filterId); } row.id = rowId.join(","); var infoRow = table.insertRow(-1); infoRow.className = row.className; infoRow.id = infoRowid; infoRow.style.display = 'none'; var infoCell = infoRow.insertCell(-1); infoCell.colSpan = this._nColumns; if (infoNode) { infoCell.innerHTML = infoNode; } } return outputDiv; //this._HTML = outputDiv.outerHTML; //return this._HTML; }; CTable.prototype.GetHTML = function () { return this._HTML; }; CTable.OnClickTitle = function (Id) { try { var Table = document.getElementById(Id); if (Table.hasAttribute("hide")) { Table.removeAttribute("hide"); } else { Table.setAttribute("hide", "hide"); } } catch (e) { alert("CTable.OnClickTitle(): " + e); } }; CTable.GetNumber = function (cell) { var numberPatten = /^\s?([\d]+\.?[\d]*)\s?_?\s?([\d]*\.?[\d]*)\s?$/; var pairTable = cell.firstChild; var numberString = cell.textContent; var numbers; if (pairTable && pairTable.nodeName == "TABLE") { numberString = pairTable.id; } if (numberPatten.test(numberString)) { numbers = []; var numberres = numberPatten.exec(numberString); if (numberres[1]) numbers.push(numberres[1]); if (numberres[2]) numbers.push(numberres[2]); } return numbers; }; CTable.OnChangeFilter = function (tableId, filterRowId) { try { var Table = document.getElementById(tableId); var filterRow = document.getElementById(filterRowId); var stringfilters = []; var orgstringfilters = []; var numberfilters = []; var filterString = ""; var showIds = []; var refilter = 0; var showHero_0 = document.getElementById(tableId + "_checkbox_0_0"); var showHero_1 = document.getElementById(tableId + "_checkbox_0_1"); var showHero = [showHero_0.checked, showHero_1.checked]; for (var i = 0; i < filterRow.cells.length; i++) { var cell = filterRow.cells[i]; var stringfilter = document.getElementById(filterRow.id + "_combobox_" + i); var orgstringfilter = document.getElementById('org_' + filterRow.id + "_combobox_" + i); var numberfilter = document.getElementById(filterRow.id + "_textbox_" + i); if (stringfilter) { stringfilters.push(stringfilter.value); refilter += stringfilter.selectedIndex > 0 ? 1 : 0; } else stringfilters.push(null); if (orgstringfilter) { for (var ii = 0, ij = orgstringfilter.options.length; ii < ij; ++ii) { if (orgstringfilter.options[ii].value === stringfilter.value) { orgstringfilter.selectedIndex = ii; break; } } orgstringfilters.push([stringfilter, orgstringfilter]); showIds.push([]); } if (numberfilter) numberfilters.push(numberfilter.value); else numberfilters.push(null); } var index = 0; var patten = /([\(|\[|>|<|=|]*)\s*([\d]*\.?[\d]*)\s*-?\s*([\d]*\.?[\d]*)\s*([\)|\]|\s]?)/; for (var i = 2; i < Table.rows.length; i = i + 2) { var row = Table.rows[i]; var rowInfo = Table.rows[i + 1]; var rowIds = row.id.split(","); var show = true; var hero = row.cells[0].getElementsByTagName('a')[0]; var heroKind = hero.getAttribute("kind"); show = showHero[heroKind]; if (show) { for (var fi = 0; fi < stringfilters.length; fi++) { var sfilter = stringfilters[fi]; if (!sfilter) continue; if (sfilter != fi + "_all" && sfilter != rowIds[fi]) { show = false; break; } } } if (show) { for (var fi = 0; fi < numberfilters.length; fi++) { var nfilter = numberfilters[fi]; if (!nfilter) continue; else { var numbers = CTable.GetNumber(row.cells[fi]); var nfilters = nfilter.split(/\s*[,|,]\s*/); for (ni = 0; ni < numbers.length; ni++) { var theFilter = nfilters[ni]; var testString = ""; if (theFilter && patten.test(theFilter)) { var op = "=="; var res = patten.exec(theFilter); if (res[1]) { op = res[1]; if (res[3]) { if (op == "[") op = ">="; if (op == "(") op = ">"; if (op == "=") op = "=="; } } else { if (res[3]) op = ">="; } testString = numbers[ni] + op + res[2]; if (res[3]) { op = "<="; if (res[4]) { op = res[4]; if (op == "]") op = "<="; if (op == ")") op = "<"; } testString += " && " + numbers[ni] + op + res[3]; } show = eval(testString); if (!show) break; } } } if (!show) break; } } row.style.display = show ? '' : 'none'; rowInfo.style.display = show ? rowInfo.style.display : 'none'; if (show) { row.className = "row" + index % 2; rowInfo.className = row.className; index++; for (var fi = 0; fi < orgstringfilters.length; fi++) { var id = rowIds[fi]; if (showIds[fi].indexOf(id) <= -1) showIds[fi].push(id); } } } if (orgstringfilters.length - refilter > 1) { for (var fi = 0; fi < orgstringfilters.length; fi++) { var sfilter = orgstringfilters[fi][0]; var sfilterorg = orgstringfilters[fi][1]; if (!sfilter) continue; if (refilter == 1 && sfilter.selectedIndex > 0) continue; for (var i = sfilter.options.length - 1; i > 0; i--) sfilter.remove(i); for (var i = 0; i < sfilterorg.options.length; i++) { var opt = sfilterorg.options[i]; if (showIds[fi].indexOf(opt.value) > -1) { var newopt = new Option(opt.text, opt.value); newopt.selected = opt.selected; sfilter.add(newopt); } } } } } catch (e) { alert("CTable.OnChangeFilter(): " + e); } }; CTable.OnChangeOrder = function (tableId, columnIndex, numberIndex) { var Table = document.getElementById(tableId); var index = numberIndex; var ths = Table.getElementsByTagName("th"); if (index === null) index = 0; var th = ths[columnIndex]; var order = th.getAttribute("order"); for (var i = 0; i < ths.length - 1; i++) { var span = document.getElementById(tableId + '_orderInfo_' + i); var spans = span.getElementsByTagName('span'); if (spans && spans.length == 2) { spans[0].innerHTML = ''; spans[1].innerHTML = ''; if (i == columnIndex) spans[numberIndex].innerHTML = order > 0 ? '▲' : '▼'; } } for (var i = 2; i < Table.rows.length - 2; i = i + 2) { for (var j = i + 2; j < Table.rows.length; j = j + 2) { var row_1 = Table.rows[i]; var row_1_info = Table.rows[i + 1]; var row_2 = Table.rows[j]; var row_2_info = Table.rows[j + 1]; var cell_1 = row_1.cells[columnIndex]; var cell_2 = row_2.cells[columnIndex]; n1 = CTable.GetNumber(cell_1); n2 = CTable.GetNumber(cell_2); var change = false; if (columnIndex == ths.length - 1) { var n11 = Number(row_1.getAttribute("oriorder")); var n12 = Number(row_2.getAttribute("oriorder")); change = n11 > n12; } else { var c1 = row_1.cells[0].firstChild.className.replace("my", ""); var c2 = row_2.cells[0].firstChild.className.replace("my", ""); var s1 = cell_1.textContent; var s2 = cell_2.textContent; var cc = CompareString(c1, c2); if (cc < 0) change = false; else if (cc > 0) change = true; else { if (n1 && n2 && n1.length > 0 && n2.length > 0) { var number_1 = n1[index] * order; var number_2 = n2[index] * order; change = number_1 > number_2; } else change = (CompareString(s1, s2) == order); } } if (change) { row_2.parentNode.insertBefore(row_2, row_1); row_2_info.parentNode.insertBefore(row_2_info, row_1); } } Table.rows[i].className = "row" + (i / 2) % 2; Table.rows[i + 1].className = Table.rows[i].className; } th.setAttribute("order", -1 * order); }; CTable.OnShowDetail = function (rowid, activeRows) { var row = document.getElementById(rowid); var cell = row.cells[0]; var button = row.previousSibling.getElementsByTagName('input')[0]; activeRows = activeRows || []; if (cell) { if (row.style.display == '') { button.value = '显示'; row.style.display = 'none'; } else { button.value = '隐藏'; row.style.display = ''; } var table = cell.getElementsByTagName('table')[0]; if (table.rows.length <= 1) { if (activeRows.length > 0) { var ids = activeRows[0].split('_'); var level = Number(ids[1]); var ac = table.insertRow(-1).insertCell(-1); ac.colSpan = '3'; ac.innerHTML = '<hr/><br />层 ' + level + '<br /><hr/>'; for (var i = 0; i < activeRows.length; i++) { ids = activeRows[i].split('_'); var newlevel = Number(ids[1]); if (newlevel != level) { ac = table.insertRow(-1).insertCell(-1); ac.colSpan = '3'; ac.innerHTML = '<hr/><br />层 ' + newlevel + '<br /><hr/>'; level = newlevel; } var theRow = document.getElementById(activeRows[i]).cloneNode(true); if (theRow) { table.appendChild(theRow); var c = table.insertRow(-1).insertCell(-1); c.colSpan = '3'; c.innerHTML = '<hr/>'; } } } } } }; /////////////////////////////////////////////////////////////////////////////// function CActiveInfo() { this.nIniRoll; this.nCurrAction; this.nTotalActions; this.Char = new CChar(); this.nCharId; this.ActionType = new CActionType(); this.Skill = new CSkill(); this.gAttackRoll; this.gPosition = new CKeyList(); this.nSkillMP; this.nSkillHP; this.gItem = new CKeyList(); } function CPassiveInfo() { this.Char = new CChar(); this.nCharId; this.Skill = new CSkill(); this.nDefenceRoll; this.nSkillMP; this.gItem = new CKeyList(); this.HitType = new CHitType(); this.bStruckDown; this.gDamage = []; this.DamagedItem = new CItem(); this.nItemDamage; this.nHealedHP; this.nHealedMP; } function CNavi(nLevel, nRoom, nRound, nRow) { this.nLevel = nLevel; this.nRoom = nRoom; this.nRound = nRound; this.nRow = nRow; this.toString = function () { return this.nLevel + '_' + this.nRoom + '_' + this.nRound + '_' + this.nRow; }; } function CActionInfo(Navi) { this.Navi = Navi; this.Active = new CActiveInfo(); this.gPassive = []; this.ActiveRow = 'activeRow_' + this.Navi.toString(); } function CActiveValue(ActiveRow, Value) { this.Value = Value; this.ActiveRow = ActiveRow; } /////////////////////////////////////////////////////////////////////////////// // Class: Key // Every key should have two function properties: compareTo() and toString(), // and can work without initialization parameters var CKey = DefineClass({ methods: { compareTo: function (that) { return this - that; }, toString: function () { var theNode = this.toHTMLNode(); return (theNode.nodeType == Node.COMMENT_NODE || theNode.nodeType == Node.TEXT_NODE) ? theNode.data : theNode.outerHTML; }, toText: function () { return this.toHTMLNode().textContent; }, toHTMLNode: function () { return document.createTextNode(""); } } }); CKey.UNKNOWN = -1; var CKeyList = DefineClass({ extend: CKey, construct: function () { this._gKey = []; }, methods: { push: function (Key) { return this._gKey.push(Key); }, compareTo: function (that) { var result = this._gKey.length - that._gKey.length; if (result != 0) return result; var i = 0; while (i < this._gKey.length && this._gKey[i].compareTo(that._gKey[i]) === 0) ++i; if (i === this._gKey.length) return 0; else return this._gKey[i].compareTo(that._gKey[i]); }, toHTMLNode: function () { var ret = document.createElement('span'); ret.innerHTML = this._gKey.join(", "); return ret; } } }); var CTypeKey = DefineClass({ extend: CKey, construct: function (TypeText) { this._sType; this._nKind = CKey.UNKNOWN; this._text; if (TypeText != null) { this._sType = TypeText; this._text = TypeText; this.Init(); } }, methods: { Init: function () { }, GetType: function () { return this._sType; }, GetKind: function () { return this._nKind; }, compareTo: function (that) { return CompareString(this._sType, that._sType); }, toText: function () { return this._text; }, setText: function (text) { this._text = text; }, setKind: function (kind) { this._nKind = kind; }, toHTMLNode: function () { return document.createTextNode(this._text); } } }); // Attack position var CPositionType = DefineClass({ extend: CTypeKey, construct: function (PositionText) { CTypeKey.call(this, PositionText); } }); // Action type var CActionType = DefineClass({ extend: CTypeKey, construct: function (ActionText) { CTypeKey.call(this, ActionText); }, methods: { Init: function () { this._text = 'unknown'; if (Local.OrigTextList_AttackActionType.indexOf(this._sType) > -1) { this._nKind = CActionType.ATTACK; this.setText(Local.TextList_AttackType[Local.OrigTextList_AttackActionType.indexOf(this._sType)]); } else if (Local.OrigTextList_HealActionType.indexOf(this._sType) > -1) { this._nKind = CActionType.HEAL; this.setText(Local.TextList_HealType); } else if (Local.OrigTextList_BuffActionType.indexOf(this._sType) > -1) { this._nKind = CActionType.BUFF; this.setText(Local.TextList_BuffType); } else if (Local.OrigTextList_WaitActionType.indexOf(this._sType) > -1) { this._nKind = CActionType.WAIT; this.setText(Local.TextList_WaitType); } else if (this._sType.indexOf("(") > -1) { this._nKind = CActionType.ATTACK2; this.setText("其他"); } } } }); CActionType.ATTACK = 0; CActionType.HEAL = 1; CActionType.BUFF = 2; CActionType.WAIT = 3; CActionType.ATTACK2 = 4; // hit type var CHitType = DefineClass({ extend: CTypeKey, construct: function (HitClassText) { CTypeKey.call(this, HitClassText); }, methods: { Init: function () { switch (this._sType) { case "rep_miss": this._nKind = CHitType.MISS; break; case "rep_hit": this._nKind = CHitType.HIT; break; case "rep_hit_good": this._nKind = CHitType.GOOD; break; case "rep_hit_crit": this._nKind = CHitType.CRIT; break; default: this._nKind = CKey.UNKNOWN; } if (this._nKind != CKey.UNKNOWN) this.setText(Local.TextList_HitType[this._nKind]); else this.setText(''); }, compareTo: function (that) { return this._nKind - that._nKind; } } }); CHitType.MISS = 0; CHitType.HIT = 1; CHitType.GOOD = 2; CHitType.CRIT = 3; // heal type var CHealType = DefineClass({ extend: CTypeKey, construct: function (HealText) { CTypeKey.call(this, HealText); }, methods: { Init: function () { switch (this._sType) { case "HP": this._nKind = CHealType.HP; break; case "MP": this._nKind = CHealType.MP; break; default: this._nKind = CKey.UNKNOWN; } } } }); CHealType.HP = 0; CHealType.MP = 1; // buff type var CBuffType = DefineClass({ extend: CTypeKey, construct: function (BuffText) { CTypeKey.call(this, BuffText); } }); // Damage Type var CDamageType = DefineClass({ extend: CTypeKey, construct: function (DamageTypeText) { CTypeKey.call(this, DamageTypeText); }, methods: { Init: function () { this.setText(this._sType.replace('伤害', '')); } } }); var CElementKey = DefineClass({ extend: CKey, construct: function (HTMLElement) { this._Name = ''; this._Href; this._OnClick; this._Class; this._nKind = CKey.UNKNOWN; if (HTMLElement != null) { this._Name = HTMLElement.firstChild.data; this._Href = HTMLElement.href; this._OnClick = HTMLElement.getAttribute("onclick"); this._Class = HTMLElement.className; this.Init(); } }, methods: { Init: function () { }, GetKind: function () { return this._nKind; }, compareTo: function (that) { var result = this._nKind - that._nKind; if (result !== 0) return result; return CompareString(this._Name, that._Name); }, toHTMLNode: function () { if (this._Name != null) { var ret = document.createElement('A'); var name = document.createTextNode(this._Name); ret.appendChild(name); ret.href = this._Href; ret.setAttribute("onclick", this._OnClick); ret.setAttribute('kind', this._nKind); if (this._Class) ret.className = this._Class; return ret; } else return document.createTextNode(''); }, toText: function () { return this._Name; }, setText: function (name) { this._Name = name; } } }); var CChar = DefineClass({ extend: CElementKey, construct: function (HTMLElement) { CElementKey.call(this, HTMLElement); }, methods: { Init: function () { switch (this._Class) { case "rep_hero": case "rep_myhero": this._nKind = CChar.HERO; break; case "rep_monster": case "rep_myhero_defender": this._nKind = CChar.MONSTER; break; default: this._nKind = CKey.UNKNOWN; } } } }); CChar.HERO = 0; CChar.MONSTER = 1; var CSkill = DefineClass({ extend: CElementKey, construct: function (HTMLElement) { CElementKey.call(this, HTMLElement); } }); var CItem = DefineClass({ extend: CElementKey, construct: function (HTMLElement) { CElementKey.call(this, HTMLElement); } }); var CDamage = DefineClass({ extend: CKey, construct: function (HTMLElement) { this._nBasicDmg; this._nActualDmg; this._nArmor; this._sType; this._cType; if (HTMLElement != null) { var Str; if (HTMLElement.nodeType != Node.TEXT_NODE) { Str = HTMLElement.getAttribute("onmouseover"); // \1 basic damage var Patt_BasicDamage = Local.Pattern_BasicDamage; var result = Patt_BasicDamage.exec(Str); if (result == null) throw "CDamage() :" + Str; this._nBasicDmg = Number(result[1]); Str = HTMLElement.firstChild.data; } else Str = HTMLElement.data; // \1 actual damage // \2 armor // \3 damage type var Patt_Damage = Local.Pattern_Damage; var result = Patt_Damage.exec(Str); if (result == null) throw "CDamage() :" + Str; this._nActualDmg = Number(result[1]); this._nArmor = result[2] != null ? Number(result[2]) : 0; this._sType = result[3] || ""; this._cType = new CDamageType(this._sType); if (this._nBasicDmg == null) this._nBasicDmg = this._nActualDmg + this._nArmor; } }, methods: { GetType: function () { return this._sType; }, GetDamageType: function () { return this._cType; }, GetBasicDmg: function () { return this._nBasicDmg; }, GetArmor: function () { return this._nArmor; }, GetActualDmg: function () { return this._nActualDmg; }, IsHPDamage: function () { return Local.OrigTextList_NoneHPDamageType.indexOf(this._sType) <= -1; }, compareTo: function (that) { return this._nBasicDmg - that._nBasicDmg; }, toHTMLNode: function () { var Str = ''; if (this._sType != null) { Str = String(this._nBasicDmg); if (this._nArmor > 0) Str += " - " + this._nArmor + " -> " + this._nActualDmg; else if (this._nBasicDmg !== this._nActualDmg) Str += " -> " + this._nActualDmg; Str += " " + this._sType; } document.createTextNode(Str); } } }); /////////////////////////////////////////////////////////////////////////////// // Class: Value list // Value list is a special key, it can contains any type of values, including keys var CValueList = DefineClass({ extend: CKey, construct: function () { this._gValue = []; this._nValue = []; this._ActiveValue = []; this._nAvgValue; // unsure type this._nMaxValue; // unsure type this._nMinValue; // unsure type this._nSTDValue; // unsure type this._nTotalValue; // unsure type }, methods: { GetLength: function () { return document.createTextNode(this._gValue.length); }, Calculate: function () { }, push: function (ActiveRow, Value) { this._nValue.push(Value); if (this._ActiveValue.indexOf(ActiveRow) <= -1) this._ActiveValue.push(ActiveRow); var activeValue = new CActiveValue(ActiveRow, Value); return this._gValue.push(activeValue); }, compareTo: function (that) { return this._nAvgValue - that._nAvgValue; }, AvgValue: function () { return this.getNode(this._nAvgValue); }, MaxValue: function () { return this.getNode(this._nMaxValue); }, MinValue: function () { return this.getNode(this._nMinValue); }, STDValue: function () { return this.getNode(this._nSTDValue); }, TotalValue: function () { return this.getNode(this._nTotalValue); }, ActiveValue: function () { return this._ActiveValue; }, toHTMLNode: function () { var table = document.createElement('table'); table.style.width = '100%'; var cell = table.insertRow(-1).insertCell(-1); cell.colSpan = "3"; cell.style.textAlign = 'center'; var ret = document.createElement("span"); var value = this.sortValue(this._nValue); ret.innerHTML = value.join(", "); cell.appendChild(ret); return table; }, sortValue: function (value) { return value.sort(); }, getNode: function (data) { return document.createTextNode(String(data)); }, Legend: function () { return null; } } }); var CVLString = DefineClass({ extend: CValueList, construct: function () { CValueList.call(this); }, methods: { Calculate: function () { this._nAvgValue = ""; this._nMaxValue = ""; this._nMinValue = ""; this._nSTDValue = ""; this._nTotalValue = ""; }, compareTo: function (that) { return 0; }, toHTMLNode: function () { var table = document.createElement('table'); table.style.width = '100%'; var cell = table.insertRow(-1).insertCell(-1); cell.colSpan = "3"; cell.style.textAlign = 'center'; return table; } } }); var CVLNumber = DefineClass({ extend: CValueList, construct: function () { CValueList.call(this); }, methods: { Calculate: function () { this._nTotalValue = 0; for (var i = 0; i < this._nValue.length; ++i) this._nTotalValue += Number(this._nValue[i]); this._nAvgValue = Number((this._nTotalValue / this._gValue.length)).toFixed(2); this._nMaxValue = getMax(this._nValue); this._nMinValue = getMin(this._nValue); this._nSTDValue = getSTD(this._nValue); }, sortValue: function (value) { return value.sort(function (a, b) { return b - a; }); } } }); // value: [Number1, Number2] var CVLPairNumber = DefineClass({ extend: CValueList, construct: function () { CValueList.call(this); this._nTotalValue = [0, 0]; this.gValueZero = []; this.gValueFirst = []; this.nSorting = []; }, methods: { Calculate: function () { this.setPair(); this.doCalculate(); }, setPair: function () { for (var i = 0; i < this._nValue.length; ++i) { var theValue = this._nValue[i]; this.gValueZero.push(theValue[0]); this.gValueFirst.push(theValue[1]); this._nTotalValue[0] += theValue[0]; this._nTotalValue[1] += theValue[1]; this.nSorting.push(theValue[0], theValue[1]); }; }, doCalculate: function () { this._nAvgValue = new Array(2); this._nAvgValue[0] = Number((this._nTotalValue[0] / this._gValue.length).toFixed(2)); this._nAvgValue[1] = Number((this._nTotalValue[1] / this._gValue.length).toFixed(2)); this._nMaxValue = new Array(2); this._nMaxValue[0] = getMax(this.gValueZero); this._nMaxValue[1] = getMax(this.gValueFirst); this._nMinValue = new Array(2); this._nMinValue[0] = getMin(this.gValueZero); this._nMinValue[1] = getMin(this.gValueFirst); this._nSTDValue = new Array(2); this._nSTDValue[0] = getSTD(this.gValueZero); this._nSTDValue[1] = getSTD(this.gValueFirst); }, compareTo: function (that) { if (this._nAvgValue[0] !== 0 || that._nAvgValue[0] !== 0) return this._nAvgValue[0] - that._nAvgValue[0]; else return this._nAvgValue[1] - that._nAvgValue[1]; }, toHTMLNode: function () { var table = document.createElement('table'); table.style.width = '100%'; var cell = table.insertRow(-1).insertCell(-1); cell.style.textAlign = 'center'; cell.colSpan = "3"; this.nSorting.sort(function (a, b) { return b[0] - a[0]; }); for (var i = 0; i < this.nSorting.length; ++i) { var ret = document.createElement("span"); ret.className = "pair_value"; var theValue = this.nSorting[i]; var s = document.createElement('span'); s.innerHTML = (theValue[0] != null) ? theValue[0] : 0; ret.appendChild(s); s = document.createElement('span'); s.innerHTML = ' [ ' + ((theValue[1] != null) ? theValue[1] : 0) + ' ]'; ret.appendChild(s); if (i < this.nSorting.length - 1) ret.appendChild(document.createTextNode(', ')); cell.appendChild(ret); } return table; }, getNode: function (data) { var table = document.createElement('table'); table.className = "pair_value"; table.id = data[0] + "_" + data[1]; var row = table.insertRow(0); var cell1 = row.insertCell(0); var cell2 = row.insertCell(1); cell1.innerHTML = String(data[0]); cell2.innerHTML = String(data[1]); return table; }, Legend: function () { var infospan = document.createElement("span"); infospan.className = "pair_value"; infospan.innerHTML = '<span>ROLL点</span><span>&bnsp;&bnsp;实际值</span>: '; return infospan; } } }); // value: An Array of CDamage var CVLDamage = DefineClass({ extend: CVLPairNumber, construct: function () { CVLPairNumber.call(this); }, methods: { setPair: function () { for (var i = 0; i < this._nValue.length; ++i) { var nSumOneAtkValue = [0, 0]; var theActiveValue = this._nValue[i]; for (var j = 0; j < theActiveValue.length; ++j) { var theValue = theActiveValue[j]; this._nTotalValue[0] += theValue.GetBasicDmg(); this._nTotalValue[1] += theValue.GetActualDmg(); nSumOneAtkValue[0] = nSumOneAtkValue[0] + theValue.GetBasicDmg(); nSumOneAtkValue[1] = nSumOneAtkValue[1] + theValue.GetActualDmg(); } this.gValueZero.push(nSumOneAtkValue[0]); this.gValueFirst.push(nSumOneAtkValue[1]); this.nSorting.push(nSumOneAtkValue); } } } }); /////////////////////////////////////////////////////////////////////////////// // Class: Info list function CCellContent(value, rowspan, show, filterId, activeRows) { this.value = value; this.rowspan = rowspan; this.show = show; this.filterId = filterId; this.activeRows = activeRows || []; } function CKeyType(name, type, legend) { this.Name = name; this.Type = type; this.legend = legend ? legend.cloneNode(true) : null; this.getValue = function (info) { var value = info.ValueList; switch (this.Name) { case Local.Text_Table_AvgRoll: case Local.Text_Table_ItemDamagePoints: return value.AvgValue(); case Local.Text_Table_Times: return value.GetLength(); case Local.Text_Table_MaxRoll: return value.MaxValue(); case Local.Text_Table_MinRoll: return value.MinValue(); case Local.Text_Table_STDRoll: return value.STDValue(); case Local.Text_Table_Total: return value.TotalValue(); case Local.Text_Table_RollList: case Local.Text_Table_DetailList: var ret = document.createElement("input"); ret.type = "button"; ret.className = "button"; ret.value = Local.Text_Button_Show; ret.setAttribute("data", value.toString()); return ret; default: return document.createTextNode(this.Name); } }; } CKeyType.AvgRoll = function (legend) { return new CKeyType(Local.Text_Table_AvgRoll, "number", legend); }; CKeyType.Times = function (legend) { return new CKeyType(Local.Text_Table_Times, "number", legend); }; CKeyType.MaxRoll = function (legend) { return new CKeyType(Local.Text_Table_MaxRoll, "number", legend); }; CKeyType.MinRoll = function (legend) { return new CKeyType(Local.Text_Table_MinRoll, "number", legend); }; CKeyType.STDRoll = function (legend) { return new CKeyType(Local.Text_Table_STDRoll, "number", legend); }; CKeyType.TotalRoll = function (legend) { return new CKeyType(Local.Text_Table_Total, "number", legend); }; CKeyType.RollList = function (legend) { return new CKeyType(Local.Text_Table_RollList, "button", legend); }; CKeyType.DetailList = function (legend) { return new CKeyType(Local.Text_Table_DetailList, "button", legend); }; CKeyType.Char = function (legend) { var _legend = legend; if (!legend) { var info = document.createElement("table"); info.className = 'pair_hero'; var hero = info.insertRow(-1).insertCell(-1); var check = document.createElement("INPUT"); check.type = 'checkbox'; check.value = CChar.HERO; check.checked = true; hero.appendChild(check); hero.appendChild(document.createTextNode('英雄')); var npc = info.rows[0].insertCell(-1); check = document.createElement("INPUT"); check.type = 'checkbox'; check.value = CChar.MONSTER; check.checked = true; npc.appendChild(check); npc.appendChild(document.createTextNode('对手')); _legend = info; } return new CKeyType(Local.Text_Table_Char, "string", _legend); }; CKeyType.ProviderChar = function (legend) { return new CKeyType(Local.Text_Table_Buffer, "string", legend); }; CKeyType.ReceiverChar = function (legend) { return new CKeyType(Local.Text_Table_BuffeReceiver, "string", legend); }; CKeyType.AttackType = function (legend) { return new CKeyType(Local.Text_Table_AttackType, "string", legend); }; CKeyType.Skill = function (legend) { return new CKeyType(Local.Text_Table_Skill, "string", legend); }; CKeyType.Item = function (legend) { return new CKeyType(Local.Text_Table_Item, "string", legend); }; CKeyType.Position = function (legend) { return new CKeyType(Local.Text_Table_Position, "string", legend); }; CKeyType.HealType = function (legend) { return new CKeyType(Local.Text_Table_HealType, "string", legend); }; CKeyType.BuffType = function (legend) { return new CKeyType(Local.Text_Table_BuffType, "string", legend); }; CKeyType.DamageType = function (legend) { return new CKeyType(Local.Text_Table_DamageType, "string", legend); }; CKeyType.DefenceType = function (legend) { return new CKeyType(Local.Text_Table_DefenceType, "string", legend); }; CKeyType.ItemDamagePoints = function (legend) { return new CKeyType(Local.Text_Table_ItemDamagePoints, "string", legend); }; CKeyType.ValueName = function (legend) { return [CKeyType.AvgRoll(legend), CKeyType.Times(), CKeyType.MaxRoll(legend), CKeyType.MinRoll(legend), CKeyType.STDRoll(legend), CKeyType.RollList()]; }; CKeyType.TotalValueName = function (legend) { return [CKeyType.TotalRoll(legend), CKeyType.AvgRoll(legend), CKeyType.Times(), CKeyType.MaxRoll(legend), CKeyType.MinRoll(legend), CKeyType.STDRoll(legend), CKeyType.RollList()]; }; var CInfoList = DefineClass({ construct: function (CValueList, Title, Id, gKeyName, gValueName) { this._gInfo = []; this._gKeyName = gKeyName || []; this._nKeys = this._gKeyName.length; this._CValueList = CValueList || []; this._Table = null; this._Title = Title || ""; this._Id = Id || ""; this._gValueName = gValueName || []; this._Allkey = this._gKeyName.concat(this._gValueName); }, methods: { _CompareKeys: function (gKeyA, gKeyB) { for (var i = 0; i < this._nKeys; ++i) { var result = gKeyA[i].compareTo(gKeyB[i]); if (result !== 0) return result; } return 0; }, _SetTableBodyCellContents: function () { if (this._gInfo.length <= 0) return; var tablecontent = []; var keys = this._gInfo[0].gKey.length; var filters = new Array(keys); for (var i = 0; i < keys; i++) { var filter = []; filters[i] = filter; } for (var i = 0; i < this._gInfo.length; ++i) { for (var j = 0; j < this._gInfo[i].gKey.length; ++j) { var value = this._gInfo[i].gKey[j]; var filter = value.toText(); if (filters[j].indexOf(filter) <= -1) filters[j].push(filter); } } for (var i = 0; i < this._gInfo.length; ++i) { var gBodyCellContent = []; for (var j = 0; j < this._gInfo[i].gKey.length; ++j) { if (j > 0) filters[j].sort(CompareString); var value = this._gInfo[i].gKey[j]; var filter = value.toText(); gBodyCellContent.push(new CCellContent(value.toHTMLNode(), 1, true, filters[j].indexOf(filter), this._gInfo[i].ValueList.ActiveValue())); } for (var j = 0; j < this._gValueName.length; ++j) gBodyCellContent.push(new CCellContent(this._gValueName[j].getValue(this._gInfo[i]), 1, true, -1, this._gInfo[i].ValueList.ActiveValue())); tablecontent.push(gBodyCellContent); } this._Table.SetHeadCellContentFilters.apply(this._Table, filters); if (groupData) { for (var i = tablecontent.length - 1; i > 0; i--) { for (var j = 0; j < keys; j++) { if (tablecontent[i][j].value.compareTo(tablecontent[i - 1][j].value) === 0) { tablecontent[i][j].show = false; tablecontent[i - 1][j].rowspan = tablecontent[i][j].rowspan + 1; } else break; } } } for (var i = 0; i < tablecontent.length; i++) this._Table.SetBodyCellContents.apply(this._Table, tablecontent[i]); }, SaveInfo: function (Info) { }, Show: function (isExport) { if (this._gInfo.length > 0) { this.CalculateValue(); this.sort(); return this.CreateTable(isExport); } return ""; }, getTab: function (isExport) { function FactoryTabClick(Id) { return function () { CStat.OnTabClick(Id); }; } var tab = document.createElement('li'); tab.id = 'tab_' + this._Id; tab.className = 'not_selected'; var a = document.createElement('A'); var name = document.createTextNode(this._Title); a.appendChild(name); a.href = '#'; if (isExport) a.setAttribute("onclick", "st('" + this._Id + "');"); else a.addEventListener("click", FactoryTabClick(this._Id), false); tab.appendChild(a); return tab; }, // Call this function when read all data, and before sort and export data CalculateValue: function () { for (var i = 0; i < this._gInfo.length; ++i) this._gInfo[i].ValueList.Calculate(); }, CreateTable: function (isExport) { // Key1, Key2, ..., AverageValue, Times, MaxValue, MinValue, STDValue, ValueList this._Table = new CTable(this._Title, this._Id, this._Allkey.length, isExport); var gHeadCellContent = new Array(this._Allkey.length); var gHeadCellLegend = new Array(this._Allkey.length); var gBodyCellContentType = new Array(this._Allkey.length); for (var i = 0; i < this._Allkey.length; ++i) { gHeadCellContent[i] = this._Allkey[i].Name; gBodyCellContentType[i] = this._Allkey[i].Type; gHeadCellLegend[i] = this._Allkey[i].legend; } this._Table.SetHeadCellContents.apply(this._Table, gHeadCellContent); this._Table.SetHeadCellLegends.apply(this._Table, gHeadCellLegend); this._Table.SetBodyCellContentTypes.apply(this._Table, gBodyCellContentType); this._SetTableBodyCellContents(); return this._Table.CreateHTML(); }, // Call this function when edited the info list (for example, re-sorted it) ReCreateTableHTML: function () { this._SetTableBodyCellContents(); return this._Table.CreateHTML(); }, push: function (ActiveRow, gKey, Value) { for (var i = 0; i < this._gInfo.length; ++i) { if (this._CompareKeys(this._gInfo[i].gKey, gKey) === 0) { this._gInfo[i].ValueList.push(ActiveRow, Value); return this._gInfo.length; } } var ValueList = new this._CValueList(); ValueList.push(ActiveRow, Value); return this._gInfo.push(new CInfoList._CInfo(gKey, ValueList)); }, sort: function (gSortKeyId) { function Factory(gId) { return function (A, B) { return CInfoList._CompareInfo(A, B, gId); }; } return this._gInfo.sort(Factory(gSortKeyId)); } }, statics: { _CInfo: function (gKey, ValueList) { this.gKey = gKey; this.ValueList = ValueList; }, // SortKeyId: Id of keys, or null // The list will be sorted in this way: sort them by the first key, if there are // elements are still equal, then sort them by the second key, and so on. // If SortKeyId is null, then sort the list by value // If gSortKeyId is null, then sort the list by default order of keys _CompareInfo: function (InfoA, InfoB, gSortKeyId) { if (gSortKeyId == null) { for (var i = 0; i < InfoA.gKey.length; ++i) { var result = InfoA.gKey[i].compareTo(InfoB.gKey[i]); if (result !== 0) return result; } return 0; } else { for (var i = 0; i < gSortKeyId.length; ++i) { var KeyId = gSortKeyId[i]; var result = (KeyId != null) ? InfoA.gKey[KeyId].compareTo(InfoB.gKey[KeyId]) : InfoA.ValueList.compareTo(InfoB.ValueList); if (result !== 0) return result; } return 0; } } } }); /////////////////////////////////////////////////////////////////////////////// // Sub classes of CInfoList // // var CIL_ = DefineClass({ // extend: CInfoList, // construct: function(_nKeys, CValueList) {this.superclass(_nKeys, CValueList);}, // methods: // { // _SetTableBodyCellContents: function() {}, // SaveInfo: function(Info) {}, // Show: function() {}, // CreateTable: function(Title, Id, gKeyName) {} // } // }); var CILIni = DefineClass({ extend: CInfoList, construct: function (CValueList) { this.superclass(CValueList, Local.Text_Table_Ini, "stat_ini", [CKeyType.Char()], CKeyType.ValueName()); }, methods: { SaveInfo: function (Info) { if (Info.Active.nCurrAction === 1) this.push(Info.ActiveRow, [Info.Active.Char], Info.Active.nIniRoll); } } }); var CILAttackRoll = DefineClass({ extend: CInfoList, construct: function (CValueList) { this.superclass(CValueList, Local.Text_Table_Attack, "stat_attack", [CKeyType.Char(), CKeyType.AttackType(), CKeyType.Skill(), CKeyType.Item(), CKeyType.Position()], CKeyType.ValueName()); }, methods: { SaveInfo: function (Info) { if (Info.Active.ActionType.GetKind() === CActionType.ATTACK && Info.Active.gAttackRoll.length != 0) { for (var i = 0; i < Info.Active.gAttackRoll.length; ++i) { this.push(Info.ActiveRow, [Info.Active.Char, Info.Active.ActionType, Info.Active.Skill, Info.Active.gItem, Info.Active.gPosition._gKey[i]], Info.Active.gAttackRoll[i]); } } } } }); var CILDefenceRoll = DefineClass({ extend: CInfoList, construct: function (CValueList) { this.superclass(CValueList, Local.Text_Table_Defence, "stat_defence", [CKeyType.Char(), CKeyType.DefenceType(), CKeyType.Skill(), CKeyType.Item()], CKeyType.ValueName()); }, methods: { SaveInfo: function (Info) { if (Info.Active.ActionType.GetKind() === CActionType.ATTACK) { for (var i = 0; i < Info.gPassive.length; ++i) { if (Info.gPassive[i].nDefenceRoll != null) this.push(Info.ActiveRow, [Info.gPassive[i].Char, Info.Active.ActionType, Info.gPassive[i].Skill, Info.gPassive[i].gItem], Info.gPassive[i].nDefenceRoll); } } } } }); var CILDamage = DefineClass({ extend: CInfoList, construct: function (CValueList) { var infospan = document.createElement("span"); infospan.className = "pair_value"; infospan.innerHTML = '<span>ROLL点</span> <span>实际值</span>'; this.superclass(CValueList, Local.Text_Table_Damage, "stat_damage", [CKeyType.Char(), CKeyType.AttackType(), CKeyType.Skill(), CKeyType.Item(), CKeyType.DamageType()], CKeyType.TotalValueName(infospan)); }, methods: { SaveInfo: function (Info) { if (Info.Active.ActionType.GetKind() === CActionType.ATTACK) { for (var i = 0; i < Info.gPassive.length; ++i) { if (Info.gPassive[i].gDamage.length > 0) { //var damage = []; //damage.push(Info.gPassive[i].gDamage); for (var index = 0; index < Info.gPassive[i].gDamage.length; index++) { this.push(Info.ActiveRow, [Info.Active.Char, Info.Active.ActionType, Info.Active.Skill, Info.Active.gItem, Info.gPassive[i].gDamage[index].GetDamageType()], [Info.gPassive[i].gDamage[index]]); } } } } } } }); var CILDamaged = DefineClass({ extend: CInfoList, construct: function (CValueList) { var infospan = document.createElement("span"); infospan.className = "pair_value"; infospan.innerHTML = '<span>ROLL点</span> <span>实际值</span>'; this.superclass(CValueList, Local.Text_Table_Damaged, "stat_damaged", [CKeyType.Char(), CKeyType.AttackType(), CKeyType.Skill(), CKeyType.Item(), CKeyType.DamageType()], CKeyType.TotalValueName(infospan)); }, methods: { SaveInfo: function (Info) { if (Info.Active.ActionType.GetKind() === CActionType.ATTACK) { for (var i = 0; i < Info.gPassive.length; ++i) { if (Info.gPassive[i].gDamage.length > 0) { //var damage = []; //damage.push(Info.gPassive[i].gDamage); for (var index = 0; index < Info.gPassive[i].gDamage.length; index++) { this.push(Info.ActiveRow, [Info.gPassive[i].Char, Info.Active.ActionType, Info.Active.Skill, Info.Active.gItem, Info.gPassive[i].gDamage[index].GetDamageType()], [Info.gPassive[i].gDamage[index]]); } } } } } } }); var CILHeal = DefineClass({ extend: CInfoList, construct: function (CValueList) { this.superclass(CValueList, Local.Text_Table_Heal, "stat_heal", [CKeyType.Char(), CKeyType.Skill(), CKeyType.Item(), CKeyType.HealType()], CKeyType.TotalValueName()); }, methods: { SaveInfo: function (Info) { if (Info.Active.ActionType.GetKind() === CActionType.HEAL) { for (var i = 0; i < Info.gPassive.length; ++i) { if (Info.gPassive[i].nHealedHP != null) this.push(Info.ActiveRow, [Info.Active.Char, Info.Active.Skill, Info.Active.gItem, new CHealType('HP')], [Number(Info.gPassive[i].nHealedHP)]); if (Info.gPassive[i].nHealedMP != null) this.push(Info.ActiveRow, [Info.Active.Char, Info.Active.Skill, Info.Active.gItem, new CHealType('MP')], [Number(Info.gPassive[i].nHealedMP)]); } } } } }); var CILHealed = DefineClass({ extend: CInfoList, construct: function (CValueList) { this.superclass(CValueList, Local.Text_Table_Healed, "stat_healed", [CKeyType.Char(), CKeyType.HealType()], CKeyType.TotalValueName()); }, methods: { SaveInfo: function (Info) { if (Info.Active.ActionType.GetKind() === CActionType.HEAL) { for (var i = 0; i < Info.gPassive.length; ++i) { if (Info.gPassive[i].nHealedHP != null) this.push(Info.ActiveRow, [Info.gPassive[i].Char, new CHealType('HP')], [Number(Info.gPassive[i].nHealedHP)]); if (Info.gPassive[i].nHealedMP != null) this.push(Info.ActiveRow, [Info.gPassive[i].Char, new CHealType('MP')], [Number(Info.gPassive[i].nHealedMP)]); } } } } }); var CILBuff = DefineClass({ extend: CInfoList, construct: function (CValueList) { this.superclass(CValueList, Local.Text_Table_Buff, "stat_buff", [CKeyType.Char(), CKeyType.Skill(), CKeyType.Item(), CKeyType.BuffType()], [CKeyType.Times(), CKeyType.DetailList()]); }, methods: { SaveInfo: function (Info) { if (Info.Active.ActionType.GetKind() === CActionType.BUFF) { this.push(Info.ActiveRow, [Info.Active.Char, Info.Active.Skill, Info.Active.gItem, new CBuffType(Info.Active.nIniRoll == null ? '回合前' : '回合中')], [0]); } } } }); var CILBuffed = DefineClass({ extend: CInfoList, construct: function (CValueList) { this.superclass(CValueList, Local.Text_Table_Buffed, "stat_buffed", [CKeyType.Char(), CKeyType.Skill(), CKeyType.Item(), CKeyType.BuffType()], [CKeyType.Times(), CKeyType.DetailList()]); }, methods: { SaveInfo: function (Info) { if (Info.Active.ActionType.GetKind() === CActionType.BUFF) { for (var i = 0; i < Info.gPassive.length; ++i) this.push(Info.ActiveRow, [Info.gPassive[i].Char, Info.Active.Skill, Info.Active.gItem, new CBuffType(Info.Active.nIniRoll == null ? '回合前' : '回合中')], [0]); } } } }); var CILItemDamage = DefineClass({ extend: CInfoList, construct: function (CValueList) { this.superclass(CValueList, Local.Text_Table_DamagedItems, "stat_item_damage", [CKeyType.Char(), CKeyType.Item()], [CKeyType.TotalRoll(), CKeyType.Times(), CKeyType.ItemDamagePoints(), CKeyType.RollList()]); }, methods: { SaveInfo: function (Info) { if (Info.Active.ActionType.GetKind() === CActionType.ATTACK) { for (var i = 0; i < Info.gPassive.length; ++i) { if (Info.gPassive[i].nItemDamage != null) this.push(Info.ActiveRow, [Info.gPassive[i].Char, Info.gPassive[i].DamagedItem], Info.gPassive[i].nItemDamage); } } } } }); // FUNCTIONS ////////////////////////////////////////////////////////////////// function CountStat(page, bLastSubPage, alsoSaveEntire) { // Read the last round only when reading the last sub page if (!bLastSubPage) RemoveLastRound(page); var nLevel = GetHiddenInfo(page, "current_level", 1); var ret = GetRepPageInfo(page, [1, 1]); var nCurrRepPage = ret[0]; var Navi = new CNavi(nLevel, nCurrRepPage, 0, 0); var allRows = page.getElementsByTagName("tr"); Stat.nTotalRows = allRows.length; for (var i = 0; i < allRows.length; ++i) { Stat.nReadRows = i + 1; var Info = new CActionInfo(Navi); var IniColumn = first_child(allRows[i]); if (!GetIniInfo(IniColumn, Info)) continue; Navi.nRow++; allRows[i].setAttribute('id', Info.ActiveRow); if (Stat.iscurrentPage == false) { Stat._reportInfoDiv.firstChild.appendChild(allRows[i].cloneNode(true)); } if (alsoSaveEntire && StatEntire.iscurrentPage == false) { StatEntire._reportInfoDiv.firstChild.appendChild(allRows[i].cloneNode(true)); } var ActiveColumn = node_after(IniColumn); GetActiveInfo(ActiveColumn, Info); switch (Info.Active.ActionType.GetKind()) { case CActionType.ATTACK: // Attack { var PassiveColumn = node_after(ActiveColumn); if (PassiveColumn) GetAttackedInfo(PassiveColumn, Info); break; } case CActionType.HEAL: // Heal { if (includeFilter.Healed) { var PassiveColumn = node_after(ActiveColumn); GetHealedBuffedInfo(PassiveColumn, Info); break; } } case CActionType.BUFF: // Buff { if (includeFilter.Buffed) { var PassiveColumn = node_after(ActiveColumn); GetHealedBuffedInfo(PassiveColumn, Info); break; } } case CActionType.WAIT: // Wait default: // Unknown ; } Stat.SaveInfo(Info); if (alsoSaveEntire) StatEntire.SaveInfo(Info); }; } function RemoveLastRound(page) { var allRows = page.getElementsByTagName("tr"); for (var i = 0; i < allRows.length; ++i) { if (allRows[i].className != null && rValue.Pattern_logRow.test(allRows[i].className)) { var allH1 = allRows[i].getElementsByTagName("h1"); if (allH1[0] != null && allH1[0].firstChild != null && allH1[0].firstChild.nodeType == Node.TEXT_NODE && allH1[0].firstChild.data == Local.OrigText_LastRound) { allRows[i].parentNode.removeChild(allRows[i]); break; } } }; } function GetIniInfo(Node, Info) { if (Node == null || Node.className != "rep_initiative") return false; if (Node.innerHTML == " ") return true; if (includeFilter.Init) { // \1 ini // \2 current action // \3 total actions var Patt_Ini = Local.Pattern_Ini; var result = Patt_Ini.exec(Node.innerHTML); if (result == null) { DbgMsgAction(Info, "IniInfo: " + Node.innerHTML); return false; } var active = Info.Active; active.nIniRoll = Number(result[1]); active.nCurrAction = Number(result[2]); active.nTotalActions = Number(result[3]); return active.nIniRoll != null; } return false; } // return: whether the format is right function GetActiveInfo(Node, Info) { if (Node === null) { DbgMsgAction(Info, "ActiveInfo: null"); return false; } var nStartNode = 0; var Str = Node.innerHTML; var active = Info.Active; // \1 span node // \2 npc Id var Patt_Char = Local.Pattern_Active_Char; var result = Patt_Char.exec(Str); if (result === null) { DbgMsgAction(Info, "ActiveInfo (Char): " + Node.innerHTML); return true; } var CharNode = result[1] != null ? Node.childNodes[nStartNode].childNodes[0] : Node.childNodes[nStartNode]; active.Char = new CChar(CharNode); active.nCharId = result[2] != null ? Number(result[2]) : null; nStartNode += result[1] != null ? 1 : (result[2] != null ? 2 : 1); Str = Str.substring(result[0].length); // \1 attack // \2 heal or buff // \3 left parenthesis var Patt_Action1 = Local.Pattern_Active_Action1; result = Patt_Action1.exec(Str); if (result === null) { // \1 other action var Patt_Action2 = Local.Pattern_Active_Action2; result = Patt_Action2.exec(Str); if (result === null) { DbgMsgAction(Info, "ActiveInfo (Action2): " + Node.innerHTML); return false; } if (result[3] != null) { active.ActionType.setKind(CActionType.ATTACK); active.ActionType.setText(""); active.gAttackRoll = []; active.gAttackRoll.push(Number(result[3])); active.gPosition.push(new CPositionType("")); active.Skill = new CSkill(null); } else active.ActionType = new CActionType(result[1]); return true; } if (result[1] != null) { active.ActionType = new CActionType(result[1]); if (active.ActionType.GetKind() !== CActionType.ATTACK) { DbgMsgAction(Info, "ActiveInfo (Attack Type): " + result[1]); return false; } nStartNode += 1; Str = Str.substring(result[0].length); } else { active.ActionType = new CActionType(result[2]); if (active.ActionType.GetKind() !== CActionType.HEAL && active.ActionType.GetKind() !== CActionType.BUFF) { DbgMsgAction(Info, "ActiveInfo (Heal/Buff Type): " + result[2]); return false; } active.Skill = new CSkill(Node.childNodes[nStartNode + 1]); if (result[3] === null) return true; nStartNode += 3; Str = Str.substring(result[0].length); } switch (active.ActionType.GetKind()) { case CActionType.ATTACK: // attack { // \1 single roll // \2 multiple positions and rolls // \3 position n (only the last one) // \4 multiple roll n (only the last one) // \5 MP // \6 item list // \7 HP if (includeFilter.Attack) { var Patt_ActtackDetails = Local.Pattern_Active_AttackDetails; result = Patt_ActtackDetails.exec(Str); if (result === null) { DbgMsgAction(Info, "ActiveInfo (ActtackDetails): " + Node.innerHTML); return false; } active.Skill = new CSkill(Node.childNodes[nStartNode]); active.gAttackRoll = []; active.gPosition = new CKeyList(); if (result[1] != null) { active.gAttackRoll.push(Number(result[1])); active.gPosition.push(new CPositionType('')); } if (result[2] != null) { var pattern_pos_atk = /^([^\u0000-\u007F]+): ([\d]+)$/; var gPos_Atk = result[2].split('/'); for (var i = 1; i < gPos_Atk.length; ++i) { var inner_result = pattern_pos_atk.exec(gPos_Atk[i]); active.gAttackRoll.push(Number(inner_result[2])); active.gPosition.push(new CPositionType(inner_result[1])); } } active.nSkillMP = result[5] != null ? Number(result[5]) : null; active.nSkillHP = result[7] != null ? Number(result[7]) : null; if (result[6] != null) { active.gItem = new CKeyList(); nStartNode += result[5] != null ? 4 : 2; var ItemNode; while ((ItemNode = Node.childNodes[nStartNode]) != null) { if (ItemNode.tagName == 'A') { active.gItem.push(new CItem(ItemNode)); nStartNode += 2; } else { nStartNode++; } } } } return true; } case CActionType.HEAL: // heal case CActionType.BUFF: // buff { // \1 MP // \2 normal item list // \3 magical potion if ((includeFilter.Heal && active.ActionType.GetKind() === CActionType.HEAL) || (includeFilter.Buff && active.ActionType.GetKind() === CActionType.BUFF)) { var Patt_HealBuffDetails = Local.Pattern_Active_HealBuffDetails; result = Patt_HealBuffDetails.exec(Str); if (result === null) { DbgMsgAction(Info, "ActiveInfo (HealBuffDetails): " + Node.innerHTML); return false; } active.nSkillMP = result[1] != null ? Number(result[1]) : null; if (result[2] != null) { active.gItem = new CKeyList(); nStartNode += result[1] != null ? 2 : 0; var ItemNode; while ((ItemNode = Node.childNodes[nStartNode]) != null) { if (ItemNode.tagName == 'A') { active.gItem.push(new CItem(ItemNode)); nStartNode += 2; } else { nStartNode++; } } } else if (result[3] != null) { active.gItem = new CKeyList(); nStartNode += result[1] != null ? 2 : 0; active.gItem.push(new CItem(Node.childNodes[nStartNode])); // nStartNode: determine by the number of reagents } } return true; } default: // impossible, the value can only be 0, 1, or 2 return false; } } // return: whether the format is right function GetAttackedInfo(Node, Info) { if (Node === null) { DbgMsgAction(Info, "AttackedInfo: null"); return false; } var nStartNode = 0; var Str = Node.innerHTML; // \1 char span node // \2 char Id // \3 skill // \4 defence roll // \5 MP // \6 item list // \7 hit type // \8 struck down // \9 damage list // \10 item damage // \11 next flag var Patt_Attacked = Local.Pattern_Passive_Attacked; var bEnd = false; while (!bEnd) { var PassiveInfo = new CPassiveInfo(); var result = Patt_Attacked.exec(Str); if (result === null) { DbgMsgAction(Info, "AttackedInfo: " + Node.innerHTML); return true; } var CharNode = result[1] != null ? Node.childNodes[nStartNode].childNodes[0] : Node.childNodes[nStartNode]; PassiveInfo.Char = new CChar(CharNode); PassiveInfo.nCharId = result[2] != null ? Number(result[2]) : null; nStartNode += result[1] != null ? 1 : (result[2] != null ? 2 : 1); if (result[3] != null) { PassiveInfo.Skill = new CSkill(Node.childNodes[nStartNode + 1]); nStartNode += 2; } PassiveInfo.nDefenceRoll = Number(result[4]); if (result[5] != null) { PassiveInfo.nSkillMP = Number(result[5]); nStartNode += 2; } if (result[6] != null) { PassiveInfo.gItem = new CKeyList(); nStartNode += 1; var ItemNode = Node.childNodes[nStartNode]; while (ItemNode != null && ItemNode.nodeName == "A") { PassiveInfo.gItem.push(new CItem(ItemNode)); nStartNode += 2; ItemNode = Node.childNodes[nStartNode]; } } else nStartNode += 1; PassiveInfo.HitType = new CHitType(result[7]); PassiveInfo.bStruckDown = (result[8] != null); nStartNode += result[8] != null ? 2 : 1; if (result[9] != null) { PassiveInfo.gDamage = []; nStartNode += 1; var DamageNode = Node.childNodes[nStartNode]; while (DamageNode != null && (DamageNode.nodeType == Node.TEXT_NODE || (DamageNode.nodeName == "SPAN" && DamageNode.firstChild != null && DamageNode.firstChild.nodeType == Node.TEXT_NODE))) { PassiveInfo.gDamage.push(new CDamage(DamageNode)); nStartNode += 2; DamageNode = Node.childNodes[nStartNode]; } nStartNode -= 1; } if (result[10] != null) { PassiveInfo.DamagedItem = new CItem(Node.childNodes[nStartNode + 1]); PassiveInfo.nItemDamage = Number(result[10]); nStartNode += 3; } if (result[11] != null) nStartNode += 1; else bEnd = true; Info.gPassive.push(PassiveInfo); Str = Str.substring(result[0].length); } return true; } // return: whether the format is right function GetHealedBuffedInfo(Node, Info) { if (Node === null) { DbgMsgAction(Info, "HealedBuffedInfo: null"); return false; } var nStartNode = 0; var Str = Node.innerHTML; // \1 span node // \2 char Id // \3 self // \4 HP // \5 MP // \6 next flag var Patt_HealedBuffed = Local.Pattern_Passive_Healed_Buffed; var bEnd = false; while (!bEnd) { var PassiveInfo = new CPassiveInfo(); var result = Patt_HealedBuffed.exec(Str); if (result === null) { DbgMsgAction(Info, "HealedBuffedInfo: " + Node.innerHTML); return true; } if (result[3] != null) { PassiveInfo.Char = Info.Active.Char; PassiveInfo.nCharId = Info.Active.nCharId; } else { var CharNode = result[1] != null ? Node.childNodes[nStartNode].childNodes[0] : Node.childNodes[nStartNode]; PassiveInfo.Char = new CChar(CharNode); PassiveInfo.nCharId = result[2] != null ? Number(result[2]) : null; nStartNode += result[1] != null ? 1 : (result[2] != null ? 2 : 1); } PassiveInfo.nHealedHP = result[4] != null ? Number(result[4]) : null; PassiveInfo.nHealedMP = result[5] != null ? Number(result[5]) : null; nStartNode += 1; if (result[6] != null) nStartNode += 1; else bEnd = true; Info.gPassive.push(PassiveInfo); Str = Str.substring(result[0].length); } return true; } function DbgMsgAction(Info, Text) { if (DEBUG) alert("[" + Info.Navi.nLevel + "." + Info.Navi.nRoom + "." + Info.Navi.nRound + "." + Info.Navi.nRow + "] " + Text); } // GLOBAL VARIABLES /////////////////////////////////////////////////////////// var DEBUG = false; var groupData = false; var useFilter = true; var Contents = { OrigText_Button_DungeonDetails: ["details", "详细资料"], OrigText_Button_DuelDetails: ["Details", "详细"], OrigText_Button_DungeonStat: ["statistics", "统计表"], OrigText_Level: ["Level", "层数"], OrigText_LastRound: ["Last round:", "最后回合:"], OrigTextList_AttackActionType: [ [ "attacks", "ranged attacks", "attacks with magic", "socially attacks", "cunningly attacks", "activates on", "works as a force of nature upon", "infected", "casts an explosion at", "deactivated", "magic projectile", "curse", "scare", "other", ], [ "近战攻击", "远程攻击", "魔法攻击", "心理攻击", "偷袭", "触发", "作为自然灾害", "散布", "制造爆炸", "解除", "魔法投射", "诅咒", "恐吓", "冲击", "魔法弹", ], ], OrigTextList_HealActionType: [["heals with"], ["治疗"]], OrigTextList_BuffActionType: [ ["uses", "summons with"], ["使用", "召唤"], ], OrigTextList_WaitActionType: [ ["is unable to do anything.", "looks around in boredom and waits."], ["不能执行任何动作.", "无聊的打量四周,等待着."], ], OrigTextList_NoneHPDamageType: [ ["mana damage", "mana"], ["法力伤害", "法力"], ], Pattern_Ini: [ /^Initiative ([\d]+)<br><span .*?>Action ([\d]+) of ([\d]+)<\/span>$/, /^先攻([\d]+)<br><span .*?>第([\d]+)步行动 \/ 共([\d]+)步<\/span>$/, ], Pattern_Active_Char: [ /^(<span .*?>)?<a .*?>.*?<\/a>(?:<span .*?>([\d]+)<\/span>)?(?:<img .*?><\/span>)?/, /^(<span .*?>)?<a .*?>.*?<\/a>(?:<span .*?>([\d]+)<\/span>)?(?:<img .*?><\/span>)?/, ], Pattern_Active_Action1: [ /^\s*(?:([A-Za-z][A-Za-z ]+[A-Za-z]) +\(|([A-Za-z][A-Za-z ]+[A-Za-z]) +<a .*?>.*?<\/a>(?:( \()|$| on $))/, /^\s*(?:([^\u0000-\u007F]+) +\(|([^\u0000-\u007F]+)<a .*?>.*?<\/a>(?:( \()|$|给$))/, ], Pattern_Active_Action2: [ /^\s*([\S][^/(^/)]*[\S])([/(]([\d]+)[/)])?\s*$/, /^\s*([\S][^/(^/)]*[\S])([/(]([\d]+)[/)])?\s*$/, ], Pattern_Active_AttackDetails: [ /^<a .*?>.*?<\/a>(?:\/([\d]+)|(?:\/([A-Za-z ]+): ([\d]+))+)(?:\/<span .*?>([\d]+) MP<\/span>)?(\/(?:<a .*?>.*?<\/a>,)*<a .*?>.*?<\/a>)?\)$/, /^<a .*?>.*?<\/a>(?:\/([\d]+)|((?:\/([^\u0000-\u007F]+): ([\d]+))+))(?:\/<span .*?>([\d]+) (?:法力|神力|怒气|灵能|动力|魂能|动能|动能)<\/span>)?(\/(?:<a .*?>.*?<\/a>\s*(?:<img .*?>)*,)*<a .*?>.*?<\/a>\s*(?:<img .*?>)*)?(?:\/<span .*?>(?:<b>)?(?:-|\+)([\d]+) HP(?:<\/b>)?<\/span>)?(?:\/<span .*?>(?:<b>)?(?:-|\+)([\d]+) (?:法力|神力|怒气|灵能|动力|魂能|动能)(?:<\/b>)?<\/span>)?\)$/, ], Pattern_Active_HealBuffDetails: [ /^(?:<span .*?>([\d]+) MP<\/span>)?(?:\/)?(?:((<a .*?>.*?<\/a>,)*<a .*?>.*?<\/a>)|(<a .*?>.*?<\/a>\s+(?:<img .*?>)+))?\)(?: on )?$/, /^(?:<span .*?>(?:-|\+)?([\d]+) (?:法力|神力|怒气|灵能|动力|魂能|动能)<\/span>)?(?:\/)?(?:((<a .*?>.*?<\/a>\s*(?:<img .*?>)*,)*<a .*?>.*?<\/a>\s*(?:<img .*?>)*))?\)(?:给)?$/, ], Pattern_Passive_Attacked: [ /^(<span .*?>)?<a .*?>.*?<\/a>(?:<span .*?>([\d]+)<\/span>)?(?:<img .*?><\/span>)?\s*\((<a .*?>.*?<\/a>\/)?([\d]+)(?:\/<span .*?>([\d]+) MP<\/span>)?(\/(?:<a .*?>.*?<\/a>,)*<a .*?>.*?<\/a>)?\): <span class="([A-Za-z_]+)">[A-Za-z ]+<\/span>( - [A-Za-z ]+)?(<br>(?:<span .*?>)?(?:-)?[\d]+ (?:\[(?:\+|-)[\d]+\] )?[A-Za-z ]+(?:<img .*?><\/span>)?)*(?:<br><a .*?>.*?<\/a> -([\d]+) HP)?(?:(<br>)|$)/, /^(<span .*?>)?<a .*?>.*?<\/a>(?:<span .*?>([\d]+)<\/span>)?(?:<img .*?><\/span>)?\s*\((<a .*?>.*?<\/a>\/)?([\d]+)(?:\/<span .*?>([\d]+) (?:法力|神力|怒气|灵能|动力|魂能|动能)<\/span>)?(\/(?:<a .*?>.*?<\/a>\s*(?:<img .*?>)*,)*<a .*?>.*?<\/a>\s*(?:<img .*?>)*)?\): <span class="([A-Za-z_]+)">[^\u0000-\u007F]+<\/span>( - [^\u0000-\u007F]+ *)?(<br>(?:<span .*?>)?(?:-)?[\d]+ (?:\[(?:\+|-)[\d]+\] )?[^\u0000-\u007F]+(?:<img .*?><\/span>)?)*(?:<br><a .*?>.*?<\/a> (?:-|\+)([\d]+) HP)?(?:(<br>)|$)/, ], Pattern_BasicDamage: [/causes: <b>([\d]+)<\/b>/, /造成: <b>([\d]+)<\/b>/], Pattern_Damage: [ /^((?:-)?[\d]+) (?:\[((?:\+|-)[\d]+)\] )?([A-Za-z][A-Za-z ]+[A-Za-z])$/, /^((?:-)?[\d]+) (?:\[((?:\+|-)[\d]+)\] )?([^\u0000-\u007F]+)$/, ], Pattern_Passive_Healed_Buffed: [ /^(?:(<span .*?>)?<a .*?>.*?<\/a>(?:<span .*?>([\d]+)<\/span>)?(?:<img .*?><\/span>)?\s+|(themselves))(?: \+([\d]+) HP)?(?: \+([\d]+) MP)?(?:(<br>)|$)/, /^(?:(<span .*?>)?<a .*?>.*?<\/a>(?:<span .*?>([\d]+)<\/span>)?(?:<img .*?><\/span>)?\s+|(自己|自身))(?: \+([\d]+) HP)?(?: \+([\d]+) (?:法力|神力|怒气|灵能|动力|魂能|动能))?(?:(<br>)|$)/, ], Text_Button_ExtraStat: ["Extra Stat", "额外统计"], Text_Button_EntireStat: ["Entire Extra Stat", "全城额外统计"], Text_Button_Show: ["Show", "显示"], Text_Button_Hide: ["Hide", "隐藏"], Text_Button_ShowAll: ["Show All", "全部显示"], Text_Button_HideAll: ["Hide All", "全部隐藏"], Text_Button_Default: ["Default", "默认"], TextList_AttackType: [ [ "melee", "ranged", "spell", "social", "ambush", "trap", "nature", "disease", "detonate", "disarm trap", "magic projectile", "curse", "scare", "other", ], [ "近战", "远程", "魔法", "心理", "偷袭", "陷阱", "自然", "疾病", "爆破", "解除陷阱", "魔法投射", "诅咒", "恐吓", "冲击", "魔法弹", ], ], TextList_HealType: [["heal"], ["治疗"]], TextList_BuffType: [["buff"], ["使用"]], TextList_WaitType: [["wait"], ["等待"]], TextList_HitType: [ ["failed", "success", "good success", "critical success"], ["闪避", "普通", "重击", "致命一击"], ], Text_Loading: ["Loading", "载入中"], Text_Options: ["Options:", "选项:"], Text_DefaultMsg: [ "All the data this script stored in your machine has been cleared.", "此脚本储存在你的机器上的所有数据已被清除。", ], Text_Table_Ini: ["Initiative", "先攻权"], Text_Table_Attack: ["Attack", "攻击骰"], Text_Table_Defence: ["Defence", "防御骰"], Text_Table_Damage: ["Damage", "造成伤害"], Text_Table_Damaged: ["Damage", "受到伤害"], Text_Table_DamageType: ["Damage Type", "伤害类型"], Text_Table_HealType: ["Heal Type", "治疗类型"], Text_Table_BuffType: ["Buff Type", "增益类型"], Text_Table_Heal: ["Healing By The Hero", "给予治疗"], Text_Table_Healed: ["Healing On The Hero", "接受治疗"], Text_Table_Buff: ["Buffing By The Hero", "给予增益"], Text_Table_Buffed: ["Buffing On The Hero", "接受增益"], Text_Table_Buffer: ["Buffing Provider", "提供者"], Text_Table_BuffeReceiver: ["Buffing Receiver", "提供给"], Text_Table_DamagedItems: ["Damaged Items", "物品损坏"], Text_Table_Char: ["Character", "人物"], Text_Table_AttackType: ["Attack type", "攻击类型"], Text_Table_DefenceType: ["Defence type", "防御类型"], Text_Table_Skill: ["Skill", "技能"], Text_Table_Item: ["Item", "物品"], Text_Table_Position: ["Pos", "位置"], Text_Table_AvgRoll: ["Average roll", "平均值"], Text_Table_MaxRoll: ["Max roll", "Max值"], Text_Table_MinRoll: ["Min roll", "Min值"], Text_Table_STDRoll: ["STD roll", "STD值"], Text_Table_Total: ["Total", "总数"], Text_Table_Times: ["Times", "次数"], Text_Table_RollList: ["Roll list", "数值列表"], Text_Table_DetailList: ["Detail list", "详细列表"], Text_Table_ItemDamagePoints: ["Damage Points", "损坏点数"], Text_Table_AllData: ["All", "全部"], }; var Style = "div.stat_all {font-size:14px;} " + "div.stat_header {margin:1em auto 0.5em auto;} " + "span.stat_title {margin: auto 1em auto 0em; font-size:20px; font-weight:bold; color:#FFF;} span.clickable {cursor:pointer;} " + "span.pair_value {width:100%; font-size:12px;} span.pair_value span {width:50%; min-width:3em; text-align:right; color:#F8A400;} span.pair_value span + span {color:#00CC00;} " + "table.pair_hero {width:100%; font-size:12px;} table.pair_hero td {width:50%; min-width:3em; text-align:right; color:#00CC00;} table.pair_hero td + td {color:#F8A400;} " + "table[hide] {display:none;} " + "table.pair_value {width:100%;} table.pair_value td {width:50%; min-width:3em; text-align:right; color:#F8A400;} table.pair_value td + td {color:#00CC00;} " + "#myProgress {position: relative; width: 100%; height: 3px; background-color: #ddd;} " + "#myBar { position: absolute; width: 1%; height: 100%; background-color: #4CAF50;}"; var Local; var Stat; var includeFilter = { Init: true, Attack: true, Defence: true, Damage: true, Damaged: true, Heal: true, Healed: true, Buff: true, Buffed: true, DamagedItems: true }; var localInfo = document; var reportInfoDiv; var progress; var dataPage; var heroes = []; var heroLvMap = {}; if (typeof GM_addStyle == "undefined") { function GM_addStyle(styles) { var S = document.createElement("style"); S.type = "text/css"; var T = "" + styles + ""; T = document.createTextNode(T); S.appendChild(T); document.body.appendChild(S); return; } } var clickedButton; // FUNCTIONS ////////////////////////////////////////////////////////////////// function CreateStat(node, infoNode, isExport) { // Stat initialization includeFilter.Init = document.getElementById("chk_Text_Table_Ini").checked; includeFilter.Attack = document.getElementById( "chk_Text_Table_Attack" ).checked; includeFilter.Defence = document.getElementById( "chk_Text_Table_Defence" ).checked; includeFilter.Damage = document.getElementById( "chk_Text_Table_Damage" ).checked; includeFilter.Damaged = document.getElementById( "chk_Text_Table_Damaged" ).checked; includeFilter.Heal = document.getElementById( "chk_Text_Table_Heal" ).checked; includeFilter.Healed = document.getElementById( "chk_Text_Table_Healed" ).checked; includeFilter.Buff = document.getElementById( "chk_Text_Table_Buff" ).checked; includeFilter.Buffed = document.getElementById( "chk_Text_Table_Buffed" ).checked; includeFilter.DamagedItems = document.getElementById( "chk_Text_Table_DamagedItems" ).checked; var theStat = new CStat(node, infoNode); if (includeFilter.Init) theStat.RegInfoList(new CILIni(CVLNumber, isExport)); if (includeFilter.Attack) theStat.RegInfoList(new CILAttackRoll(CVLNumber, isExport)); if (includeFilter.Defence) theStat.RegInfoList(new CILDefenceRoll(CVLNumber, isExport)); if (includeFilter.Damage) theStat.RegInfoList(new CILDamage(CVLDamage, isExport)); if (includeFilter.Damaged) theStat.RegInfoList(new CILDamaged(CVLDamage, isExport)); if (includeFilter.Heal) theStat.RegInfoList(new CILHeal(CVLNumber, isExport)); if (includeFilter.Healed) theStat.RegInfoList(new CILHealed(CVLNumber, isExport)); if (includeFilter.Buff) theStat.RegInfoList(new CILBuff(CVLString, isExport)); if (includeFilter.Buffed) theStat.RegInfoList(new CILBuffed(CVLString, isExport)); if (includeFilter.DamagedItems) theStat.RegInfoList(new CILItemDamage(CVLNumber, isExport)); return theStat; } function Main() { // Language selection Local = GetLocalContents(Contents); if (Local === null) return; //GM_log(Local); // Add CSS GM_addStyle(Style); // Add buttons var KeyButton = AddButtonBesideDisabledButton( [ Local.OrigText_Button_DungeonDetails, Local.Text_Button_ExtraStat, OnCountStat, ], [ Local.OrigText_Button_DungeonStat, Local.Text_Button_EntireStat, OnCountEntireStat, ], [ Local.OrigText_Button_DuelDetails, Local.Text_Button_ExtraStat, OnCountStat, ] ); if (KeyButton === null) return; KeyButton = addFilter(KeyButton); addStatusBar(KeyButton); dataPage = document.createElement("div"); dataPage.innerHTML = ""; } function addStatusBar(node) { var progressDiv = document.createElement("div"); progressDiv.id = "myProgress"; reportInfoDiv = document.createElement("div"); reportInfoDiv.id = "myBar"; progressDiv.appendChild(reportInfoDiv); node.parentNode.insertBefore(progressDiv, node.nextSibling); } function hideFilter() { // 隐藏复选项 var AllFilter = document.getElementsByName("ExtraFilter"); for (var i = 0, l = AllFilter.length; i < l; i++) { AllFilter[i].style.display = "none"; } } function addFilter(KeyButton) { if (isaddFilter) { //首次执行插入复选项 var newLine = document.createElement("br"); newLine.setAttribute("name", "ExtraFilter"); KeyButton = KeyButton.parentNode.insertBefore( newLine, KeyButton.nextSibling ); var newSpan = document.createElement("span"); newSpan.innerHTML = "选择要统计的项目:"; newSpan.setAttribute("name", "ExtraFilter"); KeyButton = KeyButton.parentNode.insertBefore( newSpan, KeyButton.nextSibling ); //先攻 var newCheckBox = document.createElement("input"); newCheckBox.setAttribute("type", "checkbox"); newCheckBox.setAttribute("class", "checkbox"); newCheckBox.setAttribute("value", ""); newCheckBox.setAttribute("name", "ExtraFilter"); if (includeFilter.Init) newCheckBox.setAttribute("checked", "true"); newCheckBox.id = "chk_Text_Table_Ini"; KeyButton = KeyButton.parentNode.insertBefore( newCheckBox, KeyButton.nextSibling ); newSpan = document.createElement("label"); newSpan.innerHTML = Local.Text_Table_Ini; newSpan.setAttribute("name", "ExtraFilter"); newSpan.setAttribute("for", newCheckBox.id); KeyButton = KeyButton.parentNode.insertBefore( newSpan, KeyButton.nextSibling ); //攻击骰 newCheckBox = document.createElement("input"); newCheckBox.setAttribute("type", "checkbox"); newCheckBox.setAttribute("class", "checkbox"); newCheckBox.setAttribute("value", ""); if (includeFilter.Attack) newCheckBox.setAttribute("checked", "true"); newCheckBox.id = "chk_Text_Table_Attack"; newCheckBox.setAttribute("name", "ExtraFilter"); KeyButton = KeyButton.parentNode.insertBefore( newCheckBox, KeyButton.nextSibling ); newSpan = document.createElement("label"); newSpan.innerHTML = Local.Text_Table_Attack; newSpan.setAttribute("name", "ExtraFilter"); newSpan.setAttribute("for", newCheckBox.id); KeyButton = KeyButton.parentNode.insertBefore( newSpan, KeyButton.nextSibling ); //防御骰 newCheckBox = document.createElement("input"); newCheckBox.setAttribute("type", "checkbox"); newCheckBox.setAttribute("class", "checkbox"); newCheckBox.setAttribute("value", ""); if (includeFilter.Defence) newCheckBox.setAttribute("checked", "true"); newCheckBox.id = "chk_Text_Table_Defence"; newCheckBox.setAttribute("name", "ExtraFilter"); KeyButton = KeyButton.parentNode.insertBefore( newCheckBox, KeyButton.nextSibling ); newSpan = document.createElement("label"); newSpan.innerHTML = Local.Text_Table_Defence; newSpan.setAttribute("name", "ExtraFilter"); newSpan.setAttribute("for", newCheckBox.id); KeyButton = KeyButton.parentNode.insertBefore( newSpan, KeyButton.nextSibling ); //造成伤害 newCheckBox = document.createElement("input"); newCheckBox.setAttribute("type", "checkbox"); newCheckBox.setAttribute("class", "checkbox"); newCheckBox.setAttribute("value", ""); if (includeFilter.Damage) newCheckBox.setAttribute("checked", "true"); newCheckBox.id = "chk_Text_Table_Damage"; newCheckBox.setAttribute("name", "ExtraFilter"); KeyButton = KeyButton.parentNode.insertBefore( newCheckBox, KeyButton.nextSibling ); newSpan = document.createElement("label"); newSpan.innerHTML = Local.Text_Table_Damage; newSpan.setAttribute("name", "ExtraFilter"); newSpan.setAttribute("for", newCheckBox.id); KeyButton = KeyButton.parentNode.insertBefore( newSpan, KeyButton.nextSibling ); //受到伤害 newCheckBox = document.createElement("input"); newCheckBox.setAttribute("type", "checkbox"); newCheckBox.setAttribute("class", "checkbox"); newCheckBox.setAttribute("value", ""); if (includeFilter.Damaged) newCheckBox.setAttribute("checked", "true"); newCheckBox.id = "chk_Text_Table_Damaged"; newCheckBox.setAttribute("name", "ExtraFilter"); KeyButton = KeyButton.parentNode.insertBefore( newCheckBox, KeyButton.nextSibling ); newSpan = document.createElement("label"); newSpan.innerHTML = Local.Text_Table_Damaged; newSpan.setAttribute("name", "ExtraFilter"); newSpan.setAttribute("for", newCheckBox.id); KeyButton = KeyButton.parentNode.insertBefore( newSpan, KeyButton.nextSibling ); //给予治疗 newCheckBox = document.createElement("input"); newCheckBox.setAttribute("type", "checkbox"); newCheckBox.setAttribute("class", "checkbox"); newCheckBox.setAttribute("value", ""); if (includeFilter.Heal) newCheckBox.setAttribute("checked", "true"); newCheckBox.id = "chk_Text_Table_Heal"; newCheckBox.setAttribute("name", "ExtraFilter"); KeyButton = KeyButton.parentNode.insertBefore( newCheckBox, KeyButton.nextSibling ); newSpan = document.createElement("label"); newSpan.innerHTML = Local.Text_Table_Heal; newSpan.setAttribute("name", "ExtraFilter"); newSpan.setAttribute("for", newCheckBox.id); KeyButton = KeyButton.parentNode.insertBefore( newSpan, KeyButton.nextSibling ); //接受治疗 newCheckBox = document.createElement("input"); newCheckBox.setAttribute("type", "checkbox"); newCheckBox.setAttribute("class", "checkbox"); newCheckBox.setAttribute("value", ""); if (includeFilter.Healed) newCheckBox.setAttribute("checked", "true"); newCheckBox.id = "chk_Text_Table_Healed"; newCheckBox.setAttribute("name", "ExtraFilter"); KeyButton = KeyButton.parentNode.insertBefore( newCheckBox, KeyButton.nextSibling ); newSpan = document.createElement("label"); newSpan.innerHTML = Local.Text_Table_Healed; newSpan.setAttribute("name", "ExtraFilter"); newSpan.setAttribute("for", newCheckBox.id); KeyButton = KeyButton.parentNode.insertBefore( newSpan, KeyButton.nextSibling ); //给予增益 newCheckBox = document.createElement("input"); newCheckBox.setAttribute("type", "checkbox"); newCheckBox.setAttribute("class", "checkbox"); newCheckBox.setAttribute("value", ""); if (includeFilter.Buff) newCheckBox.setAttribute("checked", "true"); newCheckBox.id = "chk_Text_Table_Buff"; newCheckBox.setAttribute("name", "ExtraFilter"); KeyButton = KeyButton.parentNode.insertBefore( newCheckBox, KeyButton.nextSibling ); newSpan = document.createElement("label"); newSpan.innerHTML = Local.Text_Table_Buff; newSpan.setAttribute("name", "ExtraFilter"); newSpan.setAttribute("for", newCheckBox.id); KeyButton = KeyButton.parentNode.insertBefore( newSpan, KeyButton.nextSibling ); //接受增益 newCheckBox = document.createElement("input"); newCheckBox.setAttribute("type", "checkbox"); newCheckBox.setAttribute("class", "checkbox"); newCheckBox.setAttribute("value", ""); if (includeFilter.Buffed) newCheckBox.setAttribute("checked", "true"); newCheckBox.id = "chk_Text_Table_Buffed"; newCheckBox.setAttribute("name", "ExtraFilter"); KeyButton = KeyButton.parentNode.insertBefore( newCheckBox, KeyButton.nextSibling ); newSpan = document.createElement("label"); newSpan.innerHTML = Local.Text_Table_Buffed; newSpan.setAttribute("name", "ExtraFilter"); newSpan.setAttribute("for", newCheckBox.id); KeyButton = KeyButton.parentNode.insertBefore( newSpan, KeyButton.nextSibling ); //物品损坏 newCheckBox = document.createElement("input"); newCheckBox.setAttribute("type", "checkbox"); newCheckBox.setAttribute("class", "checkbox"); newCheckBox.setAttribute("value", ""); if (includeFilter.DamagedItems) newCheckBox.setAttribute("checked", "true"); newCheckBox.id = "chk_Text_Table_DamagedItems"; newCheckBox.setAttribute("name", "ExtraFilter"); KeyButton = KeyButton.parentNode.insertBefore( newCheckBox, KeyButton.nextSibling ); newSpan = document.createElement("label"); newSpan.innerHTML = Local.Text_Table_DamagedItems; newSpan.setAttribute("name", "ExtraFilter"); newSpan.setAttribute("for", newCheckBox.id); KeyButton = KeyButton.parentNode.insertBefore( newSpan, KeyButton.nextSibling ); isaddFilter = false; return KeyButton; } else { //多次执行重新显示复选项 var AllFilter = document.getElementsByName("ExtraFilter"); for (var i = 0, l = AllFilter.length; i < l; i++) { AllFilter[i].style.display = ""; } return KeyButton; } } // It will only add the first eligible button // return: the node of the first eligible disabled button, or null if didn't find anyone function AddButtonBesideDisabledButton(/* [DisabledButtonText, ButtonText, ClickEvent], [...], ... */) { var allInputs = document.getElementsByTagName("input"); for (var i = 0; i < allInputs.length; ++i) { if (allInputs[i].className == "button_disabled") { for (var j = 0; j < arguments.length; ++j) { if (allInputs[i].getAttribute("value") == arguments[j][0]) { return AddButton(allInputs[i], arguments[j][1], arguments[j][2]); } } } } return null; } // Add a button to the end of the given node's parent node function AddButton(SiblingNode, Value, OnClick) { var newButton = document.createElement("input"); newButton.setAttribute("type", "button"); newButton.setAttribute("class", "button"); newButton.setAttribute("value", Value); newButton.addEventListener("click", OnClick, false); var newBlank = document.createTextNode(" "); SiblingNode.parentNode.appendChild(newBlank); SiblingNode.parentNode.appendChild(newButton); return newButton; } function OnCountStat() { try { clickedButton = this; if (this.className == "button_disabled") return; else this.className = "button_disabled"; var InfoDiv = document.createElement("div"); InfoDiv.id = "report_info"; Stat = CreateStat(node_after(this.parentNode), InfoDiv, false); reportInfoDiv.style.width = "1%"; Stat.nTotalPages = 1; //Stat.nReadPages = 1; Stat.iscurrentPage = true; Stat.ShowProgress(); if (progress) clearInterval(progress); progress = setInterval(Stat.ShowProgress.bind(Stat), 1); ReadPage(document, true); } catch (e) { alert("OnCountStat(): " + e); } } function OnCountEntireStat() { try { clickedButton = this; if (this.className == "button_disabled") return; else this.className = "button_disabled"; var InfoDiv = document.createElement("div"); InfoDiv.id = "report_Entire_info"; Stat = CreateStat(node_after(this.parentNode), InfoDiv, false); reportInfoDiv.style.width = "1%"; CountEntireStat(); } catch (e) { alert("OnCountEntireStat(): " + e); } } function CountEntireStat() { var nCurrRepId = GetHiddenInfo(document, "report_id[0]", ""); var nMaxLevel = (Stat.nTotalPages = GetStatPageMaxLevel(document, 1)); Stat.ShowProgress(); if (progress) clearInterval(progress); progress = setInterval(Stat.ShowProgress.bind(Stat), 1); for (var CurrLevel = 1; CurrLevel <= nMaxLevel; ++CurrLevel) GetPage(nCurrRepId, CurrLevel, 1, true); //Stat.ShowProgress(); } function GetPage(nRepId, nLevel, nRepPage, bFirstRead) { var XmlHttp = new XMLHttpRequest(); XmlHttp.onreadystatechange = function () { try { if (XmlHttp.readyState == 4 && XmlHttp.status == 200) { dataPage.innerHTML = XmlHttp.responseText; //Stat.nReadPages = nRepPage; Stat.iscurrentPage = false; ReadPage(dataPage, bFirstRead); } } catch (e) { alert("XMLHttpRequest.onreadystatechange(): " + e); } }; var URL = location.protocol + "//" + location.host + "/wod/spiel/dungeon/report.php" + "?cur_rep_id=" + nRepId + "&gruppe_id=¤t_level=" + nLevel + "&REPORT_PAGE=" + nRepPage + "&IS_POPUP=1"; Stat.ShowProgress(); XmlHttp.open("GET", URL, true); XmlHttp.send(null); } function ReadPage(page, bFirstRead) { var ret = GetRepPageInfo(page, [1, 1]); var nCurrRepPage = ret[0]; var nMaxRepPage = ret[1]; if (bFirstRead && nMaxRepPage > 1) { var nRepId = GetHiddenInfo(page, "report_id[0]", ""); var nLevel = GetHiddenInfo(page, "current_level", 1); Stat.nTotalPages += nMaxRepPage - 1; for (var i = 1; i <= nMaxRepPage; ++i) { Stat.ShowProgress(); if (i !== nCurrRepPage) GetPage(nRepId, nLevel, i, false); } } Stat.nReadPages++; Stat.ShowProgress(); CountStat(page, nCurrRepPage === nMaxRepPage); if (Stat.nReadPages >= Stat.nTotalPages) { Stat.Show(false); if (clickedButton) clickedButton.className = "button"; } } function GetHiddenInfo(page, InfoName, DefaultValue) { var allInputs = page.getElementsByTagName("input"); for (var i = 0; i < allInputs.length; ++i) { if ( allInputs[i].getAttribute("type") == "hidden" && allInputs[i].name == InfoName ) return allInputs[i].value; } return DefaultValue; } function GetStatPageMaxLevel(page, DefaultValue) { var allTds = page.getElementsByTagName("td"); for (var i = 0; i < allTds.length; ++i) { if (first_child(allTds[i].parentNode) != allTds[i]) continue; var LevelNode = first_child(allTds[i]); if ( LevelNode != null && LevelNode.nodeType == Node.TEXT_NODE && LevelNode.data == Local.OrigText_Level ) { var Patt_Level = /^(?:<span .*?>)?(?:[\d]+)\/([\d]+)(?:<\/span>)?$/; var result = Patt_Level.exec(node_after(allTds[i]).innerHTML); if (result === null) return DefaultValue; return Number(result[1]); } } return DefaultValue; } // return: an array, [0]: nCurrRepPage, [1]: nMaxRepPage function GetRepPageInfo(page, DefaultValue) { var ret = [DefaultValue[0], DefaultValue[1]]; var allInputs = page.getElementsByTagName("input"); var IndexPatt = /\D*([\d]+)\D*/; var pages = []; for (var i = 0; i < allInputs.length; ++i) { var theInput = allInputs[i]; if (theInput.className == "paginator_selected clickable") { var Result = IndexPatt.exec(theInput.value); if (Result && Result[1]) { pages.push(Number(Result[1])); ret[0] = Number(Result[1]); } } } allInputs = page.getElementsByTagName("a"); for (var i = 0; i < allInputs.length; ++i) { var theInput = allInputs[i]; if (theInput.className == "paginator") { var Result = IndexPatt.exec(theInput.textContent); if (Result && Result[1]) pages.push(Number(Result[1])); } } if (pages.length > 0) ret[1] = Math.max.apply(Math, pages); return ret; } //=============================================================================================== // code for save report only. //=============================================================================================== var StatEntire; var StatEntireDiv; function es_addStyle(page, styles) { var S = document.createElement("style"); S.type = "text/css"; var T = "" + styles + ""; T = document.createTextNode(T); S.appendChild(T); page.appendChild(S); return; } function InsertButton(Node, Value, OnClick) { var newButton = document.createElement("input"); newButton.setAttribute("type", "button"); newButton.setAttribute("class", "button"); newButton.setAttribute("value", Value); newButton.addEventListener("click", OnClick, false); Node.parentNode.insertBefore(newButton, Node.nextSibling); } function changeAllSelection(select) { var allCheckbox = document.getElementsByTagName("input"); for (var i = 0; i < allCheckbox.length; ++i) { var theCheckbox = allCheckbox[i]; if ( rValue.Pattern_checkboxName.test(theCheckbox.getAttribute("name")) ) { theCheckbox.checked = select; } } } function selectAll() { if (!gIsWorking) changeAllSelection(true); } function cleartAll() { if (!gIsWorking) changeAllSelection(false); } function getTimeStrFromWodTimeStr(report) { if (report == null) { return; } let timestr = $(report.getAttribute("reporttime")).text(); const today = dayjs(); if (timestr.includes("昨天")) { timestr = timestr.replace( "昨天", today.subtract(1, "d").format("YYYY年MM月DD日") ); } else if (timestr.includes("今天")) { timestr = timestr.replace("今天", today.format("YYYY年MM月DD日")); } else if (timestr.includes("明天")) { timestr = timestr.replace( "明天", today.add(1, "d").format("YYYY年MM月DD日") ); } return timestr; } function parseTime(timeStr) { timeStr = timeStr.replace("年", "-").replace("月", "-").replace("日", ""); return dayjs(timeStr, "YYYY-MM-DD HH:mm"); } function getTimeFromWodTimeStr(report) { const timestr = getTimeStrFromWodTimeStr(report); return parseTime(timestr); } function formatTime(date, format) { return date.format(format); } function formatTime4report(report, format) { return formatTime(getTimeFromWodTimeStr(report), format); } function getOverviewDiv() { let $overviewDiv = $("div#overview"); if (!$overviewDiv.length) { $("body:first").append( $( '<div style="visibility: hidden;"><div id="overview"><div id="progressbar"><div class="progress-label">初始化...</div></div><div id="detailMsg"></div></div></div>' ) ); $overviewDiv = $("div#overview"); } return $overviewDiv; } function exportLog() { if (gIsWorking && !DEBUG) return; gIsWorking = true; // 获取前缀 var prefix = document.getElementById("prefix").value; var timeFormatSuffix = document.getElementById("suffix").value; var includeCheckbox = document.getElementById(rValue.Chk_includeData); var singleCheckbox = document.getElementById(rValue.Chk_single); var withLvCheckbox = document.getElementById(rValue.Chk_withLv); var singleCheck = singleCheckbox.checked; includeData = includeCheckbox.checked; gWithLv = withLvCheckbox.checked; var allCheckbox = document.getElementsByTagName("input"); // 单文件导出走特殊流程 if (singleCheck) { gIsWorking = false; let $overviewDiv = getOverviewDiv(); let $processbar = $overviewDiv.find("#progressbar"); let $processLabel = $overviewDiv.find("#progressbar .progress-label"); let $detailMsg = $overviewDiv.find("#detailMsg"); $overviewDiv.dialog({ autoOpen: true, // 是否自动弹出窗口 modal: true, // 设置为模态对话框 resizable: true, width: 540, //弹出框宽度 height: 620, //弹出框高度 title: "导出进度", //弹出框标题 position: { my: "center", at: "center", of: window }, //窗口显示的位置 buttons: { 关闭: function () { $(this).dialog("close"); }, }, }); $processbar.progressbar({ value: false, change: function () { $processLabel.text($processbar.progressbar("value") + "%"); }, complete: function () { $processLabel.text("任务已全部完成!"); }, }); let total = 0; let remain = 0; // 设置定时任务,每秒检测导出进度 var interval = setInterval(function () { $detailMsg.html($("#infoDiv").html()); if (!gIsWorking) { allCheckbox = document.getElementsByTagName("input"); allCheckbox = Array.prototype.slice .call(allCheckbox) .filter( (c) => rValue.Pattern_checkboxName.test(c.getAttribute("name")) && c.checked ); if (allCheckbox.length) { gIsWorking = true; if (total < allCheckbox.length) total = allCheckbox.length; remain = allCheckbox.length; var report = allCheckbox[0]; gSelectedReport = [report]; heroes = []; heroLvMap = {}; default_gTitle = prefix + (gWithLv ? rValue.Holder_Lv : "") + report .getAttribute("reportname") .replace(/<[^>]+>/g, "") .replace(/[ ]|[\r\n\t]/g, ""); if (timeFormatSuffix) { var firstTimeStr = formatTime4report(report, timeFormatSuffix); default_gTitle += firstTimeStr; } gTitle = default_gTitle; // 更新进度 $processbar.progressbar( "value", parseFloat((((total - remain) * 100) / total).toFixed(0)) ); gZip = new JSZip(); headDiv = document .getElementsByTagName("head")[0] .cloneNode(true); handleHead(headDiv); gIndexDiv = gIndexTemplateDiv.cloneNode(true); var table = document.createElement("div"); gCurrentReport = gSelectedReport[0]; if (includeData) { StatEntireDiv = document.createElement("div"); var EntireInfoDiv = document.createElement("div"); EntireInfoDiv.id = "report_entire_info"; StatEntire = CreateStat(StatEntireDiv, EntireInfoDiv, true); StatEntire.iscurrentPage = false; } if (!isDuel) GetLevelPage(1, 1); else GetDuelPage(); } else { clearInterval(interval); $overviewDiv.dialog("close"); } } }, 1000); return; } gSelectedReport = []; for (var i = 0; i < allCheckbox.length; ++i) { var theCheckbox = allCheckbox[i]; if ( rValue.Pattern_checkboxName.test(theCheckbox.getAttribute("name")) ) { if (theCheckbox.checked) { gSelectedReport.push(theCheckbox); default_gTitle = prefix + (gWithLv ? rValue.Holder_Lv : "") + theCheckbox .getAttribute("reportname") .replace(/<[^>]+>/g, "") .replace(/[ ]|[\r\n\t]/g, ""); // 获取前缀和最下面勾选的战报名字作为默认,正则去除html标签,空格,换行,制表符 } } } if (gSelectedReport.length > 0) { heroes = []; heroLvMap = {}; // 处理后缀 if (timeFormatSuffix) { var firstReport = gSelectedReport[0]; var lastReport = gSelectedReport[gSelectedReport.length - 1]; var firstTimeStr = formatTime4report(firstReport, timeFormatSuffix); var lastTimeStr = formatTime4report(lastReport, timeFormatSuffix); default_gTitle += firstTimeStr; if (firstReport != lastReport && firstTimeStr != lastTimeStr) { default_gTitle += "-" + lastTimeStr; } } gTitle = window.prompt("输入战报名称", default_gTitle); if (gTitle != null) { gZip = new JSZip(); headDiv = document.getElementsByTagName("head")[0].cloneNode(true); handleHead(headDiv); gIndexDiv = gIndexTemplateDiv.cloneNode(true); var table = document.createElement("div"); gCurrentReport = gSelectedReport[0]; if (includeData) { StatEntireDiv = document.createElement("div"); var EntireInfoDiv = document.createElement("div"); EntireInfoDiv.id = "report_entire_info"; StatEntire = CreateStat(StatEntireDiv, EntireInfoDiv, true); StatEntire.iscurrentPage = false; } if (!isDuel) GetLevelPage(1, 1); else GetDuelPage(); } else gIsWorking = false; } else { window.alert("没有选择任何战报"); gIsWorking = false; } } function GetDuelPage() { var XmlHttp = new XMLHttpRequest(); XmlHttp.onreadystatechange = function () { try { if (XmlHttp.readyState == 4 && XmlHttp.status == 200) { gResponseDiv.innerHTML = XmlHttp.responseText; ReadDuelPage(); } } catch (e) { alert("GetLevelPage XMLHttpRequest.onreadystatechange(): " + e); } }; XmlHttp.open( "GET", gCurrentReport.getAttribute("href") + "&IS_POPUP=1¤t_view[1]", true ); XmlHttp.send(null); } function ReadDuelPage() { var rows = gIndexDiv.getElementsByTagName("tr"); var row = rows[rows.length - 1]; row.parentNode.appendChild(row.cloneNode(true)); row.setAttribute("class", gIndexRowclass); if (gIndexRowclass == "row0") gIndexRowclass = "row1"; else gIndexRowclass = "row0"; row.cells[0].innerHTML = replaceDate(gCurrentReport.getAttribute("c0")); row.cells[1].innerHTML = gCurrentReport.getAttribute("c1"); row.cells[2].innerHTML = gCurrentReport.getAttribute("reporttime"); var cell = row.cells[3]; cell.innerHTML = ""; addIndexNewButton( cell, "细节", "document.location.href='" + gCurrentReport.value + "/detail.html';" ); if (includeData) { var EntireInfoDiv = document.createElement("div"); EntireInfoDiv.id = "report_entire_info"; Stat = CreateStat( node_before(gResponseDiv.getElementsByTagName("h2")[0].nextSibling), EntireInfoDiv, true ); Stat.nTotalPages = 1; Stat.iscurrentPage = true; } multiPageDiv.push(gResponseDiv); infodiv.innerHTML = "保存决斗: " + gTitle; if (includeData) CountStat(gResponseDiv, true, true); for (var i = 0; i < multiPageDiv.length; i++) { var thepage = multiPageDiv[i]; var theFileName = gCurrentReport.value + "/detail.html"; if (i > 0) { theFileName = gCurrentReport.value + "/detail_" + (i + 1) + ".html"; Stat.iscurrentPage = false; } if (includeData) { Stat.setNode( node_before(thepage.getElementsByTagName("h1")[0].nextSibling) ); Stat.Show(true); } gZip.file(theFileName, handlePage(thepage, null)); } multiPageDiv = []; gCurrentReport.checked = false; for (var i = 0; i < gSelectedReport.length; ++i) { var theCheckbox = gSelectedReport[i]; if (theCheckbox.checked) { gCurrentReport = theCheckbox; if (includeData) { StatEntireDiv = document.createElement("div"); var EntireInfoDiv = document.createElement("div"); EntireInfoDiv.id = "report_entire_info"; StatEntire = CreateStat(StatEntireDiv, EntireInfoDiv, true); StatEntire.iscurrentPage = false; } GetDuelPage(); return; } } handleIndexPage(); infodiv.innerHTML = "保存决斗战报: " + gTitle + "<br/>" + gCurrentReport.getAttribute("title"); var indexStr = "<html>\n" + headDiv.outerHTML + "\n<body>\n<h1>" + gTitle + "</h1><br/>\n" + gIndexDiv.innerHTML + "\n</body>\n</html>"; gZip.file("index.html", indexStr); gZip .generateAsync({ type: "blob", compression: "DEFLATE", compressionOptions: { level: 7 }, }) .then(function (content) { //saveAs(content, "wodlog" + '_' + Math.random().toString(36).substr(2, 9) + ".zip"); saveAs(content, "wodlog" + "_" + gTitle + ".zip"); }); // alert("zip文件生成完毕"); console.log("zip文件生成完毕"); infodiv.innerHTML = ""; gResponseDiv.innerHTML = ""; gIsWorking = false; } function GetLevelPage(nLevel, nRepPage) { var XmlHttp = new XMLHttpRequest(); XmlHttp.onreadystatechange = function () { try { if (XmlHttp.readyState == 4 && XmlHttp.status == 200) { gResponseDiv.innerHTML = XmlHttp.responseText; ReadLevelPage(nLevel, nRepPage); } } catch (e) { alert("GetLevelPage XMLHttpRequest.onreadystatechange(): " + e); } }; var URL = location.protocol + "//" + location.host + "/wod/spiel/dungeon/report.php" + "?cur_rep_id=" + gCurrentReport.value + "&gruppe_id=¤t_level=" + nLevel + "&REPORT_PAGE=" + nRepPage + "&IS_POPUP=1"; XmlHttp.open("GET", URL, true); XmlHttp.send(null); } function ReadLevelPage(nLevel, nRepPage) { if (nLevel == 1) { gCurrentReport.setAttribute("maxLevel", GetMaxLevel(gResponseDiv, 1)); var rows = gIndexDiv.getElementsByTagName("tr"); var row = rows[rows.length - 1]; row.parentNode.appendChild(row.cloneNode(true)); row.setAttribute("class", gIndexRowclass); if (gIndexRowclass == "row0") gIndexRowclass = "row1"; else gIndexRowclass = "row0"; row.cells[0].innerHTML = replaceDate( gCurrentReport.getAttribute("reporttime") ); row.cells[1].innerHTML = gCurrentReport.getAttribute("reportname"); var cell = row.cells[2]; cell.innerHTML = ""; addIndexNewButton( cell, "统计表", "document.location.href='" + gCurrentReport.value + "/statistics.html';" ); addIndexNewButton( cell, "获得物品", "document.location.href='" + gCurrentReport.value + "/items.html';" ); for (var i = 1; i <= gCurrentReport.getAttribute("maxLevel"); i++) { addIndexNewButton( cell, "层 " + i, "document.location.href='" + gCurrentReport.value + "/level" + i + ".html';" ); } } var ret = GetRepPageInfo(gResponseDiv, [1, 1]); var nCurrRepPage = ret[0]; var nMaxRepPage = ret[1]; if (includeData && nCurrRepPage == 1) { var EntireInfoDiv = document.createElement("div"); EntireInfoDiv.id = "report_entire_info"; Stat = CreateStat( node_before(gResponseDiv.getElementsByTagName("h2")[0].nextSibling), EntireInfoDiv, true ); Stat.nTotalPages = nMaxRepPage; Stat.iscurrentPage = true; } if (nMaxRepPage > 1) { var copyDiv = document.createElement("div"); copyDiv.innerHTML = gResponseDiv.innerHTML; multiPageDiv.push(copyDiv); if (includeData) Stat.iscurrentPage = false; } else multiPageDiv.push(gResponseDiv); var maxLevel = gCurrentReport.getAttribute("maxLevel"); infodiv.innerHTML = "保存战报: " + gTitle + "<br/>" + gCurrentReport.getAttribute("title") + " - 第 " + nLevel + "/" + maxLevel + " 层详细资料"; if (includeData) CountStat(gResponseDiv, nCurrRepPage === nMaxRepPage, true); if (nCurrRepPage === nMaxRepPage) { for (var i = 0; i < multiPageDiv.length; i++) { var thepage = multiPageDiv[i]; var theFileName = gCurrentReport.value + "/level" + nLevel + ".html"; if (i > 0) { theFileName = gCurrentReport.value + "/level" + nLevel + "_" + (i + 1) + ".html"; if (includeData) Stat.iscurrentPage = false; } if (includeData) { Stat.setNode( node_before(thepage.getElementsByTagName("h2")[0].nextSibling) ); Stat.Show(true); } gZip.file(theFileName, handlePage(thepage, nLevel)); } multiPageDiv = []; } if (nCurrRepPage < nMaxRepPage) GetLevelPage(nLevel, nCurrRepPage + 1); else if (nLevel < maxLevel) GetLevelPage(nLevel + 1, 1); else GetStatPage(); } function GetStatPage() { var queryString = $("form[name='the_form']").formSerialize() + "&IS_POPUP=1&" + gCurrentReport.getAttribute(rValue.Text_Stat) + "=" + rValue.Text_Stat; var XmlHttp = new XMLHttpRequest(); XmlHttp.onreadystatechange = function () { try { if (XmlHttp.readyState == 4 && XmlHttp.status == 200) { gResponseDiv.innerHTML = XmlHttp.responseText; infodiv.innerHTML = "保存战报: " + gTitle + "<br/>" + gCurrentReport.getAttribute("title") + " - 统计表"; if (includeData) { StatEntire.setNode( node_before( gResponseDiv.getElementsByTagName("h2")[0].nextSibling ) ); StatEntire.Show(true); } gZip.file( gCurrentReport.value + "/statistics.html", handlePage(gResponseDiv) ); GetItemPage(); } } catch (e) { alert("GetItemPage XMLHttpRequest.onreadystatechange(): " + e); } }; var URL = location.protocol + "//" + location.host + "/wod/spiel/dungeon/report.php"; XmlHttp.open("POST", URL, true); XmlHttp.setRequestHeader( "Content-type", "application/x-www-form-urlencoded" ); // XmlHttp.setRequestHeader("Content-length", queryString.length); // XmlHttp.setRequestHeader("Connection", "close"); XmlHttp.send(queryString); } function getAvgLvTip() { if (!heroes.length) { return ""; } let finalMap = {}; for (let heroName of heroes) { heroLvMap[heroName] && (finalMap[heroName] = parseInt(heroLvMap[heroName])); } let avgLv = Math.round( (100 * Object.values(finalMap).reduce((a, b) => a + b)) / Object.keys(finalMap).length ) / 100; return "「" + avgLv.toFixed(2) + "级」"; } function GetItemPage() { var queryString = $("form[name='the_form']").formSerialize() + "&IS_POPUP=1&" + gCurrentReport.getAttribute(rValue.Text_Item) + "=" + rValue.Text_Item; var XmlHttp = new XMLHttpRequest(); XmlHttp.onreadystatechange = function () { try { if (XmlHttp.readyState == 4 && XmlHttp.status == 200) { gResponseDiv.innerHTML = XmlHttp.responseText; infodiv.innerHTML = "保存战报: " + gTitle + "<br/>" + gCurrentReport.getAttribute("title") + " - 获得物品"; gZip.file( gCurrentReport.value + "/items.html", handlePage(gResponseDiv) ); gCurrentReport.checked = false; for (var i = 0; i < gSelectedReport.length; ++i) { var theCheckbox = gSelectedReport[i]; if (theCheckbox.checked) { gCurrentReport = theCheckbox; if (includeData) { StatEntireDiv = document.createElement("div"); var EntireInfoDiv = document.createElement("div"); EntireInfoDiv.id = "report_entire_info"; StatEntire = CreateStat(StatEntireDiv, EntireInfoDiv, true); StatEntire.iscurrentPage = false; } GetLevelPage(1, 1); return; } } handleIndexPage(); // 导出前把平均等级替换上去 if (gWithLv) { gTitle = gTitle.replace(rValue.Holder_Lv, getAvgLvTip()); } infodiv.innerHTML = "保存战报: " + gTitle + "<br/>" + "生成Zip文件"; var indexStr = "<html>\n" + headDiv.outerHTML + "\n<body>\n<h1>" + gTitle + "</h1><br/>\n" + gIndexDiv.innerHTML + "\n</body>\n</html>"; gZip.file("index.html", indexStr); gZip .generateAsync({ type: "blob", compression: "DEFLATE", compressionOptions: { level: 7 }, }) .then(function (content) { //saveAs(content, "wodlog" + '_' + Math.random().toString(36).substr(2, 9) + ".zip"); saveAs(content, "wodlog" + "_" + gTitle + ".zip"); gIsWorking = false; }); // alert("zip文件生成完毕"); console.log("zip文件生成完毕"); infodiv.innerHTML = ""; gResponseDiv.innerHTML = ""; } } catch (e) { alert("GetItemPage XMLHttpRequest.onreadystatechange(): " + e); } }; var URL = location.protocol + "//" + location.host + "/wod/spiel/dungeon/report.php"; XmlHttp.open("POST", URL, true); XmlHttp.setRequestHeader( "Content-type", "application/x-www-form-urlencoded" ); // XmlHttp.setRequestHeader("Content-length", queryString.length); // XmlHttp.setRequestHeader("Connection", "close"); XmlHttp.send(queryString); } function GetMaxLevel(page, DefaultValue) { var ret = DefaultValue; var allInputs = page.getElementsByTagName("input"); for (var i = 0; i < allInputs.length; ++i) { var name = allInputs[i].getAttribute("name"); if (rValue.Pattern_level.test(name)) { var levelnumber = Number(rValue.Pattern_idNumber.exec(name)[1]); if (levelnumber > ret) ret = levelnumber; } } return ret; } function handlePage(page, nLevel) { if (gWithLv) { let $page = $(page); if ($page.find('h1:contains("战斗统计: ")').length) { let $heroThs = $page.find( "h2 ~ table.content_table table tr:first th:gt(0)" ); heroes = []; $heroThs.each(function (i, el) { heroes.push($(el).text().trim()); }); console.log(heroes); } let $heroLvTrs = $page.find("table.rep_status_table tr:not(:first)"); if ($heroLvTrs.length) { heroLvMap = {}; $heroLvTrs.each(function (i, el) { let heroName = $(el).find("td:eq(1)").text().trim(); let heroLv = parseInt($(el).find("td:eq(2)").text().trim()); if (heroName && heroLv) { heroLvMap[heroName] = parseInt(heroLv); } }); console.log(heroLvMap); } } var thepage = page.getElementsByTagName("form")[0]; var h2 = thepage.getElementsByTagName("h2")[0]; if (h2) { h2.innerHTML = replaceDate(h2.innerHTML); } //removePageInput(thepage); replaceURL(thepage, "link", "href"); replaceURL(thepage, "script", "src"); replaceURL(thepage, "img", "src"); replaceURL(thepage, "a", "href", "#"); replaceButton(thepage); if (nLevel) replaceLevelPage(thepage, nLevel); return ( "<html>\n" + headDiv.outerHTML + "\n<body>\n" + replaceOther(thepage.outerHTML) + "\n</body>\n</html>" ); } function handleHead(head) { if (gTitle == null) gTitle = default_gTitle; head.getElementsByTagName("title")[0].innerHTML = gTitle.replace( rValue.Holder_Lv, "" ); replaceURL(head, "link", "href"); var bodyScript = document .getElementsByTagName("body")[0] .cloneNode(true) .getElementsByTagName("script"); for (var i = 0; i < bodyScript.length; i++) head.appendChild(bodyScript[i]); var scripts = head.getElementsByTagName("script"); for (var i = scripts.length - 1; i >= 0; i--) { script = scripts[i]; handleScript(script); } replaceURL(head, "script", "src"); var metas = head.getElementsByTagName("meta"); for (var i = metas.length - 1; i >= 0; i--) { var meta = metas[i]; if (!meta.httpEquiv) meta.parentNode.removeChild(meta); } if (includeData) es_addStyle(head, Style); head.innerHTML = head.innerHTML + "\n"; return head; } function handleScript(script) { var patten = /wod_standard.js|wodtooltip.js/; var scriptPatten = /(wodToolTipInit\(.*\);)\s*(wodInitialize\([^;]*\);)/; if (script.src) { if (!patten.test(script.src)) script.parentNode.removeChild(script); } else if (script.firstChild) { var scriptStr = script.firstChild.data; var result = scriptPatten.exec(scriptStr); if (result != null) if (result[1] && result[2]) scriptStr = "window.onload = function(e){" + result[1] + result[2] + "}"; scriptStr = scriptStr .replace( /wodInitialize\(''/g, "wodInitialize('" + location.host + "'" ) .replace("'0'", "'1'"); scriptStr += '\nfunction o(t,n){ \n var url="' + location.origin + '/wod/spiel/";\n'; scriptStr += 'if(t=="n"){url += "help/npc"}\n'; scriptStr += 'if(t=="s"){url += "hero/skill"}\n'; scriptStr += 'if(t=="i"){url += "hero/item"}\n'; scriptStr += 'return wo(url + ".php?name=" + n + "&IS_POPUP=1");}\n'; if (includeData) { scriptStr += "var CTable=function(){};\n"; scriptStr += "CTable.GetNumber = " + CTable.GetNumber.toString() + "\n"; scriptStr += "CompareString = " + CompareString.toString() + "\n"; scriptStr += "ct = " + CTable.OnClickTitle.toString() + "\n"; scriptStr += "cf = " + CTable.OnChangeFilter.toString() + "\n"; scriptStr += "co = " + CTable.OnChangeOrder.toString() + "\n"; scriptStr += "sd = " + CTable.OnShowDetail.toString() + "\n"; scriptStr += "st = " + CStat.OnTabClick.toString() + "\n"; } script.firstChild.data = scriptStr; } } function removePageInput(page) { var inputs = page.getElementsByTagName("input"); for (var i = inputs.length - 1; i >= 0; i--) { var theInput = inputs[i]; if (theInput.type == "hidden") { theInput.parentNode.removeChild(theInput); break; } } return page; } function replaceURL(page, tag, attr, value) { var test_pattern = /^\//; var test1_pattern = /^#/; var onclick_pattern = /([^\/]*)\.php\?name=([^&]*)/; var allLink = page.getElementsByTagName(tag); var path = location.origin + location.pathname; var m = path.match(/(.*)[\/\\]([^\/\\]+)\.\w+$/); for (var i = 0; i < allLink.length; i++) { var link = allLink[i]; if (link.hasAttribute(attr)) { var uri = link.getAttribute(attr); if (value) { if (!test1_pattern.test(uri)) link.setAttribute(attr, value); if (link.hasAttribute("onclick")) { var result = onclick_pattern.exec(link.getAttribute("onclick")); if (result && result[1] && result[2]) link.setAttribute( "onclick", "return o('" + result[1].substr(0, 1) + "','" + result[2] + "');" ); } } else { if (!rValue.pattern_http.test(uri)) { if (test_pattern.test(uri)) { link.setAttribute(attr, location.origin + uri); } else if (!test1_pattern.test(uri)) { link.setAttribute(attr, m[1] + "/" + uri); } } } } } } function replaceButton(page) { var allInputs = page.getElementsByTagName("input"); for (var i = 0; i < allInputs.length; ++i) { var name = allInputs[i].getAttribute("name"); if (rValue.Pattern_level.test(name)) { var levelURL = "document.location.href='level" + rValue.Pattern_idNumber.exec(name)[1] + ".html';"; var button = allInputs[i]; button.setAttribute("type", "button"); button.setAttribute("onclick", levelURL); } if (rValue.Pattern_item.test(name)) { var levelURL = "document.location.href='items.html';"; var button = allInputs[i]; button.setAttribute("type", "button"); button.setAttribute("onclick", levelURL); } if (rValue.Pattern_stat.test(name)) { var levelURL = "document.location.href='statistics.html';"; var button = allInputs[i]; button.setAttribute("type", "button"); button.setAttribute("onclick", levelURL); } if (rValue.Pattern_detail.test(name)) { var levelURL = "document.location.href='level1.html';"; var button = allInputs[i]; button.setAttribute("type", "button"); button.setAttribute("onclick", levelURL); } if (name == "overview" || name == "") { var levelURL = "document.location.href='../index.html';"; var button = allInputs[i]; button.setAttribute("type", "button"); button.setAttribute("onclick", levelURL); } } } function replaceLevelPage(page, nLevel) { var IndexPatt = /\D*([\d]+)\D*/; allURL = page.getElementsByTagName("a"); for (var i = 0; i < allURL.length; ++i) { var theURL = allURL[i]; if (theURL.className == "paginator") { var Result = IndexPatt.exec(theURL.textContent); var pageNum = Number(Result[1]); theURL.href = "level" + nLevel + (pageNum > 1 ? "_" + pageNum : "") + ".html"; } } } function replaceDate(sDate) { var today = new Date(); var yesterday = new Date(); yesterday.setDate(yesterday.getDate() - 1); var ret = sDate.replace( "今天", today.getFullYear() + "年" + (today.getMonth() + 1) + "月" + today.getDate() + "日" ); ret = ret.replace( "昨天", yesterday.getFullYear() + "年" + (yesterday.getMonth() + 1) + "月" + yesterday.getDate() + "日" ); return ret; } function replaceOther(sHTML) { var ret = sHTML.replace( /wodInitialize\(''/g, "wodInitialize('" + location.host + "'" ); ret = ret.replace(/wo\('\/wod/g, "wo('" + location.origin + "/wod"); return ret; } function prepareIndexPageTemplate() { var allRow = gIndexTemplateDiv.getElementsByTagName("tr"); for (var j = allRow.length - 1; j > 1; --j) { var row = allRow[j]; if (rValue.Pattern_logRow.test(row.getAttribute("class"))) { row.parentNode.removeChild(row); } } } function addIndexNewButton(cell, buttonText, url) { var newButton = document.createElement("input"); newButton.setAttribute("type", "button"); newButton.setAttribute("class", "button clickable"); newButton.setAttribute("value", buttonText); newButton.setAttribute("onclick", url); cell.appendChild(newButton); } function handleIndexPage() { var allRow = gIndexDiv.getElementsByTagName("tr"); var row = allRow[allRow.length - 1]; row.parentNode.removeChild(row); } function insertFilter() { if (this.checked) addFilter(this.nextSibling); else hideFilter(); } var gIndexRowclass = "row0"; var gCurrentReport; var gZip; var rLocal; var infodiv; var gTitle; var gSelectedReport = []; var gIndexTemplateDiv; var gResponseDiv; var multiPageDiv = []; var gIndexDiv; var gIsWorking = false; var includeData = false; var gWithLv = false; var headDiv; var world = ""; var default_gTitle; var isaddFilter = true; var rContents = { OrigText_H1_DungeonLog: ["Battle Report", "战报"], OrigText_H1_DuelLog: ["Battle Report", "您的决斗"], OrigText_Button_DungeonDetails: ["details", "详细资料"], Text_Button_Exportlog: ["Export Log", "导出战报"], Text_Button_SelectAll: ["Select All", "全选"], Text_Button_ClearAll: ["Clear All", "清除"], }; var rValue = { Text_Item: "items", Text_Stat: "stats", Text_Checkbox: "chkLog", Chk_includeData: "export_with_data", Chk_single: "single_export", Chk_withLv: "withLv_export", Holder_Lv: "「等级」", Pattern_level: /^level\[[\d]+\]/, Pattern_stat: /^stats\[[\d]+\]/, Pattern_item: /^items\[[\d]+\]/, Pattern_detail: /^details\[[\d]+\]/, Pattern_checkboxName: /^chkLog/, Pattern_logRow: /^row\d/, Pattern_idNumber: /([\d]+)/, pattern_http: /^http/i, }; var isDuel = false; //----------------------------------------------------------------------------- // "main" //----------------------------------------------------------------------------- function ReprotMain() { rLocal = GetLocalContents(rContents); if (rLocal === null) return; var allH1 = document.getElementsByTagName("h1"); var i = 0; var h1; var shouldContinue = false; if (allH1 === "undefined") return; for (i = 0; i < allH1.length; ++i) { h1 = allH1[i]; if ( h1.innerHTML == rLocal.OrigText_H1_DungeonLog || h1.innerHTML == rLocal.OrigText_H1_DuelLog ) { infodiv = document.createElement("div"); infodiv.innerHTML = ""; infodiv.id = "infoDiv"; h1.parentNode.insertBefore(infodiv, h1.nextSibling); var newLabel = document.createElement("label"); newLabel.innerHTML = "同时保存统计信息"; h1.parentNode.insertBefore(newLabel, h1.nextSibling); var newCheckBox = document.createElement("input"); newCheckBox.setAttribute("type", "checkbox"); newCheckBox.setAttribute("class", "checkbox"); newCheckBox.setAttribute("value", "同时保存统计信息"); newCheckBox.addEventListener("change", insertFilter, false); newCheckBox.id = rValue.Chk_includeData; newLabel.setAttribute("for", newCheckBox.id); h1.parentNode.insertBefore(newCheckBox, h1.nextSibling); // 插入单文件导出复选框 var singleCheckLabel = document.createElement("label"); singleCheckLabel.innerHTML = "单文件导出"; h1.parentNode.insertBefore(singleCheckLabel, h1.nextSibling); var singleCheckBox = document.createElement("input"); singleCheckBox.setAttribute("type", "checkbox"); singleCheckBox.setAttribute("class", "checkbox"); singleCheckBox.setAttribute("value", "单文件导出"); singleCheckBox.id = rValue.Chk_single; singleCheckLabel.setAttribute("for", singleCheckBox.id); h1.parentNode.insertBefore(singleCheckBox, h1.nextSibling); // 插入文件名包含平均等级复选框 var withLvLabel = document.createElement("label"); withLvLabel.innerHTML = "平均等级"; h1.parentNode.insertBefore(withLvLabel, h1.nextSibling); var withLvCheckBox = document.createElement("input"); withLvCheckBox.setAttribute("type", "checkbox"); withLvCheckBox.setAttribute("class", "checkbox"); withLvCheckBox.setAttribute("value", "平均等级"); withLvCheckBox.setAttribute("checked", true); withLvCheckBox.id = rValue.Chk_withLv; withLvLabel.setAttribute("for", withLvCheckBox.id); h1.parentNode.insertBefore(withLvCheckBox, h1.nextSibling); // 插入日期后缀框 var suffixBox = document.createElement("input"); suffixBox.setAttribute("id", "suffix"); suffixBox.setAttribute("size", "14"); suffixBox.setAttribute("type", "text"); suffixBox.setAttribute("placeholder", "日期后缀"); // 默认使用年月日时分为后缀 suffixBox.setAttribute("value", "YYYYMMDDHHmm"); suffixBox.innerHTML = "YYYYMMDDHHmm"; h1.parentNode.insertBefore(suffixBox, h1.nextSibling); var suffixSpan = document.createElement("span"); suffixSpan.innerHTML = "日期后缀:"; h1.parentNode.insertBefore(suffixSpan, h1.nextSibling); // 插入前缀框 var prefixBox = document.createElement("input"); prefixBox.setAttribute("id", "prefix"); prefixBox.setAttribute("size", "14"); prefixBox.setAttribute("type", "text"); prefixBox.setAttribute("placeholder", "战报导出命名前缀"); // 默认使用团队名作为前缀 prefixBox.setAttribute( "value", "[" + document.getElementsByName("gruppe_name")[0].value + "]" ); prefixBox.innerHTML = "[" + document.getElementsByName("gruppe_name")[0].value + "]"; h1.parentNode.insertBefore(prefixBox, h1.nextSibling); var newLabel = document.createElement("span"); newLabel.innerHTML = "战报导出命名前缀:"; h1.parentNode.insertBefore(newLabel, h1.nextSibling); InsertButton(h1, rLocal.Text_Button_Exportlog, exportLog); InsertButton(h1, rLocal.Text_Button_ClearAll, cleartAll); InsertButton(h1, rLocal.Text_Button_SelectAll, selectAll); gResponseDiv = document.createElement("div"); gResponseDiv.innerHTML = ""; gIndexTemplateDiv = document.createElement("div"); gIndexTemplateDiv.innerHTML = ""; shouldContinue = true; break; } } if (!shouldContinue) return; var allTable = document.getElementsByTagName("table"); for (i = 0; i < allTable.length; ++i) { var theTable = allTable[i]; if (theTable.getAttribute("class") == "content_table") { gIndexTemplateDiv.innerHTML = theTable.outerHTML; prepareIndexPageTemplate(); var allRow = theTable.getElementsByTagName("tr"); for (var j = 0; j < allRow.length; ++j) { var row = allRow[j]; var newCheckbox = document.createElement("input"); newCheckbox.setAttribute("type", "checkbox"); if (rValue.Pattern_logRow.test(row.getAttribute("class"))) { if (isDuel) { var reportName = "<span>" + row.cells[0].innerHTML.replace("<hr>", " <b>对战</b> ") + " " + row.cells[1].innerText + "</span>"; var reportTime = "<span>" + row.cells[2].innerText + "</span>"; var title = reportName + " - " + reportTime; var allduel = row.cells[3].getElementsByTagName("a"); var href = allduel[0].href; var onclick_pattern = /\?DuellId=([^&]*)/; var result = onclick_pattern.exec(href); newCheckbox.setAttribute( "name", rValue.Text_Checkbox + "[" + j + "]" ); newCheckbox.setAttribute( "id", rValue.Text_Checkbox + "[" + j + "]" ); newCheckbox.setAttribute("value", result[1]); newCheckbox.setAttribute("href", href); newCheckbox.setAttribute("title", title); newCheckbox.setAttribute("reportname", reportName); newCheckbox.setAttribute("reporttime", reportTime); newCheckbox.setAttribute( "c0", row.cells[0].innerHTML.replace("<hr>", " <b>对战</b> ") ); newCheckbox.setAttribute("c1", row.cells[1].innerHTML); newCheckbox.setAttribute("maxLevel", 1); row.cells[0].insertBefore(newCheckbox, row.cells[0].firstChild); } else { var reportName = "<span>" + row.cells[1].firstChild.innerHTML + "</span>"; var reportTime = "<span>" + row.cells[0].firstChild.innerHTML + "</span>"; var title = reportName + " - " + reportTime; var allInput = row.cells[2].getElementsByTagName("input"); var id = ""; var index = ""; for (var k = 0; k < allInput.length; ++k) { var input = allInput[k]; var name = input.getAttribute("name"); var value = input.getAttribute("value"); if (name.indexOf("report_id") != -1) { var Result = rValue.Pattern_idNumber.exec(name); index = Number(Result[1]); id = value; break; } } newCheckbox.setAttribute( "name", rValue.Text_Checkbox + "[" + index + "]" ); newCheckbox.setAttribute( "id", rValue.Text_Checkbox + "[" + index + "]" ); newCheckbox.setAttribute("value", id); newCheckbox.setAttribute("title", title); newCheckbox.setAttribute("reportname", reportName); newCheckbox.setAttribute("reporttime", reportTime); newCheckbox.setAttribute("maxLevel", 1); newCheckbox.setAttribute( rValue.Text_Item, rValue.Text_Item + "%5B" + index + "%5D" ); newCheckbox.setAttribute( rValue.Text_Stat, rValue.Text_Stat + "%5B" + index + "%5D" ); row.cells[0].insertBefore(newCheckbox, row.cells[0].firstChild); } } } break; } } var allInput = document.getElementsByTagName("input"); for (var i = 0; i < allInput.length; i++) { var input = allInput[i]; if (input.name && input.name == "wod_post_world") { world = input.value; break; } } } //////////////////////////////////////////////////////////////////////////////////////////////// function test(o) { alert('test'); } function filterMain() { function Factoryfilter(o) { return function () { filterReport(o); }; } var tables = document.getElementsByTagName("table"); for (var i = 0; i < tables.length; i++) { var table = tables[i]; if (table.className == "rep_status_table") { for (var j = 0; j < table.rows.length; j++) { var row = table.rows[j]; for (var k = 0; k < row.cells.length; k++) { var cell = row.cells[k]; if (cell.className == "hero") { var newCheckbox = document.createElement("input"); newCheckbox.setAttribute("type", "checkbox"); newCheckbox.setAttribute("class", "filter"); newCheckbox.value = cell.firstChild.textContent; cell.insertBefore(newCheckbox, cell.firstChild); //newCheckbox.setAttribute("onclick", "test(this);"); newCheckbox.addEventListener("click", Factoryfilter(newCheckbox), false); break; } } } } } } filterReport = function (o) { var checkboxlist = document.getElementsByTagName("input"); var selectedheros = []; var classNamepattern = /^[rep_monster|rep_hero|rep_myhero]/; for (var i = 0; i < checkboxlist.length; i++) { var checkbox = checkboxlist[i]; if (checkbox.getAttribute("type") == "checkbox" && checkbox.getAttribute("class") == "filter") { if (checkbox.value == o.value) checkbox.checked = o.checked; if (checkbox.checked && selectedheros.indexOf(checkbox.value) <= -1) selectedheros.push(checkbox.value); } } var tables = document.getElementsByTagName("table"); for (var i = 0; i < tables.length; i++) { var table = tables[i]; if (table.className != "rep_status_table") { var istheTable = false; for (var j = 0; j < table.rows.length; j++) { var row = table.rows[j]; var show = false; if (row.cells.length <= 0 || row.cells[0].colSpan > 1) continue; if (istheTable || row.cells[0].className == "rep_initiative") { istheTable = true; for (var k = 0; k < row.cells.length; k++) { var cell = row.cells[k]; var links = cell.getElementsByTagName("a"); for (var index = 0; index < links.length; index++) { var link = links[index]; if (classNamepattern.test(link.className)) { var name = link.textContent; if (selectedheros.length <= 0 || selectedheros.indexOf(name) > -1) { show = true; break; } } } if (show) break; } row.style.display = show ? '' : 'none'; } } } } }; try { isDuel = (window.location.href.indexOf("duell.php") > 0); Main(); ReprotMain(); //filterMain(); } catch (e) { alert("Main(): " + e); } })();