From 7c8dca87c3f77467fbc1567538457bce43d2ed46 Mon Sep 17 00:00:00 2001 From: ZXMushroom63 Date: Mon, 17 Mar 2025 17:53:37 +0800 Subject: [PATCH 1/5] fixed efserver loader --- injector.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/injector.js b/injector.js index 30b93ce..fcf1995 100644 --- a/injector.js +++ b/injector.js @@ -368,7 +368,7 @@ document.querySelector("#givemeserver").addEventListener("click", () => { patchedFile = await shronk(patchedFile); } - patchedFile.replace(`{"._|_libserverside_|_."}`, `(${EFServer.toString()})()`); + patchedFile = patchedFile.replace(`{"._|_libserverside_|_."}`, `(${EFServer.toString()})()`); var blob = new Blob([patchedFile], { type: file.type }); saveAs(blob, "efserver." + fileType); }); From 3f5da2d21c5d0454ea6e7f108033c4886bc34466 Mon Sep 17 00:00:00 2001 From: ZXMushroom63 Date: Mon, 17 Mar 2025 18:37:17 +0800 Subject: [PATCH 2/5] EFI server injector patch --- injector.js | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/injector.js b/injector.js index 13ce07d..c0b4607 100644 --- a/injector.js +++ b/injector.js @@ -388,7 +388,11 @@ document.querySelector("#givemeserver").addEventListener("click", () => { } patchedFile = patchedFile.replace(`{"._|_libserverside_|_."}`, `(${EFServer.toString()})()`); + backgroundLog("[EFSERVER] Injecting libserverside corelib"); + patchedFile = patchedFile.replace("EFI", "<title>EF Server"); + backgroundLog("[EFSERVER] Patching title"); var blob = new Blob([patchedFile], { type: file.type }); saveAs(blob, "efserver." + fileType); + backgroundLog("Saving file...", true); }); }); From 191e7a4684cceeefe591356aa5cb696b0ecebc0f Mon Sep 17 00:00:00 2001 From: ZXMushroom63 <robert.pirtea.junior@gmail.com> Date: Mon, 17 Mar 2025 19:42:34 +0800 Subject: [PATCH 3/5] ef server v1.0 --- examplemods/servermod.js | 95 +++++++++++++++++++++++++++++++++------- 1 file changed, 78 insertions(+), 17 deletions(-) diff --git a/examplemods/servermod.js b/examplemods/servermod.js index 0cb8b2d..5650f23 100644 --- a/examplemods/servermod.js +++ b/examplemods/servermod.js @@ -11,6 +11,8 @@ gui.style.zIndex = 254; gui.style.position = "fixed"; gui.style.display = "none"; + gui.style.height = "calc(100vh - 1rem - 4px)"; + gui.style.overflowY = "scroll"; gui.style.color = "white"; gui.style.top = gui.style.left = gui.style.bottom = gui.style.right = 0; document.documentElement.appendChild(gui); @@ -26,6 +28,7 @@ cmdbox.style.background = "black"; cmdbox.style.zIndex = 255; cmdbox.style.color = "white"; + cmdbox.style.height = "1rem"; cmdbox.type = "text"; cmdbox.addEventListener("keydown", (e) => { e.stopPropagation(); @@ -37,12 +40,16 @@ if (e.key === "Enter") { e.preventDefault(); toServer("chat", cmdbox.value); + cmdbox.value = ""; } }, true); document.documentElement.appendChild(cmdbox); function worldUpdate() { if (ModAPI.mc && ModAPI.mc.theWorld) { + ModAPI.hooks.methods.nmcs_GameSettings_saveOptions = ()=>{}; + ModAPI.settings.limitFramerate = 1; + ModAPI.settings.enableVsync = 0; showgui(); openSharedWorld() } else { @@ -67,17 +74,53 @@ cmdbox.style.display = "none"; } + function EFB2__defineExecCmdAsGlobal() { + var getServer = ModAPI.reflect.getClassById("net.minecraft.server.MinecraftServer").staticMethods.getServer.method; + globalThis.efb2__executeCommandAs = function efb2__executeCommandAs($commandsender, command, feedback) { + var server = getServer(); + if (!server) { return }; + var commandManager = server.$commandManager; - function openSharedWorld(){ - if(ModAPI.mc.theWorld && !ModAPI.hooks.methods.nlevsl_LANServerController_isLANOpen()){ - ModAPI.hooks.methods.nlevi_PlatformWebRTC_startRTCLANServer(); - var worldName = ModAPI.util.unstr(ModAPI.mc.thePlayer.getName()) + "'s World"; - var ls = ModAPI.mc.loadingScreen; - var code = ModAPI.hooks.methods.nlevsl_LANServerController_shareToLAN(ls.resetProgressAndMessage, worldName, false) - if (code != null) { - ModAPI.hooks.methods.nlevs_SingleplayerServerController_configureLAN(ModAPI.mc.playerController.getCurrentGameType(), false); - alert("code: " + code +" relay: " + ModAPI.hooks.methods.nlevsl_LANServerController_getCurrentURI()) - } + //lie a bit + var x = $commandsender.$canCommandSenderUseCommand; + $commandsender.$canCommandSenderUseCommand = () => 1; + + var y = $commandsender.$sendCommandFeedback; + $commandsender.$sendCommandFeedback = feedback ? () => 1 : () => 0; + + try { + commandManager.$executeCommand($commandsender, ModAPI.util.str(command)); + } catch (error) { + console.error(error); + } + + $commandsender.$canCommandSenderUseCommand = x; + $commandsender.$sendCommandFeedback = y; + } + } + ModAPI.dedicatedServer.appendCode(EFB2__defineExecCmdAsGlobal); + + ModAPI.hooks.methods.nmc_LoadingScreenRenderer_eaglerShow = ()=>{}; + var opening = false; + function openSharedWorld() { + var platform = ModAPI.reflect.getClassById("net.lax1dude.eaglercraft.v1_8.internal.PlatformWebRTC"); + if (!opening && ModAPI.mc.theWorld && !ModAPI.hooks.methods.nlevsl_LANServerController_isLANOpen()) { + platform.staticVariables.rtcLANServer = ModAPI.reflect.getClassById("net.lax1dude.eaglercraft.v1_8.internal.PlatformWebRTC$LANServer").constructors[0](); + var worldName = ModAPI.util.unstr(ModAPI.mc.thePlayer.getName().getRef()) + "'s World"; + opening = true; + ModAPI.promisify(ModAPI.hooks.methods.nlevsl_LANServerController_shareToLAN)({ + $accept: (status)=>{ + gui.innerText += "\n" + ModAPI.util.ustr(status); + } + }, ModAPI.util.str(worldName), 0).then(code => { + opening = true; //change to false later + if (code != null) { + ModAPI.hooks.methods.nlevs_SingleplayerServerController_configureLAN(ModAPI.mc.playerController.currentGameType.getRef(), 0); + var msg = "code: " + ModAPI.util.ustr(code) + " relay: " + ModAPI.util.ustr(ModAPI.hooks.methods.nlevsl_LANServerController_getCurrentURI()); + alert(msg); + gui.innerText += "\n" + msg; + } + }); } else { return; } @@ -100,11 +143,15 @@ var token = crypto.randomUUID(); const clientMessageHandlers = { chat: function (data) { + if (gui.scrollHeight > (innerHeight * 5)) { + gui.innerText = "Console cleared. Logs were over 5 pages long."; + } gui.innerText += data + "\n"; + gui.scrollTop = gui.scrollHeight; }, }; var client_comms_channel = new BroadcastChannel("efserv:" + token); - client_comms_channel.addEventListener("message", (ev)=>{ + client_comms_channel.addEventListener("message", (ev) => { if (ev.data.audience !== "client") { return; } @@ -144,11 +191,10 @@ const messageHandlers = { chat: function (data) { - ModAPI.hooks.methods.nmc_CommandHandler_executeCommand( - ModAPI.server.commandManager.getRef(), - getHostPlayer(), - ModAPI.util.str(data) - ); //host has to use /say + console.log("Received cmd: ", data); + console.log("Received hostplayer: ", getHostPlayer()); + getHostPlayer().$addChatMessage = (comp)=>{toClient("chat", ModAPI.util.ustr(comp.$getUnformattedText()))}; + efb2__executeCommandAs(getHostPlayer(), data, true); }, }; @@ -166,9 +212,24 @@ toClient("chat", ModAPI.util.ustr(args[2])); return oldLog.apply(this, args); }; + + ModAPI.addEventListener("tick", ()=>{ + var host = ModAPI.util.wrap(getHostPlayer()); + host.posY = -10; + host.posX = 0; + host.posZ = 0; + host.capabilities.disableDamage = 1; + host.capabilities.isCreativeMode = 1; + host.capabilities.isFlying = 1; + host.motionY = 0; + host.motionX = 0; + host.motionZ = 0; + host.isDead = 0; + host.setHealth(20); + }); }); - + function renameButton(array, originalName, newName) { array.find( From a7e22b7f23bffa70377929f54fd1c4e185e2ef53 Mon Sep 17 00:00:00 2001 From: ZXMushroom63 <robert.pirtea.junior@gmail.com> Date: Mon, 17 Mar 2025 19:49:03 +0800 Subject: [PATCH 4/5] fix bug --- examplemods/servermod.js | 3 +++ 1 file changed, 3 insertions(+) diff --git a/examplemods/servermod.js b/examplemods/servermod.js index 5650f23..dc5e5d5 100644 --- a/examplemods/servermod.js +++ b/examplemods/servermod.js @@ -179,6 +179,9 @@ var host = null; ModAPI.server.getRef().$worldServers.data.forEach((world) => { host ||= world.$playerEntities.$array1.data.find((player) => { + if (!player) { + return; + } var nameKey = ModAPI.util.getNearestProperty( player.$gameProfile, "$name" From 7393608fb43db57add66d02f3ce2c803bb4cd32f Mon Sep 17 00:00:00 2001 From: ZXMushroom63 <robert.pirtea.junior@gmail.com> Date: Mon, 17 Mar 2025 20:02:08 +0800 Subject: [PATCH 5/5] push modded server --- efserver.js | 284 ++++++++++++++++++++++++++++++++++++++- examplemods/servermod.js | 14 +- index.html | 4 +- 3 files changed, 294 insertions(+), 8 deletions(-) diff --git a/efserver.js b/efserver.js index 4429559..f7751e7 100644 --- a/efserver.js +++ b/efserver.js @@ -1,4 +1,284 @@ function EFServer() { - //Todo: write mod that disables rendering engine, autodisplays gui, and makes run server button. - console.log("hello world"); + ModAPI.meta.title("Server Manager"); + ModAPI.meta.version("a0"); + ModAPI.meta.description("_"); + ModAPI.meta.credits("ZXMushroom63 & radmanplays"); + + + const gui = document.createElement("div"); + gui.innerText = "EFSERVER CONSOLE"; + gui.style.background = "black"; + gui.style.fontFamily = "sans-serif"; + gui.style.zIndex = 254; + gui.style.position = "fixed"; + gui.style.display = "none"; + gui.style.height = "calc(100vh - 1rem - 4px)"; + gui.style.overflowY = "scroll"; + gui.style.color = "white"; + gui.style.top = gui.style.left = gui.style.bottom = gui.style.right = 0; + document.documentElement.appendChild(gui); + + var cmdbox = document.createElement("input"); + cmdbox.style.position = "absolute"; + cmdbox.style.left = "0"; + cmdbox.style.bottom = "0"; + cmdbox.style.right = "0"; + cmdbox.style.position = "inline-block"; + cmdbox.style.border = "0"; + cmdbox.style.borderTop = "2px solid white"; + cmdbox.style.background = "black"; + cmdbox.style.zIndex = 255; + cmdbox.style.color = "white"; + cmdbox.style.height = "1rem"; + cmdbox.type = "text"; + cmdbox.addEventListener("keydown", (e) => { + e.stopPropagation(); + e.stopImmediatePropagation(); + }, true); + cmdbox.addEventListener("keyup", (e) => { + e.stopPropagation(); + e.stopImmediatePropagation(); + if (e.key === "Enter") { + e.preventDefault(); + toServer("chat", cmdbox.value); + cmdbox.value = ""; + } + }, true); + document.documentElement.appendChild(cmdbox); + + function worldUpdate() { + if (ModAPI.mc && ModAPI.mc.theWorld) { + ModAPI.hooks.methods.nmcs_GameSettings_saveOptions = ()=>{}; + ModAPI.settings.limitFramerate = 1; + ModAPI.settings.enableVsync = 0; + showgui(); + openSharedWorld() + } else { + hidegui(); + } + } + + setInterval(() => { + worldUpdate(); + }, 100); + + function showgui() { + gui.style.opacity = "1"; + gui.style.display = "block"; + cmdbox.style.opacity = "1"; + cmdbox.style.display = "block"; + } + function hidegui() { + gui.style.opacity = "0"; + gui.style.display = "none"; + cmdbox.style.opacity = "0"; + cmdbox.style.display = "none"; + } + + function EFB2__defineExecCmdAsGlobal() { + var getServer = ModAPI.reflect.getClassById("net.minecraft.server.MinecraftServer").staticMethods.getServer.method; + globalThis.efb2__executeCommandAs = function efb2__executeCommandAs($commandsender, command, feedback) { + var server = getServer(); + if (!server) { return }; + var commandManager = server.$commandManager; + + //lie a bit + var x = $commandsender.$canCommandSenderUseCommand; + $commandsender.$canCommandSenderUseCommand = () => 1; + + var y = $commandsender.$sendCommandFeedback; + $commandsender.$sendCommandFeedback = feedback ? () => 1 : () => 0; + + try { + commandManager.$executeCommand($commandsender, ModAPI.util.str(command)); + } catch (error) { + console.error(error); + } + + $commandsender.$canCommandSenderUseCommand = x; + $commandsender.$sendCommandFeedback = y; + } + } + ModAPI.dedicatedServer.appendCode(EFB2__defineExecCmdAsGlobal); + + ModAPI.hooks.methods.nmc_LoadingScreenRenderer_eaglerShow = ()=>{}; + var opening = false; + function openSharedWorld() { + var platform = ModAPI.reflect.getClassById("net.lax1dude.eaglercraft.v1_8.internal.PlatformWebRTC"); + if (!opening && ModAPI.mc.theWorld && !ModAPI.hooks.methods.nlevsl_LANServerController_isLANOpen()) { + platform.staticVariables.rtcLANServer = ModAPI.reflect.getClassById("net.lax1dude.eaglercraft.v1_8.internal.PlatformWebRTC$LANServer").constructors[0](); + var worldName = ModAPI.util.unstr(ModAPI.mc.thePlayer.getName().getRef()) + "'s World"; + opening = true; + ModAPI.promisify(ModAPI.hooks.methods.nlevsl_LANServerController_shareToLAN)({ + $accept: (status)=>{ + gui.innerText += "\n" + ModAPI.util.ustr(status); + } + }, ModAPI.util.str(worldName), 0).then(code => { + opening = true; //change to false later + if (code != null) { + ModAPI.hooks.methods.nlevs_SingleplayerServerController_configureLAN(ModAPI.mc.playerController.currentGameType.getRef(), 0); + var msg = "code: " + ModAPI.util.ustr(code) + " relay: " + ModAPI.util.ustr(ModAPI.hooks.methods.nlevsl_LANServerController_getCurrentURI()); + alert(msg); + gui.innerText += "\n" + msg; + } + }); + } else { + return; + } + } + + + /* + NETWORKING OPCODES + chat - bidirectional, send chat to server/client + */ + + function toServer(opcode, data) { + client_comms_channel.postMessage({ + opcode: opcode, + audience: "server", + data: data, + }); + } + + var token = crypto.randomUUID(); + const clientMessageHandlers = { + chat: function (data) { + if (gui.scrollHeight > (innerHeight * 5)) { + gui.innerText = "Console cleared. Logs were over 5 pages long."; + } + gui.innerText += "\n" + data.replaceAll("§r", ""); + gui.scrollTop = gui.scrollHeight; + }, + }; + var client_comms_channel = new BroadcastChannel("efserv:" + token); + client_comms_channel.addEventListener("message", (ev) => { + if (ev.data.audience !== "client") { + return; + } + if (clientMessageHandlers[ev.data.opcode]) { + clientMessageHandlers[ev.data.opcode](ev.data.data); + } + }); + ModAPI.dedicatedServer.appendCode( + `globalThis.efhost_security_token = "${token}";` + ); + ModAPI.dedicatedServer.appendCode(function () { + var comms = new BroadcastChannel( + "efserv:" + globalThis.efhost_security_token + ); + + function toClient(opcode, data) { + comms.postMessage({ + opcode: opcode, + audience: "client", + data: data, + }); + } + + function getHostPlayer() { + var host = null; + ModAPI.server.getRef().$worldServers.data.forEach((world) => { + host ||= world.$playerEntities.$array1.data.find((player) => { + if (!player) { + return; + } + var nameKey = ModAPI.util.getNearestProperty( + player.$gameProfile, + "$name" + ); + return ModAPI.util.ustr(player.$gameProfile[nameKey]) === "HOST"; + }); + }); + return host; + } + + const messageHandlers = { + chat: function (data) { + var host = getHostPlayer(); + if (!host) { + return; + } + host.$addChatMessage = (comp)=>{toClient("chat", ModAPI.util.ustr(comp.$getUnformattedText()))}; + efb2__executeCommandAs(getHostPlayer(), data, true); + }, + }; + + comms.addEventListener("message", (ev) => { + if (ev.data.audience !== "server") { + return; + } + if (messageHandlers[ev.data.opcode]) { + messageHandlers[ev.data.opcode](ev.data.data); + } + }); + + var oldLog = ModAPI.hooks.methods.nlevl_Logger_log; + ModAPI.hooks.methods.nlevl_Logger_log = function (...args) { + toClient("chat", ModAPI.util.ustr(args[2])); + return oldLog.apply(this, args); + }; + + ModAPI.addEventListener("tick", ()=>{ + var host = ModAPI.util.wrap(getHostPlayer()); + if (!host) { + return; + } + host.posY = -10; + host.posX = 0; + host.posZ = 0; + host.capabilities.disableDamage = 1; + host.capabilities.isCreativeMode = 1; + host.capabilities.isFlying = 1; + host.motionY = 0; + host.motionX = 0; + host.motionZ = 0; + host.isDead = 0; + host.setHealth(20); + }); + }); + + + + function renameButton(array, originalName, newName) { + array.find( + (x) => ModAPI.util.ustr(x.displayString.getRef()) === originalName + ).displayString = ModAPI.util.str(newName); + } + + const mainmenuinit = ModAPI.hooks.methods.nmcg_GuiMainMenu_initGui; + ModAPI.hooks.methods.nmcg_GuiMainMenu_initGui = function (...args) { + var result = mainmenuinit.apply(this, args); + var wrappedGuiObject = ModAPI.util.wrap(args[0], args[0], false, false); + wrappedGuiObject.splashText = ModAPI.util.str("Server Hosting Mode"); + var btnarray = wrappedGuiObject.buttonList.array1; + renameButton(btnarray, "Singleplayer", "Host Server"); + + return result; + }; + + const GuiSelectWorldinit = ModAPI.hooks.methods.nmcg_GuiSelectWorld_initGui; + ModAPI.hooks.methods.nmcg_GuiSelectWorld_initGui = function (...args) { + var result = GuiSelectWorldinit.apply(this, args); + var wrappedGuiObject = ModAPI.util.wrap(args[0], args[0], false, false); + var btnarray = wrappedGuiObject.buttonList.array1.data; + //renameButton(btnarray, "Create", "Create Server"); + + return result; + }; + + const mainmenuactions = ModAPI.hooks.methods.nmcg_GuiMainMenu_actionPerformed; + ModAPI.hooks.methods.nmcg_GuiMainMenu_actionPerformed = function (...args) { + ModAPI.hooks.methods.nlevp_EaglerProfile_setName(ModAPI.util.str("HOST")); + var idKey = ModAPI.util.getNearestProperty(args[1], "$id"); + var guiButtonid = args[1][idKey]; + var blockedIds = [2]; // put the blocked/disabled button ids in there + if (blockedIds.includes(guiButtonid)) { + return 0; + } + return mainmenuactions.apply(this, args); + }; + + // disable rendering + ModAPI.hooks.methods.nmcr_EntityRenderer_renderWorld = () => { }; } \ No newline at end of file diff --git a/examplemods/servermod.js b/examplemods/servermod.js index dc5e5d5..9c54614 100644 --- a/examplemods/servermod.js +++ b/examplemods/servermod.js @@ -6,6 +6,7 @@ const gui = document.createElement("div"); + gui.innerText = "EFSERVER CONSOLE"; gui.style.background = "black"; gui.style.fontFamily = "sans-serif"; gui.style.zIndex = 254; @@ -146,7 +147,7 @@ if (gui.scrollHeight > (innerHeight * 5)) { gui.innerText = "Console cleared. Logs were over 5 pages long."; } - gui.innerText += data + "\n"; + gui.innerText += "\n" + data.replaceAll("§r", ""); gui.scrollTop = gui.scrollHeight; }, }; @@ -194,9 +195,11 @@ const messageHandlers = { chat: function (data) { - console.log("Received cmd: ", data); - console.log("Received hostplayer: ", getHostPlayer()); - getHostPlayer().$addChatMessage = (comp)=>{toClient("chat", ModAPI.util.ustr(comp.$getUnformattedText()))}; + var host = getHostPlayer(); + if (!host) { + return; + } + host.$addChatMessage = (comp)=>{toClient("chat", ModAPI.util.ustr(comp.$getUnformattedText()))}; efb2__executeCommandAs(getHostPlayer(), data, true); }, }; @@ -218,6 +221,9 @@ ModAPI.addEventListener("tick", ()=>{ var host = ModAPI.util.wrap(getHostPlayer()); + if (!host) { + return; + } host.posY = -10; host.posX = 0; host.posZ = 0; diff --git a/index.html b/index.html index 7b73985..612df54 100644 --- a/index.html +++ b/index.html @@ -99,8 +99,8 @@      <code id="status">Awaiting input...</code></span> <br /><br /> <button class="btn btn-primary" id="giveme">Make modded client</button> - <button class="btn btn-primary" id="givemeserver" disabled> - Make modded server (coming soonish maybe) + <button class="btn btn-primary" id="givemeserver"> + Make modded server (cALPHA) </button> </div>