pasta_la_wista

analyzer

Jul 12th, 2025
15
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. // ==UserScript==
  2. // @name        new_GN_BattleLogAnalyzer
  3. // @namespace   Gradient
  4. // @description Анализатор протокола боев
  5. // @match       https://www.heroeswm.ru/*
  6. // @match       https://my.lordswm.com/*
  7. // @match       https://www.lordswm.com/*
  8. // @exclude     /^https{0,1}:\/\/(www\.heroeswm\.ru|178\.248\.235\.15|my\.lordswm\.com)\/(login|war|cgame|frames|chat|chatonline|ch_box|chat_line|ticker|chatpost|chat2020|battlechat|campaign)\.php
  9. // @version     1.0.14
  10. // ==/UserScript==
  11. let chosen_faction = "Фараон"
  12. let factions = {
  13.     "1": "Рыцарь",
  14.     "2": "Некромант",
  15.     "3": "Маг",
  16.     "4": "Эльф",
  17.     "5": "Варвар",
  18.     "6": "Темный эльф",
  19.     "7": "Демон",
  20.     "8": "Гном",
  21.     "9": "Степной варвар",
  22.     "10": "Фараон"
  23. }
  24.  
  25. let temp123 = `// @exclude     /^https{0,1}:\/\/(www\.heroeswm\.ru|178\.248\.235\.15)\/(login|war|cgame|frames|chat|chatonline|ch_box|chat_line|ticker|chatpost|chat2020|battlechat|campaign)\.php.*/`
  26. "use strict";
  27.  
  28. //----------------------------------------------------------------------------//
  29.  
  30. var script_name = 'GN_BattleLogAnalyzer'; // Enter your script name here
  31.  
  32. //----------------------------------------------------------------------------//
  33.  
  34. (function() {
  35.     try { // wrapper start
  36.  
  37.         //----------------------------------------------------------------------------//
  38.         // UnifiedLibrary 1.7.0 start
  39.         //----------------------------------------------------------------------------//
  40.  
  41.         //----------------------------------------------------------------------------//
  42.         // SysUtils
  43.         //----------------------------------------------------------------------------//
  44.  
  45.         var GN_SysUtils = new SysUtils(script_name);
  46.         var SU = GN_SysUtils;
  47.  
  48.         //----------------------------------------------------------------------------//
  49.  
  50.         function SysUtils(name) { // wrapper start
  51.  
  52.             //----------------------------------------------------------------------------//
  53.  
  54.             this.show_error = function(error_string, use_alert) {
  55.                 if (use_alert)
  56.                     alert(error_string);
  57.  
  58.                 throw new Error(error_string);
  59.             };
  60.  
  61.             if (arguments.length != 1)
  62.                 this.show_error('Wrong SysUtils arguments');
  63.  
  64.             if (!arguments[0])
  65.                 this.show_error('Empty SysUtils argument');
  66.  
  67.             //----------------------------------------------------------------------------//
  68.  
  69.             this.compare = function(a, b) {
  70.                 return (a == b) ? 0 : (a > b ? 1 : -1);
  71.             };
  72.  
  73.             //----------------------------------------------------------------------------//
  74.  
  75.             this.send_get = function(url) {
  76.                 var xhr = new XMLHttpRequest();
  77.                 xhr.open('GET', url, false);
  78.                 xhr.overrideMimeType('text/plain; charset=windows-1251');
  79.                 xhr.send(null);
  80.  
  81.                 if (xhr.status == 200)
  82.                     return xhr.responseText;
  83.  
  84.                 return null;
  85.             };
  86.  
  87.             //----------------------------------------------------------------------------//
  88.  
  89.             this.save_value = function(desc, value) {
  90.                 var div = document.getElementById('GN_GM_Handler');
  91.                 div.setAttribute('desc', desc);
  92.                 div.setAttribute('value', value);
  93.                 div.setAttribute('operation', 'save');
  94.  
  95.                 div.click();
  96.  
  97.                 if (div.getAttribute('state') != 'complete')
  98.                     this.show_error('Ошибка при сохранении значения');
  99.             };
  100.  
  101.             //----------------------------------------------------------------------------//
  102.  
  103.             this.load_value = function(value, def) {
  104.                 var div = document.getElementById('GN_GM_Handler');
  105.                 div.setAttribute('desc', value);
  106.                 div.setAttribute('operation', 'load');
  107.  
  108.                 div.click();
  109.  
  110.                 if (div.getAttribute('state') != 'complete')
  111.                     this.show_error('Ошибка при загрузке значения');
  112.  
  113.                 return (div.getAttribute('is_null') == 'true' ? def : div.getAttribute('value'));
  114.             };
  115.  
  116.             //----------------------------------------------------------------------------//
  117.  
  118.             this.remove_value = function(value) {
  119.                 var div = document.getElementById('GN_GM_Handler');
  120.                 div.setAttribute('desc', value);
  121.                 div.setAttribute('operation', 'remove');
  122.  
  123.                 div.click();
  124.  
  125.                 if (div.getAttribute('state') != 'complete')
  126.                     this.show_error('Ошибка при удалении значения');
  127.             };
  128.  
  129.             //----------------------------------------------------------------------------//
  130.  
  131.             var current_id = null;
  132.             //----------------------------------------------------------------------------//
  133.  
  134.             //----------------------------------------------------------------------------//
  135.  
  136.             //----------------------------------------------------------------------------//
  137.  
  138.             function check_mandatory_scripts(alerter) {
  139.                 var persistent_storage_sign = document.getElementById('GN_GM_Handler');
  140.                 var common_values_sign = document.getElementById('GN_CommonValuesSign');
  141.                 var alert_sign = document.getElementById('GN_AlertSign');
  142.  
  143.                 if (!alert_sign) {
  144.                     alert_sign = document.createElement('div');
  145.                     alert_sign.id = 'GN_AlertSign';
  146.                     alert_sign.setAttribute('alerted', 'false');
  147.                     document.body.appendChild(alert_sign);
  148.                 }
  149.  
  150.                 var alerted = alert_sign.getAttribute('alerted') != 'false';
  151.  
  152.                 if (!persistent_storage_sign) {
  153.                     alert_sign.setAttribute('alerted', 'true');
  154.                     alerter('Скрипт ' + name + ' требует для своей работы скрипт управления данными (GN_PersistentStorage), который должен стоять первым в порядке выполнения скриптов.\n' +
  155.                         'Подробнее здесь: "https://greasyfork.org/ru/scripts/14049-Как-устанавливать-скрипты-читать-здесь"', !alerted);
  156.                 }
  157.  
  158.                 if (!common_values_sign) {
  159.                     alert_sign.setAttribute('alerted', 'true');
  160.                     alerter('Скрипт ' + name + ' требует для своей работы скрипт, хранящий данные (GN_CommonValuesFiller), который должен стоять вторым в порядке выполнения скриптов.\n' +
  161.                         'Подробнее здесь: "https://greasyfork.org/ru/scripts/14049-Как-устанавливать-скрипты-читать-здесь"', !alerted);
  162.                 }
  163.             }
  164.  
  165.             this.check_login = function() {
  166.                 var re = /.*?pl_id=(\d+)[^\d]*?/gmi;
  167.                 var matches = re.exec(document.cookie.toString());
  168.  
  169.                 if (matches) {
  170.                     current_id = +matches[1];
  171.  
  172.                     check_mandatory_scripts(this.show_error);
  173.                 }
  174.             };
  175.  
  176.             //----------------------------------------------------------------------------//
  177.  
  178.             this.save_file = function(text, info) {
  179.                 var res = 'data:text/csv;charset=utf-8,' + encodeURI(text);
  180.  
  181.                 if (info)
  182.                     alert(info);
  183.  
  184.                 window.open(res);
  185.             };
  186.  
  187.             //----------------------------------------------------------------------------//
  188.  
  189.             this.string_to_date = function(str) {
  190.                 var matches = /(\d{2})-(\d{2})-(\d{2})\s(\d{2}):(\d{2})/.exec(str);
  191.  
  192.                 return new Date(2000 + +matches[3], +matches[2] - 1, +matches[1], +matches[4], +matches[5]);
  193.             };
  194.  
  195.             //----------------------------------------------------------------------------//
  196.  
  197.             function get_char(e) {
  198.                 if (e.which && e.charCode) {
  199.                     if (e.which < 32)
  200.                         return null;
  201.  
  202.                     return String.fromCharCode(+e.which)
  203.                 }
  204.  
  205.                 return null;
  206.             }
  207.  
  208.             this.number_input = function(e) {
  209.                 if (e.ctrlKey || e.altKey || e.metaKey)
  210.                     return false;
  211.  
  212.                 var chr = get_char(e);
  213.  
  214.                 return chr == null || (chr >= '0' && chr <= '9');
  215.             };
  216.  
  217.             //----------------------------------------------------------------------------//
  218.  
  219.             this.check_login();
  220.  
  221.             //----------------------------------------------------------------------------//
  222.  
  223.         } // wrapper end
  224.  
  225.         //----------------------------------------------------------------------------//
  226.         // CommonValues
  227.         //----------------------------------------------------------------------------//
  228.  
  229.         var GN_CommonValues = new CommonValues();
  230.  
  231.         //----------------------------------------------------------------------------//
  232.  
  233.         function CommonValues() { // wrapper start
  234.  
  235.             //----------------------------------------------------------------------------//
  236.             // Battle types
  237.             //----------------------------------------------------------------------------//
  238.  
  239.             this.enum_sbt = { // sync?
  240.                 pvp: 0,
  241.                 hunter: 1,
  242.                 mercenary: 2,
  243.                 thief: 3,
  244.                 ranger: 4,
  245.                 war: 5,
  246.                 event: 6,
  247.                 instance: 7,
  248.                 other: 8,
  249.                 guardian: 9,
  250.                 campaign: 10,
  251.                 leader: 11,
  252.                 unknown: 12
  253.             };
  254.  
  255.             this.sorted_battle_types = JSON.parse(SU.load_value('GN_CommonValues_SortedBattleTypes', '[]'));
  256.             this.battle_types = JSON.parse(SU.load_value('GN_CommonValues_BattleTypes', '[]'));
  257.  
  258.             //----------------------------------------------------------------------------//
  259.  
  260.             this.get_battle_type = function(id) {
  261.                 for (var i = 0; i < this.battle_types.length; ++i)
  262.                     if (this.battle_types[i].id == id)
  263.                         return this.battle_types[i];
  264.  
  265.                 var new_type = { id: id, sbt: this.enum_sbt.unknown, name: id }; // sync?
  266.                 this.battle_types.push(new_type);
  267.  
  268.                 return new_type;
  269.             };
  270.  
  271.             //----------------------------------------------------------------------------//
  272.  
  273.         } // wrapper end
  274.  
  275.         //----------------------------------------------------------------------------//
  276.         // GUIController
  277.         //----------------------------------------------------------------------------//
  278.  
  279.         var GN_GUIController = new GUIController();
  280.  
  281.         //----------------------------------------------------------------------------//
  282.  
  283.         function GUIController() { // wrapper start
  284.  
  285.             //----------------------------------------------------------------------------//
  286.  
  287.             clear_flash_z_index();
  288.  
  289.             //----------------------------------------------------------------------------//
  290.  
  291.             var script_name = 'GN_GUIController';
  292.             this.script_name = function() {
  293.                 return script_name;
  294.             };
  295.  
  296.             //----------------------------------------------------------------------------//
  297.  
  298.             this.registerObject = function(object) {
  299.                 root_div = document.getElementById(root.div.id);
  300.  
  301.                 if (!root_div)
  302.                     root_div = create_node(root, document.body);
  303.                 else {
  304.                     var custom = root_div.getAttribute('custom').split('|');
  305.                     root.div.top = +custom[0];
  306.                     root.div.left = +custom[1];
  307.                     root.div.width = +custom[2];
  308.                     root.div.height = +custom[3];
  309.                 }
  310.  
  311.                 object.div.left = root.div.left + left;
  312.                 object.div.top = top;
  313.  
  314.                 var childs = root_div.childNodes;
  315.  
  316.                 for (var i = 0; i < childs.length; ++i)
  317.                     if (childs[i].nodeName.toLowerCase() == 'div') {
  318.                         var height = +childs[i].getAttribute('custom').split('|')[3];
  319.                         object.div.top += height;
  320.                     }
  321.  
  322.                 create_node(object, root_div);
  323.                 align_childs(root_div);
  324.                 collapse_childs(root_div);
  325.             };
  326.  
  327.             //----------------------------------------------------------------------------//
  328.  
  329.             this.hide_all = function() {
  330.                 if (!root_div)
  331.                     return;
  332.  
  333.                 var childs = root_div.childNodes;
  334.                 for (var i = 0; i < childs.length; ++i)
  335.                     if (childs[i].nodeName.toLowerCase() == 'div')
  336.                         childs[i].style.top = +childs[i].getAttribute('custom').split('|')[0];
  337.  
  338.                 align_childs(root_div);
  339.                 collapse_childs(root_div);
  340.             };
  341.  
  342.             var hide_all = this.hide_all;
  343.  
  344.             //----------------------------------------------------------------------------//
  345.  
  346.             const left = 10;
  347.             const top = 10;
  348.  
  349.             var root = {
  350.                 div: {
  351.                     id: script_name + 'MainDiv',
  352.                     top: top,
  353.                     left: left,
  354.                     width: 0,
  355.                     height: 0
  356.                 },
  357.  
  358.                 input: {
  359.                     id: script_name + 'MainInput',
  360.                     value: 'Скрипты',
  361.                     title: 'Конфигурация и запуск скриптов, не относящихся к определенной странице'
  362.                 },
  363.  
  364.                 child_divs: []
  365.             };
  366.  
  367.             var root_div = document.getElementById(root.div.id);
  368.  
  369.             //----------------------------------------------------------------------------//
  370.  
  371.             function create_node(object, parent) {
  372.                 var div_ = div(object.div);
  373.                 div_.setAttribute('expanded', 'false');
  374.                 parent.appendChild(div_);
  375.  
  376.                 set_div_style(object.div);
  377.  
  378.                 var input_ = input(object.input);
  379.                 div_.appendChild(input_);
  380.  
  381.                 set_input_style(object.input);
  382.  
  383.                 object.div.left += div_.clientWidth;
  384.                 object.div.width = div_.clientWidth;
  385.                 object.div.height = div_.clientHeight;
  386.  
  387.                 var custom = [object.div.top, object.div.left, object.div.width, object.div.height];
  388.                 div_.setAttribute('custom', custom.join('|'));
  389.  
  390.                 if (object.child_divs.length || object.div.id == root.div.id) {
  391.                     input_.addEventListener('click', function() {
  392.                         expand_childs(div_);
  393.                     });
  394.  
  395.                     create_child_nodes(object, div_);
  396.                 }
  397.  
  398.                 return div_;
  399.             }
  400.  
  401.             //----------------------------------------------------------------------------//
  402.  
  403.             function create_child_nodes(object, parent) {
  404.                 var childs = object.child_divs;
  405.  
  406.                 for (var i = 0; i < childs.length; ++i) {
  407.                     var child = childs[i];
  408.                     child.div.top = top;
  409.                     child.div.left = left;
  410.  
  411.                     if (i) {
  412.                         var total_height = 0;
  413.  
  414.                         for (var j = 0; j < i; ++j) {
  415.                             var sibling = childs[j];
  416.                             var sibling_div = document.getElementById(sibling.div.id);
  417.  
  418.                             total_height += sibling_div.clientHeight;
  419.                         }
  420.  
  421.                         child.div.top += total_height;
  422.                     }
  423.  
  424.                     child.div.left += object.div.left;
  425.  
  426.                     create_node(child, parent);
  427.                 }
  428.             }
  429.  
  430.             //----------------------------------------------------------------------------//
  431.  
  432.             function expand_childs(el) {
  433.                 var now_expanded = (el.getAttribute('expanded') == 'true');
  434.  
  435.                 if (now_expanded && el == root_div) {
  436.                     hide_all();
  437.                     return;
  438.                 }
  439.  
  440.                 var childs = el.childNodes;
  441.  
  442.                 for (var i = 0; i < childs.length; ++i)
  443.                     if (childs[i].nodeName.toLowerCase() == 'div')
  444.                         childs[i].style.display = !now_expanded ? 'block' : 'none';
  445.  
  446.                 if (now_expanded) {
  447.                     collapse_childs(el);
  448.  
  449.                     if (el.parentNode == root_div) {
  450.                         childs = root_div.childNodes;
  451.  
  452.                         for (i = 0; i < childs.length; ++i)
  453.                             if (childs[i].nodeName.toLowerCase() == 'div' && childs[i] != el)
  454.                                 childs[i].style.display = 'block';
  455.  
  456.                         el.style.top = +el.getAttribute('custom').split('|')[0];
  457.                         el.style.width = +el.getAttribute('custom').split('|')[2];
  458.  
  459.                         align_childs(root_div);
  460.                     }
  461.                 }
  462.  
  463.                 if (!now_expanded && el.parentNode == root_div) {
  464.                     childs = root_div.childNodes;
  465.  
  466.                     for (i = 0; i < childs.length; ++i) {
  467.                         if (childs[i].nodeName.toLowerCase() == 'div' && childs[i] != el)
  468.                             childs[i].style.display = 'none';
  469.                     }
  470.  
  471.                     el.style.top = top;
  472.                     el.style.width = +el.getAttribute('custom').split('|')[2];
  473.                 }
  474.  
  475.                 el.setAttribute('expanded', now_expanded ? 'false' : 'true');
  476.             }
  477.  
  478.             //----------------------------------------------------------------------------//
  479.  
  480.             function align_childs(el) {
  481.                 var max_width = 0;
  482.                 var childs = el.childNodes;
  483.  
  484.                 for (var i = 0; i < childs.length; ++i)
  485.                     if (childs[i].nodeName.toLowerCase() == 'div') {
  486.                         var width = +childs[i].getAttribute('custom').split('|')[2];
  487.  
  488.                         if (width >= max_width)
  489.                             max_width = width;
  490.                     }
  491.  
  492.                 for (i = 0; i < childs.length; ++i)
  493.                     if (childs[i].nodeName.toLowerCase() == 'div')
  494.                         childs[i].style.width = max_width;
  495.             }
  496.  
  497.             //----------------------------------------------------------------------------//
  498.  
  499.             function collapse_childs(el) {
  500.                 var divs = el.querySelectorAll('div');
  501.  
  502.                 for (var i = 0; i < divs.length; ++i) {
  503.                     divs[i].setAttribute('expanded', 'false');
  504.                     divs[i].style.display = 'none';
  505.                 }
  506.  
  507.                 el.setAttribute('expanded', 'false');
  508.             }
  509.  
  510.             //----------------------------------------------------------------------------//
  511.  
  512.             function div(object) {
  513.                 var div = document.createElement('div');
  514.                 div.id = object.id;
  515.  
  516.                 return div;
  517.             }
  518.  
  519.             //----------------------------------------------------------------------------//
  520.  
  521.             function set_div_style(object) {
  522.                 var div = document.getElementById(object.id);
  523.                 var style = div.style;
  524.  
  525.                 style.position = 'fixed';
  526.                 style.top = object.top + 'px';
  527.                 style.left = object.left + 'px';
  528.                 style.zIndex = 100;
  529.             }
  530.  
  531.             //----------------------------------------------------------------------------//
  532.  
  533.             function input(object) {
  534.                 var input = document.createElement('input');
  535.                 input.type = 'button';
  536.                 input.id = object.id;
  537.                 input.value = object.value;
  538.                 input.title = object.title;
  539.  
  540.                 return input;
  541.             }
  542.  
  543.             //----------------------------------------------------------------------------//
  544.  
  545.             function set_input_style(object) {
  546.                 var input = document.getElementById(object.id);
  547.                 var style = input.style;
  548.  
  549.                 style.display = 'block';
  550.                 style.width = '95%';
  551.                 style.border = '1px solid rgb(153, 153, 153)';
  552.                 style.padding = '1px';
  553.                 style.margin = '2px';
  554.                 style.background = 'none repeat scroll 0% 0% rgb(204, 204, 204)';
  555.                 style.fontSize = '12px';
  556.                 style.cursor = 'pointer';
  557.                 style.zIndex = 100;
  558.             }
  559.  
  560.             //----------------------------------------------------------------------------//
  561.  
  562.             function clear_flash_z_index() {
  563.                 var objects = document.querySelectorAll('object');
  564.  
  565.                 for (var i = 0; i < objects.length; ++i) {
  566.                     var o = objects[i];
  567.  
  568.                     if (!o.querySelector('param[name="wmode"]')) {
  569.                         var param = document.createElement('param');
  570.                         param.setAttribute('name', 'wmode');
  571.                         param.setAttribute('value', 'opaque');
  572.  
  573.                         o.insertBefore(param, o.firstChild);
  574.                     }
  575.                 }
  576.             }
  577.  
  578.             //----------------------------------------------------------------------------//
  579.  
  580.         } // wrapper end
  581.  
  582.         //----------------------------------------------------------------------------//
  583.         // UnifiedLibrary end
  584.         //----------------------------------------------------------------------------//
  585.  
  586.         var compare = SU.compare;
  587.         var load_value = SU.load_value;
  588.         var save_value = SU.save_value;
  589.         var remove_value = SU.remove_value;
  590.         var send_get = SU.send_get;
  591.         var number_input = SU.number_input;
  592.         var string_to_date = SU.string_to_date;
  593.         var save_file = SU.save_file;
  594.  
  595.         var CV = GN_CommonValues;
  596.  
  597.         var sorted_battle_types = CV.sorted_battle_types;
  598.         sorted_battle_types.sort(function(a, b) {
  599.             return compare(a.name, b.name);
  600.         });
  601.  
  602.         var battle_types = CV.battle_types;
  603.         battle_types.sort(function(a, b) {
  604.             return compare(a.name, b.name);
  605.         });
  606.  
  607.         var is_parser_running = false;
  608.         var searched = [];
  609.         var colspan = '4';
  610.         var empty_option = 'all_values';
  611.         var count_counter = 0;
  612.         var mercenaries = [];
  613.         var hunters = [];
  614.         var settings = load_settings();
  615.         var save_to_file = false;
  616.  
  617.         var enum_exodus = {
  618.             win: 0,
  619.             draw: 1,
  620.             loss: 2
  621.         };
  622.  
  623.         var GC = GN_GUIController;
  624.         GC.registerObject({
  625.             div: { id: GC.script_name() + '_' + script_name + 'Div' },
  626.  
  627.             input: {
  628.                 id: GC.script_name() + '_' + script_name + 'Input',
  629.                 value: 'Анализатор протокола боев',
  630.                 title: 'Анализатор протокола боев'
  631.             },
  632.  
  633.             child_divs: []
  634.         });
  635.  
  636.         var start_button = document.getElementById(GC.script_name() + '_' + script_name + 'Input');
  637.  
  638.         start_button.addEventListener('click', function(e) {
  639.             draw_div(document.body);
  640.         });
  641.  
  642.         //----------------------------------------------------------------------------//
  643.  
  644.         function draw_div(parent) {
  645.             var div = document.createElement('div');
  646.             div.id = script_name + 'Div';
  647.             div.style.position = 'fixed';
  648.             div.style.display = 'block';
  649.             div.style.top = '50px';
  650.             div.style.zIndex = 100;
  651.             div.style.overflowX = 'hidden';
  652.  
  653.             var width = 700;
  654.             div.style.width = width + 'px';
  655.             div.style.left = (document.body.clientWidth - width) / 2;
  656.             div.style.background = start_button.style.backgroundColor;
  657.  
  658.             parent.appendChild(div);
  659.  
  660.             draw_content(div);
  661.             set_settings();
  662.         }
  663.  
  664.         //----------------------------------------------------------------------------//
  665.  
  666.         function draw_content(parent) {
  667.             var table = document.createElement('table');
  668.             table.style.width = '100%';
  669.             table.style.border = 'medium none';
  670.  
  671.             parent.appendChild(table);
  672.  
  673.             draw_header(table);
  674.             draw_first_row(table);
  675.             draw_second_row(table);
  676.             draw_third_row(table);
  677.             draw_fourth_row(table);
  678.             draw_fifth_row(table);
  679.  
  680.             var tr = document.createElement('tr');
  681.             table.appendChild(tr);
  682.  
  683.             var td = document.createElement('td');
  684.             td.setAttribute('align', 'center');
  685.             td.setAttribute('colspan', '5');
  686.             tr.appendChild(td);
  687.  
  688.             var input = document.createElement('input');
  689.             input.id = script_name + 'StartInput';
  690.             input.type = 'button';
  691.             input.value = 'Начать поиск';
  692.             input.addEventListener('click', function(e) {
  693.                 e.preventDefault();
  694.  
  695.                 if (!save_settings())
  696.                     return;
  697.  
  698.                 save_to_file = settings.save_file;
  699.                 searched = [];
  700.                 enable_settings(false);
  701.                 draw_search_table(parent);
  702.                 recheck_rect();
  703.  
  704.                 parse_data();
  705.             });
  706.             td.appendChild(input);
  707.         }
  708.  
  709.         //----------------------------------------------------------------------------//
  710.  
  711.         function draw_header(parent) {
  712.             var tr = document.createElement('tr');
  713.             parent.appendChild(tr);
  714.  
  715.             var td = document.createElement('td');
  716.             td.setAttribute('colspan', '5');
  717.             tr.appendChild(td);
  718.  
  719.             var table = document.createElement('table');
  720.             table.style.width = '100%';
  721.             td.appendChild(table);
  722.  
  723.             tr = document.createElement('tr');
  724.             table.appendChild(tr);
  725.  
  726.             td = document.createElement('td');
  727.             td.setAttribute('align', 'center');
  728.             td.textContent = 'Панель настроек';
  729.             tr.appendChild(td);
  730.  
  731.             td = document.createElement('td');
  732.             td.setAttribute('align', 'center');
  733.             td.style.width = '100px';
  734.  
  735.             var a = document.createElement('a');
  736.             a.href = '';
  737.             a.textContent = '(очистить все)';
  738.             a.addEventListener('click', function(e) {
  739.                 e.preventDefault();
  740.                 clear_settings();
  741.             });
  742.             td.appendChild(a);
  743.             tr.appendChild(td);
  744.  
  745.             td = document.createElement('td');
  746.             td.setAttribute('align', 'center');
  747.             td.style.width = '25px';
  748.             td.textContent = 'x';
  749.             td.style.backgroundColor = 'red';
  750.             td.style.fontSize = '16';
  751.             td.title = 'Закрыть окно';
  752.             td.addEventListener('click', function(e) {
  753.                 remove_div();
  754.             });
  755.             tr.appendChild(td);
  756.         }
  757.  
  758.         //----------------------------------------------------------------------------//
  759.  
  760.         function draw_first_row(parent) {
  761.             var tr = document.createElement('tr');
  762.             parent.appendChild(tr);
  763.  
  764.             var td = document.createElement('td');
  765.             tr.appendChild(td);
  766.  
  767.             td.appendChild(document.createTextNode('ID персонажа:'));
  768.  
  769.             td = document.createElement('td');
  770.             tr.appendChild(td);
  771.  
  772.             var input = document.createElement('input');
  773.             input.id = script_name + 'IDInput';
  774.             input.type = 'text';
  775.             input.style.width = '150px';
  776.             input.onkeypress = number_input;
  777.             input.title = 'Идентификатор персонажа, по чьему протоколу будет вестись поиск';
  778.             td.appendChild(input);
  779.  
  780.             td = document.createElement('td');
  781.             tr.appendChild(td);
  782.  
  783.             td.appendChild(document.createTextNode('Что ищем:'));
  784.  
  785.             td = document.createElement('td');
  786.             tr.appendChild(td);
  787.  
  788.             input = document.createElement('input');
  789.             input.id = script_name + 'SearchInput';
  790.             input.type = 'text';
  791.             input.style.width = '150px';
  792.             input.title = 'Фраза для поиска. Может не указываться, если включен поиск и фильтр по всем боям';
  793.             td.appendChild(input);
  794.  
  795.             td = document.createElement('td');
  796.             tr.appendChild(td);
  797.  
  798.             var chb = document.createElement('input');
  799.             chb.type = 'checkbox';
  800.             chb.title = 'Поиск будет осуществляться без учета регистра';
  801.             chb.id = script_name + 'CIChb';
  802.             td.appendChild(chb);
  803.  
  804.             td.appendChild(document.createTextNode('без учета регистра'));
  805.         }
  806.  
  807.         //----------------------------------------------------------------------------//
  808.  
  809.         function draw_second_row(parent) {
  810.             var tr = document.createElement('tr');
  811.             parent.appendChild(tr);
  812.  
  813.             var td = document.createElement('td');
  814.             tr.appendChild(td);
  815.  
  816.             td.appendChild(document.createTextNode('Тип боя:'));
  817.  
  818.             td = document.createElement('td');
  819.             tr.appendChild(td);
  820.  
  821.             var select = document.createElement('select');
  822.             select.id = script_name + 'SBTSelect';
  823.             select.style.width = '150px';
  824.             select.title = 'Поиск по общему типу боя';
  825.             select.addEventListener('change', function(e) {
  826.                 reload_battle_types();
  827.             });
  828.             td.appendChild(select);
  829.  
  830.             var option = document.createElement('option');
  831.             option.setAttribute('value', empty_option);
  832.             select.appendChild(option);
  833.  
  834.             sorted_battle_types.forEach(function(current) {
  835.                 option = document.createElement('option');
  836.                 option.setAttribute('value', current.id);
  837.                 option.appendChild(document.createTextNode(current.name));
  838.  
  839.                 select.appendChild(option);
  840.             });
  841.  
  842.             td = document.createElement('td');
  843.             tr.appendChild(td);
  844.  
  845.             td.appendChild(document.createTextNode('Вид боя:'));
  846.  
  847.             td = document.createElement('td');
  848.             tr.appendChild(td);
  849.  
  850.             select = document.createElement('select');
  851.             select.id = script_name + 'BTSelect';
  852.             select.style.width = '150px';
  853.             select.title = 'Поиск по конкретному виду боя';
  854.             td.appendChild(select);
  855.  
  856.             option = document.createElement('option');
  857.             option.setAttribute('value', empty_option);
  858.             select.appendChild(option);
  859.  
  860.             battle_types.forEach(function(current) {
  861.                 option = document.createElement('option');
  862.                 option.setAttribute('value', current.id);
  863.                 option.appendChild(document.createTextNode(current.name));
  864.  
  865.                 select.appendChild(option);
  866.             });
  867.  
  868.             td = document.createElement('td');
  869.             tr.appendChild(td);
  870.  
  871.             var chb = document.createElement('input');
  872.             chb.type = 'checkbox';
  873.             chb.title = 'При включении будет использоваться фильтр по типу и/или виду боя';
  874.             chb.id = script_name + 'BTChb';
  875.             td.appendChild(chb);
  876.  
  877.             td.appendChild(document.createTextNode('использовать фильтр'));
  878.         }
  879.  
  880.         //----------------------------------------------------------------------------//
  881.  
  882.         function draw_third_row(parent) {
  883.             var tr = document.createElement('tr');
  884.             parent.appendChild(tr);
  885.  
  886.             var td = document.createElement('td');
  887.             tr.appendChild(td);
  888.  
  889.             td.appendChild(document.createTextNode('До Х дней:'));
  890.  
  891.             td = document.createElement('td');
  892.             tr.appendChild(td);
  893.  
  894.             var input = document.createElement('input');
  895.             input.id = script_name + 'DaysInput';
  896.             input.type = 'text';
  897.             input.style.width = '150px';
  898.             input.onkeypress = number_input;
  899.             input.title = 'Поиск по количеству дней от текущей даты';
  900.             td.appendChild(input);
  901.  
  902.             td = document.createElement('td');
  903.             tr.appendChild(td);
  904.  
  905.             td.appendChild(document.createTextNode('До Y боев:'));
  906.  
  907.             td = document.createElement('td');
  908.             tr.appendChild(td);
  909.  
  910.             input = document.createElement('input');
  911.             input.id = script_name + 'CountInput';
  912.             input.type = 'text';
  913.             input.style.width = '150px';
  914.             input.onkeypress = number_input;
  915.             input.title = 'Поиск по количеству боев';
  916.             td.appendChild(input);
  917.  
  918.             td = document.createElement('td');
  919.             tr.appendChild(td);
  920.  
  921.             var chb = document.createElement('input');
  922.             chb.type = 'checkbox';
  923.             chb.title = 'При включении будет использоваться фильтр по количеству дней от текущей даты и/или числу боев. Если указан 0 или пусто, поиск осуществляться не будет';
  924.             chb.id = script_name + 'DCChb';
  925.             td.appendChild(chb);
  926.  
  927.             td.appendChild(document.createTextNode('использовать фильтр'));
  928.         }
  929.  
  930.         //----------------------------------------------------------------------------//
  931.  
  932.         function draw_fourth_row(parent) {
  933.             var tr = document.createElement('tr');
  934.             parent.appendChild(tr);
  935.  
  936.             var td = document.createElement('td');
  937.             td.setAttribute('colspan', '2');
  938.             td.setAttribute('align', 'left');
  939.             tr.appendChild(td);
  940.  
  941.             var chb = document.createElement('input');
  942.             chb.type = 'checkbox';
  943.             chb.title = 'Искать только максимальный результат в боях (только для ГО/ГН). Например: армия(макс) будет показана, армия(макс-1) уже проигнорируется';
  944.             chb.id = script_name + 'MaxBTChb';
  945.             td.appendChild(chb);
  946.  
  947.             td.appendChild(document.createTextNode('только максимальные бои(ГН/ГО)'));
  948.  
  949.             td = document.createElement('td');
  950.             td.setAttribute('colspan', '3');
  951.             td.setAttribute('align', 'left');
  952.             tr.appendChild(td);
  953.  
  954.             chb = document.createElement('input');
  955.             chb.setAttribute('disabled', ''); // NB: future
  956.             chb.type = 'checkbox';
  957.             chb.title = 'Зарезервировано на будущее';
  958.             chb.id = script_name + 'MaxWinBTChb';
  959.             td.appendChild(chb);
  960.  
  961.             td.appendChild(document.createTextNode('только выигрышные макс. бои(ГН/ГО)'));
  962.         }
  963.  
  964.         //----------------------------------------------------------------------------//
  965.  
  966.         function draw_fifth_row(parent) {
  967.             var tr = document.createElement('tr');
  968.             parent.appendChild(tr);
  969.  
  970.             var td = document.createElement('td');
  971.             td.setAttribute('colspan', '5');
  972.             td.setAttribute('align', 'left');
  973.             tr.appendChild(td);
  974.  
  975.             var chb = document.createElement('input');
  976.             chb.type = 'checkbox';
  977.             chb.title = 'Сохранение результатов поиска в файл (если что-то нашлось)';
  978.             chb.id = script_name + 'SaveFileChb';
  979.             td.appendChild(chb);
  980.  
  981.             td.appendChild(document.createTextNode('сохранять результаты поиска'));
  982.         }
  983.  
  984.         //----------------------------------------------------------------------------//
  985.  
  986.         function remove_div() {
  987.             var div = document.getElementById(script_name + 'Div');
  988.             div.parentNode.removeChild(div);
  989.         }
  990.  
  991.         //----------------------------------------------------------------------------//
  992.  
  993.         function draw_search_table(parent) {
  994.             var table = document.getElementById(script_name + 'SearchTable');
  995.  
  996.             if (table) {
  997.                 set_search_info();
  998.  
  999.                 var trs = table.querySelectorAll('tr:not([id])');
  1000.                 for (var i = 0; i < trs.length; ++i)
  1001.                     table.removeChild(trs[i]);
  1002.  
  1003.                 var el = document.getElementById(script_name + 'Stopper');
  1004.                 el.removeAttribute('disabled');
  1005.             } else {
  1006.                 table = document.createElement('table');
  1007.                 table.style.width = '100%';
  1008.                 table.id = script_name + 'SearchTable';
  1009.                 parent.appendChild(table);
  1010.  
  1011.                 draw_search_header(table);
  1012.                 set_search_info();
  1013.             }
  1014.         }
  1015.  
  1016.         //----------------------------------------------------------------------------//
  1017.  
  1018.         function set_search_info() {
  1019.             var el = document.getElementById(script_name + 'SearchInfo');
  1020.             while (el.firstChild)
  1021.                 el.removeChild(el.firstChild);
  1022.  
  1023.             if (!is_parser_running) {
  1024.                 el.textContent = '';
  1025.                 return;
  1026.             }
  1027.  
  1028.             var chapters = [];
  1029.             chapters.push('Идет поиск по протоколу игрока [ID = ' + settings.id + ']');
  1030.             chapters.push('Фраза для поиска: "' + settings.search + (settings.ci_c ? '" (без учета регистра)' : '" (с учетом регистра)'));
  1031.  
  1032.             if (settings.bt_c) {
  1033.                 var str = '';
  1034.                 if (settings.sbt != empty_option) {
  1035.                     var select = document.getElementById(script_name + 'SBTSelect');
  1036.                     str = 'Тип боя: ' + select.options[select.selectedIndex].text;
  1037.                 }
  1038.  
  1039.                 if (settings.bt != empty_option) {
  1040.                     var select = document.getElementById(script_name + 'BTSelect');
  1041.                     str += (str.length ? ', вид боя: ' : 'Вид боя: ') + select.options[select.selectedIndex].text;
  1042.                 }
  1043.  
  1044.                 if (str.length)
  1045.                     chapters.push(str);
  1046.             }
  1047.  
  1048.             if (settings.dc_c)
  1049.                 chapters.push('До ' + settings.days + ' дней, до ' + settings.count + ' боев');
  1050.  
  1051.             chapters.forEach(function(current) {
  1052.                 el.appendChild(document.createTextNode(current));
  1053.                 el.appendChild(document.createElement('br'));
  1054.             });
  1055.         }
  1056.  
  1057.         //----------------------------------------------------------------------------//
  1058.  
  1059.         function set_progress_info(counter) {
  1060.             var el = document.getElementById(script_name + 'ProgressInfo');
  1061.             while (el.firstChild)
  1062.                 el.removeChild(el.firstChild);
  1063.  
  1064.             var wins = searched.filter(function(current) {
  1065.                 return current.exodus == enum_exodus.win;
  1066.             });
  1067.  
  1068.             var b_str = 'Найдено записей: ' + searched.length;
  1069.             if (searched.length)
  1070.                 b_str += ', побед: ' + wins.length + ', процент побед: ' + (100 * wins.length / searched.length).toFixed(2) + '%';
  1071.  
  1072.             if (!is_parser_running) {
  1073.                 el.textContent = 'Поиск завершен. ' + b_str;
  1074.                 return;
  1075.             }
  1076.  
  1077.             var p_str = 'Обработано ' + counter.current + '/' + counter.last + ' страниц(' + (100 * counter.current / counter.last).toFixed(2) + '%)';
  1078.  
  1079.             el.appendChild(document.createTextNode(p_str));
  1080.             el.appendChild(document.createElement('br'));
  1081.             el.appendChild(document.createTextNode(b_str));
  1082.         }
  1083.  
  1084.         //----------------------------------------------------------------------------//
  1085.  
  1086.         function draw_search_header(parent) {
  1087.             var tr = document.createElement('tr');
  1088.             tr.id = script_name + 'SearchInfoTR';
  1089.             parent.appendChild(tr);
  1090.  
  1091.             var td = document.createElement('td');
  1092.             td.id = script_name + 'SearchInfo';
  1093.             td.setAttribute('colspan', colspan);
  1094.             td.setAttribute('align', 'center');
  1095.             tr.appendChild(td);
  1096.  
  1097.             tr = document.createElement('tr');
  1098.             tr.id = script_name + 'ProgressInfoTR';
  1099.             parent.appendChild(tr);
  1100.  
  1101.             td = document.createElement('td');
  1102.             td.id = script_name + 'ProgressInfo';
  1103.             td.setAttribute('colspan', colspan);
  1104.             td.setAttribute('align', 'center');
  1105.             tr.appendChild(td);
  1106.  
  1107.             tr = document.createElement('tr');
  1108.             tr.id = script_name + 'StopperTR';
  1109.             parent.appendChild(tr);
  1110.  
  1111.             td = document.createElement('td');
  1112.             td.setAttribute('colspan', colspan);
  1113.             td.setAttribute('align', 'center');
  1114.             tr.appendChild(td);
  1115.  
  1116.             var input = document.createElement('input');
  1117.             input.id = script_name + 'Stopper';
  1118.             input.type = 'button';
  1119.             input.value = 'Окончить поиск';
  1120.             input.addEventListener('click', function(e) {
  1121.                 on_stop();
  1122.             });
  1123.             td.appendChild(input);
  1124.  
  1125.             tr = document.createElement('tr');
  1126.             tr.setAttribute('bgColor', '#DCDCDC');
  1127.             tr.id = script_name + 'SearchHeaderTR';
  1128.             parent.appendChild(tr);
  1129.  
  1130.             ['ID боя', 'Дата', 'Описание', 'Исход'].forEach(function(current) {
  1131.                 td = document.createElement('td');
  1132.                 td.textContent = current;
  1133.                 tr.appendChild(td);
  1134.             });
  1135.         }
  1136.  
  1137.         //----------------------------------------------------------------------------//
  1138.         function if_faction(string, id, faction) {
  1139.             let ids = {}
  1140.             for (let i = 1; i < 7; i++) {
  1141.                 let selector = `plid${i}|`
  1142.                 if (!string.includes(selector)) break;
  1143.                 ids[i] = string.split(selector)[1].split("|")[0]
  1144.             }
  1145.             let umka = string.split("umka|")[1].split("|")[0]
  1146.             let tail = 0
  1147.             while (true) {
  1148.                 let head = tail + 14
  1149.                 if (head > umka.length) {
  1150.                     return false
  1151.                     break;
  1152.                 }
  1153.                 let info = umka.slice(tail, head)
  1154.                 if (ids[info.slice(0, 1)] === id.toString() && faction.toLowerCase() === factions[info.slice(1, 2)].toLowerCase()) return true;
  1155.                 tail = head;
  1156.             }
  1157.         }
  1158.  
  1159.         function draw_search_row(parent, obj) {
  1160.             let string = send_get(`${location.protocol}//${location.host}/war.php?lt=-1&warid=${obj.id}`)
  1161.             if (chosen_faction !== undefined) {
  1162.                 if (!if_faction(string, settings.id, chosen_faction)) return
  1163.             }
  1164.             var tr = document.createElement('tr');
  1165.             parent.appendChild(tr);
  1166.  
  1167.             var td = document.createElement('td');
  1168.             var a = document.createElement('a');
  1169.             a.href = '/war.php?lt=-1&warid=' + obj.id + (obj.id_append ? obj.id_append : '');
  1170.             a.textContent = obj.id;
  1171.             td.appendChild(a);
  1172.             td.style.width = '90px';
  1173.             tr.appendChild(td);
  1174.  
  1175.             td = document.createElement('td');
  1176.             td.textContent = obj.date.toLocaleString();
  1177.             td.style.width = '90px';
  1178.             tr.appendChild(td);
  1179.  
  1180.             td = document.createElement('td');
  1181.             td.textContent = obj.desc;
  1182.             tr.appendChild(td);
  1183.  
  1184.             td = document.createElement('td');
  1185.             td.setAttribute('align', 'center');
  1186.             td.style.width = '25px';
  1187.             td.textContent = obj.exodus == enum_exodus.draw ? 'Н' : (obj.exodus == enum_exodus.win ? 'В' : 'П');
  1188.             td.style.backgroundColor = obj.exodus == enum_exodus.draw ? 'grey' : (obj.exodus == enum_exodus.win ? 'green' : 'red');
  1189.             tr.appendChild(td);
  1190.  
  1191.             recheck_rect();
  1192.         }
  1193.  
  1194.         //----------------------------------------------------------------------------//
  1195.  
  1196.         function on_stop() {
  1197.             is_parser_running = false;
  1198.             enable_settings(true);
  1199.             set_search_info();
  1200.             set_progress_info(null);
  1201.             recheck_rect();
  1202.             count_counter = 0;
  1203.             mercenaries = [];
  1204.             hunters = [];
  1205.  
  1206.             document.body.style.cursor = 'default';
  1207.  
  1208.             var el = document.getElementById(script_name + 'Stopper');
  1209.             el.setAttribute('disabled', '');
  1210.  
  1211.             if (save_to_file) {
  1212.                 save_to_file = false;
  1213.                 export_to_file();
  1214.             }
  1215.         }
  1216.  
  1217.         //----------------------------------------------------------------------------//
  1218.  
  1219.         function parse_data() {
  1220.             if (is_parser_running)
  1221.                 return;
  1222.  
  1223.             document.body.style.cursor = 'wait';
  1224.             is_parser_running = true;
  1225.  
  1226.             var counter = {
  1227.                 current: 0,
  1228.                 last: get_last_page()
  1229.             };
  1230.  
  1231.             search_next(counter);
  1232.         }
  1233.  
  1234.         //----------------------------------------------------------------------------//
  1235.  
  1236.         function search_next(counter) {
  1237.             if (!is_parser_running) {
  1238.                 on_stop();
  1239.                 return;
  1240.             }
  1241.  
  1242.             set_progress_info(counter);
  1243.  
  1244.             var url = '/pl_warlog.php?id=' + settings.id + '&page=' + counter.current;
  1245.             send_async_get(url, counter);
  1246.         }
  1247.  
  1248.         //----------------------------------------------------------------------------//
  1249.  
  1250.         function send_async_get(url, counter) {
  1251.             var xhr = new XMLHttpRequest();
  1252.             xhr.open('GET', url, true);
  1253.             xhr.overrideMimeType('text/plain; charset=windows-1251');
  1254.             xhr.onreadystatechange = function() {
  1255.                 if (xhr.readyState == 4) {
  1256.                     if (xhr.status == 200) {
  1257.                         ++counter.current;
  1258.                         search_value(xhr.response);
  1259.  
  1260.                         if (counter.current <= counter.last)
  1261.                             search_next(counter);
  1262.                         else
  1263.                             on_stop();
  1264.                     }
  1265.                 }
  1266.             };
  1267.  
  1268.             xhr.send(null);
  1269.         }
  1270.  
  1271.         //----------------------------------------------------------------------------//
  1272.  
  1273.         function search_value(response_) {
  1274.             var re = /.*?<a href="warlog\.php\?warid=(\d+)(&show_for_all=[^"]+)*">(\d{2}-\d{2}-\d{2}\s\d{2}:\d{2})(.+?)<!--(\d+?)--><br>.*?/gmi;
  1275.  
  1276.             var raw_data = [],
  1277.                 matches = [];
  1278.  
  1279.             while (matches = re.exec(response_))
  1280.                 raw_data.push({ id: +matches[1], id_append: matches[2], battle_date: string_to_date(matches[3]), battle_str: matches[4], battle_type: +matches[5] });
  1281.  
  1282.             raw_data.sort(function(a, b) {
  1283.                 return compare(b.id, a.id);
  1284.             });
  1285.  
  1286.             var table = document.getElementById(script_name + 'SearchTable');
  1287.  
  1288.             raw_data.forEach(function(current) {
  1289.                 //any specific cases
  1290.                 var battle_type = current.battle_type;
  1291.  
  1292.                 switch (battle_type) {
  1293.                     case 0:
  1294.                         var hunt_re = /<i>.+?\(\d+\)(<\/b>)?<\/i>/gmi;
  1295.                         battle_type = hunt_re.test(current.battle_str) ? 0 : -1; // from CommonValuesFiller - hunt or old battles
  1296.                         break;
  1297.  
  1298.                     case 40: // from CommonValuesFiller - tactic guild
  1299.                         var ai_re = /<i>(<b>)?\*.+?\*(<\/b>)?<\//gmi;
  1300.                         var count = 0;
  1301.  
  1302.                         while (ai_re.test(current.battle_str))
  1303.                             ++count;
  1304.  
  1305.                         if (count)
  1306.                             battle_type = count == 3 ? -3 : -4; // from CommonValuesFiller - 3 ai or 2 ai
  1307.                         else {
  1308.                             var splitted = split_pvp_helper(current.battle_str);
  1309.                             var levels_before = splitted[0],
  1310.                                 levels_after = splitted[1];
  1311.  
  1312.                             if (levels_before.length == 1 && levels_after.length == 1)
  1313.                                 battle_type = -5; // from CommonValuesFiller - duel
  1314.                             else if (JSON.stringify(levels_before) == JSON.stringify(levels_after))
  1315.                                 battle_type = -6; // from CommonValuesFiller - pair vs pair
  1316.                             else
  1317.                                 battle_type = -7; // from CommonValuesFiller - mixed
  1318.                         }
  1319.  
  1320.                         break;
  1321.  
  1322.                     case 61: // from CommonValuesFiller - ranger guild
  1323.                         var pvp_re = /.*?pl_info\.php\?id=.*?/gmi;
  1324.                         var count = 0;
  1325.  
  1326.                         while (pvp_re.test(current.battle_str))
  1327.                             ++count;
  1328.  
  1329.                         battle_type = count == 1 ? 61 : -2; // from CommonValuesFiller - ai or pvp
  1330.                         break;
  1331.  
  1332.                     case 89: // from CommonValuesFiller - KBO
  1333.                         var splitted = split_pvp_helper(current.battle_str);
  1334.                         var levels_before = splitted[0],
  1335.                             levels_after = splitted[1];
  1336.                         var hero_on_left_side = splitted[2];
  1337.  
  1338.                         if (levels_before.length == levels_after.length)
  1339.                             if (levels_before.length == 1)
  1340.                                 battle_type = hero_on_left_side ? -12 : -13; // from CommonValuesFiller - attack or defence vs solo player
  1341.                             else
  1342.                                 battle_type = hero_on_left_side ? -8 : -9; // from CommonValuesFiller - attack or defence
  1343.                         else {
  1344.                             if (levels_before.length > levels_after.length)
  1345.                                 battle_type = hero_on_left_side ? -12 : -11; // from CommonValuesFiller - attack or defence vs solo player
  1346.                             else
  1347.                                 battle_type = hero_on_left_side ? -10 : -13; // from CommonValuesFiller - solo attack or defence
  1348.                         }
  1349.  
  1350.                         break;
  1351.  
  1352.                     case 104: // from CommonValuesFiller - tax battles
  1353.                         var splitted = split_pvp_helper(current.battle_str);
  1354.                         var levels_before = splitted[0],
  1355.                             levels_after = splitted[1];
  1356.                         var hero_on_left_side = splitted[2];
  1357.  
  1358.                         if (levels_before.length == levels_after.length)
  1359.                             battle_type = hero_on_left_side ? -14 : -15; // from CommonValuesFiller - attack or defence
  1360.                         else
  1361.                             battle_type = hero_on_left_side ? -16 : -17; // from CommonValuesFiller - attack or defence vs/as solo player
  1362.  
  1363.                         break;
  1364.                 }
  1365.  
  1366.                 var win_re = /<b>(.+?)<\/b>/gmi;
  1367.                 var win_matches = win_re.exec(current.battle_str);
  1368.  
  1369.                 var exodus = enum_exodus.win;
  1370.  
  1371.                 if (!win_matches)
  1372.                     exodus = enum_exodus.draw;
  1373.                 else {
  1374.                     var win = win_matches[1].indexOf(settings.id) != -1;
  1375.  
  1376.                     while (win_matches = win_re.exec(current.battle_str))
  1377.                         if (!win)
  1378.                             win = win_matches[1].indexOf(settings.id) != -1;
  1379.  
  1380.                     exodus = win ? enum_exodus.win : enum_exodus.loss;
  1381.                 }
  1382.  
  1383.                 var text_re = /.*?>([^<]+?)<.*?/gmi;
  1384.                 var desc = '';
  1385.                 var text_matches = [];
  1386.  
  1387.                 while (text_matches = text_re.exec(current.battle_str))
  1388.                     desc += text_matches[1];
  1389.  
  1390.                 var obj = { id: current.id, id_append: current.id_append, date: current.battle_date, desc: clear_specific_symbols(desc), exodus: exodus, bt: battle_type, original_bt: current.battle_type, raw_desc: current.battle_str };
  1391.  
  1392.                 var is_suit = is_suitable(obj);
  1393.                 if (is_parser_running && is_suit) {
  1394.                     searched.push(obj);
  1395.                     draw_search_row(table, obj);
  1396.                 }
  1397.  
  1398.                 if (settings.dc_c) {
  1399.                     if (settings.count && is_suit && settings.count <= ++count_counter)
  1400.                         is_parser_running = false;
  1401.  
  1402.                     var date = new Date();
  1403.                     date.setDate(date.getDate() - settings.days);
  1404.                     if (settings.days && obj.date <= date)
  1405.                         is_parser_running = false;
  1406.                 }
  1407.             });
  1408.         }
  1409.  
  1410.         //----------------------------------------------------------------------------//
  1411.  
  1412.         function split_pvp_helper(text) {
  1413.             var splitter = text.split('> vs <');
  1414.             if (splitter.length != 2)
  1415.                 throw new Error('Incorrect splitter length');
  1416.  
  1417.             var levels_before = [],
  1418.                 levels_after = [];
  1419.             var pvp_re = /.*?pl_info\.php\?id=.*?>.+?\[(\d+)]/gmi;
  1420.  
  1421.             var pvp_matches = [];
  1422.             while (pvp_matches = pvp_re.exec(splitter[0]))
  1423.                 levels_before.push(pvp_matches[1]);
  1424.  
  1425.             while (pvp_matches = pvp_re.exec(splitter[1]))
  1426.                 levels_after.push(pvp_matches[1]);
  1427.  
  1428.             if (!(levels_before.length && levels_after.length))
  1429.                 throw new Error('Incorrect levels length');
  1430.  
  1431.             var hero_on_left = splitter[0].indexOf('font color=red') != -1;
  1432.  
  1433.             return [levels_before, levels_after, hero_on_left];
  1434.         }
  1435.  
  1436.         //----------------------------------------------------------------------------//
  1437.  
  1438.         function clear_specific_symbols(str) {
  1439.             var res = str;
  1440.  
  1441.             [': ', '• ', '&omega;&nbsp;', '&pi;&nbsp;', '&tau;&nbsp;', '&deg;&nbsp;', '•• ', '&#9674;&nbsp;'].forEach(function(current) {
  1442.                 if (!res.indexOf(current))
  1443.                     res = res.substring(current.length);
  1444.             });
  1445.  
  1446.             return res;
  1447.         }
  1448.  
  1449.         //----------------------------------------------------------------------------//
  1450.  
  1451.         function is_suitable(obj) {
  1452.             if (settings.search.length) {
  1453.                 var desc = settings.ci_c ? obj.desc.toLowerCase() : obj.desc;
  1454.                 var search = settings.ci_c ? settings.search.toLowerCase() : settings.search;
  1455.  
  1456.                 if (desc.indexOf(search) == -1)
  1457.                     return false;
  1458.             }
  1459.  
  1460.             var bt = CV.get_battle_type(obj.bt);
  1461.  
  1462.             if (settings.bt_c) {
  1463.                 if (settings.sbt != empty_option)
  1464.                     if (bt.sbt != +settings.sbt)
  1465.                         return false;
  1466.  
  1467.                 if (settings.bt != empty_option && +settings.bt != obj.bt && +settings.bt != obj.original_bt)
  1468.                     return false;
  1469.             }
  1470.  
  1471.             if (settings.dc_c) {
  1472.                 if (settings.count && settings.count <= count_counter)
  1473.                     return false;
  1474.  
  1475.                 var date = new Date();
  1476.                 date.setDate(date.getDate() - settings.days);
  1477.                 if (settings.days && obj.date <= date)
  1478.                     return false;
  1479.             }
  1480.  
  1481.             var max_choosed = (settings.max_bt_c || settings.max_win_bt_c),
  1482.                 suitable_type = (bt.sbt == CV.enum_sbt.hunter || bt.sbt == CV.enum_sbt.mercenary);
  1483.  
  1484.             if (max_choosed && suitable_type) {
  1485.                 if (bt.sbt == CV.enum_sbt.mercenary) {
  1486.                     var re = obj.exodus == enum_exodus.loss ? /<i><b>(.+?)\s{(\d+)}<\/b><\/i>/gmi : /<i>(.+?)\s{(\d+)}<\/i>/gmi;
  1487.                     var matches = re.exec(obj.raw_desc);
  1488.  
  1489.                     if (!matches) {
  1490.                         re = obj.exodus == enum_exodus.loss ? /<b><i>(.+?)\s{(\d+)}<\/i><\/b>/gmi : /<i>(.+?)\s{(\d+)}<\/i>/gmi;
  1491.                         matches = re.exec(obj.raw_desc);
  1492.                     }
  1493.  
  1494.                     if (!matches && obj.exodus == enum_exodus.draw) {
  1495.                         re = /<i>(.+?)\s{(\d+)}<\/i>/gmi;
  1496.                         matches = re.exec(obj.raw_desc);
  1497.                     }
  1498.  
  1499.                     var merc = get_mercenary(matches[1]);
  1500.  
  1501.                     if (merc)
  1502.                         return false;
  1503.  
  1504.                     mercenaries.push({ str: matches[1], lvl: +matches[2], exodus: obj.exodus });
  1505.                 } else if (bt.sbt == CV.enum_sbt.hunter) {
  1506.                     var re = obj.exodus == enum_exodus.loss ? /<i><b>(.+?)\s\((\d+)\)<\/b><\/i>/gmi : /<i>(.+?)\s\((\d+)\)<\/i>/gmi;
  1507.                     var matches = re.exec(obj.raw_desc);
  1508.  
  1509.                     if (!matches) {
  1510.                         re = obj.exodus == enum_exodus.loss ? /<b><i>(.+?)\s\((\d+)\)<\/i><\/b>/gmi : /<i>(.+?)\s\((\d+)\)<\/i>/gmi;
  1511.                         matches = re.exec(obj.raw_desc);
  1512.                     }
  1513.  
  1514.                     if (!matches && obj.exodus == enum_exodus.draw) {
  1515.                         re = /<i>(.+?)\s\((\d+)\)<\/i>/gmi;
  1516.                         matches = re.exec(obj.raw_desc);
  1517.                     }
  1518.  
  1519.                     var hunt = get_hunter(matches[1]);
  1520.  
  1521.                     if (hunt)
  1522.                         return false;
  1523.  
  1524.                     hunters.push({ str: matches[1], count: +matches[2], exodus: obj.exodus });
  1525.                 }
  1526.             }
  1527.  
  1528.             return true;
  1529.         }
  1530.  
  1531.         //----------------------------------------------------------------------------//
  1532.  
  1533.         function get_mercenary(str) {
  1534.             for (var i = 0; i < mercenaries.length; ++i)
  1535.                 if (mercenaries[i].str == str)
  1536.                     return mercenaries[i];
  1537.  
  1538.             return null;
  1539.         }
  1540.  
  1541.         //----------------------------------------------------------------------------//
  1542.  
  1543.         function get_hunter(str) {
  1544.             for (var i = 0; i < hunters.length; ++i)
  1545.                 if (hunters[i].str == str)
  1546.                     return hunters[i];
  1547.  
  1548.             return null;
  1549.         }
  1550.  
  1551.         //----------------------------------------------------------------------------//
  1552.  
  1553.         function enable_settings(enable) {
  1554.             ['IDInput', 'SearchInput', 'CIChb', 'SBTSelect', 'BTSelect', 'BTChb', 'DaysInput',
  1555.                 'CountInput', 'DCChb', 'MaxBTChb', /*'MaxWinBTChb', */ 'StartInput', 'SaveFileChb'
  1556.             ].forEach(function(current) {
  1557.                 var el = document.getElementById(script_name + current);
  1558.                 enable ? el.removeAttribute('disabled') : el.setAttribute('disabled', '');
  1559.             });
  1560.         }
  1561.  
  1562.         //----------------------------------------------------------------------------//
  1563.  
  1564.         function reload_battle_types() {
  1565.             var el = document.getElementById(script_name + 'SBTSelect');
  1566.             var val = el.options[el.selectedIndex].value;
  1567.  
  1568.             el = document.getElementById(script_name + 'BTSelect');
  1569.             while (el.options.length)
  1570.                 el.removeChild(el.options[0]);
  1571.  
  1572.             var tmp_bt = battle_types;
  1573.  
  1574.             if (val != empty_option)
  1575.                 tmp_bt = tmp_bt.filter(function(current) {
  1576.                     return current.sbt == val;
  1577.                 });
  1578.  
  1579.             var option = document.createElement('option');
  1580.             option.setAttribute('value', empty_option);
  1581.             el.appendChild(option);
  1582.  
  1583.             tmp_bt.forEach(function(current) {
  1584.                 option = document.createElement('option');
  1585.                 option.setAttribute('value', current.id);
  1586.  
  1587.                 var text = document.createTextNode(current.name);
  1588.                 option.appendChild(text);
  1589.  
  1590.                 el.appendChild(option);
  1591.             });
  1592.         }
  1593.  
  1594.         //----------------------------------------------------------------------------//
  1595.  
  1596.         function load_settings() {
  1597.             var settings_ = load_value(script_name + 'Settings');
  1598.  
  1599.             if (settings_)
  1600.                 return JSON.parse(settings_);
  1601.  
  1602.             settings_ = {
  1603.                 id: '',
  1604.                 search: '',
  1605.                 sbt: empty_option,
  1606.                 bt: empty_option,
  1607.                 days: '',
  1608.                 count: '',
  1609.                 ci_c: false,
  1610.                 bt_c: false,
  1611.                 dc_c: false,
  1612.                 max_bt_c: false,
  1613.                 max_win_bt_c: false
  1614.             };
  1615.  
  1616.             return settings_;
  1617.         }
  1618.  
  1619.         //----------------------------------------------------------------------------//
  1620.  
  1621.         function save_settings() {
  1622.             var errors = [];
  1623.  
  1624.             var id = +document.getElementById(script_name + 'IDInput').value;
  1625.             if (isNaN(id) || id < 1)
  1626.                 errors.push('Идентификатор игрока выражается положительным числом');
  1627.  
  1628.             var search = document.getElementById(script_name + 'SearchInput').value.trim();
  1629.             var bt_c = document.getElementById(script_name + 'BTChb').checked;
  1630.  
  1631.             if (!bt_c && !search.length)
  1632.                 errors.push('Не указаны условия поиска');
  1633.  
  1634.             var dc_c = document.getElementById(script_name + 'DCChb').checked;
  1635.             var days = +document.getElementById(script_name + 'DaysInput').value;
  1636.             var count = +document.getElementById(script_name + 'CountInput').value;
  1637.  
  1638.             if (dc_c) {
  1639.                 var days_correct = !isNaN(days) && days >= 1;
  1640.                 var count_correct = !isNaN(count) && count >= 1;
  1641.  
  1642.                 if (!days_correct && !count_correct)
  1643.                     errors.push('Не указано количество дней и/или боев поиска');
  1644.             }
  1645.  
  1646.             var max_bt_c = document.getElementById(script_name + 'MaxBTChb').checked;
  1647.             var max_win_bt_c = document.getElementById(script_name + 'MaxWinBTChb').checked;
  1648.  
  1649.             if (max_bt_c && max_win_bt_c)
  1650.                 errors.push('Поиск макс. и макс. выигрышных боев не может осуществляться одновременно');
  1651.  
  1652.             if (errors.length) {
  1653.                 alert('Ошибки при сохранении:\n\n' + errors.join('\n'));
  1654.                 return false;
  1655.             }
  1656.  
  1657.             var select = document.getElementById(script_name + 'SBTSelect');
  1658.             settings.sbt = select.options[select.selectedIndex].value;
  1659.  
  1660.             select = document.getElementById(script_name + 'BTSelect');
  1661.             settings.bt = select.options[select.selectedIndex].value;
  1662.  
  1663.             settings.id = id;
  1664.             settings.search = search;
  1665.             settings.days = days;
  1666.             settings.count = count;
  1667.  
  1668.             settings.ci_c = document.getElementById(script_name + 'CIChb').checked;
  1669.             settings.bt_c = bt_c;
  1670.             settings.dc_c = dc_c;
  1671.             settings.max_bt_c = max_bt_c;
  1672.             settings.max_win_bt_c = max_win_bt_c;
  1673.  
  1674.             settings.save_file = document.getElementById(script_name + 'SaveFileChb').checked;
  1675.  
  1676.             save_value(script_name + 'Settings', JSON.stringify(settings));
  1677.             return true;
  1678.         }
  1679.  
  1680.         //----------------------------------------------------------------------------//
  1681.  
  1682.         function set_settings() {
  1683.             var el = document.getElementById(script_name + 'IDInput');
  1684.             el.value = settings.id;
  1685.  
  1686.             el = document.getElementById(script_name + 'SearchInput');
  1687.             el.value = settings.search;
  1688.  
  1689.             el = document.getElementById(script_name + 'CIChb');
  1690.             el.checked = settings.ci_c;
  1691.  
  1692.             el = document.getElementById(script_name + 'SBTSelect');
  1693.  
  1694.             for (var i = 0; i < el.options.length; ++i)
  1695.                 if (el.options[i].value == settings.sbt) {
  1696.                     el.options[i].selected = true;
  1697.                     break;
  1698.                 }
  1699.  
  1700.             reload_battle_types();
  1701.  
  1702.             el = document.getElementById(script_name + 'BTSelect');
  1703.  
  1704.             for (var i = 0; i < el.options.length; ++i)
  1705.                 if (el.options[i].value == settings.bt) {
  1706.                     el.options[i].selected = true;
  1707.                     break;
  1708.                 }
  1709.  
  1710.             el = document.getElementById(script_name + 'BTChb');
  1711.             el.checked = settings.bt_c;
  1712.  
  1713.             el = document.getElementById(script_name + 'DaysInput');
  1714.             el.value = settings.days;
  1715.  
  1716.             el = document.getElementById(script_name + 'CountInput');
  1717.             el.value = settings.count;
  1718.  
  1719.             el = document.getElementById(script_name + 'DCChb');
  1720.             el.checked = settings.dc_c;
  1721.  
  1722.             el = document.getElementById(script_name + 'MaxBTChb');
  1723.             el.checked = settings.max_bt_c;
  1724.  
  1725.             el = document.getElementById(script_name + 'MaxWinBTChb');
  1726.             el.checked = settings.max_win_bt_c;
  1727.  
  1728.             el = document.getElementById(script_name + 'SaveFileChb');
  1729.             el.checked = settings.save_file;
  1730.         }
  1731.  
  1732.         //----------------------------------------------------------------------------//
  1733.  
  1734.         function clear_settings() {
  1735.             if (is_parser_running)
  1736.                 return;
  1737.  
  1738.             remove_value(script_name + 'Settings');
  1739.             settings = load_settings();
  1740.             set_settings();
  1741.         }
  1742.  
  1743.         //----------------------------------------------------------------------------//
  1744.  
  1745.         function get_last_page() {
  1746.             var url = '/pl_warlog.php?id=' + settings.id + '&page=999999';
  1747.             var response = send_get(url);
  1748.             var page = /a class="active" href="#">(\d+?)</gmi.exec(response);
  1749.  
  1750.             return page ? (+page[1] - 1) : 0;
  1751.         }
  1752.  
  1753.         //----------------------------------------------------------------------------//
  1754.  
  1755.         function recheck_rect() {
  1756.             var div = document.getElementById(script_name + 'Div');
  1757.             var trs = div.querySelectorAll('tr');
  1758.  
  1759.             var height = 40;
  1760.             for (var i = 0; i < trs.length; ++i)
  1761.                 height += trs[i].clientHeight;
  1762.  
  1763.             div.style.height = height > 700 ? 700 : height;
  1764.             div.style.overflowY = height > 700 ? 'scroll' : 'hidden';
  1765.         }
  1766.  
  1767.         //----------------------------------------------------------------------------//
  1768.  
  1769.         function export_to_file() {
  1770.             if (!searched.length)
  1771.                 return;
  1772.  
  1773.             var linebreak = '\n';
  1774.             var res = ['ID боя', 'Описание', 'Результат'].join(';') + linebreak;
  1775.  
  1776.             searched.forEach(function(current) {
  1777.                 res += [current.id + (current.id_append ? current.id_append : ''), current.desc, current.exodus].join(';') + linebreak;
  1778.             });
  1779.  
  1780.             save_file(res, 'Сейчас будет предложено сохранить файл с результатами. Переименуйте его в формат .csv, разделитель - ";"');
  1781.         }
  1782.  
  1783.         //----------------------------------------------------------------------------//
  1784.  
  1785.     } catch (e) {
  1786.         alert('Ошибка в скрипте ' + script_name + ', обратитесь к разработчику:\n' + e);
  1787.         throw e;
  1788.     }
  1789. }()); // wrapper end
  1790.  
  1791. //----------------------------------------------------------------------------//
Add Comment
Please, Sign In to add comment