HeroWarsHelper

Automation of actions for the game Hero Wars

< 脚本 HeroWarsHelper 的反馈

提问 / 留言

§
发布于:2025-04-14

Hello, any chance for automatic campaign?

orb
§
发布于:2025-04-16
编辑于:2025-04-16

not sure if this is what you mean, but I made this extension a while ago (with the generous help of zinger)


// ==UserScript==
// @name            HWHCampaign
// @namespace       HWHCampaign
// @version         0.0.18
// @description     HWH campaign auto pass
// @author          ZingerY
// @match           https://www.hero-wars.com/*
// @match           https://apps-1701433570146040.apps.fbsbx.com/*
// @run-at          document-start
// @grant           none
// ==/UserScript==

(function () {
    if (!this.HWHClasses) {
        console.log('%cHeroWarsHelper not found', 'color: red');
        return;
    }

    console.log('%cHWHAoC loaded', 'color: green');
    const { addExtentionName } = HWHFuncs;
    addExtentionName(GM_info.script.name, GM_info.script.version, GM_info.script.author);

    try {
        const { buttons } = globalThis.HWHData;
        const { 
            I18N,

            confShow,
            popup
        } = HWHFuncs;

        function testCompany(missions, isRaids = false) {
            const { ExecuteCompany } = HWHClasses;
            return new Promise((resolve, reject) => {
                const tower = new ExecuteCompany(resolve, reject);
                tower.start(missions, isRaids);
            });
        }

        const {ExecuteCompay} = HWHClasses;

        buttons["PassCampaign"] = {
            name: "Pass Campaign",
            title: "Complete all available campaign levels",
            color: "red",
            onClick: async () => {
                try {
                    const missionData = await Caller.send("missionGetAll");
                    const lastLevel = missionData[missionData.length - 1].id;
                    console.log('lastlevel:',lastLevel);
                    // const firstCampaignLevel = 126;

                    const campaignLevels = Array.from(
                        { length: 500 },
                        (_, i) => ({ id: parseInt(lastLevel) + i, times: 1 })
                    );

                    confShow(
                        ('PASS_CAMPAIGN_CONFIRMATION'), 
                        () => testCompany(campaignLevels)
                    );
                } catch (error) {
                    console.error('Campaign error:', error);
                    popup(('ERROR_OCCURRED') + ': ' + error.message);
                }
            }
        };

        // Update buttons if HWHFuncs is available
        if (window.HWHFuncs?.updateButtons) {
            window.HWHFuncs.updateButtons();
        }

    } catch (e) {
        console.error("CampaignExt initialization failed:", e);
    }
})();

save this as a .js file and import it with tampermonkey/violentmonkey

§
发布于:2025-05-19

yes, this is fine, but I want to do RAIDS,
for example: I am not VIP 5, but I'm VIP 1 and I can press raid, Can't the script push raid?
Now maybe you'll understand me.

orb
§
发布于:2025-05-19
编辑于:2025-05-19

I see what you mean. I have made an extension for that as well, but it's not user friendly. Still, it's better than nothing, you can use it if you want. You need to know the mission ID you want to raid, to do that: Open your browser console (F12), go to the "network" tab, then do the raid you want, click on the request that appeared, make sure you're in the "request" tab, scroll down, it should show "mission raid", and above that it should have "missionID".

Then just click the "Raid Mission" button and fill in the missionID, and the amount of times you want to raid it. (tip: to get 1 fragment you need 5 raids on average, this is true for purple items and above.) here is the script extension:

IMPORTANT NOTES: 1) It doesn't show you progress, but you can see logs in the console. When it's done, it will notify you 2) You won't see the items gained and energy gained until you press the "SYNC" button.

// ==UserScript==
// @name            HWHRAIDExt
// @namespace       HWHRAIDExt
// @version         0.3
// @description     HWH auto raid
// @author          ZingerY
// @match           https://www.hero-wars.com/*
// @match           https://apps-1701433570146040.apps.fbsbx.com/*
// @run-at          document-start
// @grant           none
// ==/UserScript==

