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
dev
peshomir 2024-05-22 21:48:44 +03:00
parent ad6f0e2f05
commit 3537ffc9ad
2 changed files with 17 additions and 20 deletions

View File

@ -84,7 +84,8 @@ const generateRegularExpression = (/** @type {string} */ code, /** @type {boolea
const rawCodeSegments = [ const rawCodeSegments = [
"[0]=aV.nU[70],a0T[1]=@gIsSingleplayer?aV.nU[71]:aV.nU[72],", "[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 => { 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) // variable in the modified leaderboard click handler from the leaderboard filter)
// match , 0 !== dG[x]) && fq.hB(x, 800, false, 0), // match , 0 !== dG[x]) && fq.hB(x, 800, false, 0),
replaceOne(/,(0!==\w+\[(\w+)\])(\)&&\w+\.\w+\(\2,800,!1,0\),)/g, 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 // 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(), "); 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 // Handle player list button and leaderboard tabs mouseDown
// and create a function for scrolling the leaderboard to the top // and create a function for scrolling the leaderboard to the top
replaceOne(/(this\.\w+=function\((?<x>\w+),(?<y>\w+)\){return!!\w+\(\2,\3\))&&(\(\w+=\w+\.\w+,[^}]+),!0\)/g, replaceOne(/(this\.\w+=function\((?<x>\w+),(?<y>\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)
&& !($<y> - ${uiOffset} > leaderboardFilter.verticalClickThreshold && leaderboardFilter.handleMouseDown($<x> - ${uiOffset})) && $4),!0)`); && !($<y> - ${uiOffset} > leaderboardFilter.verticalClickThreshold && leaderboardFilter.handleMouseDown($<x> - ${uiOffset})) && $4),!0)`);
// Handle player list button and leaderboard tabs hover // Handle player list button and leaderboard tabs hover
// and create a function for repainting the leaderboard // and create a function for repainting the leaderboard
@ -329,6 +330,9 @@ replaceOne(new RegExp(`,${dictionary.playerBalances}=new Uint32Array\\(\\w+\\),`
var isEmptySpace = false; 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]) >= 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 && `); 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 { // Hovering tooltip

View File

@ -1,5 +1,5 @@
const fx_version = '0.6.4.1'; // FX Client Version const fx_version = '0.6.4.2'; // FX Client Version
const fx_update = 'May 20'; // FX Client Last Updated const fx_update = 'May 22'; // FX Client Last Updated
if (localStorage.getItem("fx_winCount") == undefined || localStorage.getItem("fx_winCount") == null) { if (localStorage.getItem("fx_winCount") == undefined || localStorage.getItem("fx_winCount") == null) {
var wins_counter = 0; 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() { 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 = [0,1,8,20,24,30,32,42,50,69,200,400,500,510,511]; // for testing
//this.playersToInclude = []; //this.playersToInclude = [];
@ -362,6 +354,7 @@ const leaderboardFilter = new (function() {
this.hoveringOverTabs = false; this.hoveringOverTabs = false;
this.scrollToTop = () => {}; this.scrollToTop = () => {};
this.repaintLeaderboard = () => {}; this.repaintLeaderboard = () => {};
this.parseClanFromPlayerName = () => { console.warn("parse function not set"); };
this.selectedTab = 0; this.selectedTab = 0;
this.tabHovering = -1; this.tabHovering = -1;
@ -417,9 +410,9 @@ const leaderboardFilter = new (function() {
}; };
this.filterByOwnClan = () => { this.filterByOwnClan = () => {
this.playersToInclude = []; this.playersToInclude = [];
const ownClan = parseClanFromPlayerName(getVar("playerNames")[getVar("playerId")]); const ownClan = this.parseClanFromPlayerName(getVar("rawPlayerNames")[getVar("playerId")]);
getVar("playerNames").forEach((name, id) => { getVar("rawPlayerNames").forEach((name, id) => {
if (parseClanFromPlayerName(name) === ownClan) this.playersToInclude.push(id); if (this.parseClanFromPlayerName(name) === ownClan) this.playersToInclude.push(id);
}); });
this.enabled = true; this.enabled = true;
this.scrollToTop(); this.scrollToTop();
@ -462,18 +455,18 @@ var donationsTracker = new (function(){
} }
}; };
function generateTableRowItem(historyItem, index, playerID, isNew) { function generateTableRowItem(historyItem, index, playerID, isNew) {
const playerNames = getVar("playerNames"); const rawPlayerNames = getVar("rawPlayerNames");
const row = document.createElement("tr"); const row = document.createElement("tr");
if (isNew) row.setAttribute("class", "new"); if (isNew) row.setAttribute("class", "new");
let content = `<td><span class="color-light-gray">${index}.</span> `; let content = `<td><span class="color-light-gray">${index}.</span> `;
if (playerID === historyItem[1]) if (playerID === historyItem[1])
content += `Received <span class="color-green">${historyItem[2]}</span> resources from ${escapeHtml(playerNames[historyItem[0]])}`; content += `Received <span class="color-green">${historyItem[2]}</span> resources from ${escapeHtml(rawPlayerNames[historyItem[0]])}`;
else content += `Sent <span class="color-red">${historyItem[2]}</span> resources to ${escapeHtml(playerNames[historyItem[1]])}`; else content += `Sent <span class="color-red">${historyItem[2]}</span> resources to ${escapeHtml(rawPlayerNames[historyItem[1]])}`;
content += "</td>"; content += "</td>";
row.innerHTML = content; row.innerHTML = content;
return row; 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); var history = donationsTracker.getHistoryOf(playerID);
console.log("History for " + playerNames[playerID] + ":"); console.log("History for " + playerNames[playerID] + ":");
console.log(history); console.log(history);