// ==UserScript==
// @name hwmAdvancedPlayerInfo
// @author alex_kocharin 2008-2012, Demin 2013-2015, Tamozhnya1 2024
// @namespace Tamozhnya1
// @version 17.4
// @description Добавляет в инфу персов и на домашнюю: ХП армии, очки и загрузку навыков, баланс рулетки и таверны, сумму умений, день рождения персонажа
// @include /^https{0,1}:\/\/(www|my)\.(heroeswm|lordswm)\.(ru|com)\/(home|pl_info)\.php/
// @grant GM_deleteValue
// @grant GM_getValue
// @grant GM_setValue
// @grant GM.xmlHttpRequest
// @license MIT
// ==/UserScript==
if(typeof GM_deleteValue != 'function') {
this.GM_getValue = function(key, def) { return localStorage[key] || def; };
this.GM_setValue = function(key, value) { localStorage[key] = value; };
this.GM_deleteValue = function(key) { return delete localStorage[key]; };
}
const playerIdMatch = document.cookie.match(/pl_id=(\d+)/);
if(playerIdMatch) {
var PlayerId = playerIdMatch[1];
}
const windowObject = window.wrappedJSObject || unsafeWindow;
const lang = document.documentElement.lang || (location.hostname == "www.lordswm.com" ? "en" : "ru");
const isEn = lang == "en";
let playerFraction;
if(location.pathname == '/home.php') {
// for new home page
let currentFractionIconContainer = document.querySelector("div.home_css_pl_fract.show_hint");
if(!currentFractionIconContainer) {
currentFractionIconContainer = document.querySelector("a[href^='castle.php?change_faction_dialog']");
}
if(currentFractionIconContainer) {
const currentFractionIconImg = currentFractionIconContainer.querySelector("img");
playerFraction = currentFractionIconImg.src.split("i/f/r")[1].split(".png")[0];
}
} else {
const playerFractionExec = /\/i\/f\/r(\d+)\.png/.exec(document.querySelector("body").innerHTML);
//console.log(playerFractionExec);
if(!playerFractionExec) {
console.log("Unknown player fraction");
return;
};
playerFraction = playerFractionExec[1];
//console.log(playerFraction);
}
const isNewPersonPage = document.querySelector("div#hwm_no_zoom") ? true : false;
let playerLevel;
if(isNewPersonPage) {
const levelInfoCell = Array.from(document.querySelectorAll("div.home_pers_info")).find(x => x.innerHTML.includes(isEn ? "Combat level" : "Боевой уровень"));
playerLevel = parseInt(levelInfoCell.querySelector("div[id=bartext] > span").innerText);
} else {
playerLevel = parseInt(new RegExp(`<b>${isEn ? "Combat level" : "Боевой уровень"}: (\\d+?)<\\/b>`).exec(document.documentElement.innerHTML)[1]) || 0;
}
const artsInfo = {
'2year_amul_lords': [2],
'3arrows': [5],
'3year_amul': [2],
'3year_art': [3],
'4year_klever': [3],
'5years_star': [5],
a_mallet: [1],
amf_body: [8],
amf_boot: [7],
amf_cl: [8],
amf_helm: [6],
amf_scroll: [8],
amf_weap: [11],
antifire_cape: [3],
barb_armor: [6],
barb_boots: [6],
barb_club: [7],
barb_helm: [4],
barb_shield: [6],
bfly: [5],
blacksword: [10],
blacksword1: [10],
bludgeon: [9],
bril_pendant: [6],
bril_ring: [5],
brush_2010y: [15],
brush_2011y: [15],
brush_2012y: [15],
bunt_medal1: [11],
bunt_medal2: [6],
bunt_medal3: [4],
bwar1: [15],
bwar2: [12],
bwar3: [10],
bwar4: [8],
bwar5: [7],
bwar6: [6],
bwar7: [5],
bwar_splo: [8],
bwar_stoj: [8],
bwar_takt: [8],
centaurbow: [5],
d_spray: [4],
darkelfboots: [7],
darkelfciras: [7],
darkelfcloack: [6],
darkelfcloak: [6],
darkelfkaska: [6],
darkelfpendant: [9],
darkelfstaff: [10],
defender_dagger: [2],
dem_amulet: [9],
dem_armor: [6],
dem_axe: [10],
dem_bootshields: [6],
dem_dmech: [6],
dem_dtopor: [11],
dem_helmet: [6],
dem_kosa: [9],
dem_shield: [6],
demwar1: [14],
demwar2: [11],
demwar3: [9],
demwar4: [7],
demwar5: [5],
demwar6: [4],
druid_amulet: [11],
druid_armor: [8],
druid_boots: [7],
druid_cloack: [8],
druid_staff: [11],
dubina: [11],
elfamulet: [9],
elfboots: [7],
elfbow: [8],
elfshirt: [7],
elfwar1: [13],
elfwar2: [11],
elfwar3: [8],
elfwar4: [7],
elfwar5: [6],
elfwar6: [4],
finecl: [6],
flower_heart: [1],
flowers1: [1],
flowers2: [1],
flowers3: [4],
flowers4: [5],
flowers5: [5],
gdubina: [7],
gm_3arrows: [5],
gm_abow: [6],
gm_amul: [5],
gm_arm: [5],
gm_defence: [5],
gm_hat: [4],
gm_kastet: [8],
gm_protect: [6],
gm_rring: [2],
gm_spdb: [2],
gm_sring: [2],
gm_sword: [8],
gmage_armor: [8],
gmage_boots: [7],
gmage_cloack: [8],
gmage_crown: [6],
gmage_scroll: [8],
gmage_staff: [11],
gnome_hammer: [2],
gnomearmor: [6],
gnomeboots: [5],
gnomehammer: [9],
gnomehelmet: [5],
gnomem_amulet: [11],
gnomem_armor: [8],
gnomem_boots: [7],
gnomem_hammer: [10],
gnomem_helmet: [6],
gnomem_shield: [7],
gnomeshield: [6],
gnomewar1: [15],
gnomewar2: [12],
gnomewar3: [10],
gnomewar4: [8],
gnomewar5: [7],
gnomewar6: [6],
gnomewar7: [5],
gnomewar_splo: [8],
gnomewar_stoj: [8],
gnomewar_takt: [8],
goldciras: [4],
half_heart_m: [2],
half_heart_w: [2],
hunter_amulet1: [3],
hunter_armor1: [3],
hunter_arrows1: [3],
hunter_boots1: [1],
hunter_boots2: [2],
hunter_boots3: [2],
hunter_bow1: [2],
hunter_bow2: [3],
hunter_gloves1: [1],
hunter_hat1: [1],
hunter_helm: [2],
hunter_jacket1: [1],
hunter_mask1: [3],
hunter_pendant1: [1],
hunter_ring1: [2],
hunter_ring2: [3],
hunter_roga1: [2],
hunter_shield1: [2],
hunter_sword1: [1],
hunterboots: [1],
hunterdagger: [2],
hunterdsword: [4],
huntershield2: [3],
huntersword2: [4],
inq_body: [9],
inq_boot: [7],
inq_cl: [8],
inq_helm: [6],
inq_weap: [12],
kn_body: [6],
kn_helm: [5],
kn_shield: [6],
kn_weap: [9],
knightarmor: [6],
knightboots: [5],
knighthelmet: [5],
knightshield: [6],
knightsword: [9],
koltsou: [6],
kopie: [9],
kwar1: [15],
kwar2: [12],
kwar3: [10],
kwar4: [8],
kwar5: [7],
kwar6: [6],
kwar7: [5],
kwar_splo: [8],
kwar_stoj: [8],
kwar_takt: [8],
lizard_armor: [2],
lizard_boots: [2],
lizard_helm: [2],
mage_boots: [7],
mage_cape: [6],
mage_hat: [6],
mage_robe: [7],
mage_scroll: [8],
mage_staff: [11],
magewar1: [12],
magewar2: [9],
magewar3: [7],
magewar4: [5],
magewar5: [4],
mart8_flowers1: [4],
mart8_ring1: [5],
merc_armor: [6],
merc_boots: [6],
merc_dagger: [6],
merc_sword: [8],
meshok: [2],
meshok2: [2],
molot_tan: [12],
necr_amulet: [5],
necr_helm: [5],
necr_robe: [5],
necr_staff: [6],
necrwar1st: [14],
necrwar2st: [10],
necrwar3st: [6],
necrwar4st: [4],
necrwar5st: [2],
nv_body: [7],
nv_boot: [6],
nv_helm: [6],
nv_shield: [7],
nv_weap: [10],
ny_bag: [3],
ny_beard: [2],
ny_bell: [5],
ny_candle: [4],
ny_cap: [4],
ny_dfur: [5],
ny_fir: [7],
ny_flaps: [3],
ny_fur: [5],
ny_furcap: [6],
ny_gloves: [3],
ny_horns: [3],
ny_icicle: [4],
ny_muff: [3],
ny_rat: [4],
ny_ring: [7],
ny_sbag: [5],
ny_sock: [4],
ny_staff: [4],
ny_star: [4],
ny_toy: [4],
paladin_armor: [8],
paladin_boots: [7],
paladin_bow: [8],
paladin_helmet: [6],
paladin_shield: [7],
paladin_sword: [11],
pen: [9],
pen_2010y: [15],
pen_2011y_clan: [15],
pen_2012y: [15],
pika: [9],
protazan: [2],
ring_of_thief: [5],
rog_demon: [10],
roses: [9],
round_shiled: [1],
ru_statue: [10],
sea_trident: [7],
sh_4arrows: [7],
sh_amulet2: [7],
sh_armor: [7],
sh_boots: [4],
sh_bow: [8],
sh_cloak: [8],
sh_helmet: [6],
sh_ring1: [6],
sh_ring2: [4],
sh_shield: [7],
sh_spear: [10],
sh_sword: [10],
shpaga: [10],
slayersword: [11],
snowflake_1: [4],
snowflake_2: [6],
soul_cape: [2],
staff2010: [1],
sword5: [5],
sunart1: [7],
sunart2: [9],
sunart3: [11],
sunart4: [12],
sv_arb: [8],
sv_body: [8],
sv_boot: [7],
sv_helm: [6],
sv_shield: [7],
sv_weap: [11],
tact1w1_wamulet: [10],
tact765_bow: [7],
tactaz_axe: [11],
tactcv1_armor: [9],
tactdff_shield: [8],
tacthapp_helmet: [8],
tactmag_staff: [10],
tactms1_mamulet: [10],
tactpow_cloack: [9],
tactsm0_dagger: [8],
tactspw_mring: [7],
tactwww_wring: [7],
tactzl4_boots: [9],
testring: [6],
thief_arb: [9],
thief_cape: [5],
thief_fastboots: [6],
thief_goodarmor: [6],
thief_ml_dagger: [7],
thief_msk: [5],
thief_neckl: [8],
thief_premiumring1: [8],
thief_premiumring2: [7],
thief_premiumring3: [6],
thief_unique_secretops: [3],
tl_medal1: [9],
tl_medal2: [4],
tl_medal3: [3],
tm_amulet: [11],
tm_arb: [12],
tm_armor: [10],
tm_boots: [8],
tm_cape: [7],
tm_knife: [11],
tm_mring: [8],
tm_msk: [8],
tm_wring: [8],
topor_skelet: [7],
tunnel_kirka: [7],
v_1armor: [9],
ve_helm: [8],
venok: [2],
verb11_sword: [11],
verbboots: [9],
vrb_shild: [8],
warmor: [6],
warthief_medal1: [7],
warthief_medal2: [6],
warthief_medal3: [5],
warthief_medal4: [4],
warthief_medal5: [3],
wboots: [6],
welfarmor: [6],
welfboots: [5],
welfbow: [6],
welfhelmet: [5],
welfshield: [6],
welfsword: [9],
whelmet: [6],
wolfjacket: [2],
zub: [10],
r_bigsword: [13],
r_magy_staff: [13],
r_dagger: [8],
r_goodscroll: [9],
r_bootsmb: [10],
r_zarmor: [10],
r_clck: [11],
r_bow: [7],
r_warriorsamulet: [11],
r_m_amulet: [11],
r_warring: [7],
r_magicsring: [7],
r_helmb: [10],
tj_helmet3: [7],
tj_helmet2: [9],
tj_helmet1: [12],
tjarmor3: [7],
tjarmor2: [10],
tjarmor1: [12],
tj_vboots3: [7],
tj_vboots2: [9],
tj_vboots1: [12],
necrohelm3: [9],
necrohelm2: [8],
necrohelm1: [4],
'6ring': [5],
goblin_bow: [8],
orc_axe: [12],
ogre_bum: [14],
ogre_helm: [12],
orc_hat: [8],
ring2013: [3],
sharik: [4],
meshok_2014: [3],
meshok2_2014: [3],
snowjinka: [4],
sosulka: [4],
'tj-shield3': [7],
'tj-shield2': [9],
'tj-shield1': [10],
'7ka': [7],
tjam3: [7],
tjam2: [9],
tjam1: [12],
n_sword: [1],
n_helmet: [1],
n_armor: [1],
n_boots: [1],
n_shield: [1],
n_amul: [2],
n_ringd: [1],
n_ringa: [1],
n_clk: [1],
gargoshield: [8],
battlem_cape: [11],
magneticarmor: [14],
'v-ring3': [5],
'v-ring2': [6],
'v-ring1': [8],
wshield: [6],
trinitypendant: [7],
quest_pendant1: [1],
dragon_crown: [5],
blackring: [4],
dudka: [5],
windsword: [10],
pegaskop: [14],
elfdagger: [12],
sniperbow: [8],
vtjcloak3: [5],
vtjcloak2: [7],
vtjcloak1: [8],
coldring_n: [6 + Math.floor(playerLevel / 4)],
cold_sword2014: [4 + Math.floor(playerLevel / 2)],
sun_armor: [1 + Math.floor(playerLevel / 2)],
cold_shieldn: [5 + Math.floor(playerLevel / 4)],
piratehat3: [7],
piratehat2: [9],
piratehat1: [12],
ttring: [4],
'8amul_inf': [8],
vbow3: [5],
vbow2: [6],
vbow1: [8],
pir_armor3: [7],
pir_armor2: [9],
pir_armor1: [12],
vbolt3: [5],
vbolt2: [6],
vbolt1: [8],
neut_amulet: [10],
bshield3: [7],
bshield2: [9],
bshield1: [10],
compass: [7],
lbow: [7],
ankh1: [7],
obereg: [4],
runkam: [4],
sandglass: [3],
rdagger1: [9],
trogloditkop: [10],
dagger_dex: [4],
dagger_myf: [6],
dagger16: [7],
dagger20: [8],
super_dagger: [7],
clover_amul: [11],
pn_ring1: [13],
sun_ring: [6],
imp_helmet: [14],
imp_amul: [19],
imp_ring: [17],
imp_armor: [14],
imp_cloak: [11],
imp_crossbow: [10],
imp_sword: [17],
imp_boots: [15],
imp_shield: [15],
imp_dagger: [14],
wood_sword: [1, 20.00],
gnome_hammer: [2, 12.00],
steel_blade: [2, 15.83],
dagger: [1, 32.00],
def_sword: [3, 32.98],
shortbow: [1, 17.45],
staff: [6, 64.50],
requital_sword: [5, 64.50],
broad_sword: [6, 80.33],
long_bow: [4, 129.00],
sor_staff: [8, 124.92],
power_sword: [8, 124.76],
mstaff8: [8, 98.27],
ssword8: [8, 97.95],
mif_staff: [9, 239.03],
mif_sword: [9, 247.34],
mstaff10: [9, 113.71],
ssword10: [9, 110.13],
energy_scroll: [6, 131.91],
composite_bow: [5, 153.07],
mm_staff: [10, 247.76],
mm_sword: [10, 250.81],
mstaff13: [10, 122.45],
ssword13: [10, 122.22],
bow14: [6, 156.23],
ffstaff15: [11, 257.87],
firsword15: [11, 257.74],
smstaff16: [11, 134.73],
ssword16: [11, 134.30],
bow17: [7, 163.69],
staff18: [12, 266.86],
scroll18: [9, 155.00],
sword18: [12, 267.00],
leatherhat: [1, 15.00],
leather_helm: [1, 21.33],
knowledge_hat: [2, 39.96],
chain_coif: [2, 39.27],
wizard_cap: [2, 46.54],
mage_helm: [4, 66.92],
steel_helmet: [3, 53.61],
shelm8: [3, 40.73],
mif_lhelmet: [5, 76.49],
mif_hhelmet: [5, 91.87],
shelm12: [5, 67.90],
mhelmetzh13: [6, 93.11],
zxhelmet13: [6, 93.11],
myhelmet15: [7, 96.03],
xymhelmet15: [7, 96.44],
shelm16: [7, 70.80],
helmet17: [8, 108.86],
mhelmet17: [8, 108.86],
bravery_medal: [2, 22.88],
amulet_of_luck: [2, 39.16],
power_pendant: [7, 125.60],
samul8: [7, 115.40],
warrior_pendant: [8, 164.30],
magic_amulet: [7, 171.10],
wzzamulet13: [9, 169.75],
mmzamulet13: [9, 169.75],
smamul14: [9, 148.73],
samul14: [9, 148.73],
bafamulet15: [9, 169.82],
mmzamulet16: [10, 172.35],
wzzamulet16: [10, 172.35],
samul17: [10, 154.00],
smamul17: [10, 154.00],
mamulet19: [11, 178.77],
amulet19: [11, 178.77],
leather_shiled: [1, 15.06],
leatherplate: [2, 46.23],
hauberk: [3, 58.42],
ciras: [4, 64.99],
mage_armor: [5, 91.18],
mif_light: [5, 91.17],
sarmor9: [5, 63.27],
full_plate: [6, 125.84],
wiz_robe: [7, 136.76],
miff_plate: [7, 133.99],
sarmor13: [7, 88.26],
robewz15: [8, 135.80],
armor15: [8, 135.80],
sarmor16: [8, 100.95],
marmor17: [9, 140.00],
armor17: [9, 142.71],
scoutcloack: [1, 15.50],
soul_cape: [2, 40.73],
antiair_cape: [3, 49.78],
powercape: [4, 136.28],
scloack8: [4, 69.83],
antimagic_cape: [5, 101.06],
wiz_cape: [7, 148.23],
cloackwz15: [8, 151.02],
scloack16: [8, 108.63],
cloack17: [9, 161.54],
round_shiled: [1, 15.71],
s_shield: [2, 18.07],
defender_shield: [3, 28.85],
sshield5: [4, 73.70],
dragon_shield: [5, 128.03],
large_shield: [6, 139.67],
sshield11: [6, 98.92],
shield13: [7, 148.40],
sshield14: [7, 105.42],
shield16: [8, 150.20],
sshield17: [8, 120.86],
shield19: [9, 157.43],
leatherboots: [1, 14.50],
hunter_boots: [1, 31.03],
boots2: [2, 29.91],
shoe_of_initiative: [3, 60.85],
steel_boots: [4, 84.39],
mif_lboots: [6, 132.80],
sboots9: [5, 72.73],
mif_hboots: [6, 121.77],
sboots12: [6, 87.29],
wiz_boots: [6, 125.80],
boots13: [7, 124.01],
mboots14: [8, 128.73],
boots15: [8, 124.84],
sboots16: [8, 110.23],
boots17: [9, 130.57],
mboots17: [9, 130.57],
i_ring: [1, 17.40],
sring4: [2, 39.40],
doubt_ring: [2, 90.50],
verve_ring: [2, 89.44],
rashness_ring: [2, 65.63],
circ_ring: [4, 132.88],
powerring: [4, 132.40],
smring10: [5, 100.33],
sring10: [5, 97.30],
warriorring: [5, 170.95],
darkring: [5, 171.10],
magring13: [6, 174.92],
warring13: [6, 174.92],
bring14: [6, 176.53],
wwwring16: [6, 176.54],
mmmring16: [6, 176.54],
smring17: [6, 102.00],
sring17: [6, 98.93],
ring19: [7, 183.08],
mring19: [7, 184.46],
flowers1: [1, 35.00],
flowers2: [1, 35.00],
venok: [2, 35.00],
defender_dagger: [2, 93.33],
flower_heart: [3, 87.50],
flowers3: [4, 233.33],
half_heart_m: [2, 210.00],
half_heart_w: [2, 210.00],
bril_pendant: [6, 490.00],
bril_ring: [5, 875.00],
d_spray: [5, 233.33],
flowers4: [5, 210.00],
flowers5: [5, 210.00],
protazan: [2, 218.75],
wboots: [6, 350.00],
roses: [9, 218.75],
goldciras: [4, 280.00],
warmor: [6, 350.00],
whelmet: [6, 350.00],
shpaga: [10, 466.67],
bfly: [5, 1050.00],
koltsou: [6, 612.50],
dagger_dex: [4, 121],
dagger_myf: [6, 151.33],
dagger16: [7, 160],
dagger20: [8, 163],
dring5: [4, 92],
dring9: [6, 211.2],
dring12: [6, 216.31],
dring15: [8, 218.57],
dring18: [9, 222.86],
dring21: [10, 227.14]
};
const unitsHealth = {
peasant: [1, 4],
conscript: [1, 6],
archer: [1, 7],
marksman: [1, 10],
footman: [1, 16],
squire: [1, 26],
griffon: [1, 30],
impergriffin: [1, 35],
priest: [1, 54],
inquisitor: [1, 80],
cavalier: [1, 90],
paladin: [1, 100],
angel: [1, 180],
archangel: [1, 220],
brute: [101, 8],
crossman: [101, 8],
vindicator: [101, 23],
battlegriffon: [101, 52],
zealot: [101, 80],
champion: [101, 100],
seraph2: [101, 220],
skeleton: [2, 4],
skeletonarcher: [2, 4],
zombie: [2, 17],
plaguezombie: [2, 17],
ghost: [2, 8],
spectre: [2, 19],
vampire: [2, 30],
vampirelord: [2, 35],
lich: [2, 50],
archlich: [2, 55],
wight: [2, 95],
wraith: [2, 100],
bonedragon: [2, 150],
spectraldragon: [2, 160],
sceletonwar: [102, 5],
rotzombie: [102, 23],
poltergeist: [102, 20],
vampireprince: [102, 40],
masterlich: [102, 55],
banshee: [102, 110],
ghostdragon: [102, 150],
gremlin: [3, 5],
mastergremlin: [3, 6],
stone_gargoyle: [3, 15],
obsgargoyle: [3, 20],
iron_golem: [3, 18],
steelgolem: [3, 24],
mage: [3, 18],
archmage: [3, 30],
djinn: [3, 40],
djinn_sultan: [3, 45],
rakshasa_rani: [3, 120],
rakshasa_raja: [3, 140],
colossus: [3, 175],
titan: [3, 190],
saboteurgremlin: [103, 6],
elgargoly: [103, 16],
magneticgolem: [103, 28],
battlemage: [103, 29],
djinn_vizier: [103, 50],
rakshasa_kshatra: [103, 135],
stormtitan: [103, 190],
pixel: [4, 5],
sprite: [4, 6],
dancer: [4, 12],
wardancer: [4, 12],
elf: [4, 10],
masterhunter: [4, 14],
druid: [4, 34],
druideld: [4, 38],
unicorn: [4, 57],
silverunicorn: [4, 77],
treant: [4, 175],
ancienent: [4, 181],
greendragon: [4, 200],
emeralddragon: [4, 200],
dryad_: [104, 6],
winddancer: [104, 14],
arcaneelf: [104, 12],
ddhigh: [104, 34],
pristineunicorn: [104, 80],
savageent: [104, 175],
crystaldragon: [104, 200],
goblin: [5, 3],
hobgoblin: [5, 4],
wolfrider: [5, 10],
wolfraider: [5, 12],
orc: [5, 12],
orcchief: [5, 18],
ogre: [5, 50],
ogremagi: [5, 65],
rocbird: [5, 55],
thunderbird: [5, 65],
cyclop: [5, 85],
cyclopking: [5, 95],
behemoth: [5, 210],
ancientbehemoth: [5, 250],
goblinarcher: [105, 3],
boarrider: [105, 14],
orcrubak: [105, 20],
ogrebrutal: [105, 70],
firebird: [105, 65],
cyclopod: [105, 100],
dbehemoth: [105, 280],
goblinmag: [205, 3],
orcshaman: [205, 13],
darkbird: [205, 60],
hyenarider: [205, 13],
ogreshaman: [205, 55],
shamancyclop: [205, 105],
cursedbehemoth: [205, 250],
scout: [6, 10],
assassin: [6, 14],
stalker: [6, 15],
maiden: [6, 16],
fury: [6, 16],
bloodsister: [6, 24],
minotaur: [6, 31],
minotaurguard: [6, 35],
taskmaster: [6, 40],
darkrider: [6, 40],
grimrider: [6, 50],
briskrider: [6, 50],
hydra: [6, 80],
deephydra: [6, 125],
foulhydra: [6, 125],
witch: [6, 80],
shadow_witch: [6, 90],
mistress: [6, 100],
shadowdragon: [6, 200],
blackdragon: [6, 240],
reddragon: [6, 235],
imp: [7, 4],
familiar: [7, 6],
horneddemon: [7, 13],
hornedoverseer: [7, 13],
hellhound: [7, 15],
cerberus: [7, 15],
succubus: [7, 20],
succubusmis: [7, 30],
hellcharger: [7, 50],
stallion: [7, 66],
pitfiend: [7, 110],
pitlord: [7, 120],
devil: [7, 166],
archdevil: [7, 199],
vermin: [107, 6],
jdemon: [107, 13],
hotdog: [107, 15],
seducer: [107, 26],
hellkon: [107, 66],
pity: [107, 140],
archdemon: [107, 211],
defender: [8, 7],
shieldguard: [8, 12],
spearwielder: [8, 10],
skirmesher: [8, 12],
bearrider: [8, 25],
blackbearrider: [8, 30],
brawler: [8, 20],
berserker: [8, 25],
runepriest: [8, 60],
runepatriarch: [8, 70],
thane: [8, 100],
thunderlord: [8, 120],
firedragon: [8, 230],
magmadragon: [8, 280],
mountaingr: [108, 12],
harpooner: [108, 10],
whitebearrider: [108, 30],
battlerager: [108, 30],
runekeeper: [108, 65],
flamelord: [108, 120],
lavadragon: [108, 275],
goblinus: [9, 3],
trapper: [9, 4],
fcentaur: [9, 6],
ncentaur: [9, 9],
warrior: [9, 12],
mauler: [9, 12],
shamaness: [9, 30],
sdaughter: [9, 35],
slayer: [9, 34],
executioner: [9, 40],
wyvern: [9, 90],
foulwyvern: [9, 105],
cyclopus: [9, 220],
untamedcyc: [9, 225],
goblinshaman: [109, 5],
mcentaur: [109, 10],
warmong: [109, 20],
eadaughter: [109, 35],
chieftain: [109, 48],
poukai: [109, 120],
bloodeyecyc: [109, 235],
scorp: [10, 4],
scorpup: [10, 5],
duneraider: [10, 12],
duneraiderup: [10, 12],
shakal: [10, 24],
shakalup: [10, 30],
dromad: [10, 40],
dromadup: [10, 45],
priestmoon: [10, 50],
priestsun: [10, 55],
slon: [10, 100],
slonup: [10, 110],
anubis: [10, 160],
anubisup: [10, 200]
};
const perkBranchCosts = {
1: {
knight_mark: 5,
attack: 9,
defense: 8,
luck: 10,
leadership: 7,
dark: 8,
light: 7
},
101: {
benediction: 7,
defense: 10,
leadership: 10,
enlightenment: 8,
light: 6,
summon: 10,
sorcery: 7
},
2: {
necr_soul: 5,
defense: 11,
enlightenment: 9,
dark: 7,
summon: 8,
sorcery: 8
},
102: {
powerraise: 6,
attack: 11,
luck: 12,
enlightenment: 8,
summon: 6,
sorcery: 7
},
3: {
magic_mirror: 7,
enlightenment: 9,
light: 10,
summon: 8,
destructive: 10,
sorcery: 7
},
103: {
nomagicdamage: 7,
attack: 8,
luck: 10,
leadership: 9,
enlightenment: 8,
destructive: 9,
sorcery: 8
},
4: {
elf_shot: 7,
attack: 10,
defense: 9,
luck: 7,
leadership: 10,
enlightenment: 10,
light: 7,
summon: 9
},
104: {
zakarrow: 4,
attack: 9,
defense: 8,
luck: 10,
leadership: 8,
enlightenment: 12
},
5: {
barb_skill: 7,
attack: 7,
defense: 9,
luck: 9,
leadership: 10
},
105: {
save_rage: 6,
attack: 7,
defense: 8,
luck: 7,
leadership: 9
},
205: {
dark_blood: 5,
defense: 9,
luck: 10,
leadership: 10,
enlightenment: 8,
dark: 6,
sorcery: 7
},
6: {
dark_power: 7,
attack: 8,
luck: 9,
leadership: 10,
enlightenment: 10,
dark: 8,
destructive: 9,
sorcery: 7
},
106: {
cre_master: 5,
attack: 8,
defense: 11,
leadership: 8,
luck: 10,
enlightenment: 8,
dark: 8
},
7: {
hellfire: 6,
attack: 7,
defense: 9,
luck: 10,
dark: 8,
destructive: 10,
sorcery: 8
},
107: {
consumecorpse: 5,
defense: 9,
enlightenment: 9,
dark: 6,
sorcery: 7
},
8: {
runeadv: 7,
defense: 9,
destructive: 11,
light: 7,
leadership: 9,
luck: 10
},
108: {
firelord: 5,
attack: 7,
defense: 10,
leadership: 8,
luck: 8,
destructive: 6,
},
9: {
memoryblood: 6,
attack: 7,
enlightenment: 9,
leadership: 9,
luck: 10,
defense: 9
},
10: {
dayandnight: 7,
attack: 8,
defense: 10,
leadership: 10,
light: 6,
dark: 6,
sorcery: 9,
enlightenment: 9
}
};
main();
async function main() {
//battleCostAndAmmunitionPoints();
tavernAndRouletteBalances();
countExp();
birthday();
await getTalentsToHome();
if(location.pathname == "/pl_info.php") {
talentsStatistics();
}
calcArmyHealth(); // После загрузки навыков, если она есть, чтоб обработать навык "vitality"
setTimeout(function() {
const talentsChanger = document.getElementById("hwmSetsMasterSkillSetSelectedValue");
const armyChanger = document.getElementById("hwmSetsMasterArmySetSelectedValue");
if(talentsChanger) {
if(location.pathname == "/pl_info.php" && getUrlParamValue(location.href, "id") == PlayerId) {
observe([talentsChanger], talentsStatistics);
}
if(location.pathname == "/home.php" || location.pathname == "/pl_info.php" && getUrlParamValue(location.href, "id") == PlayerId) {
const panels = [armyChanger];
if(location.pathname == "/pl_info.php" && getUrlParamValue(location.href, "id") == PlayerId) {
panels.push(talentsChanger);
}
observe(panels, calcArmyHealth);
}
}
}, 1500); // Здесь ждем загрузки hwmSetsMaster, чтоб подписаться на элемент hwmSetsMasterSkillSetSelectedValue и hwmSetsMasterArmySetSelectedValue
}
async function getTalentsToHome() {
if(playerLevel < 5) {
return;
}
if(location.pathname == '/home.php') {
let hwmAdvancedPlayerInfoTalentsContainer = document.getElementById("hwmAdvancedPlayerInfoTalentsContainer");
if(!hwmAdvancedPlayerInfoTalentsContainer) {
let homePageTalentsContainer;
if(isNewPersonPage) {
homePageTalentsContainer = document.querySelector("div.home_friends_block");
} else {
homePageTalentsContainer = document.querySelector("body > center > table:nth-child(2) > tbody > tr:nth-child(1) > td:nth-child(1) > table > tbody > tr:nth-child(2) > td:nth-child(1) > table > tbody > tr > td > table > tbody > tr > td");
}
addElement("br", homePageTalentsContainer);
const ShowTalentsTitleSpan = addElement("span", homePageTalentsContainer, { id: "hwmAdvancedPlayerInfoTalentsCaptionContainer", innerHTML: ` » <b>${isEn ? "Talents" : "Навыки"}:</b><b id="hwmAdvancedPlayerInfoTalentsPointsContainer"></b>`, title: getShowTalentsTitleSpanTitle() });
ShowTalentsTitleSpan.addEventListener("click", function() { setValue("ShowTalents", !getBool("ShowTalents")); this.title = getShowTalentsTitleSpanTitle(); getTalentsToHomeCore(); }, false);
addElement("br", homePageTalentsContainer);
hwmAdvancedPlayerInfoTalentsContainer = addElement("div", homePageTalentsContainer, { id: "hwmAdvancedPlayerInfoTalentsContainer" });
}
await getTalentsToHomeCore();
const talentsChanger = document.getElementById("hwmSetsMasterSkillSetSelectedValue");
if(talentsChanger) {
observe([talentsChanger], getTalentsToHomeCore);
//setTimeout(function() { observe([talentsChanger], getTalentsToHomeCore); }, 3000);
}
}
}
async function getTalentsToHomeCore() {
if(location.pathname == '/home.php' && getBool("ShowTalents")) {
const doc = await getRequest(`/pl_info.php?id=${PlayerId}`);
const perksTable = getParent(doc.querySelector("a[href^='showperkinfo.php']"), "table", 2);
if(perksTable) {
Array.from(perksTable.querySelectorAll("a[href^='showperkinfo.php'] > img")).forEach(x => { x.style.width = `48px`; x.style.height = "auto"; });
//Array.from(perksTable.querySelectorAll("a[href^='showperkinfo.php'] > img")).forEach(x => { x.setAttribute("title", x.getAttribute("hint")); x.style.width = `48px`; x.style.height = "auto"; });
document.getElementById("hwmAdvancedPlayerInfoTalentsContainer").innerHTML = perksTable.outerHTML;
if(typeof windowObject.hwm_hints_init === 'function') windowObject.hwm_hints_init();
talentsStatistics();
calcArmyHealth();
}
}
}
function getShowTalentsTitleSpanTitle() { return isEn ? `Click for ${getBool("ShowTalents") ? "disable" : "enable"} talents loading` : `Нажмите для ${getBool("ShowTalents") ? "выключения" : "включения"} загрузки навыков`; }
function battleCostAndAmmunitionPoints() {
let left_td;
let arts_td;
Array.from(document.querySelectorAll('img')).forEach(x => {
if(x.src.indexOf('/i/icons/attr_initiative.png') !== -1 && !left_td) {
if(Array.from(x.parentNode.parentNode.parentNode.querySelectorAll('img')).length >= 7) {
left_td = x.parentNode.parentNode.parentNode;
}
} else if(x.src.match(/\/i\/transport\/\d+\.png/) || x.src.match(/\/i\/slots_png\/slot0010.png/) || x.src.match(/\/i\/deer/)) {
arts_td = x.parentNode.parentNode.parentNode;
}
});
if(!left_td || !arts_td) {
return;
}
let ammunitionPointsTotal = 0;
let craftTotal = 0;
const unknownArts = [];
let battleCostTotal = 0;
let unknown_cost = false;
const artsRefs = Array.from(document.querySelectorAll("div[id^=slot] a[href^='art_info.php?id=']"));
artsRefs.forEach(x => {
const hint = x.querySelector("img[hint]").getAttribute("hint");
const craftExec = /\[(([IDN]\d{1,2})?(E\d{1,2})?(A\d{1,2})?(W\d{1,2})?(F\d{1,2})?)\]/.exec(hint);
let craftRate = 1;
if(craftExec) {
const craftInfo = craftExec[1];
const craftExec2 = craftInfo.match(/\d{1,2}/g);
const craftSum = craftExec2.reduce((t, x) => t + parseInt(x), 0);
//console.log(craftExec2)
craftTotal += craftSum;
craftRate += craftSum * 0.02;
unknown_cost = true;
//console.log(`craftInfo: ${craftInfo}, craftSum: ${craftSum}, craftRate: ${craftRate}`);
}
const artName = getUrlParamValue(x.href, "id");
const artInfo = artsInfo[artName];
if(artInfo) {
ammunitionPointsTotal += Math.floor(artInfo[0] * craftRate);
if(artInfo.length > 1) {
battleCostTotal += artInfo[1];
} else {
unknown_cost = true;
}
} else {
unknownArts.push(artName);
unknown_cost = true;
}
});
left_td.insertAdjacentHTML("beforeend", `
<tr height="23">
<td align="center">
<img title="${isEn ? "AP" : "ОА"}" src="https://dcdn.heroeswm.ru/i/icons/attr_oa.png?v=1" width="24" height="24" />
</td>
<td id="unknownArtsCell" align="center">
<b>${ammunitionPointsTotal}</b>
</td>
</tr>`);
const unknownArtsCell = document.getElementById("unknownArtsCell");
if(unknownArts.length > 0) {
const text_unknown_art = isEn ? 'Arts not found: %s. Contact developer.' : "Не найдены артефакты: %s. Сообщите разработчику.";
const hint = text_unknown_art.replace('%s', unknownArts.join(', '));
unknownArtsCell.insertAdjacentHTML("beforeend", ` (<a href="javascript:alert('${hint}');" title="${hint}">?</a>)`);
}
if(craftTotal > 0) {
left_td.insertAdjacentHTML("beforeend", `
<tr height="23">
<td align="center">
<img title="${isEn ? "Craft" : "Крафт"}" src="/i/mod_common.gif" width="18" height="18" />
</td>
<td align="center">
<b>${craftTotal}%</b>
</td>
</tr>`);
}
if(battleCostTotal > 0) {
left_td.insertAdjacentHTML("beforeend", `
<tr height="23">
<td align="center">
<img title="${isEn ? "Cost per battle" : "Цена за бой"}" src="https://dcdn2.heroeswm.ru/i/r/48/gold.png?v=3.23de65" width="24" height="24" />
</td>
<td align="center">
<b>${(Math.round(battleCostTotal) + (unknown_cost ? '+' : ''))}</b>
</td>
</tr>`);
}
}
function talentsStatistics() {
if(playerLevel < 5) {
return;
}
let talentsContainer;
let talentsCaptionContainer;
let talentsPointsContainer;
if(location.pathname == "/home.php") {
talentsContainer = document.getElementById("hwmAdvancedPlayerInfoTalentsContainer");
talentsCaptionContainer = document.getElementById("hwmAdvancedPlayerInfoTalentsCaptionContainer");
talentsPointsContainer = document.getElementById("hwmAdvancedPlayerInfoTalentsPointsContainer");
}
if(location.pathname == "/pl_info.php") {
talentsContainer = getParent(document.querySelector("a[href^='showperkinfo.php?name=']"), "td", 3);
const layerTable = getParent(talentsContainer, "table");
talentsCaptionContainer = Array.from(layerTable.rows[0].cells).find(x => x.innerHTML.includes(isEn ? "Talents" : "Навыки")).querySelector("b");
talentsPointsContainer = document.getElementById("hwmAdvancedPlayerInfoTalentsPointsContainer") || addElement("span", talentsCaptionContainer, { id: "hwmAdvancedPlayerInfoTalentsPointsContainer" });
}
if(!talentsContainer || !talentsCaptionContainer) {
return;
}
const talentBranchRows = talentsContainer.querySelectorAll(":scope > table > tbody > tr");
const playerTalentBranches = Array.from(talentBranchRows).map(x => Array.from(x.querySelectorAll("a[href^='showperkinfo.php?name=']")).map(y => getUrlParamValue(y.href, "name")));
//console.log(playerTalentBranches);
let talentPoints = 0;
const playerPerkBranchCosts = perkBranchCosts[playerFraction];
//console.log(playerPerkBranchCosts);
for(const playerPerkBranche of playerTalentBranches) {
let branchName = playerPerkBranche[0];
let firstPerkPromout = 1;
if(["1", "2", "3"].includes(branchName.slice(-1))) {
firstPerkPromout = parseInt(branchName.slice(-1));
branchName = branchName.slice(0, -1);
}
//console.log(`branchName: ${branchName}, branchCost: ${playerPerkBranchCosts[branchName]}, branchePerks: ${playerPerkBranche.length}, firstPerkPromout: ${firstPerkPromout}`);
talentPoints += playerPerkBranchCosts[branchName] * (playerPerkBranche.length + firstPerkPromout - 1);
}
talentsPointsContainer.innerText = ` (${isEn ? "points" : "очки"} ${talentPoints} ${isEn ? "from" : "из"} ${10 + 5 * (playerLevel - 5)})`;
}
function calcArmyHealth() {
let armyContainer;
if(location.pathname == "/pl_info.php") {
armyContainer = getParent(document.querySelector(".cre_creature72"), "center");
}
if(location.pathname == "/home.php") {
if(isNewPersonPage) {
armyContainer = document.querySelector("div.home_css_creature_list");
} else {
armyContainer = getParent(document.querySelector(".cre_creature72"), "center");
}
}
if(!armyContainer) {
return;
}
const creatures = Array.from(document.querySelectorAll(`div.${isNewPersonPage ? "castle_creature54" : "cre_creature72"}`)).filter(x => x.querySelector("div#add_now_count")).map(x => ({ Name: getUrlParamValue(x.querySelector("a[href^='army_info.php?name=']").href, "name"), Amount: parseInt(x.querySelector("div#add_now_count").innerText) }));
const hasVitality = document.querySelector("a[href='showperkinfo.php?name=vitality']") ? true : false;
const sum = creatures.reduce((t, x) => {
const army = unitsHealth[x.Name];
if(army) {
t += x.Amount * (army[1] + (hasVitality ? 2 : 0));
}
return t;
}, 0);
const unknownCreatures = creatures.filter(x => !unitsHealth[x.Name]);
let unknownCreaturesMessage = "";
if(unknownCreatures.length > 0) {
unknownCreaturesMessage = isEn ? `Creatures not found: ${unknownCreatures.map(x => x.Name).join(', ')}. Please, contact developer.` : `Существа не найдены: ${unknownCreatures.map(x => x.Name).join(', ')}. Пожалуйста, сообщите разработчику.`;
}
let hwmAdvancedPlayerInfoArmyHealthContainer = document.getElementById("hwmAdvancedPlayerInfoArmyHealthContainer");
if(!hwmAdvancedPlayerInfoArmyHealthContainer) {
armyContainer.insertAdjacentHTML("afterend", ` » <b>${isEn ? "Total HP" : "Общее HP"}: </b><span id=hwmAdvancedPlayerInfoArmyHealthContainer>${sum}</span>
<a id=hwmAdvancedPlayerInfouUknownCreaturesMessageContainer href="javascript:alert('${unknownCreaturesMessage}');" title="${unknownCreaturesMessage}"> (?)</a>`);
hwmAdvancedPlayerInfoArmyHealthContainer = document.getElementById("hwmAdvancedPlayerInfoArmyHealthContainer");
}
hwmAdvancedPlayerInfoArmyHealthContainer.innerText = sum;
hwmAdvancedPlayerInfoArmyHealthContainer.style.color = hasVitality ? "#ff0000" : "";
const hwmAdvancedPlayerInfouUknownCreaturesMessageContainer = document.getElementById("hwmAdvancedPlayerInfouUknownCreaturesMessageContainer");
hwmAdvancedPlayerInfouUknownCreaturesMessageContainer.style.display = unknownCreaturesMessage ? "" : "none";
hwmAdvancedPlayerInfouUknownCreaturesMessageContainer.title = unknownCreaturesMessage;
hwmAdvancedPlayerInfouUknownCreaturesMessageContainer.href = `javascript:alert('${unknownCreaturesMessage}');`;
}
function tavernAndRouletteBalances() {
if(location.pathname != "/pl_info.php") {
return;
}
// Баланс рулетки
const rouletteDebitText = findChildrenTextContainsValue("td", isEn ? "Roulette bets total" : "Поставлено в рулетке");
const rouletteCreditText = findChildrenTextContainsValue("td", isEn ? "Roulette winnings total" : "Выиграно в рулетке");
if(rouletteDebitText.length == 1 && rouletteCreditText.length == 1 && rouletteDebitText[0].nextSibling.tagName.toLowerCase() == "b" && rouletteCreditText[0].nextSibling.tagName.toLowerCase() == "b") {
const rouletteBalance = rouletteCreditText[0].nextSibling.innerText.replace(/,/g, "") - rouletteDebitText[0].nextSibling.innerText.replace(/,/g, "");
rouletteCreditText[0].nextSibling.insertAdjacentHTML("afterend", `<br> ${isEn ? 'Balance' : 'Баланс'}: <b>${rouletteBalance.toLocaleString()}</b>`);
}
// Баланс таверны
var statisticsSecondCell = getParent(document.querySelector("td.wb > a[href^='pl_transfers.php?id']"), "td").nextSibling;
var tavern_parent = statisticsSecondCell.querySelector("tr").parentNode.childNodes[0].childNodes[1].firstChild.firstChild.childNodes;
const winsRow = tavern_parent[1];
const failsRow = tavern_parent[2];
tavern_parent[0].childNodes[1].setAttribute('style', 'white-space: nowrap;');
winsRow.childNodes[1].setAttribute('style', 'white-space: nowrap;');
//console.log(winsRow)
failsRow.childNodes[1].setAttribute('style', 'white-space: nowrap;');
var tavern_0bal = winsRow.querySelector("tr");
var tavern_1bal = failsRow.querySelector("tr");
if(!tavern_0bal && !tavern_1bal) return;
let wins = 0;
let fails = 0;
if(tavern_0bal) {
wins = parseInt(winsRow.cells[1].querySelector("b").innerText.replace(/,/g, ""));
tavern_0bal.childNodes[1].setAttribute('style', 'text-align: right; padding-right: 5px;');
tavern_0bal = tavern_0bal.childNodes[1].innerHTML.replace(/,/g, "");
winsRow.childNodes[3].firstChild.width = "100%";
var totalRow = winsRow.cloneNode(true);
} else {
tavern_0bal = 0;
}
if(tavern_1bal) {
fails = parseInt(failsRow.cells[1].querySelector("b").innerText.replace(/,/g, ""));
tavern_1bal.childNodes[1].setAttribute('style', 'text-align: right; padding-right: 5px;');
tavern_1bal = tavern_1bal.childNodes[1].innerHTML.replace(/,/g, "");
failsRow.childNodes[3].firstChild.width = "100%";
var totalRow = totalRow || failsRow.cloneNode(true);
} else {
tavern_1bal = 0;
}
var tavern_bal = tavern_0bal - tavern_1bal;
totalRow.firstChild.innerHTML = ` ${isEn ? 'Balance:' : 'Баланс:'}`;
totalRow.childNodes[1].innerHTML = `<b>${(wins - fails).toLocaleString()}</b>`;
totalRow.childNodes[2].innerHTML = " ";
totalRow.childNodes[3].innerHTML = `
<table border="0" cellspacing="0" cellpadding="0" width="100%">
<tbody>
<tr>
<td>
<img class="rs" width="24" height="24" src="https://dcdn2.heroeswm.ru/i/r/48/gold.png?v=3.23de65" border="0" title="${isEn ? "Gold" : "Золото"}" alt="">
</td>
<td style="text-align: right; padding-right: 5px;">
${tavern_bal.toLocaleString()}
</td>
</tr>
</tbody>
</table>`;
failsRow.insertAdjacentElement("afterend", totalRow);
}
function countExp() {
if(location.pathname == '/home.php' || location.pathname == '/pl_info.php') {
const cells = Array.from(document.querySelectorAll("td"));
const skillInfoCell = cells.find(x => x.innerHTML.includes(isEn ? "Knight:" : "Рыцарь:") && x.innerHTML.includes(isEn ? "Enchanters' guild" : "Гильдия Оружейников") && !x.innerHTML.includes("<td"));
if(!skillInfoCell) {
return;
}
let totalSkill = 0;
const regex = /\(([\d\.\,]+)\)/g;
for(let i = 1; i <= 10; i++) {
const skillsData = regex.exec(skillInfoCell.innerHTML);
//console.log(skillsData);
if(skillsData) {
totalSkill += parseFloat(skillsData[1]);
}
}
totalSkill = round00(totalSkill);
const levelInfoBold = Array.from(document.querySelectorAll("td > b")).find(x => x.innerHTML.includes(isEn ? "Combat level:" : "Боевой уровень:"));
const levelInfoCell = levelInfoBold.parentNode;
const expRegex = /\(([\d\.\,]+)\)/g;
const expExec = expRegex.exec(levelInfoCell.innerHTML);
if(!expExec) {
console.log("Parameters hided");
return;
}
const exp = parseInt(expExec[1].replace(/,/g, ""));
const br = levelInfoCell.querySelector("br");
br.parentNode.insertBefore(createElement("span", { innerHTML: ` » <b>${isEn ? "Skills count" : "Сумма умений"}: </b>${totalSkill.toLocaleString()}, ${isEn ? "ratio" : "соотношение"}: <span title="${isEn ? "Expirience points to one skill point" : "Очков опыта на одно очко умения"}">${ Math.round(exp / totalSkill).toLocaleString() }</span>` }), br.nextSibling);
}
}
function birthday() {
if(location.pathname == "/pl_info.php") {
const playerId = getUrlParamValue(location.href, "id");
let bifthday = GM_getValue(`PlayerBifthday${playerId}`, "");
const districtBold = Array.from(document.querySelectorAll("b")).find(x => x.innerHTML.includes(isEn ? "Location" : "Район"));
districtBold.nextElementSibling.nextElementSibling.insertAdjacentHTML("afterend", ` » <b id=hwmAdvancedPlayerInfoBirthdayCaption title="${isEn ? "Click to download birthday" : "Нажмите для загрузки дня рождения"}">${isEn ? "Birthday" : "День рождения"}: </b><span id=hwmAdvancedPlayerInfoBirthday>${bifthday}</span>`);
document.getElementById("hwmAdvancedPlayerInfoBirthdayCaption").addEventListener("click", loadBirthday);
}
}
async function loadBirthday() {
const playerId = getUrlParamValue(location.href, "id");
const firstProtocolPage = await getRequest(`/pl_transfers.php?id=${playerId}&page=50000`);
const lines = firstProtocolPage.querySelector(`div#set_mobile_max_width > div > div`).innerHTML.split("<br>").filter(x => x != "");
bifthday = lines[lines.length - 2];
bifthday = bifthday.replace(/ /g, "");
GM_setValue(`PlayerBifthday${playerId}`, bifthday);
document.getElementById("hwmAdvancedPlayerInfoBirthday").innerHTML = bifthday;
}
// API
function getParent(element, parentType, number = 1) {
if(!element) {
return;
}
let result = element;
let foundNumber = 0;
while(result = result.parentNode) {
if(result.nodeName.toLowerCase() == parentType.toLowerCase()) {
foundNumber++;
if(foundNumber == number) {
return result;
}
}
}
}
function getUrlParamValue(url, paramName) { return (new URLSearchParams(url.split("?")[1])).get(paramName); }
function findChildrenTextContainsValue(selector, value) { return Array.from(document.querySelectorAll(selector)).reduce((t, x) => { const match = Array.from(x.childNodes).filter(y => y.nodeName == "#text" && y.textContent.includes(value)); return [...t, ...match]; }, []); }
function getValue(key, defaultValue) { return GM_getValue(key, defaultValue); };
function setValue(key, value) { GM_setValue(key, value); };
function deleteValue(key) { return GM_deleteValue(key); };
function getPlayerValue(key, defaultValue) { return getValue(`${key}${PlayerId}`, defaultValue); };
function setPlayerValue(key, value) { setValue(`${key}${PlayerId}`, value); };
function deletePlayerValue(key) { return deleteValue(`${key}${PlayerId}`); };
function getPlayerBool(valueName, defaultValue = false) { return getBool(valueName + PlayerId, defaultValue); }
function getBool(valueName, defaultValue = false) {
const value = getValue(valueName);
//console.log(`valueName: ${valueName}, value: ${value}, ${typeof(value)}`)
if(value) {
if(typeof(value) == "string") {
return value == "true";
}
if(typeof(value) == "boolean") {
return value;
}
}
return defaultValue;
}
function round00(value) { return Math.round(value * 100) / 100; }
function getParent(element, parentType, number = 1) {
if(!element) {
return;
}
let result = element;
let foundNumber = 0;
while(result = result.parentNode) {
if(result.nodeName.toLowerCase() == parentType.toLowerCase()) {
foundNumber++;
if(foundNumber == number) {
return result;
}
}
}
}
function addElement(type, parent, data) {
let el = createElement(type, data);
if(parent) {
parent.appendChild(el);
}
return el;
}
function createElement(type, data) {
let el = document.createElement(type);
if(data) {
for(let key in data) {
if(key == "innerText" || key == "innerHTML") {
el[key] = data[key];
} else {
el.setAttribute(key, data[key]);
}
}
}
return el;
}
function getRequest(url, overrideMimeType) {
return new Promise((resolve, reject) => {
GM.xmlHttpRequest({ method: "GET", url: url, overrideMimeType: overrideMimeType || "text/html; charset=windows-1251",
onload: function(response) { resolve((new DOMParser).parseFromString(response.responseText, "text/html")); },
onerror: function(error) { reject(error); }
});
});
}
function observe(targets, handler, config = { childList: true, subtree: true }) {
targets = Array.isArray(targets) ? targets : [targets];
targets = targets.map(x => { if(typeof x === 'function') { return x(document); } return x; }); // Можем передавать не элементы, а их селекторы
const ob = new MutationObserver(async function(mut, observer) {
//console.log(`Mutation start`);
observer.disconnect();
if(handler.constructor.name === 'AsyncFunction') {
await handler();
} else {
handler();
}
for(const target of targets) {
if(target) {
observer.observe(target, config);
}
}
});
for(const target of targets) {
if(target) {
ob.observe(target, config);
}
}
}