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 @@
Awaiting input...
-