Update v0.6.1.9

Improvements to player list UI,
the donation history viewer can now be opened from the player list,
fixed possible XSS vulnerabilities
archived
peshomir 2024-03-07 15:55:59 +02:00
parent ca3971530e
commit 5c934ce8fb
5 changed files with 37 additions and 13 deletions

View File

@ -41,6 +41,7 @@ let dictionary = {};
if (expression.exec(script) !== null) throw new Error("more than one match for: ") + expression; if (expression.exec(script) !== null) throw new Error("more than one match for: ") + expression;
for (let [key, value] of Object.entries(result.groups)) dictionary[key] = value; for (let [key, value] of Object.entries(result.groups)) dictionary[key] = value;
}); });
fs.writeFileSync("./build/fx_core.js", `const dictionary = ${JSON.stringify(dictionary)};\n` + fs.readFileSync("./build/fx_core.js").toString());
// Replace assets // Replace assets
const assets = require('./assets.js'); const assets = require('./assets.js');

View File

@ -25,8 +25,8 @@ FX Client is the first Territorial.io client, targeting better User Interface an
4. Adds a text to display "Troop Density" 4. Adds a text to display "Troop Density"
5. Adds a text to display "Maximum Troops" 5. Adds a text to display "Maximum Troops"
6. Adds a win counter 6. Adds a win counter
7. Adds the ability to view the history of who donated to a player during the game by clicking on their name in the leaderboard 7. Adds a player list
8. Adds a player list 8. Adds the ability to view the history of who donated to a player during the game by clicking on their name in the leaderboard or the player list
9. Can be installed as a PWA (progressive web app) ensuring maximum enjoyment on consoles, phones and even desktop devices 9. Can be installed as a PWA (progressive web app) ensuring maximum enjoyment on consoles, phones and even desktop devices
#### The client has a settings menu, from which you can: #### The client has a settings menu, from which you can:

View File