(function () {
    if (!this.HWHClasses) {
        console.log('%cHeroWarsHelper not found', 'color: red');
        return;
    }

    console.log('%cHWHAoC loaded', 'color: green');
    const { addExtentionName } = HWHFuncs;
    addExtentionName(GM_info.script.name, GM_info.script.version, GM_info.script.author);

    try {
        const { buttons } = globalThis.HWHData;
        const { popup } = HWHFuncs;

        function createMissionRaidBatch(missionId, count, batchNumber = 1) {
            const firstCall = {
                name: "missionRaid",
                args: { id: missionId, times: 1 },
                context: { actionTs: Date.now() },
                ident: `group_${batchNumber}_body`
            };

            const calls = [firstCall];

            for (let i = count-1; i >= 1; i--) {
                calls.push({
                    name: "missionRaid",
                    args: { id: missionId, times: 1 },
                    ident: `missionRaid_${i}`
                });
            }

            return { calls };
        }

        async function sendBatchWithRetry(batch, missionId, count, batchNumber, maxRetries = 3) {
            let attempts = 0;
            while (attempts < maxRetries) {
                try {
                    const response = await Caller.send(batch.calls);
                    if (response === null) {
                        attempts++;
                        console.log(`Batch ${batchNumber} failed (attempt ${attempts}), retrying...`);
                        await new Promise(resolve => setTimeout(resolve, 500 * attempts)); // Exponential backoff
                        continue;
                    }
                    console.log(`Successfully sent batch ${batchNumber} of ${count} raids`);
                    return true;
                } catch (error) {
                    attempts++;
                    console.error(`Error sending batch ${batchNumber}:`, error);
                    await new Promise(resolve => setTimeout(resolve, 500 * attempts));
                }
            }
            console.error(`Failed to send batch ${batchNumber} after ${maxRetries} attempts`);
            return false;
        }

        async function sendMissionRaids(totalRaids, missionId, maxPerBatch = 50) {
            const fullBatches = Math.floor(totalRaids / maxPerBatch);
            const remainder = totalRaids % maxPerBatch;
            let batchesSent = 0;
            let successfulRaids = 0;

            // Send full batches
            for (let i = 0; i < fullBatches; i++) {
                batchesSent++;
                const batch = createMissionRaidBatch(missionId, maxPerBatch, batchesSent);
                const success = await sendBatchWithRetry(batch, missionId, maxPerBatch, batchesSent);
                if (success) {
                    successfulRaids += maxPerBatch;
                }

                // Small delay between batches
                await new Promise(resolve => setTimeout(resolve, 100));
            }

            // Send remaining raids if any
            if (remainder > 0) {
                batchesSent++;
                const lastBatch = createMissionRaidBatch(missionId, remainder, batchesSent);
                const success = await sendBatchWithRetry(lastBatch, missionId, remainder, batchesSent);
                if (success) {
                    successfulRaids += remainder;
                }
            }

            if (successfulRaids === totalRaids) {
                popup.confirm(`Successfully sent all ${totalRaids} raids for mission ${missionId}!`);
            } else {
                popup.confirm(`Sent ${successfulRaids}/${totalRaids} raids for mission ${missionId}. Some batches may have failed.`);
            }
        }

        buttons["Raid Mission"] = {
            name: "Raid Mission",
            title: "Raid Mission",
            color: "red",
            onClick: async () => {
                try {
                    // Get mission ID
                    popup.confirm(
                        'Enter Mission ID:', 
                        [
                            {
                                msg: 'Continue',
                                isInput: true,
                                placeholder: 'Mission ID (e.g. 79)',
                                result: null
                            },
                            {
                                msg: 'Cancel',
                                isCancel: true,
                                result: false
                            }
                        ]
                    ).then(async (missionId) => {
                        if (!missionId || isNaN(parseInt(missionId))) {
                            popup.confirm('Invalid mission ID');
                            return;
                        }

                        missionId = parseInt(missionId);

                        // Get raid count
                        popup.confirm(
                            'Enter Number of Raids:', 
                            [
                                {
                                    msg: 'Start Raids',
                                    isInput: true,
                                    placeholder: 'Number of raids (e.g. 300)',
                                    result: null
                                },
                                {
                                    msg: 'Cancel',
                                    isCancel: true,
                                    result: false
                                }
                            ]
                        ).then(async (raidCount) => {
                            if (!raidCount || isNaN(parseInt(raidCount)) || parseInt(raidCount) < 1) {
                                popup.confirm('Invalid raid count');
                                return;
                            }

                            raidCount = parseInt(raidCount);
                            await sendMissionRaids(raidCount, missionId);
                        });
                    });
                } catch (error) {
                    console.error('Raid error:', error);
                    popup.confirm('An error occurred: ' + (error.message || 'Unknown error'));
                }
            }
        };

        // Update buttons if HWHFuncs is available
        if (window.HWHFuncs?.updateButtons) {
            window.HWHFuncs.updateButtons();
        }

    } catch (e) {
        console.error("CampaignExt initialization failed:", e);
    }
})();
§
发布于:2025-05-19

Good, can you give me a screenshot where is missionID ?

§
发布于:2025-05-19

maybe is wrong place

§
发布于:2025-05-19

or maybe is right, 197 is the ID, I found the hot water, thank you very much, it's hard but it works

orb
§
发布于:2025-05-19

glad I could help :)
When I have time I might work on a better interface, maybe integrate it inside the game's own raid button, but I'll have to look into a bunch of things to do that.

§
发布于:2025-05-19

it would be great!

§
发布于:2025-06-03

hey orb, Did you do something new? :)

orb
§
发布于:2025-06-03

Hello, regarding the raid script, I didn't. I am working on a script that levels up the skills of selected heroes automatically.

发布留言

登录以发布留言。