diff --git a/build.js b/build.js index a3df790..fe0fa95 100644 --- a/build.js +++ b/build.js @@ -74,6 +74,9 @@ async function patchGameCode() { code: `this.a = Math.floor(0.066 * b.c); d = b.d - 4 * uiSizes.gap - this.a;`, addToDictionary: ["uiSizes", "gap"] + }, { + code: `var dt=MenuManager.getState();if(dt===6){if(d===4211){/*...*/}}`, + addToDictionary: ["MenuManager", "getState"] }]; codeSegments.forEach(({ code, addToDictionary }) => { modUtils.matchCode(code, { addToDictionary }) diff --git a/modUtils.js b/modUtils.js index bf02da1..a7cef81 100644 --- a/modUtils.js +++ b/modUtils.js @@ -214,4 +214,6 @@ export function definePatch(callback) { * Helper for `modifyCode` * @param {string} code */ -export const insert = (code) => code.split(/\r?\n/g).map(l => "/*insert line:*/" + l).join("\n"); \ No newline at end of file +export const insert = (code) => ( + "\n" + code.split(/\r?\n/g).map(l => "/*insert line:*/" + l).join("\n") + "\n" +); \ No newline at end of file diff --git a/patches/customLobby.js b/patches/customLobby.js index 5568dde..5bc5af5 100644 --- a/patches/customLobby.js +++ b/patches/customLobby.js @@ -1,10 +1,7 @@ -import ModUtils from '../modUtils.js'; +import ModUtils, { insert } from '../modUtils.js'; // Custom lobby patches -export default (/** @type {ModUtils} */ { insertCode, replaceCode, replaceRawCode, safeDictionary: dict, waitForMinification }) => { - - // temporarily disabled for new versions - return; +export default (/** @type {ModUtils} */ { modifyCode, insertCode, replaceCode, replaceRawCode, safeDictionary: dict, waitForMinification }) => { // set player id correctly insertCode(`function aBG(aBE) { @@ -28,9 +25,24 @@ export default (/** @type {ModUtils} */ { insertCode, replaceCode, replaceRawCod return __fx.customLobby.setActive(false); }`) + insertCode(`this.send = function(a, b) { + if (a !== 0) {c(a);} + d[a].send(b); + }; /* here */`, "__fx.customLobby.setSendFunction(this.send)") + // when a socket error occurs on the custom lobby socket + insertCode(`this.b = function(id, t) { /* here */ this.a.push(t); if (i.h === 8 && id === 0) {if (t === 4211) {f(t);} else {/*...*/}}};`, `id===1 && __fx.customLobby.isActive() && MenuManager.getState() !== 6 && __fx.customLobby.setActive(false);`, { dictionary: {MenuManager: dict.MenuManager, getState: dict.getState} }) + // when leaving a game + modifyCode(`${insert(`if (__fx.customLobby.isActive() === false)`)} a.b.c(); + d.e(); + this.f = 0; + g.h(); + i.j.setState(0); + MenuManager.setState(0); + ${insert(`if (!__fx.customLobby.isActive()) `)} k.l.m(n); + ${insert(`if (__fx.customLobby.isActive()) __fx.customLobby.rejoinLobby(); + else`)} if (this.o === 2) {/*...*/}`) + waitForMinification(() => { - replaceRawCode("this.send=function(socketId,data){aJE(socketId),aJ4[socketId].send(data)}", - "this.send=function(socketId,data){aJE(socketId),aJ4[socketId].send(data)},__fx.customLobby.setSendFunction(this.send)") replaceRawCode("b7.dH(a0),0===b7.size?aq.kt.aJJ(wR,3205):", "b7.dH(a0),0===b7.size?aq.kt.aJJ(wR,3205):__fx.customLobby.isCustomMessage(a0)||") // set the custom lobby to inactive when clicking the "Back" button on the connection screen or leaving the lobby @@ -39,19 +51,6 @@ export default (/** @type {ModUtils} */ { insertCode, replaceCode, replaceRawCod replaceRawCode("function(){n.r(),bl.zf(),Sockets.s.ze(3240),n.o(5,5)}", `(__fx.customLobby.setLeaveFunction(() => {n.r(),bl.zf(),Sockets.s.ze(3240),__fx.customLobby.setActive(false),n.o(5,5)}), function(){n.r(),bl.zf(),Sockets.s.ze(3240),__fx.customLobby.setActive(false),n.o(5,5)})`) - // when a socket error occurs on the custom lobby socket - // TODO: Fix these after main WebSocket fix is confirmed working - /* - replaceRawCode("this.wQ=function(wR,d){if(8===i.pz&&0===wR)if(4211===d)wS(d);", - `this.wQ=function(wR,d){ - wR===1 && __fx.customLobby.isActive() && ${dict.MenuManager}.${dict.getState}() !== 6 && __fx.customLobby.setActive(false); - if(8===i.pz&&0===wR)if(4211===d)wS(d);`) - // when leaving a game - replaceRawCode("this.wl=function(zs){a1.gZ||az.oO.a11.length||(az.oO.a11=az.a12.vd()),ap.ky.zt(),this.vH=0,bU.zu(),m.n.setState(0),aN.setState(0),zs||bJ.df.show(),2===this.a3D?i.ky.a3U():1===this.a3D?i.j(19):i.j(5,5)}", - `this.wl=function(zs){a1.gZ||az.oO.a11.length||(az.oO.a11=az.a12.vd()), - __fx.customLobby.isActive() === false && ap.ky.zt(), - this.vH=0,bU.zu(),m.n.setState(0),aN.setState(0),zs||bJ.df.show(); - if (__fx.customLobby.isActive()) __fx.customLobby.rejoinLobby(); else 2===this.a3D?i.ky.a3U():1===this.a3D?i.j(19):i.j(5,5)}`) // do not display lobby UI replaceRawCode(`(sV.style.backdropFilter="blur(4px)",sV.style.webkitBackdropFilter="blur(4px)"),`, `(sV.style.backdropFilter="blur(4px)",sV.style.webkitBackdropFilter="blur(4px)"), @@ -80,6 +79,5 @@ export default (/** @type {ModUtils} */ { insertCode, replaceCode, replaceRawCod replaceRawCode("1===a.b?this.gLobbyMaxJoin=this.gHumans:this.gLobbyMaxJoin=this.data.playerCount,this.maxPlayers=this.gLobbyMaxJoin,this.gBots=this.gLobbyMaxJoin-this.gHumans,this.sg=0,", `this.gLobbyMaxJoin = __fx.customLobby.isActive() ? Math.max(Math.min(__fx.customLobby.gameInfo.botCount, this.data.playerCount), this.gHumans) : 1===a.b?this.gLobbyMaxJoin=this.gHumans:this.gLobbyMaxJoin=this.data.playerCount, this.maxPlayers=this.gLobbyMaxJoin,this.gBots=this.gLobbyMaxJoin-this.gHumans,this.sg=0,`) - */ }); } \ No newline at end of file diff --git a/src/customLobby.js b/src/customLobby.js index bb17baf..f39b4a2 100644 --- a/src/customLobby.js +++ b/src/customLobby.js @@ -1,12 +1,13 @@ import WindowManager from "./windowManager.js"; -const customLobbiesUnavailable = true; -//const socketURL = "ws://localhost:8080/"; -const socketURL = "wss://fx.peshomir.workers.dev/"; +const customLobbiesUnavailable = false; +// const socketURL = "ws://localhost:8080/"; +const socketURL = "wss://fx-lobbies.peshomir.workers.dev/"; const customMessageMarker = 120; let isActive = false; let currentCode = ""; let joinLobby = () => { }; +/** when `leaveLobby` is called, the modified code will also execute setActive(false) */ let leaveLobby = () => { }; let sendRaw = (socketId, data) => { }; const textEncoder = new TextEncoder(); @@ -33,6 +34,10 @@ const windowElement = WindowManager.create({ const header = document.createElement("h2"); header.textContent = "Custom Lobby"; +header.style.marginBottom = "0px"; +header.style.marginBlockStart = "0.5em"; +const pingIndicator = document.createElement("p"); +pingIndicator.style.marginTop = "0px"; const main = document.createElement("div"); main.className = "customlobby-main"; @@ -152,7 +157,7 @@ const copyLinkButton = createButton("Copy link", () => { }); footer.append(startButton, leaveButton, copyLinkButton); -windowElement.append(header, main, footer); +windowElement.append(header, pingIndicator, main, footer); /** @param {HTMLSelectElement} element */ function setSelectMenuOptions(options, element) { @@ -174,13 +179,13 @@ document.getElementById("lobbyCode").addEventListener("input", ({ target: input currentCode = input.value.toLowerCase(); input.value = ""; WindowManager.closeWindow("lobbyJoinMenu"); - isActive = true; + setActive(true) joinLobby(); }); document.getElementById("createLobbyButton").addEventListener("click", () => { currentCode = ""; WindowManager.closeWindow("lobbyJoinMenu"); - isActive = true; + setActive(true) joinLobby(); }); @@ -204,7 +209,12 @@ function isCustomMessage(raw) { const subArray = new Uint8Array(raw.buffer, 1); const message = JSON.parse(textDecoder.decode(subArray)); const { t: type, d: data } = message; - if (type === "lobby") { + if (type === "pong") { + const latency = performance.now() - data + pingIndicator.innerText = `Ping: ${latency} ms` + } else if (type === "lobby") { + pingIndicator.innerText = "" + sendPing() WindowManager.openWindow("customLobby"); header.textContent = "Custom Lobby " + data.code; currentCode = data.code; @@ -293,7 +303,9 @@ function updatePlayerCount() { } function getSocketURL() { - return socketURL + (currentCode === "" ? "create" : "join?" + currentCode) + if (currentCode !== "") return socketURL + "join?" + currentCode + const region = document.getElementById("customLobbyRegion").value + return socketURL + "create" + (region === "default" ? "" : `?location=${region}`) } function getPlayerId() { let id = 0; @@ -317,7 +329,7 @@ function checkForLobbyLink(isHashChangeEvent) { // in case the player is already in a lobby if (isHashChangeEvent) leaveLobby(); currentCode = hash.slice(7); - isActive = true; + setActive(true) joinLobby(); } } @@ -329,9 +341,16 @@ function setJoinFunction(f) { } function setLeaveFunction(f) { leaveLobby = f; } function setSendFunction(f) { sendRaw = f; } +function sendPing() { + sendMessage("ping", performance.now()) +} +let pingInterval; function setActive(active) { isActive = active; - if (active === false) WindowManager.closeWindow("customLobby"); + if (active === false) { + WindowManager.closeWindow("customLobby"); + if (pingInterval !== undefined) clearInterval(pingInterval) + } else pingInterval = setInterval(sendPing, 10_000) } function hideWindow() { WindowManager.closeWindow("customLobby"); diff --git a/static/index.html b/static/index.html index 027e6ef..c60f05f 100644 --- a/static/index.html +++ b/static/index.html @@ -112,7 +112,20 @@