@ -1,5 +1,5 @@
const fx_version = '0.6.1.8'; // FX Client Version const fx_version = '0.6.1.9'; // FX Client Version
const fx_update = 'Mar 5'; // FX Client Last Updated const fx_update = 'Mar 7'; // 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;
@ -8,6 +8,13 @@ if (localStorage.getItem("fx_winCount") == undefined || localStorage.getItem("fx
var wins_counter = localStorage.getItem("fx_winCount"); var wins_counter = localStorage.getItem("fx_winCount");
} }
const getVar = varName => window[dictionary[varName]];
// https://stackoverflow.com/a/6234804
function escapeHtml(unsafe) {
return unsafe.replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;").replace(/"/g, "&quot;").replace(/'/g, "&#039;");
}
function KeybindsInput(containerElement) { function KeybindsInput(containerElement) {
this.container = containerElement; this.container = containerElement;
this.keys = [ "key", "type", "value" ]; this.keys = [ "key", "type", "value" ];
@ -216,7 +223,7 @@ WindowManager.add({
beforeOpen: function() {} beforeOpen: function() {}
}); });
document.getElementById("canvasA").addEventListener("mousedown", WindowManager.closeAll); document.getElementById("canvasA").addEventListener("mousedown", WindowManager.closeAll);
document.getElementById("canvasA").addEventListener("touchstart", WindowManager.closeAll); document.getElementById("canvasA").addEventListener("touchstart", WindowManager.closeAll, { passive: true });
document.addEventListener("keydown", event => { if (event.key === "Escape") WindowManager.closeAll(); }); document.addEventListener("keydown", event => { if (event.key === "Escape") WindowManager.closeAll(); });
var settingsGearIcon = document.createElement('img'); var settingsGearIcon = document.createElement('img');
settingsGearIcon.setAttribute('src', 'assets/geari_white.png'); settingsGearIcon.setAttribute('src', 'assets/geari_white.png');
@ -224,12 +231,18 @@ settingsGearIcon.setAttribute('src', 'assets/geari_white.png');
const playerList = new (function () { const playerList = new (function () {
const playersIcon = document.createElement('img'); const playersIcon = document.createElement('img');
playersIcon.setAttribute('src', 'assets/players_icon.png'); playersIcon.setAttribute('src', 'assets/players_icon.png');
document.getElementById("playerlist_content").addEventListener("click", event => {
const playerId = event.target.closest("tr[data-player-id]")?.getAttribute("data-player-id");
if (!playerId) return;
if (getVar("gIsTeamGame")) WindowManager.closeWindow("playerList"), displayDonationsHistory(playerId);
});
this.display = function displayPlayerList(playerNames) { this.display = function displayPlayerList(playerNames) {
let listContent = ""; let listContent = "";
for (let i = 0; i < playerNames.length; i++) { for (let i = 0; i < playerNames.length; i++) {
listContent += `<span class="color-light-gray">${i}.</span> ${playerNames[i]}<br>` listContent += `<tr data-player-id="${i}"><td><span class="color-light-gray">${i}.</span> ${escapeHtml(playerNames[i])}</td></tr>`
} }
document.getElementById("playerlist_text").innerHTML = listContent; document.getElementById("playerlist_content").innerHTML = listContent;
document.getElementById("playerlist_content").setAttribute("class", getVar("gIsTeamGame") ? "clickable" : "");
WindowManager.openWindow("playerList"); WindowManager.openWindow("playerList");
} }
this.hoveringOverButton = false; this.hoveringOverButton = false;
@ -260,19 +273,18 @@ var donationsTracker = new (function(){
}; };
this.reset = function() { for (var i = 0; i < 512; i++) this.donationHistory[i] = []; }; this.reset = function() { for (var i = 0; i < 512; i++) this.donationHistory[i] = []; };
}); });
// usage from inside: displayDonationsHistory(Y, gE); function displayDonationsHistory(playerID, playerNames = getVar("playerNames"), isSingleplayer = getVar("gIsSingleplayer")) {
function displayDonationsHistory(playerID, playerNames, isSingleplayer) {
var history = donationsTracker.getRecipientHistoryOf(playerID); var history = donationsTracker.getRecipientHistoryOf(playerID);
console.log("History for " + playerNames[playerID] + ":"); console.log("History for " + playerNames[playerID] + ":");
console.log(history); console.log(history);
document.querySelector("#donationhistory h1").innerHTML = "Donation history for " + playerNames[playerID]; document.querySelector("#donationhistory h1").innerHTML = "Donation history for " + escapeHtml(playerNames[playerID]);
var historyText = ""; var historyText = "";
history.reverse(); history.reverse();
if (history.length > 0) history.forEach(function(historyItem, index) { if (history.length > 0) history.forEach(function(historyItem, index) {
historyText += `<span class="color-light-gray">${(history.length - index)}.</span> `; historyText += `<span class="color-light-gray">${(history.length - index)}.</span> `;
if (playerID === historyItem[1]) if (playerID === historyItem[1])
historyText += `Received <span class="color-green">${historyItem[2]}</span> resources from ${playerNames[historyItem[0]]}<br>`; historyText += `Received <span class="color-green">${historyItem[2]}</span> resources from ${escapeHtml(playerNames[historyItem[0]])}<br>`;
else historyText += `Sent <span class="color-red">${historyItem[2]}</span> resources to ${playerNames[historyItem[1]]}<br>`; else historyText += `Sent <span class="color-red">${historyItem[2]}</span> resources to ${escapeHtml(playerNames[historyItem[1]])}<br>`;
}); });
else historyText = "Nothing to display"; else historyText = "Nothing to display";
document.querySelector("#donationhistory p#donationhistory_text").innerHTML = historyText; document.querySelector("#donationhistory p#donationhistory_text").innerHTML = historyText;

View File

@ -108,7 +108,7 @@
</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>
<p id="playerlist_text"></p> <table><tbody id="playerlist_content"></tbody></table>
</div> </div>
<div class="window scrollable selectable" id="donationhistory" style="display:none"> <div class="window scrollable selectable" id="donationhistory" style="display:none">
<h1>Donation history for </h1> <h1>Donation history for </h1>

View File

@ -79,6 +79,17 @@ button:hover {
border-radius : 8px; border-radius : 8px;
} }
td {
padding: 0px;
}
#playerlist_content.clickable td { cursor: pointer; }
#playerlist_content.clickable td:hover { background-color: #00ff0040; }
table {
border-spacing: 0px;
}
input#userna, input#userna,
input#inputfilebtn { input#inputfilebtn {
transition: 0.2s transition: 0.2s