From 3537ffc9ad4574e3e1def23cdee3401bf545bfcf Mon Sep 17 00:00:00 2001 From: peshomir <80340328+peshomir@users.noreply.github.com> Date: Wed, 22 May 2024 21:48:44 +0300 Subject: [PATCH] Update v0.6.4.2 - fix clan leaderboard parsing bug - Changed most uses of playerNames to rawPlayerNames - The leaderboard filter now uses the clan parsing implementation from the vanilla game --- build.js | 10 +++++++--- src/fx_core.js | 27 ++++++++++----------------- 2 files changed, 17 insertions(+), 20 deletions(-) diff --git a/build.js b/build.js index 2a16e1f..746aa8d 100644 --- a/build.js +++ b/build.js @@ -84,7 +84,8 @@ const generateRegularExpression = (/** @type {string} */ code, /** @type {boolea const rawCodeSegments = [ "[0]=aV.nU[70],a0T[1]=@gIsSingleplayer?aV.nU[71]:aV.nU[72],", - "?(this.gB=Math.floor(.0536*aK.fw),g5=aK.g5-4*@uiSizes.@gap-this.gB):" + "?(this.gB=Math.floor(.0536*aK.fw),g5=aK.g5-4*@uiSizes.@gap-this.gB):", + `for(a0L=new Array(@gMaxPlayers),a0A.font=a07,@i=gMaxPlayers-1;0<=i;i--)a0L[i]=i+1+".",@playerNames[i]=aY.qW.tm(@rawPlayerNames[i],a07,a0W),a0K[i]=Math.floor(a0A.measureText(playerNames[i]).width);` ] rawCodeSegments.forEach(code => { @@ -224,7 +225,7 @@ replaceOne(/(this\.\w+=function\((\w+),(\w+)\)\{)(\2===\w+&&\(\w+\.\w+\((\w+\.\w // variable in the modified leaderboard click handler from the leaderboard filter) // match , 0 !== dG[x]) && fq.hB(x, 800, false, 0), replaceOne(/,(0!==\w+\[(\w+)\])(\)&&\w+\.\w+\(\2,800,!1,0\),)/g, - `, ${dictionary.gIsTeamGame} && donationsTracker.displayHistory($2, ${dictionary.playerNames}, ${dictionary.gIsSingleplayer}), $1 && !isEmptySpace $3`); + `, ${dictionary.gIsTeamGame} && donationsTracker.displayHistory($2, ${dictionary.rawPlayerNames}, ${dictionary.gIsSingleplayer}), $1 && !isEmptySpace $3`); // Reset donation history and leaderboard filter when a new game is started replaceOne(new RegExp(`,${dictionary.playerBalances}=new Uint32Array\\(\\w+\\),`, "g"), "$& donationsTracker.reset(), leaderboardFilter.reset(), "); @@ -238,7 +239,7 @@ replaceOne(new RegExp(`,${dictionary.playerBalances}=new Uint32Array\\(\\w+\\),` // Handle player list button and leaderboard tabs mouseDown // and create a function for scrolling the leaderboard to the top replaceOne(/(this\.\w+=function\((?\w+),(?\w+)\){return!!\w+\(\2,\3\))&&(\(\w+=\w+\.\w+,[^}]+),!0\)/g, - `leaderboardFilter.scrollToTop = function(){position = 0;}, $1 && ((${buttonBoundsCheck} && playerList.display(${dictionary.playerNames}), true) + `leaderboardFilter.scrollToTop = function(){position = 0;}, $1 && ((${buttonBoundsCheck} && playerList.display(${dictionary.rawPlayerNames}), true) && !($ - ${uiOffset} > leaderboardFilter.verticalClickThreshold && leaderboardFilter.handleMouseDown($ - ${uiOffset})) && $4),!0)`); // Handle player list button and leaderboard tabs hover // and create a function for repainting the leaderboard @@ -329,6 +330,9 @@ replaceOne(new RegExp(`,${dictionary.playerBalances}=new Uint32Array\\(\\w+\\),` var isEmptySpace = false; return ag.tQ() && -1 !== a0P && (a0P = -1, a0Y(), b3.d1 = !0), b3.dY - a0Q < 350 && a0T === a0p && -1 !== (a0p = (a0p = yr(-1, a0p, windowHeight)) !== windowHeight && vU(x, y) ? a0p : -1) && (x = (leaderboardFilter.enabled ? leaderboardArray[leaderboardFilter.filteredLeaderboard[a0p + position] ?? (isEmptySpace = true, leaderboardPositionsById[playerId])] : leaderboardArray[a0p + position]), a0p === windowHeight - 1 && (leaderboardFilter.enabled ? this.playerPos : leaderboardPositionsById[playerId]) >= position + windowHeight - 1 && (x = playerId), !isEmptySpace && `); + // Get clan parsing function + replaceRawCode(`this.uI=function(username){var uK,uJ=username.indexOf("[");return!(uJ<0)&&1<(uK=username.indexOf("]"))-uJ&&uK-uJ<=8?username.substring(uJ+1,uK).toUpperCase().trim():null}`, + `this.uI=function(username){var uK,uJ=username.indexOf("[");return!(uJ<0)&&1<(uK=username.indexOf("]"))-uJ&&uK-uJ<=8?username.substring(uJ+1,uK).toUpperCase().trim():null}, leaderboardFilter.parseClanFromPlayerName = this.uI;`); } { // Hovering tooltip diff --git a/src/fx_core.js b/src/fx_core.js index 2caa7d1..0a94623 100644 --- a/src/fx_core.js +++ b/src/fx_core.js @@ -1,5 +1,5 @@ -const fx_version = '0.6.4.1'; // FX Client Version -const fx_update = 'May 20'; // FX Client Last Updated +const fx_version = '0.6.4.2'; // FX Client Version +const fx_update = 'May 22'; // FX Client Last Updated if (localStorage.getItem("fx_winCount") == undefined || localStorage.getItem("fx_winCount") == null) { var wins_counter = 0; @@ -342,14 +342,6 @@ const playerList = new (function () { } }); -/** @param {string} name */ -function parseClanFromPlayerName(name) { - const startIndex = name.indexOf("["); - // this is probably how the algorithm works, since a player with - // the name "][a]" will count as not being in a clan in the base game - return startIndex === -1 ? "" : name.slice(startIndex + 1, name.indexOf("]")).toUpperCase(); -} - const leaderboardFilter = new (function() { this.playersToInclude = [0,1,8,20,24,30,32,42,50,69,200,400,500,510,511]; // for testing //this.playersToInclude = []; @@ -362,6 +354,7 @@ const leaderboardFilter = new (function() { this.hoveringOverTabs = false; this.scrollToTop = () => {}; this.repaintLeaderboard = () => {}; + this.parseClanFromPlayerName = () => { console.warn("parse function not set"); }; this.selectedTab = 0; this.tabHovering = -1; @@ -417,9 +410,9 @@ const leaderboardFilter = new (function() { }; this.filterByOwnClan = () => { this.playersToInclude = []; - const ownClan = parseClanFromPlayerName(getVar("playerNames")[getVar("playerId")]); - getVar("playerNames").forEach((name, id) => { - if (parseClanFromPlayerName(name) === ownClan) this.playersToInclude.push(id); + const ownClan = this.parseClanFromPlayerName(getVar("rawPlayerNames")[getVar("playerId")]); + getVar("rawPlayerNames").forEach((name, id) => { + if (this.parseClanFromPlayerName(name) === ownClan) this.playersToInclude.push(id); }); this.enabled = true; this.scrollToTop(); @@ -462,18 +455,18 @@ var donationsTracker = new (function(){ } }; function generateTableRowItem(historyItem, index, playerID, isNew) { - const playerNames = getVar("playerNames"); + const rawPlayerNames = getVar("rawPlayerNames"); const row = document.createElement("tr"); if (isNew) row.setAttribute("class", "new"); let content = `${index}. `; if (playerID === historyItem[1]) - content += `Received ${historyItem[2]} resources from ${escapeHtml(playerNames[historyItem[0]])}`; - else content += `Sent ${historyItem[2]} resources to ${escapeHtml(playerNames[historyItem[1]])}`; + content += `Received ${historyItem[2]} resources from ${escapeHtml(rawPlayerNames[historyItem[0]])}`; + else content += `Sent ${historyItem[2]} resources to ${escapeHtml(rawPlayerNames[historyItem[1]])}`; content += ""; row.innerHTML = content; return row; } - this.displayHistory = function displayDonationsHistory(playerID, playerNames = getVar("playerNames"), isSingleplayer = getVar("gIsSingleplayer")) { + this.displayHistory = function displayDonationsHistory(playerID, playerNames = getVar("rawPlayerNames"), isSingleplayer = getVar("gIsSingleplayer")) { var history = donationsTracker.getHistoryOf(playerID); console.log("History for " + playerNames[playerID] + ":"); console.log(history);