Jalan-jalan

try to travel over the world!

// ==UserScript==
// @name         Jalan-jalan
// @version      2024.1
// @description  try to travel over the world!
// @author       You
// @match        https://www.erepublik.com/id
// @icon         https://www.google.com/s2/favicons?sz=64&domain=erepublik.com
// @grant        none
// @namespace Amazing Journey
// ==/UserScript==

(function() {
    'use strict';

    const counter = Number(getLocalStorageData('counter'));
    const targetKM = Number(getLocalStorageData('target'));
    const locA = Number(getLocalStorageData('locA'));
    const locB = Number(getLocalStorageData('locB'));
    const locationName = erepublik.citizen.countryLocationName;
    const current = erepublik.citizen.regionLocationId;
    const residenceId = erepublik.citizen.residence.regionId;
    const residenceCountry = erepublik.citizen.residence.countryId;
    const now = getCurrentUnixTimestamp();
    const _token = csrfToken;
    const travelPost = `https://www.erepublik.com/en/main/travelData`;
    const movePost = `https://www.erepublik.com/en/main/travel`;

    if(locA == 0){
        saveToLocalStorage('locA', 173);
    }
    if(locB == 0){
        saveToLocalStorage('locB', 714);
    }

const captcha = checkSessionValidationExists()
if (!captcha) {
    if (now > counter) {
        observeAndCreateModal();
    } else {
        //travel();
        observeAndCreateModal();
    }
}

    async function travel(){
        //const anniv = await fetchData(`https://www.erepublik.com/id/main/anniversaryQuestData`);
        //const miles = anniv.status.inventory.miles;
        delay(2000);
        let targetLoc;
        let targetCountry;

        if(now < counter){
            const payloadMap = getTravel(current, _token);
            const dataTravel = await PostRequest(payloadMap, travelPost);

            if(current == locA){
                const countryB = dataTravel.regions[locB].countryId;
                targetLoc = locB;
                targetCountry = countryB;
            } else {
                const countryA = dataTravel.regions[locA].countryId;
                targetLoc = locA;
                targetCountry = countryA;
            }
            await delay(2000);
            console.log("TRAVEL");

            const payMove = move(targetLoc, targetCountry);
            await PostRequest(payMove, movePost);
            await delay(10000);
            reloadPage();

        } else {
            console.log("NOTHING");
            //back to residence
            if (current != residenceId){
                targetLoc = residenceId;
                targetCountry = residenceCountry;

                const payHome = move(targetLoc, targetCountry);
                await PostRequest(payHome, movePost);
                await delay(10000);
                reloadPage();
            }
        }

    }

// MODAL BOX - - - - - - - - - - - - -- - - - - -- - - - - -- - - - - -- - - - - -- - - - - -- - - - - -- - - - - -- - - - - -- - - - - -- - - - - -- - - - - -- - - - - -- - - - - -
async function createModal(miles) {
    // Check if the modal already exists



    if (document.getElementById('myModal')) {
        return; // Exit if modal is already present
    }

    // Create modal HTML with one input box and two buttons (Save and Travel)
    const modalHTML = `
    <div id="myModal" style="display:block; position:fixed; z-index:1000; left:0; top:0; width:100%; height:100%; overflow:auto; background-color:rgba(0,0,0,0.4);">
        <div style="background-color:white; margin:15% auto; padding:20px; border:1px solid #888; width:400px; max-width:90%; position:relative; display:flex; flex-direction:column; align-items:center;">
            <span id="closeModal" style="position:absolute; top:10px; right:10px; cursor:pointer; font-size:20px;">&times;</span>

            <h3>Your miles: ${miles} KM</h3>
            <h3>Location: ${locationName}</h3><br>

            <label for="target" style="font-size:16px;">Target Value (KM):</label><br>
            <input type="text" id="target" value="${getLocalStorageData(`target`)}" style="border:none; border-bottom:1px solid #ccc; outline:none; width:80%; padding:5px; margin-bottom:10px;">

            <div style="display:flex; gap:10px; margin-top:20px;">
                <button type="button" id="saveButton" style="padding:5px 10px; font-size:16px;">Save</button>
                <button type="button" id="travelButton" style="padding:5px 10px; font-size:16px;">Travel</button>
            </div>
        </div>
    </div>
    `;

    // Append modal to the body
    document.body.insertAdjacentHTML('beforeend', modalHTML);

    // Get modal and close elements
    const modal = document.getElementById('myModal');
    const closeModal = document.getElementById('closeModal');
    const saveButton = document.getElementById('saveButton');
    const travelButton = document.getElementById('travelButton');

    // Show modal
    modal.style.display = 'block';

    // Close modal when 'X' is clicked
    closeModal.onclick = function() {
        modal.style.display = 'none';
    };

    // Close modal when clicking outside of the modal content
    window.onclick = function(event) {
        if (event.target == modal) {
            modal.style.display = 'none';
        }
    };

    // Save button functionality
    saveButton.onclick = function() {
        const inputValue = document.getElementById('target').value;
        // Save selected target country
        saveToLocalStorage('target', inputValue);
        reloadPage();
    };

    // Travel button functionality
    travelButton.onclick = function() {
        const next = now + 300;
        if(targetKM > miles){
            saveToLocalStorage('counter', next);
            reloadPage();
        } else {
            reloadPage();
        }
    };
}



//OBSERVER - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
// Function to observe DOM changes and create the modal
async function observeAndCreateModal() {
    // Introduce a delay before starting to observe
    //const anniv = await fetchData(`https://www.erepublik.com/id/main/anniversaryQuestData`);
    //const miles = anniv.status.inventory.miles;
    delay(2000);

    let triggerCount = 0; // Counter for MutationObserver triggers
    const maxTriggers = 2; // Limit for triggers


    const observer = new MutationObserver((mutationsList) => {
        console.log(triggerCount);
        triggerCount += 1;

        // Check if the modal already exists
        if (!document.getElementById('myModal')) {
            createModal(miles);
        }

        // Stop observing after reaching the trigger limit
        if (triggerCount >= maxTriggers) {
            observer.disconnect();
        }
    });

    // Start observing the document for changes
    observer.observe(document, {
        childList: true,
        subtree: true
    });
}


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

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

async function reloadPage() {
    const refresh = getLocalStorageData('refresh');
    const now = getCurrentUnixTimestamp();
    const next = now + 900;
    saveToLocalStorage('refresh', next);
    await delay(200);

    const culture = erepublik.settings.culture;
    window.location.href = `https://www.erepublik.com/${culture}`;
}

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) {
        reloadPage();
        throw new Error(`Failed to fetch data from ${url}: ${error.message}`);

    }
}

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

    try {
        await delay(1000);
        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);
        reloadPage();
        return null;
    }
}

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


function saveToLocalStorage(key, value) {
        // Check if the key exists in local storage
        if (localStorage.getItem(key) === null) {
            // If key does not exist, set it to default value 0
            localStorage.setItem(key, '0');
        }
        // Update the key with the new value
        localStorage.setItem(key, value);
    }

// Function to get data from local storage or set default value
function getLocalStorageData(key) {
    let value = localStorage.getItem(key);
    if (value === null) {
        value = 0; // Default value is '0'
        localStorage.setItem(key, value);
    }
    return value;
}

    //PAYLOAD
    function getTravel(residenceId, _token) {
	const regionId = residenceId;
        const holdingId = 0;
        const battleId = 0;

        return {
            regionId,
            _token,
            holdingId,
            battleId
        };
    }

    function move(target, country) {
        const check = "moveAction";
        const travelMethod = "preferTicket";
        const inRegionId = target;
        const toCountryId = country;


        return {
            check,
            _token,
            travelMethod,
            inRegionId,
            toCountryId
        };
    }
})();