Compare commits
4 Commits
cec45e3425
...
29e6c4f507
| Author | SHA1 | Date |
|---|---|---|
|
|
29e6c4f507 | |
|
|
1607255948 | |
|
|
dff5a9ad57 | |
|
|
bd67b39745 |
3
build.js
3
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 })
|
||||
|
|
|
|||
|
|
@ -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");
|
||||
export const insert = (code) => (
|
||||
"\n" + code.split(/\r?\n/g).map(l => "/*insert line:*/" + l).join("\n") + "\n"
|
||||
);
|
||||
|
|
@ -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,`)
|
||||
*/
|
||||
});
|
||||
}
|
||||
|
|
@ -1,12 +1,26 @@
|
|||
import { definePatch } from "../modUtils.js"
|
||||
import { definePatch, insert } from "../modUtils.js"
|
||||
import { styleText } from "node:util";
|
||||
|
||||
export default definePatch(({ insertCode }) => {
|
||||
export default definePatch(({ insertCode, modifyCode }) => {
|
||||
|
||||
// Hide propaganda popup
|
||||
insertCode(`/* here */
|
||||
a = b.c + 60 * 1000;
|
||||
(new ea()).show(eS.eb, eS.colors, eS.id);
|
||||
eS = null;
|
||||
return true;`, `if (__fx.settings.hidePropagandaPopup) return;`)
|
||||
return true;`, `if (__fx.settings.hidePropagandaPopup || __fx.customLobby.isActive()) 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`))
|
||||
}
|
||||
})
|
||||
|
|
@ -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");
|
||||
|
|
|
|||
13
src/main.js
13
src/main.js
|
|
@ -14,15 +14,16 @@ import customLobby from './customLobby.js';
|
|||
import { displayChangelog } from './changelog.js';
|
||||
import { reportError } from './debugging.js';
|
||||
|
||||
const savedVersion = localStorage.getItem("fx_version");
|
||||
if (savedVersion !== version) {
|
||||
localStorage.setItem("fx_version", version);
|
||||
if (savedVersion !== null) displayChangelog();
|
||||
}
|
||||
|
||||
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");
|
||||
if (savedVersion !== version && !__fx.isCustomLobbyVersion) {
|
||||
localStorage.setItem("fx_version", version);
|
||||
if (savedVersion !== null) displayChangelog();
|
||||
}
|
||||
|
||||
__fx.settingsManager = settingsManager;
|
||||
__fx.leaderboardFilter = leaderboardFilter;
|
||||
|
|
|
|||
|
|
@ -112,7 +112,20 @@
|
|||
<div class="window flex-column" id="customLobbyJoinMenu" style="display: none">
|
||||
<input type="text" id="lobbyCode" placeholder="Enter lobby code">
|
||||
or
|
||||
<button id="createLobbyButton">Create new lobby</button>
|
||||
<div>
|
||||
<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 class="window scrollable selectable" id="playerlist" style="display: none;">
|
||||
<h1>Player List</h1>
|
||||
|
|
|
|||
10
version.json
10
version.json
|
|
@ -1,7 +1,11 @@
|
|||
{
|
||||
"version": "0.6.17",
|
||||
"lastUpdated": "Dec 4",
|
||||
"version": "0.6.18",
|
||||
"lastUpdated": "Dec 30",
|
||||
"changes": [
|
||||
"Fixes for game update v2.14.4"
|
||||
"Updated custom lobbies to the latest version",
|
||||
"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"
|
||||
]
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue