From 421a0f3f0208c55f52dbbe5ae7503af608b55e58 Mon Sep 17 00:00:00 2001 From: peshomir <80340328+peshomir@users.noreply.github.com> Date: Mon, 28 Oct 2024 17:22:52 +0200 Subject: [PATCH] Custom lobby improvements (Update 0.6.6.5) - The custom lobby host can now kick other players - Fixed a bug where the custom lobby menu would stay visible after a disconnect --- patches.js | 5 ++--- src/customLobby.js | 32 +++++++++++++++++++------- src/main.js | 4 ++-- static/main.css | 56 +++++++++++++++++++++++++--------------------- 4 files changed, 59 insertions(+), 38 deletions(-) diff --git a/patches.js b/patches.js index 6efb570..4bf29ee 100644 --- a/patches.js +++ b/patches.js @@ -313,13 +313,12 @@ canvas.font=aY.g0.g1(1,fontSize),canvas.fillStyle="rgba("+gR+","+tD+","+hj+",0.6 replaceRawCode("this.xY=function(){this.wg(),Sockets.kt.wf(3240),aN.setState(0),i___.j(5,5)}", `this.xY=function(){this.wg(),Sockets.kt.wf(3240),__fx.customLobby.setActive(false),aN.setState(0),i___.j(5,5)}, __fx.customLobby.setLeaveFunction(() => this.xY())`) - /* // if this is needed again, include a check for menu state === 6 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()&&__fx.customLobby.setActive(false); if(8===i.pz&&0===wR)if(4211===d)wS(d);")*/ + "this.wQ=function(wR,d){ wR===1&&__fx.customLobby.isActive()&&__fx.customLobby.setActive(false); if(8===i.pz&&0===wR)if(4211===d)wS(d);") // if the server is unreachable replaceRawCode("0===a7Q?g.wc(3249):", "0===a7Q?g.wc(3249):1===a7Q&&__fx.customLobby.isActive()?(g.wc(3249),__fx.customLobby.setActive(false)):") // error descriptions - const errors = { 3249: "No servers found", 4705: "Lobby not found" }; + const errors = { 3249: "No servers found", 4705: "Lobby not found", 4730: "Kicked from lobby" }; replaceRawCode(`i___.j(4,5,new k("⚠️ "+title,w3__,!0))`, `i___.j(4,5,new k("⚠️ "+title, ${JSON.stringify(errors)}[w3__] || w3__,!0))`) // map info (for the map selection menu) diff --git a/src/customLobby.js b/src/customLobby.js index 0ccf0f5..cd244a5 100644 --- a/src/customLobby.js +++ b/src/customLobby.js @@ -123,6 +123,7 @@ function sendMessage(type, data) { uint8ArrayView.set(originalArray); sendRaw(1, buffer); } +let playerIsHost = false; /** @param {Uint8Array} raw */ function isCustomMessage(raw) { if (raw[0] !== customMessageMarker) return false; @@ -134,13 +135,16 @@ function isCustomMessage(raw) { WindowManager.openWindow("customLobby"); header.textContent = "Custom Lobby " + data.code; currentCode = data.code; - startButton.disabled = !data.isHost; - optionsContainer.className = data.isHost ? "" : "disabled"; + playerIsHost = data.isHost; + startButton.disabled = !playerIsHost; + optionsContainer.className = playerIsHost ? "" : "disabled"; gameModeSelectMenu.value = data.options.mode.toString(); mapSelectMenu.value = data.options.map.toString(); displayPlayers(data.players); - } else if (type === "addPlayer") addPlayer(data); - else if (type === "removePlayer") { + } else if (type === "addPlayer") { + addPlayer(data); + updatePlayerCount(); + } else if (type === "removePlayer") { const index = data; playerElements[index].element.remove(); playerElements.splice(index, 1); @@ -152,27 +156,39 @@ function isCustomMessage(raw) { else if (option === "map") mapSelectMenu.value = value.toString(); } else if (type === "setHost") { const index = data; + playerElements[index].isHost = true; playerElements[index].hostBadge.className = ""; } else if (type === "host") { + playerIsHost = true; startButton.disabled = false; optionsContainer.className = ""; + playerElements.forEach(p => { if (!p.isHost) p.kickButton.className = "" }); } return true; } -/** @type {{ element: HTMLDivElement, hostBadge: HTMLSpanElement }[]} */ +/** @type {{ element: HTMLDivElement, hostBadge: HTMLSpanElement, kickButton: HTMLButtonElement, isHost: boolean }[]} */ let playerElements = []; /** @param {{ name: string, isHost: boolean }} player */ function addPlayer(player) { const div = document.createElement("div"); div.className = "lobby-player"; div.textContent = player.name; + const kickButton = document.createElement("button"); + kickButton.textContent = "Kick"; + kickButton.className = playerIsHost && !player.isHost ? "" : "d-none"; + kickButton.addEventListener("click", kickButtonHandler); const badge = document.createElement("span"); badge.textContent = "Host"; badge.className = player.isHost ? "" : "d-none"; - div.append(badge); + div.append(badge, kickButton); playerList.append(div); - playerElements.push({ element: div, hostBadge: badge }); - updatePlayerCount(); + playerElements.push({ element: div, hostBadge: badge, kickButton, isHost: player.isHost }); +} +function kickButtonHandler(event) { + const button = event.target; + for (let index = 0; index < playerElements.length; index++) { + if (playerElements[index].kickButton === button) sendMessage("kick", index); + } } /** @param {{ name: string, isHost: boolean }[]} players */ function displayPlayers(players) { diff --git a/src/main.js b/src/main.js index 0fa569e..b07c483 100644 --- a/src/main.js +++ b/src/main.js @@ -1,5 +1,5 @@ -const fx_version = '0.6.6.4'; // FX Client Version -const fx_update = 'Oct 26'; // FX Client Last Updated +const fx_version = '0.6.6.5'; // FX Client Version +const fx_update = 'Oct 28'; // FX Client Last Updated import settingsManager from './settings.js'; import { clanFilter, leaderboardFilter } from "./clanFilters.js"; diff --git a/static/main.css b/static/main.css index 44ce37c..ad5e63e 100644 --- a/static/main.css +++ b/static/main.css @@ -34,6 +34,31 @@ z-index : 10; } +.window button, +.window input, +.window select { + background-color: rgba(0, 0, 0, 0.7); + color : white; + font-size : 20px; + font-size : 0.9em; + padding : 0.4rem; + transition : 0.2s; + border : 1px solid #fff; + border-radius : 5px; + margin : 5px; +} + +.window :disabled, .window .disabled { + pointer-events: none; + opacity: 0.65; +} + +.window.settings button, +.window.settings input, +.window.settings select { + margin: 0px; +} + .flex { display: flex; } @@ -72,6 +97,12 @@ border-radius: 5px; } +.lobby-player button { + font-size: 0.7em; + margin: 0px 5px; + padding: 3px 5px; +} + .d-none { display: none; } @@ -84,31 +115,6 @@ hr { width: 100%; } -.window button, -.window input, -.window select { - background-color: rgba(0, 0, 0, 0.7); - color : white; - font-size : 20px; - font-size : 0.9em; - padding : 0.4rem; - transition : 0.2s; - border : 1px solid #fff; - border-radius : 5px; - margin : 5px; -} - -.window :disabled, .window .disabled { - pointer-events: none; - opacity: 0.65; -} - -.window.settings button, -.window.settings input, -.window.settings select { - margin: 0px; -} - h1 { font-weight : normal; margin-block-start: 0.5em;