Crazy Smart Stuff

try to handle all conflict

目前為 2023-12-11 提交的版本,檢視 最新版本

// ==UserScript==
// @name         Crazy Smart Stuff
// @namespace    erepFarm
// @version      2023-12-12
// @description  try to handle all conflict
// @author       Probably You
// @match        https://www.erepublik.com/ms
// @icon         https://www.google.com/s2/favicons?sz=64&domain=erepublik.com
// @grant        none
// ==/UserScript==
(function() {
    'use strict';

    let config = {
        aircraft: true,
        aircraftDamage: 60000,
        groundDamage: 500000000,
        abWeapon: -1, //-1 no weapon, 5 for Q5 and 10 for Stinger
    };
    config = adjustValues(config);
    let first = true;
    const recheck = checkLocalStorage();
    if (recheck == 1) {
        config.aircraft = false;
        first = false;
    }

    console.log("Aircraft", config.aircraft);

    const energy = erepublik.citizen.energy;
    const locationId = erepublik.citizen.countryLocationId;
    const _token = csrfToken;


    async function mainFunction() {
        const capthca = checkSessionValidationExists();
        if (!capthca) {
            createDivElement('abdamage', 'sidebar', 'Aircraft Damage:');
            displayValueInHtml('abdamage', convert(config.aircraftDamage));
            createDivElement('gbdamage', 'sidebar', 'Ground Damage:');
            displayValueInHtml('gbdamage', convert(config.groundDamage));
            createDivElement('scan', 'sidebar', '---------------------');
            createDivElement('scan', 'sidebar', 'DOING SOMETHING SMART');
            let counter = 0;
            //fetch data if energy is okay
            if (energy > 666) {
                const fetchTime = getCurrentUnixTimestamp();
                const maxStartTime = fetchTime - (85 * 60);
                const fetchlist = await fetchData(`https://www.erepublik.com/en/military/campaignsJson/list?${fetchTime}`);
                await delay(666);
                const zoneList = await fetchData(`https://www.erepublik.com/en/military/campaignsJson/citizen?${fetchTime}`);

                const list = Object.values(fetchlist.battles).filter(battle => {
                    return (
                        battle.war_type === "direct" &&
                        (battle.inv.id === locationId || battle.def.id === locationId) &&
                        battle.start < fetchTime &&
                        battle.start > maxStartTime // Check if the battle started within the last 85 minutes
                    );
                });
                createDivElement('allbattle', 'sidebar', 'Filtered Battle:');
                displayValueInHtml('allbattle', list.length);
                createDivElement('list', 'sidebar', '');

                //check all filtered battle

                for (const battle of list) {
                    let battleZoneId;
                    let division;
                    let oppositeId;
                    let deffend;
                    let weapQ;
                    let limit;
                    let totDamage = 0;
                    const idBattle = battle.id;
                    if (config.aircraft == true) {
                        battleZoneId = zoneList.battles[idBattle].aircraftZoneId;
                        division = 11;
                        weapQ = config.abWeapon;
                        limit = config.aircraftDamage;
                    } else {
                        battleZoneId = zoneList.battles[idBattle].groundZoneId;
                        division = erepublik.citizen.division;
                        weapQ = 7;
                        limit = config.groundDamage;;
                    }

                    if (locationId === battle.def.id) {
                        deffend = true;
                        oppositeId = battle.inv.id;
                    } else if (locationId === battle.inv.id) {
                        deffend = false;
                        oppositeId = battle.def.id;
                    }


                    const divData = battle.div[battleZoneId];
                    const div_end = divData.division_end;
                    let hit = false;

                    if (div_end == false) {
                        const wall = divData.wall.for;
                        const dom = divData.wall.dom;

                        if ((dom == 50 || (wall != locationId && dom == 100))) {
                            hit = true;
                            counter++;
                        }
                    }

                    if (hit == true) {
                        const round = battle.zone_id;
                        const division = config.division;
                        const urlBS = "https://www.erepublik.com/en/military/battle-console";
                        const payloadBS = payloadStat(idBattle, round, round, division, battleZoneId, _token);
                        const checkStat = await PostRequest(payloadBS, urlBS);
                        const empty = checkFighterDataEmpty(checkStat, locationId);
                        //check opposite total damage
                        const opposite = checkFighterDataEmpty(checkStat, oppositeId);
                        if (opposite == false) {
                            totDamage = calculateTotalValue(checkStat, oppositeId)
                        }

                        if (empty) {
                            const getInventory = "https://www.erepublik.com/en/military/fightDeploy-getInventory";
                            const inventoryLoad = inventoryPayload(idBattle, locationId, battleZoneId, _token);
                            const inventory = await PostRequest(inventoryLoad, getInventory);
                            const bag = skinAndDph(inventory, weapQ);
                            let pool = inventory.poolEnergy;
                            const skin = bag.skinId;
                            const damage = bag.damageBonus;
                            const wAmount = bag.weaponAmount;


                            const damageHit = checkDamage(limit, deffend, totDamage, damage);

                            if (pool > damageHit) {
                                const rocketLoad = deployLoad(idBattle, battleZoneId, locationId, weapQ, damageHit, skin, _token);
                                const Deployurl = 'https://www.erepublik.com/en/military/fightDeploy-startDeploy';
                                await PostRequest(rocketLoad, Deployurl);
                                let restTime;

                                if (weapQ == 10) {
                                    restTime = (damageHit / 10) * 1010;
                                } else {
                                    restTime = (damageHit / 10) * 366;
                                }

                                const linkText = `HIT ON ${battle.region.name} - ${totDamage}`;
                                const linkUrl = `https://www.erepublik.com/en/military/battlefield/${idBattle}/${battleZoneId}`;
                                displayLinkInHtml('list', linkText, linkUrl);

                                await delay(restTime);
                            }
                        }
                        await delay(3000);
                    }
                }
            }
            if (counter == 0 && first == true) {
                editLocalStorage(1);
                await delay(5000);
                redirectToErepublik();
            } else if (first == false) {
                editLocalStorage(0);
                createDivElement('scan', 'sidebar', '---------------------');
                createDivElement('nobattle', 'sidebar', 'NO EMPTY BATTLE');
            }
        }
    }




    //LIST OF FUNCTION ----------------------------------------------------------------------------------------------------

    function redirectToErepublik() {
        window.location.href = "https://www.erepublik.com/ms";
    }

    function checkSessionValidationExists() {
        if (typeof SERVER_DATA !== 'undefined' && SERVER_DATA.sessionValidation !== undefined) {
            return true;
        } else {
            return false;
        }
    }

    function getCurrentUnixTimestamp() {
        const currentTime = new Date();
        const unixTimestamp = Math.floor(currentTime.getTime() / 1000); // Convert milliseconds to seconds
        return unixTimestamp;
    }

    function delay(ms) {
        return new Promise(resolve => setTimeout(resolve, ms));
    }

    function adjustValues(config) {
        const rfcValue = SERVER_DATA.serverTime.rfc;
        const rfcParts = rfcValue.split(", ");
        const dayAbbreviation = rfcParts[0];

        if (dayAbbreviation == "Tue") {
            config.aircraftDamage -= config.aircraftDamage * 0.05;
            config.groundDamage -= config.groundDamage * 0.05;
        } else if (dayAbbreviation == "Thu" || dayAbbreviation == "Fri") {
            config.aircraftDamage += config.aircraftDamage * 0.05;
            config.groundDamage += config.groundDamage * 0.05;
        } else if (dayAbbreviation == "Sat" || dayAbbreviation == "Sun") {
            config.aircraftDamage += config.aircraftDamage * 0.1;
            config.groundDamage += config.groundDamage * 0.1;
        }
        return config;
    }

    async function fetchData(url) {
        try {
            const response = await fetch(url);
            if (!response.ok) {
                throw new Error(`HTTP error! Status: ${response.status}`);
            }
            const data = await response.json();
            return data;
        } catch (error) {
            throw new Error(`Failed to fetch data from ${url}: ${error.message}`);
        }
    }

    function createDivElement(divId, parentId, textContent) {
        const parentElement = document.querySelector(`.${parentId}`);
        if (parentElement) {
            const newDiv = document.createElement('div');
            newDiv.id = divId;
            newDiv.textContent = textContent;
            parentElement.appendChild(newDiv);
        } else {
            console.error(`Parent element with class '${parentId}' not found.`);
        }
    }

    // Function to display any value in HTML
    function displayValueInHtml(elementId, value) {
        const element = document.getElementById(elementId);
        if (element) {
            element.textContent = `${element.textContent} ${value}`;
        } else {
            console.error(`Element with ID '${elementId}' not found.`);
        }
    }

    function displayLinkInHtml(containerId, linkText, linkUrl) {
        const containerElement = document.getElementById(containerId);
        if (containerElement) {
            const linkElement = document.createElement('a');
            linkElement.href = linkUrl;
            linkElement.target = '_blank';
            linkElement.textContent = linkText;
            containerElement.appendChild(linkElement);
            containerElement.appendChild(document.createElement('br'));
        } else {
            console.error(`Container element with ID '${containerId}' not found.`);
        }
    }

    function checkLocalStorage() {

        const checkData = localStorage.getItem("re_check");
        if (checkData) {

            return parseInt(checkData, 10);
        } else {
            const newData = 0;
            localStorage.setItem("re_check", newData.toString());
            return parseInt(newData, 10);
        }
    }

    function editLocalStorage(newValue) {
        localStorage.setItem("re_check", newValue.toString());
    }

    function convert(number) {
        return number.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ",");
    }


    //LIST OF BATTLE FUNCTION -----------------------------------------------------------------------------------------
    function checkFighterDataEmpty(responseData, countryLocationId) {
        if (responseData && responseData[countryLocationId] && responseData[countryLocationId]["fighterData"]) {
            const fighterData = responseData[countryLocationId]["fighterData"];
            const isFighterDataEmpty = Object.keys(fighterData).length === 0;
            return isFighterDataEmpty;
        } else {
            console.log(`Could not find ${countryLocationId}.fighterData in the response.`);
        }
    }

    // Function to calculate the total value
    function calculateTotalValue(data, countryId) {
        let totalValue = 0;
        const fighterData = data[countryId] ?.fighterData || {};

        for (const key in fighterData) {
            if (fighterData.hasOwnProperty(key)) {
                const value = fighterData[key].value;
                if (typeof value === 'string') {
                    const parsedValue = parseInt(value.replace(/,/g, ''), 10);
                    if (!isNaN(parsedValue)) {
                        totalValue += parsedValue;
                    }
                }
            }
        }

        return totalValue;
    }


    // Function to send the payload using POST request
    async function PostRequest(payload, url) {

        try {
            const response = await fetch(url, {
                method: "POST",
                headers: {
                    "Content-Type": "application/x-www-form-urlencoded"
                },
                body: Object.keys(payload)
                    .map(key => `${encodeURIComponent(key)}=${encodeURIComponent(payload[key])}`)
                    .join('&')
            });

            const responseData = await response.json();
            return responseData;
        } catch (error) {
            console.error("Error:", error);
            return null;
        }
    }

    // Function to construct the payload from variables
    function payloadStat(battleId, zoneId, round, division, battleZoneId, _token) {
        const action = "battleStatistics";
        const type = "damage";
        const leftPage = 1;
        const rightPage = 1;

        return {
            battleId,
            zoneId,
            action,
            round,
            division,
            battleZoneId,
            type,
            leftPage,
            rightPage,
            _token
        };
    }

    //payload for inventory
    function inventoryPayload(battleId, sideCountryId, battleZoneId, _token) {
        return {
            battleId,
            sideCountryId,
            battleZoneId,
            _token
        };
    }

    //function to deploy
     function deployLoad(battleId, battleZoneId, sideCountryId, weaponQuality, totalEnergy, skinId, _token) {
        return {
            battleId,
            battleZoneId,
            sideCountryId,
            weaponQuality,
            totalEnergy,
            skinId,
            _token
        };
    }

    function skinAndDph(inventory, weapQu) {
        const listweapon = inventory.weapons;
        const vehicles = inventory.vehicles;
        let weaponAmount;
        let dph;
        let skinId;
        let skinBonus;


        const objectWithQuality = listweapon.find(item => item.quality === weapQu);
        if (objectWithQuality) {
            weaponAmount = objectWithQuality.amount;
            dph = objectWithQuality.damageperHit;
        }

        const skinRecommended = vehicles.find(skin => skin.isRecommended === true);
        if (skinRecommended) {
            skinId = skinRecommended.id;
            skinBonus = skinRecommended.countryData.damageBonus;
        }
        let percentage = 0;
        if (skinBonus !== null) {
            percentage = skinBonus / 100;
        }

        let damageBonus = dph + (dph * percentage);
        return {
            damageBonus,
            skinId,
            weaponAmount
        };

    }

    function checkDamage(limit, deffend, totDamage, damageBonus) {
        let targetDamage;
        let energyCount;
        let random = getRandomNumber();
        const low = limit - (limit * 0.15);
        const high = limit + (limit * 0.2);
        const lower = (totDamage / 2) + (totDamage * 0.15);
        const higher = totDamage + (totDamage * 0.1);
        const lowest = low - (low * 0.05);
        const highest = limit * 2;

        if (deffend) {
            if (totDamage == 0 || totDamage < low) {
                targetDamage = limit;
            } else if (totDamage > low && totDamage < high) {
                targetDamage = higher;
            } else {
                targetDamage = high;
            }

        } else {
            if (totDamage > limit && totDamage < high) {
                targetDamage = limit;
            } else if (totDamage > high) {
                targetDamage = lower;
            } else {
                targetDamage = low;
            }
        }

        let exactDamage = Math.floor(damageBonus);
        energyCount = Math.ceil((targetDamage / exactDamage) * 10);
        if (deffend) {
            energyCount = energyCount + (2 * random);
        } else {
            energyCount = energyCount - random;
        }
        return energyCount;

    }

    function getRandomNumber() {
        return Math.floor(Math.random() * (70 - 10 + 1)) + 10;
    }




    //Call the main function when the page loads
    window.addEventListener('load', mainFunction);
})();