Compare commits

..

No commits in common. "29e6c4f5074361d81e7155d8dd479069fb11088b" and "cec45e3425dfd68eb2eb50fa980c6f5e351d6794" have entirely different histories.

8 changed files with 44 additions and 98 deletions

View File

@ -74,9 +74,6 @@ async function patchGameCode() {
code: `this.a = Math.floor(0.066 * b.c); code: `this.a = Math.floor(0.066 * b.c);
d = b.d - 4 * uiSizes.gap - this.a;`, d = b.d - 4 * uiSizes.gap - this.a;`,
addToDictionary: ["uiSizes", "gap"] addToDictionary: ["uiSizes", "gap"]
}, {
code: `var dt=MenuManager.getState();if(dt===6){if(d===4211){/*...*/}}`,
addToDictionary: ["MenuManager", "getState"]
}]; }];
codeSegments.forEach(({ code, addToDictionary }) => { codeSegments.forEach(({ code, addToDictionary }) => {
modUtils.matchCode(code, { addToDictionary }) modUtils.matchCode(code, { addToDictionary })

View File

@ -214,6 +214,4 @@ export function definePatch(callback) {
* Helper for `modifyCode` * Helper for `modifyCode`
* @param {string} code * @param {string} code
*/ */
export const insert = (code) => ( export const insert = (code) => code.split(/\r?\n/g).map(l => "/*insert line:*/" + l).join("\n");
"\n" + code.split(/\r?\n/g).map(l => "/*insert line:*/" + l).join("\n") + "\n"
);

View File

@ -1,7 +1,10 @@
import ModUtils, { insert } from '../modUtils.js'; import ModUtils from '../modUtils.js';
// Custom lobby patches // Custom lobby patches
export default (/** @type {ModUtils} */ { modifyCode, insertCode, replaceCode, replaceRawCode, safeDictionary: dict, waitForMinification }) => { export default (/** @type {ModUtils} */ { insertCode, replaceCode, replaceRawCode, safeDictionary: dict, waitForMinification }) => {
// temporarily disabled for new versions
return;
// set player id correctly // set player id correctly
insertCode(`function aBG(aBE) { insertCode(`function aBG(aBE) {
@ -25,24 +28,9 @@ export default (/** @type {ModUtils} */ { modifyCode, insertCode, replaceCode, r
return __fx.customLobby.setActive(false); 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(() => { 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):", 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)||") "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 // set the custom lobby to inactive when clicking the "Back" button on the connection screen or leaving the lobby
@ -51,6 +39,19 @@ export default (/** @type {ModUtils} */ { modifyCode, insertCode, replaceCode, r
replaceRawCode("function(){n.r(),bl.zf(),Sockets.s.ze(3240),n.o(5,5)}", 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)}), `(__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)})`) 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 // do not display lobby UI
replaceRawCode(`(sV.style.backdropFilter="blur(4px)",sV.style.webkitBackdropFilter="blur(4px)"),`, replaceRawCode(`(sV.style.backdropFilter="blur(4px)",sV.style.webkitBackdropFilter="blur(4px)"),`,
`(sV.style.backdropFilter="blur(4px)",sV.style.webkitBackdropFilter="blur(4px)"), `(sV.style.backdropFilter="blur(4px)",sV.style.webkitBackdropFilter="blur(4px)"),
@ -79,5 +80,6 @@ export default (/** @type {ModUtils} */ { modifyCode, insertCode, replaceCode, r
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,", 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.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,`) this.maxPlayers=this.gLobbyMaxJoin,this.gBots=this.gLobbyMaxJoin-this.gHumans,this.sg=0,`)
*/
}); });
} }

View File

@ -1,26 +1,12 @@
import { definePatch, insert } from "../modUtils.js" import { definePatch } from "../modUtils.js"
import { styleText } from "node:util";
export default definePatch(({ insertCode, modifyCode }) => { export default definePatch(({ insertCode }) => {
// Hide propaganda popup // Hide propaganda popup
insertCode(`/* here */ insertCode(`/* here */
a = b.c + 60 * 1000; a = b.c + 60 * 1000;
(new ea()).show(eS.eb, eS.colors, eS.id); (new ea()).show(eS.eb, eS.colors, eS.id);
eS = null; eS = null;
return true;`, `if (__fx.settings.hidePropagandaPopup || __fx.customLobby.isActive()) return;`) return true;`, `if (__fx.settings.hidePropagandaPopup) return;`)
modifyCode(`if (!a.b.c(0)) {
d = e.f + 1000 * 1;
return;
} ${insert(`if (!__fx.settings.hidePropagandaPopup && !__fx.customLobby.isActive())`)} a.g.h(5);`)
// for the custom lobby version
try {
modifyCode(`new a("⚔️<br>" + __L(), function() {
${insert(`if (__fx.isCustomLobbyVersion) alert("This version is for use with custom lobbies only. For normal multiplayer, use the version at https://fxclient.github.io/FXclient/")
else`)} b(0);
}, ${insert(`__fx.isCustomLobbyVersion ? "rgba(50, 50, 50, 0.6)" : `)} c.d)`)
} catch (error) {
console.warn(styleText("yellow", `Warning: failed to apply patches specific to the custom lobby version`))
}
}) })

View File

@ -1,13 +1,12 @@
import WindowManager from "./windowManager.js"; import WindowManager from "./windowManager.js";
const customLobbiesUnavailable = false; const customLobbiesUnavailable = true;
//const socketURL = "ws://localhost:8080/"; //const socketURL = "ws://localhost:8080/";
const socketURL = "wss://fx-lobbies.peshomir.workers.dev/"; const socketURL = "wss://fx.peshomir.workers.dev/";
const customMessageMarker = 120; const customMessageMarker = 120;
let isActive = false; let isActive = false;
let currentCode = ""; let currentCode = "";
let joinLobby = () => { }; let joinLobby = () => { };
/** when `leaveLobby` is called, the modified code will also execute setActive(false) */
let leaveLobby = () => { }; let leaveLobby = () => { };
let sendRaw = (socketId, data) => { }; let sendRaw = (socketId, data) => { };
const textEncoder = new TextEncoder(); const textEncoder = new TextEncoder();
@ -34,10 +33,6 @@ const windowElement = WindowManager.create({
const header = document.createElement("h2"); const header = document.createElement("h2");
header.textContent = "Custom Lobby"; 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"); const main = document.createElement("div");
main.className = "customlobby-main"; main.className = "customlobby-main";
@ -157,7 +152,7 @@ const copyLinkButton = createButton("Copy link", () => {
}); });
footer.append(startButton, leaveButton, copyLinkButton); footer.append(startButton, leaveButton, copyLinkButton);
windowElement.append(header, pingIndicator, main, footer); windowElement.append(header, main, footer);
/** @param {HTMLSelectElement} element */ /** @param {HTMLSelectElement} element */
function setSelectMenuOptions(options, element) { function setSelectMenuOptions(options, element) {
@ -179,13 +174,13 @@ document.getElementById("lobbyCode").addEventListener("input", ({ target: input
currentCode = input.value.toLowerCase(); currentCode = input.value.toLowerCase();
input.value = ""; input.value = "";
WindowManager.closeWindow("lobbyJoinMenu"); WindowManager.closeWindow("lobbyJoinMenu");
setActive(true) isActive = true;
joinLobby(); joinLobby();
}); });
document.getElementById("createLobbyButton").addEventListener("click", () => { document.getElementById("createLobbyButton").addEventListener("click", () => {
currentCode = ""; currentCode = "";
WindowManager.closeWindow("lobbyJoinMenu"); WindowManager.closeWindow("lobbyJoinMenu");
setActive(true) isActive = true;
joinLobby(); joinLobby();
}); });
@ -209,12 +204,7 @@ function isCustomMessage(raw) {
const subArray = new Uint8Array(raw.buffer, 1); const subArray = new Uint8Array(raw.buffer, 1);
const message = JSON.parse(textDecoder.decode(subArray)); const message = JSON.parse(textDecoder.decode(subArray));
const { t: type, d: data } = message; const { t: type, d: data } = message;
if (type === "pong") { if (type === "lobby") {
const latency = performance.now() - data
pingIndicator.innerText = `Ping: ${latency} ms`
} else if (type === "lobby") {
pingIndicator.innerText = ""
sendPing()
WindowManager.openWindow("customLobby"); WindowManager.openWindow("customLobby");
header.textContent = "Custom Lobby " + data.code; header.textContent = "Custom Lobby " + data.code;
currentCode = data.code; currentCode = data.code;
@ -303,9 +293,7 @@ function updatePlayerCount() {
} }
function getSocketURL() { function getSocketURL() {
if (currentCode !== "") return socketURL + "join?" + currentCode return socketURL + (currentCode === "" ? "create" : "join?" + currentCode)
const region = document.getElementById("customLobbyRegion").value
return socketURL + "create" + (region === "default" ? "" : `?location=${region}`)
} }
function getPlayerId() { function getPlayerId() {
let id = 0; let id = 0;
@ -329,7 +317,7 @@ function checkForLobbyLink(isHashChangeEvent) {
// in case the player is already in a lobby // in case the player is already in a lobby
if (isHashChangeEvent) leaveLobby(); if (isHashChangeEvent) leaveLobby();
currentCode = hash.slice(7); currentCode = hash.slice(7);
setActive(true) isActive = true;
joinLobby(); joinLobby();
} }
} }
@ -341,16 +329,9 @@ function setJoinFunction(f) {
} }
function setLeaveFunction(f) { leaveLobby = f; } function setLeaveFunction(f) { leaveLobby = f; }
function setSendFunction(f) { sendRaw = f; } function setSendFunction(f) { sendRaw = f; }
function sendPing() {
sendMessage("ping", performance.now())
}
let pingInterval;
function setActive(active) { function setActive(active) {
isActive = active; isActive = active;
if (active === false) { if (active === false) WindowManager.closeWindow("customLobby");
WindowManager.closeWindow("customLobby");
if (pingInterval !== undefined) clearInterval(pingInterval)
} else pingInterval = setInterval(sendPing, 10_000)
} }
function hideWindow() { function hideWindow() {
WindowManager.closeWindow("customLobby"); WindowManager.closeWindow("customLobby");

View File

@ -14,17 +14,16 @@ import customLobby from './customLobby.js';
import { displayChangelog } from './changelog.js'; import { displayChangelog } from './changelog.js';
import { reportError } from './debugging.js'; import { reportError } from './debugging.js';
window.__fx = window.__fx || {};
const __fx = window.__fx;
__fx.version = version + " " + lastUpdated;
__fx.isCustomLobbyVersion = window.location.href.startsWith("https://fxclient.github.io/custom-lobbies")
const savedVersion = localStorage.getItem("fx_version"); const savedVersion = localStorage.getItem("fx_version");
if (savedVersion !== version && !__fx.isCustomLobbyVersion) { if (savedVersion !== version) {
localStorage.setItem("fx_version", version); localStorage.setItem("fx_version", version);
if (savedVersion !== null) displayChangelog(); if (savedVersion !== null) displayChangelog();
} }
window.__fx = window.__fx || {};
const __fx = window.__fx;
__fx.version = version + " " + lastUpdated;
__fx.settingsManager = settingsManager; __fx.settingsManager = settingsManager;
__fx.leaderboardFilter = leaderboardFilter; __fx.leaderboardFilter = leaderboardFilter;
__fx.utils = gameScriptUtils; __fx.utils = gameScriptUtils;

View File

@ -112,20 +112,7 @@
<div class="window flex-column" id="customLobbyJoinMenu" style="display: none"> <div class="window flex-column" id="customLobbyJoinMenu" style="display: none">
<input type="text" id="lobbyCode" placeholder="Enter lobby code"> <input type="text" id="lobbyCode" placeholder="Enter lobby code">
or or
<div>
<button id="createLobbyButton">Create new lobby</button> <button id="createLobbyButton">Create new lobby</button>
<label for="region">in region:</label>
<select id="customLobbyRegion" name="region"
title="Note: Region selection is a best effort, not a guarantee. The regions listed are only a subset of all the possible locations where a lobby can be created.">
<option value="default" selected>Automatic (closest to you)</option>
<option value="wnam">Western North America</option>
<option value="enam">Eastern North America</option>
<option value="weur">Western Europe</option>
<option value="eeur">Eastern Europe</option>
<option value="apac">Asia-Pacific</option>
<option value="oc">Oceania</option>
</select>
</div>
</div> </div>
<div class="window scrollable selectable" id="playerlist" style="display: none;"> <div class="window scrollable selectable" id="playerlist" style="display: none;">
<h1>Player List</h1> <h1>Player List</h1>

View File

@ -1,11 +1,7 @@
{ {
"version": "0.6.18", "version": "0.6.17",
"lastUpdated": "Dec 30", "lastUpdated": "Dec 4",
"changes": [ "changes": [
"Updated custom lobbies to the latest version", "Fixes for game update v2.14.4"
"When creating a custom lobby, you can now select a region where it will be created",
"The latency to the custom lobby server is displayed below the header in the custom lobby UI",
"Improved the propaganda blocking feature",
"Added automatic patches for the special custom lobby version (https://fxclient.github.io/custom-lobbies) which continues to serve its purpose of guaranteeing access to custom lobbies while allowing the regular version to quickly be updated to the latest Territorial.io version, neglecting the custom lobby patches if needed"
] ]
} }