Adds option to verify lineages in IB
目前為
// ==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();
})();