Infinite Craft Auto Processor (Ultra Fast for Firefox/Linux)

Ultra-fast Infinite Craft combination processor for Firefox on Linux

您需要先安裝使用者腳本管理器擴展,如 TampermonkeyGreasemonkeyViolentmonkey 之後才能安裝該腳本。

You will need to install an extension such as Tampermonkey to install this script.

您需要先安裝使用者腳本管理器擴充功能,如 TampermonkeyViolentmonkey 後才能安裝該腳本。

您需要先安裝使用者腳本管理器擴充功能,如 TampermonkeyUserscripts 後才能安裝該腳本。

你需要先安裝一款使用者腳本管理器擴展,比如 Tampermonkey,才能安裝此腳本

您需要先安裝使用者腳本管理器擴充功能後才能安裝該腳本。

(我已經安裝了使用者腳本管理器,讓我安裝!)

你需要先安裝一款使用者樣式管理器擴展,比如 Stylus,才能安裝此樣式

你需要先安裝一款使用者樣式管理器擴展,比如 Stylus,才能安裝此樣式

你需要先安裝一款使用者樣式管理器擴展,比如 Stylus,才能安裝此樣式

你需要先安裝一款使用者樣式管理器擴展後才能安裝此樣式

你需要先安裝一款使用者樣式管理器擴展後才能安裝此樣式

你需要先安裝一款使用者樣式管理器擴展後才能安裝此樣式

(我已經安裝了使用者樣式管理器,讓我安裝!)

// ==UserScript==
// @name         Infinite Craft Auto Processor (Ultra Fast for Firefox/Linux)
// @namespace    http://tampermonkey.net/
// @version      1.0
// @description  Ultra-fast Infinite Craft combination processor for Firefox on Linux
// @author       You
// @match        *://*/*   // Adjust this URL pattern to the specific game page for Infinite Craft
// @grant        none
// @run-at       document-end
// ==/UserScript==

(function() {
    'use strict';

    // Fast drag-and-drop simulation optimized for Infinite Craft
    function simulateMouseAndDrop(element, startX, startY, targetX, targetY) {
        function triggerMouseEvent(target, eventType, clientX, clientY) {
            const event = new MouseEvent(eventType, {
                bubbles: true,
                cancelable: true,
                clientX,
                clientY,
                view: window,
            });
            target.dispatchEvent(event);
        }

        // Instant drag-and-drop without gradual movement
        triggerMouseEvent(element, "mousedown", startX, startY);
        triggerMouseEvent(document, "mousemove", targetX, targetY);
        triggerMouseEvent(document, "mouseup", targetX, targetY);

        // Directly set the position of the element to avoid reflows/repaints
        element.style.left = `${targetX}px`;
        element.style.top = `${targetY}px}`;
    }

    async function beat_infinite_craft() {
        const processedPairs = new Set(JSON.parse(localStorage.getItem("processedPairs")) || []);

        // Save processed pairs to localStorage in bulk
        function saveProcessedPairs() {
            localStorage.setItem("processedPairs", JSON.stringify(Array.from(processedPairs)));
        }

        async function clickClearButton() {
            const clearBtn = document.querySelector(".clear");
            if (clearBtn) {
                clearBtn.click();
            }
        }

        async function processCombination(firstItem, secondItem, targetX, targetY) {
            const firstRect = firstItem.getBoundingClientRect();
            const secondRect = secondItem.getBoundingClientRect();

            const firstStartX = firstRect.x + firstRect.width / 2;
            const firstStartY = firstRect.y + firstRect.height / 2;

            const secondStartX = secondRect.x + secondRect.width / 2;
            const secondStartY = secondRect.y + secondRect.height / 2;

            // Simulate instant mouse drag-and-drop for both items
            simulateMouseAndDrop(firstItem, firstStartX, firstStartY, targetX, targetY);
            simulateMouseAndDrop(secondItem, secondStartX, secondStartY, targetX, targetY);

            // Click the clear button immediately to reset the crafting area
            await clickClearButton();
        }

        async function processItems(itemsRow, x, y) {
            const items = itemsRow.getElementsByClassName("item");
            const promises = []; // Use promises for parallel execution

            // Process combinations concurrently in parallel
            for (let i = 0; i < items.length; i++) {
                for (let j = 0; j < items.length; j++) {
                    if (!processedPairs.has(`${i}-${j}`)) {
                        processedPairs.add(`${i}-${j}`);
                        promises.push(processCombination(items[i], items[j], x, y)); // Concurrently process combinations
                    }
                }
            }

            // Wait for all combinations to be processed
            await Promise.all(promises);
            saveProcessedPairs(); // Save the processed pairs after finishing
        }

        // Cache DOM elements to avoid re-querying
        let itemsRows = document.getElementsByClassName("items-row");
        if (itemsRows.length === 0) {
            const itemsInner = document.querySelector(".items-inner");
            return await processItems(itemsInner, 200, 600); // Default position if no rows found
        }

        // Process all item rows concurrently
        const rowPromises = [];

        for (const row of itemsRows) {
            rowPromises.push(processItems(row, 500, 100)); // Process each row concurrently
        }

        await Promise.all(rowPromises); // Wait for all row processes to finish
    }

    // Retry mechanism for error handling with minimal delay
    async function startCrafting() {
        try {
            await beat_infinite_craft();
        } catch (error) {
            console.error("Error during crafting process:", error);
            setImmediate(startCrafting); // Retry immediately
        }
    }

    // Start the crafting process
    startCrafting();
})();