HeroWarsHelper

Automation of actions for the game Hero Wars

< Feedback on HeroWarsHelper

Question/comment

§
Posted: 2025-04-14

Hello, any chance for automatic campaign?

orb
§
Posted: 2025-04-16
Edited: 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

§
Posted: 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
§
Posted: 2025-05-19
Edited: 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);
    }
})();
§
Posted: 2025-05-19

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

§
Posted: 2025-05-19

maybe is wrong place

§
Posted: 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
§
Posted: 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.

§
Posted: 2025-05-19

it would be great!

§
Posted: 2025-06-03

hey orb, Did you do something new? :)

orb
§
Posted: 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.

Post reply

Sign in to post a reply.