Greasy Fork

Greasy Fork is available in English.

HWHNewCharacterExt

Extension for HeroWarsHelper script

当前为 2025-10-26 提交的版本,查看 最新版本

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴Greasemonkey 油猴子Violentmonkey 暴力猴,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴Violentmonkey 暴力猴,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴Userscripts ,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展后才能安装此脚本。

(我已经安装了用户脚本管理器,让我安装!)

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

(我已经安装了用户样式管理器,让我安装!)

// ==UserScript==
// @name			HWHNewCharacterExt
// @name:en			HWHNewCharacterExt
// @name:ru			HWHNewCharacterExt
// @namespace		HWHNewCharacterExt
// @version			1.0
// @description		Extension for HeroWarsHelper script
// @description:en	Extension for HeroWarsHelper script
// @description:ru	Расширение для скрипта HeroWarsHelper
// @author			ZingerY, Green
// @license 		Copyright Green
// @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 { buttons } = HWHData;
    const {
        popup,
        confShow,
        getInput,
        setProgress,
        hideProgress,
        I18N,
        send,
        getTimer,
        countdownTimer,
        getUserInfo,
        getSaveVal,
        setSaveVal,
        setIsCancalBattle,
        random,
        EventEmitterMixin,
    } = HWHFuncs;

    const { i18nLangData } = HWHData;

    const { WinFixBattle } = HWHClasses;

    const i18nLangDataEn = {

        NEWCHARACTER: 'New Character',
        NEWCHARACTER_TITLE: 'Complete quests for a new hero or titan',
        NEWCHARACTER_NOEVENT: 'The event is not active',
        NEWHERO: 'New Hero Event',
        NEWTITAN: 'New Titan Event',
        NEWHERO_COMPLETETASKS: 'Complete the tasks',
        NEWHERO_COMPLETETASKS_TITLE: 'Complete the event tasks',
        NEWHERO_COMPLETECAPTERS:'Complete chapters',
        NEWHERO_COMPLETECAPTERS_TITLE:'Complete chapters',
        NEWHERO_SELECTACTION:'Select an action',
        NEWTITAN_GETTITANS: 'Get the Titans',
        NEWTITAN_GETTITANS_TITLE: 'Get the Titans of the maximum rank by collecting fragments in the shop',
        NEWTITAN_GETHEROES: 'Get the Heroes',
        NEWTITAN_GETHEROES_TITLE: 'Get the Heroes of the maximum rank by collecting fragments in the shop',
        NEWTITAN_GETINFLUENCESKILL: 'Get influence skill',
        NEWTITAN_GETINFLUENCESKILL_TITLE: 'Get the influence skill of the maximum rank by collecting fragments in the shop',
        NEWTITAN_GETTITANSPROGRESS: '<span style="color: green;"> {counter} </span> titans left to collect. Collecting...',
        NEWTITAN_GETTITANSCOLLECTED: 'All titans have been collected',
    };

    i18nLangData['en'] = Object.assign(i18nLangData['en'], i18nLangDataEn);

    const i18nLangDataRu = {
        NEWCHARACTER: 'Новый персонаж',
        NEWCHARACTER_TITLE: 'Выполнять задания для нового героя или титана',
        NEWCHARACTER_NOEVENT: 'Ивент не активен',
        NEWHERO: 'Событие нового героя',
        NEWTITAN: 'Событие нового титана',
        NEWHERO_COMPLETETASKS: 'Выполнить задания',
        NEWHERO_COMPLETETASKS_TITLE: 'Выполнить заданий ивента',
        NEWHERO_COMPLETECAPTERS:'Проходить главы',
        NEWHERO_COMPLETECAPTERS_TITLE:'Проходить главы',
        NEWHERO_SELECTACTION:'Выберите действие',
        NEWTITAN_GETTITANS: 'Получить титанов',
        NEWTITAN_GETTITANS_TITLE: 'Получить титанов максимального ранга, собирая фрагменты в магазине',
        NEWTITAN_GETHEROES: 'Получить героев',
        NEWTITAN_GETHEROES_TITLE: 'Получить героев максимального ранга, собирая фрагменты в магазине',
        NEWTITAN_GETINFLUENCESKILL: 'Получить навыки влияния',
        NEWTITAN_GETINFLUENCESKILL_TITLE: 'Получить навыки влияния максимального ранга, собирая фрагменты в магазине',
        NEWTITAN_GETTITANSPROGRESS: 'Осталось собрать <span style="color: green;"> {counter} </span> титанов. Собираем...',
        NEWTITAN_GETTITANSCOLLECTED: 'Все титаны собраны',
    };

    i18nLangData['ru'] = Object.assign(i18nLangData['ru'], i18nLangDataRu);

    ///////////////////////////////////////////////////////////////////////////////////////////////


    // Добавление кнопоки в окно Разное
    const { othersPopupButtons } = HWHData;
    othersPopupButtons.push({
        get msg() { return I18N('NEWCHARACTER'); },
        get title() { return I18N('NEWCHARACTER_TITLE'); },
        result: async function () {
            //if(await Caller.send(['invasion_getInfo'])){
            if(true){
                await onClickNewHeroTitanButton();
            }else{
                confShow(`${I18N('NEWCHARACTER_NOEVENT')}`);
            }

        },
    });

    async function onClickNewHeroTitanButton() {
        const popupButtons = [
            {
                get msg() { return I18N('NEWHERO'); },
                get title() { return I18N('NEWHERO_COMPLETETASKS_TITLE'); },
                result:async function () {
                    await onClickNewHeroButton();
                },
            },
            {
                get msg() { return I18N('NEWTITAN'); },
                get title() { return I18N('NEWHERO_COMPLETETASKS_TITLE'); },
                result:async function () {
                    await onClickNewTitanButton();
                },
            },
        ];
        popupButtons.push({ result: false, isClose: true });
        const answer = await popup.confirm(`${I18N('NEWHERO_SELECTACTION')}`, popupButtons);
        if (typeof answer === 'function') {
            answer();
        }
    }

    async function onClickNewHeroButton() {
        const popupButtons = [
            {
                get msg() { return I18N('NEWHERO_COMPLETETASKS'); },
                get title() { return I18N('NEWHERO_COMPLETETASKS_TITLE'); },
                result:async function () {
                    confShow('Нажата кнопка');
                },
            },
            {
                get msg() { return I18N('NEWHERO_COMPLETECAPTERS'); },
                get title() { return I18N('NEWHERO_COMPLETECAPTERS_TITLE'); },
                result: () => {
                    confShow('Нажата кнопка 2');
                },
            },
        ];
        popupButtons.push({ result: false, isClose: true });
        const answer = await popup.confirm(`${I18N('NEWHERO_SELECTACTION')}`, popupButtons);
        if (typeof answer === 'function') {
            answer();
        }
    }

    async function onClickNewTitanButton() {
        const popupButtons = [
            {
                get msg() { return I18N('NEWTITAN_GETTITANS'); },
                get title() { return I18N('NEWTITAN_GETTITANS_TITLE'); },
                result:async function () {
                    //confShow('Нажата кнопка');
                    await newTitanGetTitans();
                },
            },
            {
                get msg() { return I18N('NEWTITAN_GETHEROES'); },
                get title() { return I18N('NEWTITAN_GETHEROES_TITLE'); },
                result: () => {
                    confShow('Нажата кнопка 2');
                },
            },
            {
                get msg() { return I18N('NEWTITAN_GETINFLUENCESKILL'); },
                get title() { return I18N('NEWTITAN_GETINFLUENCESKILL_TITLE'); },
                result: () => {
                    confShow('Нажата кнопка 3');
                },
            },
        ];
        popupButtons.push({ result: false, isClose: true });
        const answer = await popup.confirm(`${I18N('NEWHERO_SELECTACTION')}`, popupButtons);
        if (typeof answer === 'function') {
            answer();
        }
    }


    async function newTitanGetTitans() {

        //Получить состояние на карте
        let invasionInfoId = await Caller.send('invasion_getInfo').then(e => e.id);
        console.log("invasionInfoId " + invasionInfoId);

        //Сброс главы
        await Caller.send('invasion_resetChapter')

        //Получить id первой главый
        let chapters = Object.values(lib.data.invasion.chapter).filter(e => e.invasionId === invasionInfoId)
        let chapterId = chapters[0].id
        console.log("chapterId " + chapterId);

        //Получить id магазина
        //let heroShopId = await getShopId(chapters, "hero"); //1074; // Магазин героев

        let titanShopId = await getShopId(chapters, "titan"); //1073; // Магазин титанов

        //console.log("Id магазина героев " + heroShopId);
        console.log("Id магазина титанов " + titanShopId);


        let cycle = true;
        while( cycle ){
            //Получить титанов, которых нужно собрать
            let allTitanIdsToBuy = await getTitanIdsToBuy();
            console.log(allTitanIdsToBuy);
            if (allTitanIdsToBuy.length == 0){
                confShow(I18N('NEWTITAN_GETTITANSCOLLECTED'));
                cycle = false;
                return;
            }
            setProgress(I18N('NEWTITAN_GETTITANSPROGRESS', {counter:allTitanIdsToBuy.length}), false);

            //Активировать главу
            let chapterInfo = await Caller.send({name: 'invasion_setActiveChapter',args: {chapterId: chapterId}});
            let haveTitanFragments = chapterInfo.invasion.fragments;

            //Id миссии
            let firstMissionId = chapterInfo.invasion.actions[0].payload.id;
            let missionId = firstMissionId;

            //Жизни
            let lives = chapterInfo.invasion.lives;
            console.log("firstMissionId "+ firstMissionId);
            console.log("missionId "+ missionId);
            console.log("lives "+ lives);

            //Массив фрагментов для метода покупки
            let fragments = [0, 0];
            //Id титанов, что необходимо купить
            let titanIdsToBuy = [0, 0];
            if (allTitanIdsToBuy.length >= 2){
                titanIdsToBuy = [allTitanIdsToBuy[0], allTitanIdsToBuy[1]];
            }else{
                titanIdsToBuy = [allTitanIdsToBuy[0], Object.keys(haveTitanFragments)[0]];
            }
            if (haveTitanFragments[titanIdsToBuy[0]]){
                fragments[0] = haveTitanFragments[titanIdsToBuy[0]];
            }
            if (haveTitanFragments[titanIdsToBuy[1]]){
                fragments[1] = haveTitanFragments[titanIdsToBuy[1]];
            }

            console.log("titanShopId "+ titanShopId);
            console.log(titanIdsToBuy);
            console.log(fragments);


            while( lives > 0 && missionId <= (firstMissionId+7)){
                //Купить титанов
                await buyTitanInTheStore(titanShopId, titanIdsToBuy, fragments);

                //Не атакуем босса
                if (missionId == (firstMissionId+7)){
                    break;
                }

                //Получить атакующую команду
                let heroes = [];
                haveTitanFragments = await Caller.send('invasion_getInfo').then(e => e.fragments);
                for (let f in haveTitanFragments){
                    heroes.push(Number(f));
                    if(heroes.length == 5){
                        break;
                    }
                }
                console.log(heroes)

                let firstSpiritSkills = {};
                //Проходим миссию
                await attackTitanMission(missionId, chapterId, heroes, firstSpiritSkills);

                //Результат атаки
                let invasionInfo = await Caller.send('invasion_getInfo');
                let missions = Object.values(invasionInfo.actions);
                for(let mission of missions){
                    if (mission.payload.wins == 0){
                        missionId = mission.payload.id;
                        break;
                    }
                }
                lives = invasionInfo.lives;
                console.log("missionId "+ missionId);
                console.log("lives "+ lives);
            }
            cycle = false;
        }
    }

    //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    async function getHeroIdsToBuy() {
        const quest = await Caller.send('questGetAll');
        const heroIds = quest.filter(e => e.state == 1 && lib.data.quest.special[e.id]?.translationMethod === "invasionStallHeroFragments").map(e => lib.data.quest.special[e.id].farmCondition.eventFunc.args.fragmentId);
        return heroIds;
    }

    async function getTitanIdsToBuy() {
        const quest = await Caller.send('questGetAll');
        const titanIds = quest.filter(e => e.state == 1 && lib.data.quest.special[e.id]?.translationMethod === "invasionStallFragmentsTitans").map(e => lib.data.quest.special[e.id].farmCondition.eventFunc.args.fragmentId);
        return titanIds;
    }

    async function getTitanSkillIdsToBuy() {
        const quest = await Caller.send('questGetAll');
        const titanSkillIds = quest.filter(e => e.state == 1 && lib.data.quest.special[e.id]?.translationMethod === "invasionStallFragmentsTitanSkills").map(e => lib.data.quest.special[e.id].farmCondition.eventFunc.args.fragmentId);
        return titanSkillIds;
    }

    async function getShopId(chapters, titanOrHero){
        for (let chapter of chapters){
            if(chapter.settings.unitType === titanOrHero){
                return chapter.settings.stallShopId;
            }
        }
        return false;
    }

    async function buyTitanInTheStore(titanShopId, titanIdsToBuy, fragments) {
        console.log("Зашли в магазин");
        console.log(titanIdsToBuy);
        console.log(fragments);

        //Навыки тотемов
        let titanSkilsIdsToBuy = await getTitanSkillIdsToBuy();
        console.log(titanSkilsIdsToBuy);
        console.log(titanSkilsIdsToBuy.length);

        //Фрагменты навыка
        let titanSkilFragments = 0;

        let coins = await Caller.send('inventoryGet').then(e => e.coin[1080]);
        console.log("coins " + coins);

        while( coins >= 9){
            //Получить состояние магазина
            let result = await Caller.send([{name:'shopGet',args:{shopId: titanShopId}}]).then(e => e.slots);
            let slots = Object.values(result)
            console.log(slots);
            for (let slot of slots){
                //Пропустить скрытые лоты
                if (slot.reward.invasionFragmentTitanRand || slot.reward.invasionFragmentSkillRand){
                    continue;
                }
                //console.log(slot);
                //Купить первого титана
                if (slot.reward.invasionFragmentTitan?.[titanIdsToBuy[0]] && fragments[0] < 7){
                    if (coins >= slot.cost.coin[1080]){
                        let shopBuy = await Caller.send({name: 'shopBuy', args: {cost: {}, reward: {}, shopId: titanShopId, slot: slot.id}});
                        if(shopBuy.error){
                            await Caller.send({name: 'shop_pinSlot', args: {shopId: titanShopId, slotId: slot.id}});
                            coins = 0;
                            continue;
                        }
                        console.log("%cКуплен титан ", "color: green; font-weight: bold;")
                        coins -= slot.cost.coin[1080];
                        fragments[0] += slot.reward.invasionFragmentTitan?.[titanIdsToBuy[0]];

                        //Если c первым титаном есть второй
                        if(slot.reward.invasionFragmentTitan?.[titanIdsToBuy[1]]){
                            console.log("%cВторой титан в комплекте ", "color: green; font-weight: bold;")
                            fragments[1] += slot.reward.invasionFragmentTitan?.[titanIdsToBuy[1]];
                        }
                    }else{
                        await Caller.send({name: 'shop_pinSlot', args: {shopId: titanShopId, slotId: slot.id}});
                    }
                    continue;
                }

                //Купить второго титана
                if (slot.reward.invasionFragmentTitan?.[titanIdsToBuy[1]] && fragments[1] < 7){
                    if (coins >= slot.cost.coin[1080]){
                        let shopBuy = await Caller.send({name: 'shopBuy', args: {cost: {}, reward: {}, shopId: titanShopId, slot: slot.id}});
                        if(shopBuy.error){
                            await Caller.send({name: 'shop_pinSlot', args: {shopId: titanShopId, slotId: slot.id}});
                            coins = 0;
                            continue;
                        }
                        console.log("%cКуплен титан ", "color: green; font-weight: bold;")
                        coins -= slot.cost.coin[1080];
                        fragments[1] += slot.reward.invasionFragmentTitan?.[titanIdsToBuy[1]];
                    }
                    else{
                        await Caller.send({name: 'shop_pinSlot', args: {shopId: titanShopId, slotId: slot.id}});
                    }
                    continue;
                }
                //Потратить оставшиеся монеты, если титаны уже куплены
                if (fragments[0] >= 7 && fragments[1] >= 7){
                    console.log("Тратим монеты");
                    //Покупаем часть тотема
                    if (titanSkilsIdsToBuy.length >= 1){
                        //console.log("Покупаем часть тотема");
                        if (slot.reward.invasionFragmentSkill?.[titanSkilsIdsToBuy[0]]){
                            if (coins >= slot.cost.coin[1080]){
                                let shopBuy = await Caller.send({name: 'shopBuy', args: {cost: {}, reward: {}, shopId: titanShopId, slot: slot.id}});
                                if(shopBuy.error){
                                    await Caller.send({name: 'shop_pinSlot', args: {shopId: titanShopId, slotId: slot.id}});
                                    coins = 0;
                                    continue;
                                }
                                console.log("%cКуплена часть тотема ", "color: green; font-weight: bold;")
                                coins -= slot.cost.coin[1080];
                                titanSkilFragments += slot.reward.invasionFragmentSkill?.[titanSkilsIdsToBuy[0]];
                                if (titanSkilFragments >= 7){
                                    titanSkilsIdsToBuy = await getTitanSkillIdsToBuy();
                                    titanSkilFragments = 0;
                                }
                            }else{
                                await Caller.send({name: 'shop_pinSlot', args: {shopId: titanShopId, slotId: slot.id}});
                            }
                        }
                    }else{
                        if (coins >= slot.cost.coin[1080]){
                            let shopBuy = await Caller.send({name: 'shopBuy', args: {cost: {}, reward: {}, shopId: titanShopId, slot: slot.id}});
                            coins -= slot.cost.coin[1080];
                            if(shopBuy.error){
                                coins = 0;
                                continue;
                            }
                        }
                    }
                }
            }
            //Обновить магазин
            if (coins >= 12){
                let shopRefresh = await Caller.send({name: 'shopRefresh', args: {shopId: titanShopId}});
                //await new Promise((e) => setTimeout(e, 1000));
                coins -= 3;
                console.log("Обновили магазин. Осталось монет " + coins);
                let coins2 = await Caller.send('inventoryGet').then(e => e.coin[1080]);
                console.log("coins2 " + coins2);
                if(shopRefresh.error){
                    coins = 0;
                }
            }else{
                break;
                return;
            }
        }
    }


    async function buyHeroInTheStore(heroShopId, herosId) {
        let coins = await Caller.send('inventoryGet').then(e => e.coin[1080]);
        console.log("coins" + coins);
        //Получить состояние магазина
        const result = await Caller.send([{name:'shopGet',args:{shopId: shopId}}]).then(e => e.slots);
        let slots = Object.values(result)
        for (let slot of slots){
            //Пропустить скрытые лоты
            if (slot.reward.invasionFragmentHeroRand){
                continue;
            }
            console.log(slot);
            console.log(slot.id)
            console.log(slot.cost.coin[1080])
        }
    }
    //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    async function attackTitanMission(missionId, chapterId, heroes, firstSpiritSkills) {
        const startBattle = await Caller.send({
            name: 'invasion_bossStart',
            args: {
                id: missionId,
                chapterId:chapterId,
                heroes: heroes,
                //firstSpiritElement: "earth",
                firstSpiritSkills:firstSpiritSkills,
                favor: {},
            },
        });
        const calcBattle = await Calc(startBattle);

        if (!calcBattle.result.win) {
            const cloneBattle = structuredClone(startBattle);
            const bFix = new WinFixBattle(cloneBattle);
            let result = await bFix.start(cloneBattle.endTime, Infinity);
            if (result.result?.win) {
                calcBattle.result = result.result;
                calcBattle.progress = result.progress;
            }
        }

        /*if (!calcBattle.result.win) {
            // Поражение
            return;
        }*/

        const endBattle = await Caller.send({
            name: 'invasion_bossEnd',
            args: {
                id: missionId,
                result: calcBattle.result,
                progress: calcBattle.progress,
            },
        });
    }
    //////////////////
    async function attackHeroMission(missionId, chapterId, attacHero, pet) {
        const startBattle = await Caller.send({
            name: 'invasion_bossStart',
            args: {
                id: missionId,
                chapterId:chapterId,
                heroes: attacHero,
                pet: pet,
                favor: {},
            },
        });
        const calcBattle = await Calc(startBattle);

        if (!calcBattle.result.win) {
            const cloneBattle = structuredClone(startBattle);
            const bFix = new WinFixBattle(cloneBattle);
            let result = await bFix.start(cloneBattle.endTime, Infinity);
            if (result.result?.win) {
                calcBattle.result = result.result;
                calcBattle.progress = result.progress;
            }
        }

        /*if (!calcBattle.result.win) {
            // Поражение
            return;
        }*/

        const endBattle = await Caller.send({
            name: 'invasion_bossEnd',
            args: {
                id: missionId,
                result: calcBattle.result,
                progress: calcBattle.progress,
            },
        });
    }

})();