Spaces:
Running
Running
(function servermod() { | |
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 = false; | |
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 = () => { }; | |
})(); | |