From 1f2995ad1c6fba831f50324a26fb2ec94ef6e6bc Mon Sep 17 00:00:00 2001 From: ZXMushroom63 Date: Sun, 8 Sep 2024 13:27:58 +0800 Subject: [PATCH] Add metadata module --- examplemods/lib.customitems.js | 4 +++ modgui.injector.js | 48 ++++++++++++++++++++++++---- modgui.js | 48 ++++++++++++++++++++++++---- modloader.injector.js | 7 ++-- modloader.js | 6 ++-- postinit.injector.js | 58 ++++++++++++++++++++++++++++++++++ postinit.js | 58 ++++++++++++++++++++++++++++++++++ 7 files changed, 213 insertions(+), 16 deletions(-) diff --git a/examplemods/lib.customitems.js b/examplemods/lib.customitems.js index 0dac7aa..a805424 100644 --- a/examplemods/lib.customitems.js +++ b/examplemods/lib.customitems.js @@ -1,5 +1,9 @@ // Library to make adding custom items with EaglerForgeInjector much easier. (function LibItems() { + ModAPI.meta.title("LibCustomItems"); + ModAPI.meta.credits("By ZXMushroom63"); + ModAPI.meta.icon("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAAXNSR0IArs4c6QAAAQdJREFUOE9jZGBg+M9AAWAEGbBl2QmyjPCJsmAgaABbdybc8F+l01EswmsATONXLi4GYSkpBgZ+foY1O3cyuHWuhhuC1QBkjf///QMrFtHWZmD4+BHDEBQDUGzU1ITb8ubqVZyGoBjwsCONQYqXl0FYU5MBpAlsKxRgM+STUwoDhgG66upgZ4IAuiEooRcXx/DpCRuqAU97shg0jYzgfsVpSFwcg5mZGcOedRewGDBhAgPDokUohsBthmoE8U+dOoXdBfHHjoElUQxB03i9oABspnTJNFQXgARB3oAbwsAAdirMRmSNMFdhTQcwQ/BpxGsAzCUwRSCn4gJE5QV8uQxuAFlZEaoJAKrYrAHl38o6AAAAAElFTkSuQmCC"); + ModAPI.meta.description("Library to make adding basic custom items easier."); ModAPI.events.newEvent("lib:libcustomitems:loaded"); function libServerside() { globalThis.LCI_REGISTRY ||= []; diff --git a/modgui.injector.js b/modgui.injector.js index fda999f..be4b2e3 100644 --- a/modgui.injector.js +++ b/modgui.injector.js @@ -184,21 +184,57 @@ globalThis.modapi_guikit = `// ModAPI GUI made by TheIdiotPlays tbody.innerHTML = ""; modsList.forEach((modtxt, i) => { if (!modtxt) { return } + var hash = ModAPI.util.hashCode(modtxt); var tr = document.createElement("tr"); var mod = document.createElement("td"); - if (modtxt.length > 125) { - try { - mod.innerText = modtxt.match(/data:text\\/\\S+?;fs=\\S+;/m)[0] - } catch (error) { - mod.innerText = "Unknown Mod."; + + if (ModAPI.meta._titleMap[hash]) { + //Mod has metadata + if (ModAPI.meta._iconMap[hash]) { + var img = document.createElement("img"); + img.style.width = "48px"; + img.style.height = "48px"; + img.style.imageRendering = "pixelated"; + img.src = ModAPI.meta._iconMap[hash]; + mod.appendChild(img); + } + var h4 = document.createElement("h4"); + h4.style.margin = 0; + h4.style.padding = 0; + h4.innerText = ModAPI.meta._titleMap[hash]; + mod.appendChild(h4); + if (ModAPI.meta._developerMap[hash]) { + var h6 = document.createElement("h6"); + h6.style.margin = 0; + h6.style.padding = 0; + h6.innerText = ModAPI.meta._developerMap[hash]; + mod.appendChild(h6); + } + if (ModAPI.meta._descriptionMap[hash]) { + var span = document.createElement("span"); + span.style.fontSize = "0.65rem"; + span.innerText = ModAPI.meta._descriptionMap[hash]; + mod.appendChild(span); } - } else { mod.innerText = modtxt; } + } else { + //Mod does not have metadata + if (modtxt.length > 125) { + try { + mod.innerText = modtxt.match(/data:text\\/\\S+?;fs=\\S+;/m)[0] + } catch (error) { + mod.innerText = "Unknown Mod."; + } + } else { mod.innerText = modtxt; } + } + var spacer = document.createElement("td"); spacer.classList.add("nothing"); var controls = document.createElement("td"); var button = document.createElement("button"); button.innerText = "Delete"; + button.style.height = "3rem"; + button.style.marginTop = "calc(50% - 1.5rem)"; button.addEventListener("click", async () => { await removeMod(i); window.modapi_displayModGui(); diff --git a/modgui.js b/modgui.js index b3df844..c8017bd 100644 --- a/modgui.js +++ b/modgui.js @@ -184,21 +184,57 @@ tbody.innerHTML = ""; modsList.forEach((modtxt, i) => { if (!modtxt) { return } + var hash = ModAPI.util.hashCode(modtxt); var tr = document.createElement("tr"); var mod = document.createElement("td"); - if (modtxt.length > 125) { - try { - mod.innerText = modtxt.match(/data:text\/\S+?;fs=\S+;/m)[0] - } catch (error) { - mod.innerText = "Unknown Mod."; + + if (ModAPI.meta._titleMap[hash]) { + //Mod has metadata + if (ModAPI.meta._iconMap[hash]) { + var img = document.createElement("img"); + img.style.width = "48px"; + img.style.height = "48px"; + img.style.imageRendering = "pixelated"; + img.src = ModAPI.meta._iconMap[hash]; + mod.appendChild(img); + } + var h4 = document.createElement("h4"); + h4.style.margin = 0; + h4.style.padding = 0; + h4.innerText = ModAPI.meta._titleMap[hash]; + mod.appendChild(h4); + if (ModAPI.meta._developerMap[hash]) { + var h6 = document.createElement("h6"); + h6.style.margin = 0; + h6.style.padding = 0; + h6.innerText = ModAPI.meta._developerMap[hash]; + mod.appendChild(h6); + } + if (ModAPI.meta._descriptionMap[hash]) { + var span = document.createElement("span"); + span.style.fontSize = "0.65rem"; + span.innerText = ModAPI.meta._descriptionMap[hash]; + mod.appendChild(span); } - } else { mod.innerText = modtxt; } + } else { + //Mod does not have metadata + if (modtxt.length > 125) { + try { + mod.innerText = modtxt.match(/data:text\/\S+?;fs=\S+;/m)[0] + } catch (error) { + mod.innerText = "Unknown Mod."; + } + } else { mod.innerText = modtxt; } + } + var spacer = document.createElement("td"); spacer.classList.add("nothing"); var controls = document.createElement("td"); var button = document.createElement("button"); button.innerText = "Delete"; + button.style.height = "3rem"; + button.style.marginTop = "calc(50% - 1.5rem)"; button.addEventListener("click", async () => { await removeMod(i); window.modapi_displayModGui(); diff --git a/modloader.injector.js b/modloader.injector.js index b99f9d5..66c62d7 100644 --- a/modloader.injector.js +++ b/modloader.injector.js @@ -57,6 +57,7 @@ async function removeMod(index) { async function resetMods() { await saveMods([]); + console.log("Mods reset"); } window.modLoader = async function modLoader(modsArr = []) { @@ -131,8 +132,9 @@ window.modLoader = async function modLoader(modsArr = []) { try { console.log("[EaglerML] Loading " + currentMod + " via method B."); var script = document.createElement("script"); + script.setAttribute("data-hash", ModAPI.util.hashCode("web@"+currentMod)); script.src = currentMod; - script.setAttribute("data-isMod", true); + script.setAttribute("data-isMod", "true"); script.onerror = () => { console.log( "[EaglerML] Failed to load " + currentMod + " via method B!" @@ -166,6 +168,7 @@ window.modLoader = async function modLoader(modsArr = []) { req.onload = function xhrLoadHandler() { console.log("[EaglerML] Loading " + currentMod + " via method A."); var script = document.createElement("script"); + script.setAttribute("data-hash", ModAPI.util.hashCode("web@"+currentMod)); try { script.src = "data:text/javascript," + encodeURIComponent(req.responseText); @@ -173,7 +176,7 @@ window.modLoader = async function modLoader(modsArr = []) { methodB(currentMod); return; } - script.setAttribute("data-isMod", true); + script.setAttribute("data-isMod", "true"); script.onerror = () => { console.log( "[EaglerML] Failed to load " + currentMod + " via method A!" diff --git a/modloader.js b/modloader.js index e810b29..02cda35 100644 --- a/modloader.js +++ b/modloader.js @@ -132,8 +132,9 @@ window.modLoader = async function modLoader(modsArr = []) { try { console.log("[EaglerML] Loading " + currentMod + " via method B."); var script = document.createElement("script"); + script.setAttribute("data-hash", ModAPI.util.hashCode("web@"+currentMod)); script.src = currentMod; - script.setAttribute("data-isMod", true); + script.setAttribute("data-isMod", "true"); script.onerror = () => { console.log( "[EaglerML] Failed to load " + currentMod + " via method B!" @@ -167,6 +168,7 @@ window.modLoader = async function modLoader(modsArr = []) { req.onload = function xhrLoadHandler() { console.log("[EaglerML] Loading " + currentMod + " via method A."); var script = document.createElement("script"); + script.setAttribute("data-hash", ModAPI.util.hashCode("web@"+currentMod)); try { script.src = "data:text/javascript," + encodeURIComponent(req.responseText); @@ -174,7 +176,7 @@ window.modLoader = async function modLoader(modsArr = []) { methodB(currentMod); return; } - script.setAttribute("data-isMod", true); + script.setAttribute("data-isMod", "true"); script.onerror = () => { console.log( "[EaglerML] Failed to load " + currentMod + " via method A!" diff --git a/postinit.injector.js b/postinit.injector.js index b0d58f0..0631739 100644 --- a/postinit.injector.js +++ b/postinit.injector.js @@ -14,6 +14,54 @@ globalThis.modapi_postinit = `(() => { globalThis.PluginAPI ||= ModAPI; ModAPI.mcinstance ||= {}; ModAPI.javaClient ||= {}; + ModAPI.meta = {}; + ModAPI.meta._titleMap = {}; + ModAPI.meta._descriptionMap = {}; + ModAPI.meta._developerMap = {}; + ModAPI.meta._iconMap = {}; + function limitSize(x, n) { + if (x.length > n) { + return x.substring(0, n) + "…"; + } else { + return x; + } + } + ModAPI.meta.title = function (title) { + if (document.currentScript.getAttribute("data-isMod") !== "true") { + return console.log("[ModAPIMeta] Cannot set meta for non-mod script."); + } + if (!document.currentScript.hasAttribute("data-hash")) { + return console.log("[ModAPIMeta] Script does not have a hashcode."); + } + ModAPI.meta._titleMap[document.currentScript.getAttribute("data-hash")] = limitSize(title, 14); + } + ModAPI.meta.icon = function (iconSrc) { + if (document.currentScript.getAttribute("data-isMod") !== "true") { + return console.log("[ModAPIMeta] Cannot set meta for non-mod script."); + } + if (!document.currentScript.hasAttribute("data-hash")) { + return console.log("[ModAPIMeta] Script does not have a hashcode."); + } + ModAPI.meta._iconMap[document.currentScript.getAttribute("data-hash")] = iconSrc; + } + ModAPI.meta.credits = function (cd) { + if (document.currentScript.getAttribute("data-isMod") !== "true") { + return console.log("[ModAPIMeta] Cannot set meta for non-mod script."); + } + if (!document.currentScript.hasAttribute("data-hash")) { + return console.log("[ModAPIMeta] Script does not have a hashcode."); + } + ModAPI.meta._developerMap[document.currentScript.getAttribute("data-hash")] = limitSize(cd, 16); + } + ModAPI.meta.description = function (desc) { + if (document.currentScript.getAttribute("data-isMod") !== "true") { + return console.log("[ModAPIMeta] Cannot set meta for non-mod script."); + } + if (!document.currentScript.hasAttribute("data-hash")) { + return console.log("[ModAPIMeta] Script does not have a hashcode."); + } + ModAPI.meta._descriptionMap[document.currentScript.getAttribute("data-hash")] = limitSize(desc, 64); + } ModAPI.reflect ||= {}; ModAPI.server = ModAPI.serverInstance = null; ModAPI.dedicatedServer ||= {}; @@ -439,6 +487,16 @@ globalThis.modapi_postinit = `(() => { return ModAPI.hooks._teavm.$rt_createArrayFromData(arrayClass, arrayContents); } + ModAPI.util.hashCode = function hashCode(string){ + var hash = 0; + for (var i = 0; i < string.length; i++) { + var code = string.charCodeAt(i); + hash = ((hash<<5)-hash)+code; + hash = hash & hash; + } + return Math.floor(Math.abs(hash)) + ""; + }; + ModAPI.clickMouse = function () { ModAPI.hooks.methods["nmc_Minecraft_clickMouse"](ModAPI.javaClient); } diff --git a/postinit.js b/postinit.js index c865c00..3e4c7b1 100644 --- a/postinit.js +++ b/postinit.js @@ -14,6 +14,54 @@ globalThis.PluginAPI ||= ModAPI; ModAPI.mcinstance ||= {}; ModAPI.javaClient ||= {}; + ModAPI.meta = {}; + ModAPI.meta._titleMap = {}; + ModAPI.meta._descriptionMap = {}; + ModAPI.meta._developerMap = {}; + ModAPI.meta._iconMap = {}; + function limitSize(x, n) { + if (x.length > n) { + return x.substring(0, n) + "…"; + } else { + return x; + } + } + ModAPI.meta.title = function (title) { + if (document.currentScript.getAttribute("data-isMod") !== "true") { + return console.log("[ModAPIMeta] Cannot set meta for non-mod script."); + } + if (!document.currentScript.hasAttribute("data-hash")) { + return console.log("[ModAPIMeta] Script does not have a hashcode."); + } + ModAPI.meta._titleMap[document.currentScript.getAttribute("data-hash")] = limitSize(title, 14); + } + ModAPI.meta.icon = function (iconSrc) { + if (document.currentScript.getAttribute("data-isMod") !== "true") { + return console.log("[ModAPIMeta] Cannot set meta for non-mod script."); + } + if (!document.currentScript.hasAttribute("data-hash")) { + return console.log("[ModAPIMeta] Script does not have a hashcode."); + } + ModAPI.meta._iconMap[document.currentScript.getAttribute("data-hash")] = iconSrc; + } + ModAPI.meta.credits = function (cd) { + if (document.currentScript.getAttribute("data-isMod") !== "true") { + return console.log("[ModAPIMeta] Cannot set meta for non-mod script."); + } + if (!document.currentScript.hasAttribute("data-hash")) { + return console.log("[ModAPIMeta] Script does not have a hashcode."); + } + ModAPI.meta._developerMap[document.currentScript.getAttribute("data-hash")] = limitSize(cd, 16); + } + ModAPI.meta.description = function (desc) { + if (document.currentScript.getAttribute("data-isMod") !== "true") { + return console.log("[ModAPIMeta] Cannot set meta for non-mod script."); + } + if (!document.currentScript.hasAttribute("data-hash")) { + return console.log("[ModAPIMeta] Script does not have a hashcode."); + } + ModAPI.meta._descriptionMap[document.currentScript.getAttribute("data-hash")] = limitSize(desc, 64); + } ModAPI.reflect ||= {}; ModAPI.server = ModAPI.serverInstance = null; ModAPI.dedicatedServer ||= {}; @@ -439,6 +487,16 @@ return ModAPI.hooks._teavm.$rt_createArrayFromData(arrayClass, arrayContents); } + ModAPI.util.hashCode = function hashCode(string){ + var hash = 0; + for (var i = 0; i < string.length; i++) { + var code = string.charCodeAt(i); + hash = ((hash<<5)-hash)+code; + hash = hash & hash; + } + return Math.floor(Math.abs(hash)) + ""; + }; + ModAPI.clickMouse = function () { ModAPI.hooks.methods["nmc_Minecraft_clickMouse"](ModAPI.javaClient); }