您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
Extension for HeroWarsHelper script
// ==UserScript== // @name HWHhuntFragmentExt // @name:en HWHhuntFragmentExt // @name:ru HWHhuntFragmentExt // @namespace HWHhuntFragmentExt // @version 0.0.49 // @description Extension for HeroWarsHelper script // @description:en Extension for HeroWarsHelper script // @description:ru Расширение для скрипта HeroWarsHelper // @author dimaka1256 // @license Copyright dimaka1256 // @homepage none // @icon https://zingery.ru/scripts/VaultBoyIco16.ico // @icon64 https://zingery.ru/scripts/VaultBoyIco64.png // @match https://www.hero-wars.com/* // @match https://apps-1701433570146040.apps.fbsbx.com/* // @run-at document-start // ==/UserScript== (function () { if (!this.HWHClasses) { console.log('%cObject for extension not found', 'color: red'); return; } console.log('%cStart Extension ' + GM_info.script.name + ', v' + GM_info.script.version + ' by ' + GM_info.script.author, 'color: red'); const { addExtentionName } = HWHFuncs; addExtentionName(GM_info.script.name, GM_info.script.version, GM_info.script.author); const { setProgress, getSaveVal, setSaveVal, popup, I18N, getUserInfo, } = HWHFuncs; let {buttons,i18nLangData} = HWHData; let ruLang ={ FRAGMENT_HUNT: 'Слить энку', FRAGMENT_HUNT_TITLE: 'Добывать фрагменты шмоток/рецептов', FRAGMENT_HUNT_SETUP: '⚙️', FRAGMENT_HUNT_SETUP_TITLE: 'Выбор фрагмента/миссии', FRAGMENT_HUNT_ENERGY: '⚡️', FRAGMENT_HUNT_FR: '🧩', FRAGMENT_HUNT_MISSION: 'миссия', FRAGMENT_HUNT_WORLD: 'Глава', FRAGMENT_HUNT_SPENT: 'Потратили ', FRAGMENT_HUNT_GOTFRAGMENTS: ', получили такой лут:', FRAGMENT_HUNT_PCS: 'шт', FRAGMENT_HUNT_WEHUNT: 'Добываем предметы', FRAGMENT_HUNT_ENOUGH1: ', хватит на ', FRAGMENT_HUNT_ENOUGH2: ' рейдов x10', FRAGMENT_HUNT_CHANGE: 'Выбрать', FRAGMENT_HUNT_PARTS1: 'Фиол шмот', FRAGMENT_HUNT_PARTS2: 'Фиол свитки А-О', FRAGMENT_HUNT_PARTS3: 'Фиол свитки П-Я', FRAGMENT_HUNT_PARTS4: 'Жёлтый шмот', FRAGMENT_HUNT_PARTS5: 'Жёлтые свитки А-К', FRAGMENT_HUNT_PARTS6: 'Жёлтые свитки Л-Я', FRAGMENT_HUNT_PARTS7: 'Красный шмот', FRAGMENT_HUNT_PARTS8: 'Красные свитки', FRAGMENT_HUNT_CHOOSEPART: 'Какую категорию шмотки ищём?', FRAGMENT_HUNT_CHOOSEITEM: 'Какую шмотку ищём?', FRAGMENT_HUNT_CHOOSEMISSION: 'В какой миссии? (см. ещё дроп)', FRAGMENT_HUNT_NOTENOUGH: 'Недостаточно энергии', FRAGMENT_HUNT_NOMISSION: 'Не выбрана миссия, нечего добывать', FRAGMENT_HUNT_DOALL: 'Слить энку на миссию', FRAGMENT_HUNT_NOVIP: 'Сорри, без VIP1 не работает', FRAGMENT_HUNT_SMALLVIP: 'Без VIP5 бьёт одиночными рейдами', } let enLang ={ FRAGMENT_HUNT: 'Spend Stamina', FRAGMENT_HUNT_TITLE: 'Hunt for Item/Scroll fragment', FRAGMENT_HUNT_SETUP: '⚙️', FRAGMENT_HUNT_SETUP_TITLE: 'Choose fragment/mission', FRAGMENT_HUNT_ENERGY: '⚡️', FRAGMENT_HUNT_SPENT: 'Spent ', FRAGMENT_HUNT_FR: '🧩', FRAGMENT_HUNT_MISSION: 'mission', FRAGMENT_HUNT_WORLD: 'World', FRAGMENT_HUNT_GOTFRAGMENTS: ',g ot this loot:', FRAGMENT_HUNT_PCS: 'pcs', FRAGMENT_HUNT_WEHUNT: 'We hunt for items', FRAGMENT_HUNT_ENOUGH1: ', enough for ', FRAGMENT_HUNT_ENOUGH2: ' raids x10', FRAGMENT_HUNT_CHANGE: 'Choose', FRAGMENT_HUNT_PARTS1: 'Purple gear', FRAGMENT_HUNT_PARTS2: 'Purple scrolls 1', FRAGMENT_HUNT_PARTS3: 'Purple scrolls 2', FRAGMENT_HUNT_PARTS4: 'Yellow gear', FRAGMENT_HUNT_PARTS5: 'Yellow scrolls 1', FRAGMENT_HUNT_PARTS6: 'Yellow scrolls 2', FRAGMENT_HUNT_PARTS7: 'Red gear', FRAGMENT_HUNT_PARTS8: 'Red scrolls', FRAGMENT_HUNT_CHOOSEPART: 'Choose fragment category:', FRAGMENT_HUNT_CHOOSEITEM: 'Choose fragment:', FRAGMENT_HUNT_CHOOSEMISSION: 'Choose mission(look at other drop)', FRAGMENT_HUNT_NOTENOUGH: 'Not enough stamina', FRAGMENT_HUNT_NOMISSION: 'Mission not chosen', FRAGMENT_HUNT_DOALL: 'Consume stamina to a mission', FRAGMENT_HUNT_NOVIP: 'This requires at least VIP1 to run', FRAGMENT_HUNT_SMALLVIP: 'Only single raids without VIP5', } Object.assign(i18nLangData.ru, ruLang) Object.assign(i18nLangData.en, enLang) this.HWHData.i18nLangData = i18nLangData; const fragmentHuntButton = { fragmentHuntButton: { isCombine: true, combineList: [ { get name() { return I18N('FRAGMENT_HUNT'); }, get title() { return I18N('FRAGMENT_HUNT_TITLE'); }, onClick: gohuntFragment, hide: false, color: 'red' }, { get name() { return I18N('FRAGMENT_HUNT_SETUP'); }, get title() { return I18N('FRAGMENT_HUNT_SETUP_TITLE'); }, onClick: setuphuntFragment, hide: false, color: 'red' }, ] }} Object.assign(buttons,fragmentHuntButton) this.HWHData.buttons = buttons; function setuphuntFragment() { let fragment= new huntFragment(); fragment.setup(); } function gohuntFragment() { let fragment= new huntFragment(); fragment.start(); } //добавить галочку в "сделать всё" //я буду гореть за это в аду const task = { name: 'gohuntFragment', label: I18N('FRAGMENT_HUNT_DOALL'), checked: false } const functions2 = { gohuntFragment } const {doYourBest} = HWHClasses; const doIt = new doYourBest(); let myfuncList=doIt.funcList myfuncList.splice (-3,0,task); let myfunctions = doIt.functions Object.assign(myfunctions, functions2) class extdoYourBest extends doYourBest { funcList = myfuncList functions = myfunctions } this.HWHClasses.doYourBest = extdoYourBest; class huntFragment { inventoryGet = [] droptable = [] stamina = 0 raids = 0 missionID = 0 energyNeeded = 0 missionEnergy (id) { if (id == 0) {return 999999}; if (id > 145) {return 10}; if (id < 86) {return 6}; return 8 } checkvip() { let currentVipPoints = (getUserInfo()).vipPoints; if (currentVipPoints >999) {return 5} if (currentVipPoints >9) {return 1} return 0 } isWithinRange(value, min, max) { return value >= min && value <= max; } generateArray(start, size) { return Array.from({length: size}, (_, index) => index + start); } getType(id){ let type = "oops" if (this.isWithinRange (id, 21, 55) || this.isWithinRange (id, 56, 99) || this.isWithinRange (id, 167, 178) || this.isWithinRange (id, 221, 232)) {type="Gear"} if (this.isWithinRange (id, 141, 166) || this.isWithinRange (id, 190, 220) || this.isWithinRange (id, 244, 254)) {type="Scroll"} return type } getColor(id){ if (this.isWithinRange (id, 21, 55)) {return "green"} if (this.isWithinRange (id, 141, 145)) {return "green"} if (this.isWithinRange (id, 56, 90)) {return "blue"} if (this.isWithinRange (id, 91, 166)) {return "purple"} if (this.isWithinRange (id, 167, 220)) {return "orange"} if (this.isWithinRange (id, 221, 254)) {return "red"} console.log ("getColor oops", id); return "white" } getName(id){ this.updatemyData() let itemAvailable = 0 let fullitemAvailable = 0; switch (this.getType(id)) { case "Gear": { itemAvailable = this.inventoryGet.fragmentGear[id] ?? 0; fullitemAvailable = this.inventoryGet.gear[id] ?? 0; break; } case "Scroll": { itemAvailable = this.inventoryGet.fragmentScroll[id] ?? 0; fullitemAvailable = this.inventoryGet.scroll[id] ?? 0; break; } } let color = this.getColor(id) let name = cheats.translate(`LIB_${(this.getType(id)).toUpperCase()}_NAME_${id}`); let words = name.split(" ") for (let i in words) {if (words[i].length > 8){name=name.replace(words[i],(words[i]).substring(0,5)+".")}} name = name.replace(" - Рецепт","-р"); name = name.replace(", уровень ","-"); name = name.replace(" уровень ","-");//эти сокращения локалить впадлу, совсем let out ="" //out+=id //если нужен ид шмотки out+=' <span style="color:'+color+';">'+name+'</span> ('+fullitemAvailable+'+'+itemAvailable+I18N('FRAGMENT_HUNT_FR')+')'; return out } generateitembuttons(itemids) { const buttons = []; for (let itemid in itemids) { let gearID = itemids[itemid] let name = this.getName(gearID); buttons.push({ msg: name, result: itemids[itemid], get title() { return name }, }); } buttons.push({msg: I18N('BTN_CANCEL'), result: false, isCancel: true}) return buttons } generatemissionbuttons(missions, itemid) { const buttons = []; for (let mission in missions) { let missionID = missions[mission] let thismission = this.droptable.filter(m=>m.id===missionID)[0] let otheritems = thismission.drop.filter(d=>d != itemid) let name = I18N('FRAGMENT_HUNT_WORLD')+" "+thismission.world+" "+I18N('FRAGMENT_HUNT_MISSION')+" "+thismission.index+" "+this.missionEnergy(thismission.id)+I18N('FRAGMENT_HUNT_ENERGY')+"<br>" // I18N('FRAGMENT_HUNT_MISSION')+" "+ thismission.id for(let i in otheritems) {if (this.getType(otheritems[i]) === "oops"){continue;};name+=this.getName(otheritems[i])+"<br>";} buttons.push({ msg: name, result: missionID, get title() { return name }, }); } buttons.push({msg: I18N('BTN_CANCEL'), result: false, isCancel: true}) return buttons } async updatemyData(){ let calls = [{ name: "userGetInfo", args: {}, ident: "userGetInfo" },{ name: "inventoryGet", args: {}, ident: "inventoryGet" }]; let result = await Send(JSON.stringify({ calls })); let infos = result.results; this.stamina = (infos[0].result.response.refillable.find(n => n.id == 1)).amount; this.inventoryGet = infos[1].result.response; this.energyNeeded = this.missionEnergy(this.missionID) //if (this.missionID > 145) {this.energyNeeded = 10}; //if (this.missionID < 86) {this.energyNeeded = 6}; //console.log ("vip",this.checkvip()) switch (this.checkvip()){ case 5: {this.raids = Math.floor(this.stamina/(this.energyNeeded*10)); break;} case 1: {this.raids = Math.floor(this.stamina/(this.energyNeeded)); break} case 0: {this.raids = 0; setProgress(I18N('FRAGMENT_HUNT_NOVIP'))} } return "ok" } async makeMission(mission,count){ let nrg = this.energyNeeded*count; let calls = [] switch (this.checkvip()){ case 5: {calls.push({name: "missionRaid",args: {id: mission.id,times: (count)},ident: "body"}); break;} case 1: { for (let i = 0; i < count; i++) { calls.push({name: "missionRaid",args: {id: mission.id,times: 1},ident: "body"+"i"}) } } } let result = await Send({ calls }) console.log(result) let loot2 = [] for (let j in result.results) { let loot = result.results[j].result.response for (let i in loot){ if (!!loot[i].fragmentScroll) {loot2.push(loot[i].fragmentScroll)} if (!!loot[i].fragmentGear) {loot2.push(loot[i].fragmentGear)} } } let loot3=[] //console.log("loot2",loot2) for (let i in loot2) { for (let j in Object.keys(loot2[i])) {loot3.push(Object.keys(loot2[i])[j])} } await this.updatemyData() //console.log("loot3",loot3) let str = I18N('FRAGMENT_HUNT_SPENT')+nrg+I18N('FRAGMENT_HUNT_ENERGY')+ I18N('FRAGMENT_HUNT_GOTFRAGMENTS')+"<br>" let usedids = [] let loot4=[] for (let i in loot3) { if (!usedids.includes(loot3[i])){loot4.push({id:loot3[i],qty:1}); usedids.push(loot3[i])} else {(loot4.find(e => e.id== loot3[i])).qty++} } for (let i in loot4){ str+=this.getName(loot4[i].id)+": "+loot4[i].qty+ I18N('FRAGMENT_HUNT_PCS')+"<br>" } setProgress(str) //if (this.raids >0) {this.start(false)} } updateDroptable(){ const dropTable2 = ((types = ['gear', 'fragmentGear', 'scroll', 'fragmentScroll']) => { return Object.values(lib.data.mission).map(e => { const lastWave = e.normalMode?.waves?.at(-1); const lastEnemy = lastWave?.enemies?.at(-1); let dropList = lastEnemy?.drop ?? []; let heromissions = [] for(const i of dropList) { const type = Object.keys(i.reward)[0] if (type == 'fragmentHero') { //console.log('heromission',e.id); heromissions.push(e.id) } } const drop = []; for(const d of dropList) { const type = Object.keys(d.reward).pop() if (d.chance && types.includes(type) && !(heromissions.includes(e.id))) { const id = Object.keys(d.reward[type]).pop() if (id>90) {drop.push(+id)} } } return {id: e.id, world: e.world, index: e.index, drop} }).filter(n => n.drop.length) })() //console.log("dropTable2",dropTable2) this.droptable = dropTable2 } async start() { this.updateDroptable() this.missionID = getSaveVal('huntFragmentMission', 999) let mission = this.droptable.filter(m=>m.id===this.missionID)[0] //console.log ("start missionID",this.missionID,mission) if (!mission) {console.log("nomission"); this.setup();} //если в конфиге кака сначала настройка await this.updatemyData() console.log("Энки у нас",this.stamina," рейдов доступно",this.raids) if (this.raids >0) { if (this.checkvip() == 5){this.makeMission(mission,this.raids*10); } else {this.makeMission(mission,this.raids); } } else {setProgress(I18N('FRAGMENT_HUNT_NOTENOUGH'))} } async setup() { this.updateDroptable() //console.log("droptable2 updated",this.droptable) this.missionID = getSaveVal('huntFragmentMission', 999) let mission = this.droptable.filter(m=>m.id===this.missionID)[0] //console.log ("setup missionID",this.missionID) let message = ""; let maxraid =""; let target=""; if (this.checkvip() != 5) {message+=I18N('FRAGMENT_HUNT_SMALLVIP')} if (!mission) { this.raids = 0; message = I18N('FRAGMENT_HUNT_NOMISSION')} //костыль чтоб точно выбрали миссию else { await this.updatemyData() for (let i in mission.drop){let id=mission.drop[i]; target+=this.getName(id)+"<br>";} maxraid = I18N('RAID')+" х" if (this.checkvip()==5) {maxraid+=this.raids*10} else {maxraid+=this.raids} message = I18N('FRAGMENT_HUNT_WEHUNT')+":<br> "+target+" <br>"+I18N('FRAGMENT_HUNT_WORLD')+" "+mission.world+" "+I18N('FRAGMENT_HUNT_MISSION')+" "+mission.index+" "+this.energyNeeded+" "+I18N('FRAGMENT_HUNT_ENERGY')+"<br>"+I18N('FRAGMENT_HUNT_ENERGY')+" "+this.stamina+I18N('FRAGMENT_HUNT_ENOUGH1')+this.raids+I18N('FRAGMENT_HUNT_ENOUGH2') } let buttons0 = [] if (this.raids > 0 && this.checkvip()==5) {buttons0.push({msg: I18N('RAID')+" х10", result: "1"})} if (this.raids > 1) {buttons0.push({msg: maxraid, result: "2"})} buttons0.push({msg: I18N('FRAGMENT_HUNT_CHANGE'), result: "3"}) buttons0.push({msg: I18N('BTN_CANCEL'), result: false}) this.answerr = await popup.confirm(message, buttons0); const parts = [I18N('FRAGMENT_HUNT_PARTS1'),I18N('FRAGMENT_HUNT_PARTS2'),I18N('FRAGMENT_HUNT_PARTS3'),I18N('FRAGMENT_HUNT_PARTS4'),I18N('FRAGMENT_HUNT_PARTS5'),I18N('FRAGMENT_HUNT_PARTS6'),I18N('FRAGMENT_HUNT_PARTS7'),I18N('FRAGMENT_HUNT_PARTS8')] const buttons = []; for (let i in parts ) { buttons.push({ msg: parts[i], result: i, get title() { return "test" }, }); } buttons.push({msg: I18N('BTN_CANCEL'), result: false, isCancel: true}) let answer=0; switch (this.answerr) { case "1": { //console.log("тут будет рейд х10",mission.id); this.makeMission(mission,10) break; } case "2": { //console.log("тут будет макс рейд",mission.id); this.makeMission(mission,this.raids*10) break;} case "3": {answer = await popup.confirm(I18N('FRAGMENT_HUNT_CHOOSEPART'), buttons); break;} default: {return;} } if (!answer) {return} let array=[] switch (answer) { case "0": { array=this.generateArray(91,8);break;} case "1": { array=[158,153,162,164,165,157,152,166]; break;} //(152,15) case "2": { array=[163,159,154,161,156,160,155]; break;} case "3": { array=this.generateArray(167,12);break;} case "4": { array=[190,194,197,205,204,215,214,196,218,193,219,217,206]; break;} case "5": { array=[198,220,195,192,216,191,199,200]; break;} case "6": { array=this.generateArray(221,12); break;} case "7": { array=this.generateArray(244,11); break;} default: {console.log("oops"); break;} } let answer2 = await popup.confirm(I18N('FRAGMENT_HUNT_CHOOSEITEM'), this.generateitembuttons(array)); if (!answer2) {return} let missions = this.droptable.filter(m=>m.drop.includes(answer2)) let missarray = [] for (let i in missions) {missarray.push(missions[i].id)} let answer3 = await popup.confirm(I18N('FRAGMENT_HUNT_CHOOSEMISSION')+"<br>"+this.getName(answer2), this.generatemissionbuttons(missarray,answer2)); if (!answer3) {return} setSaveVal('huntFragmentMission', answer3) this.setup() } } this.HWHClasses.huntFragment = huntFragment; })(); //TODO: // формат "одной кнопки" для "сделать всё"