IB Lineage Verifyer

Adds option to verify lineages in IB

目前為 2025-01-19 提交的版本,檢視 最新版本

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

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

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

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

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

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

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

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

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

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

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

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

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

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

// ==UserScript==
// @name         IB Lineage Verifyer
// @namespace    http://tampermonkey.net/
// @version      1.0
// @license      MIT
// @description  Adds option to verify lineages in IB
// @icon         https://i.imgur.com/WlkWOkU.png
// @author       @activetutorial on discord
// @match        https://infinibrowser.wiki/item/*
// @run-at       document-end
// @grant        none
// ==/UserScript==

(function() {
    'use strict';

    (window.AT ||= {}).lineagefverify = {
        lineage: null,
        getLineage: async function() {
            const itemID = location.href.split("item/")[1];
            const custom = document.getElementById("item_footer")?.textContent == "This is an unverified user-submitted element";
            const baseURL = (custom ? "https://infinibrowser.wiki/api/recipe/custom?id=" : "https://infinibrowser.wiki/api/recipe?id=");
            const response = await fetch(baseURL + itemID);
            this.lineage = (await response.json()).steps;
        },
        createElements: function() { // Create the button
            document.querySelector("h3").insertAdjacentHTML
            ('afterend',
             '<div style="margin-top:1rem"><button id="verify-recipe" class="btn">Verify Recipe</button></div>'
            );
            this.verifyButton = document.getElementById("verify-recipe");
        },
        getUncrafted: async function() {
            const uncrafted = new Set();
            this.lineage.forEach((step, i) => {
                const partLineage = this.lineage.slice(0, i); // Slice lineage to avoid circular recipes
                // Verify if ingredients have been crafted
                const ingredientAValid = !partLineage.every(partStep => !(
                    step.a.id.toLowerCase() === partStep.result.id.toLowerCase()
                ));
                const ingredientBValid = !partLineage.every(partStep => !(
                    step.b.id.toLowerCase() === partStep.result.id.toLowerCase()
                ));

                if (!ingredientAValid) uncrafted.add(step.a.id);
                if (!ingredientBValid) uncrafted.add(step.b.id);
            });
            return [...uncrafted];
        },
        check: async function (first, second, result, mainneal=false) {
            // Either proxy or neals server
            const baseURL = (mainneal ? "https://neal.fun/api/infinite-craft/pair?ref=app&" : "https://infiniteback.active-tutorial-video.workers.dev/?");
            const response = await fetch(`${baseURL}first=${encodeURIComponent(first)}&second=${encodeURIComponent(second)}`);
            const data = await response?.json()
            return data?.result?.toLowerCase() === result?.toLowerCase(); // Return if its true
        },
        verifyLineage: async function() {
            let uncrafted = await this.getUncrafted();
            const incorrectCrafts = [];
            const allowedUncrafted = ["Water", "Fire", "Earth", "Wind"]; // Allowed missing items
            uncrafted = uncrafted.filter(item => !allowedUncrafted.includes(item)); // Subtract allowed items
            console.log(uncrafted);
            alert("Uncrafted items: " + uncrafted);
            this.lineage.forEach(async step => {
                 await this.check(step.a.id, step.b.id, step.result.id, false) ||
                 await this.check(step.a.id, step.b.id, step.result.id, true) ||
                 incorrectCrafts.push(step); // If false both times, craft is incorrect
            });
            console.log(incorrectCrafts);
            alert("Incorrect lineage steps: " + JSON.stringify(incorrectCrafts));

            incorrectCrafts.length || uncrafted.length ||
            alert("Lineage fully valid!");
        },
        start: function () {
            if (document.querySelector('.ibuttons')) { // Wait for IB to load
                this.createElements();
                // Button event listener
                this.verifyButton.addEventListener("click", this.verifyLineage.bind(this));
                // Get current lineage
                this.getLineage();

            } else {
                setTimeout(this.start.bind(this), 200);
            }
        }
    };

    window.AT.lineagefverify.start();
})();