9 Commits

Author SHA1 Message Date
53c2c2e7e3 Fix bug on attack calculator
Some checks failed
Continuous Deployment / lint (push) Successful in 32s
Continuous Deployment / deploy-chrome (push) Failing after 19s
Continuous Deployment / deploy-firefox (push) Successful in 4m2s
2025-12-03 23:05:38 +01:00
0d369c4c1e Add calculator form to new tab
Some checks failed
Continuous Deployment / lint (push) Successful in 29s
Continuous Deployment / deploy-chrome (push) Failing after 17s
Continuous Deployment / deploy-firefox (push) Successful in 3m22s
2025-11-29 12:31:00 +01:00
ede3ce1f0b Fix several bugs and refacto
Some checks failed
Continuous Deployment / lint (push) Successful in 30s
Continuous Deployment / deploy-chrome (push) Failing after 20s
Continuous Deployment / deploy-firefox (push) Successful in 3m9s
2025-11-28 19:11:21 +01:00
5b075f057e Fix market target bug 2025-11-28 10:30:53 +01:00
8d8ccd8e9d Add player id in ranking and ally members
Some checks failed
Continuous Deployment / lint (push) Successful in 30s
Continuous Deployment / deploy-chrome (push) Failing after 21s
Continuous Deployment / deploy-firefox (push) Successful in 4m38s
2025-11-24 19:04:59 +01:00
9a3c9c1401 Send resources by thousands
Some checks failed
Continuous Deployment / lint (push) Successful in 27s
Continuous Deployment / deploy-chrome (push) Failing after 17s
Continuous Deployment / deploy-firefox (push) Successful in 1m42s
2025-11-20 02:07:53 +01:00
067b1ef385 Code simplification
All checks were successful
Continuous Deployment / lint (push) Successful in 26s
Continuous Deployment / deploy-chrome (push) Successful in 33s
Continuous Deployment / deploy-firefox (push) Successful in 2m51s
2025-11-18 20:36:46 +01:00
fe33b9a334 Add button to select all units
All checks were successful
Continuous Deployment / lint (push) Successful in 27s
Continuous Deployment / deploy-chrome (push) Successful in 33s
Continuous Deployment / deploy-firefox (push) Successful in 3m42s
2025-11-18 10:50:35 +01:00
255ca528a5 Add tenth of seconds in attack sending page
All checks were successful
Continuous Deployment / lint (push) Successful in 26s
Continuous Deployment / deploy-chrome (push) Successful in 30s
Continuous Deployment / deploy-firefox (push) Successful in 5m27s
2025-11-17 19:22:39 +01:00
5 changed files with 571 additions and 176 deletions

View File

@@ -1,5 +1,43 @@
# Changelog # Changelog
## 1.11.4 (2026-12-03)
- correction du bug sur le calculateur
## 1.11.3 (2026-11-21)
- ajout du calculateur de trajet vers un nouvel onglet
## 1.11.2 (2026-11-28)
- correction du bug sur les multiples attaques avec comte
- correction du bug sur le bouton pour sélectionner toutes les troupes
- correction du bug sur l'envoi de ressources vers un village cible
- ajout des ids dans la liste des joueurs d'une alliance
- ajout de l'id sur le profil d'un joueur
## 1.11.1 (2026-11-24)
- ajout de l'id des joueurs dans le classement général et la liste des membres de l'alliance
## 1.10.1 (2026-11-20)
- envoi des ressources par milliers sur le marché
## 1.9.2 (2025-11-18)
- simplification du code
## 1.9.1 (2025-11-18)
- ajout d'un bouton pour sélectionner toutes les troupes
## 1.8.1 (2025-11-17)
- remplacement de 'attaques' par 'occurrences'
- correction du calcul d'arrivée des unités
- ajout des dizièmes de seconde pour envoyer des unités
## 1.7.4 (2025-11-16) ## 1.7.4 (2025-11-16)
- correction bug de calcul des secondes en utilisant search regex - correction bug de calcul des secondes en utilisant search regex

1
images/blank.svg Normal file
View File

@@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 640 640"><!--!Font Awesome Free v7.1.0 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free Copyright 2025 Fonticons, Inc.--><path fill="#000000" d="M416.5 88L416.5 160L352.5 160C273 160 208.5 224.5 208.5 304C208.5 397.4 291.3 438.8 309.1 446.6C311.3 447.6 313.7 448 316.2 448L318.7 448C328.5 448 336.5 440 336.5 430.2C336.5 421.9 330.6 414.7 323.7 409.9C314.8 403.7 304.5 391.7 304.5 369.4C304.5 324.4 341 287.9 386 287.9L416.5 287.9L416.5 359.9C416.5 369.6 422.3 378.4 431.3 382.1C440.3 385.8 450.6 383.8 457.5 376.9L593.5 240.9C602.9 231.5 602.9 216.3 593.5 207L457.5 71C450.6 64.1 440.3 62.1 431.3 65.8C422.3 69.5 416.5 78.3 416.5 88zM144.5 160C100.3 160 64.5 195.8 64.5 240L64.5 496C64.5 540.2 100.3 576 144.5 576L400.5 576C444.7 576 480.5 540.2 480.5 496L480.5 464C480.5 446.3 466.2 432 448.5 432C430.8 432 416.5 446.3 416.5 464L416.5 496C416.5 504.8 409.3 512 400.5 512L144.5 512C135.7 512 128.5 504.8 128.5 496L128.5 240C128.5 231.2 135.7 224 144.5 224L160.5 224C178.2 224 192.5 209.7 192.5 192C192.5 174.3 178.2 160 160.5 160L144.5 160z"/></svg>

After

Width:  |  Height:  |  Size: 1.1 KiB

View File

@@ -1,7 +1,7 @@
{ {
"manifest_version": 3, "manifest_version": 3,
"name": "KAplus", "name": "KAplus",
"version": "1.7.4", "version": "1.11.4",
"developer": { "developer": {
"name": "Samuel Campos", "name": "Samuel Campos",

View File

@@ -5,8 +5,8 @@
"firefox" "firefox"
], ],
"release_notes": { "release_notes": {
"fr": "- correction bug de calcul des secondes en utilisant search regex", "fr": "- correction du bug sur le calculateur",
"en-US": "- fix bug on seconds by using search regex" "en-US": "- fix bug on attack calculator"
} }
} }
} }

View File

@@ -1,3 +1,8 @@
let tomorrow = new Date(new Date().getTime() + 24*60*60*1000);
tomorrow.setHours(0, 0, 0, 0);
let afterTomorrow = new Date(tomorrow.getTime() + 24*60*60*1000);
let movingDuration = 0;
function num(s) { function num(s) {
return parseInt(s.replace(".", "")); return parseInt(s.replace(".", ""));
} }
@@ -18,27 +23,50 @@ function str(n) {
return s.replace(/^0+/, ""); return s.replace(/^0+/, "");
} }
function createRow(key, value) { function createCustomElement(tag, attrs, text, style) {
let keyCell = document.createElement("td"); let elt = document.createElement(tag);
keyCell.textContent = key; if (attrs) {
for (let [key, value] of Object.entries(attrs)) {
if (value !== null) {
elt.setAttribute(key, value.toString());
}
}
}
if (text) {
elt.textContent = text.toString();
}
if (style) {
for (let [key, value] of Object.entries(style)) {
elt.style[key] = value.toString();
}
}
return elt;
}
let valueCell = document.createElement("td"); function createCustomInput(type, name, value, attrs, style) {
valueCell.textContent = value; let mergedAttrs = {};
if (attrs) {
mergedAttrs = attrs;
}
mergedAttrs["type"] = type;
if (name) {
mergedAttrs["name"] = name;
}
if (value) {
mergedAttrs["value"] = value;
}
return createCustomElement("input", mergedAttrs, null, style);
}
let row = document.createElement("tr"); function createKeyValueRow(key, value) {
let row = createCustomElement("tr");
let keyCell = createCustomElement("td", null, key);
let valueCell = createCustomElement("td", null, value);
row.appendChild(keyCell); row.appendChild(keyCell);
row.appendChild(valueCell); row.appendChild(valueCell);
return row; return row;
} }
function createInput(type, name, value) {
let elt = document.createElement("input");
elt.setAttribute("type", type);
elt.setAttribute("name", name);
elt.setAttribute("value", value);
return elt;
}
function searchPoint(text) { function searchPoint(text) {
let index = text.search(/\d{3}\|\d{3}/); let index = text.search(/\d{3}\|\d{3}/);
let point = text.slice(index, index + 7).split("|"); let point = text.slice(index, index + 7).split("|");
@@ -61,24 +89,439 @@ function shortcutElementReplace(elt, img, text) {
} }
} }
let spanImageElement = document.createElement("span"); let spanImageElement = createCustomElement("span", {"class": "shortcut_element_image"});
spanImageElement.classList.add("shortcut_element_image"); let imgElement = createCustomElement("img", {"src": chrome.runtime.getURL("images/" + img + ".svg")});
let imgElement = document.createElement("img");
imgElement.setAttribute("src", chrome.runtime.getURL("images/" + img + ".svg"));
spanImageElement.appendChild(imgElement); spanImageElement.appendChild(imgElement);
aElements[0].textContent = ""; aElements[0].textContent = "";
aElements[0].appendChild(spanImageElement); aElements[0].appendChild(spanImageElement);
if (text) { if (text) {
let spanDescElement = document.createElement("span"); let spanDescElement = createCustomElement("span", {"class": "shortcut_element_desc"}, text);
spanDescElement.classList.add("shortcut_element_desc");
spanDescElement.textContent = text;
aElements[0].appendChild(spanDescElement); aElements[0].appendChild(spanDescElement);
} }
} }
function customizeNavbar(layCastleElement) {
/* Improve navbar icons */
let shortcutElements = layCastleElement.getElementsByClassName("shortcut_element");
shortcutElementReplace(shortcutElements[0], "ranking", shortcutElements[0].textContent.replace(/[^0-9]/g, ""));
shortcutElementReplace(shortcutElements[1], "ally", "");
shortcutElementReplace(shortcutElements[2], "profile", "");
shortcutElementReplace(shortcutElements[3], "premium", "");
shortcutElementReplace(shortcutElements[4], "messages", "");
shortcutElementReplace(shortcutElements[5], "tools", "");
shortcutElementReplace(shortcutElements[6], "favorites", "");
/* Center navbar */
let shortcutContainers = layCastleElement.getElementsByClassName("shortcut_container");
shortcutContainers[0].classList.add("shortcut_container_left");
shortcutContainers[2].classList.add("shortcut_container_right");
}
function countUpMs() {
let arrivalDate = new Date(new Date().getTime() + movingDuration * 1000);
let prefix = "";
if (arrivalDate >= afterTomorrow) {
prefix = "le " + arrivalDate.getDate() + "." + arrivalDate.getMonth() + " ";
} else if (arrivalDate > tomorrow) {
prefix = "demain ";
}
document.getElementById("countup-time-ms").textContent = prefix
+ "à "
+ arrivalDate.getHours().toString().padStart(2, "0")
+ ":"
+ arrivalDate.getMinutes().toString().padStart(2, "0")
+ ":"
+ arrivalDate.getSeconds().toString().padStart(2, "0")
+ ":"
+ Math.floor(arrivalDate.getMilliseconds() / 100);
}
function removeAdsBanner() {
/* Remove iframe banner */
document.getElementById("banner_skyscraper").remove();
}
function showPlayersId() {
/* Add a column with player id */
let mainContentPane = document.getElementsByClassName("contentpane")[1];
let borderListTable = mainContentPane.getElementsByClassName("borderlist")[0];
let playerRows = borderListTable.getElementsByTagName("tr");
let headerCells = playerRows[0].getElementsByTagName("th");
let nameCellIndex = -1;
for (let i = 0; i < headerCells.length; i ++) {
if (headerCells[i].textContent === "Nom") {
nameCellIndex = i;
break;
}
}
if (nameCellIndex === -1) {
/* Name column not found, so return */
console.log("Column 'Nom' not found, cannot show player ids :(");
return;
}
let idHeaderCell = createCustomElement("th", {"class": headerCells[0].getAttribute("class")}, "Id");
for (let i = 1; i < playerRows.length; i ++) {
let playerCells = playerRows[i].getElementsByTagName("td");
let playerProfileLink = playerCells[nameCellIndex].getElementsByTagName("a")[0].getAttribute("href");
let idValue = playerProfileLink.replace(/^.*id=(\d+)$/, "$1");
let idCell = createCustomElement("td", {"class": playerCells[0].getAttribute("class")}, idValue);
playerRows[i].insertBefore(idCell, playerCells[nameCellIndex]);
}
playerRows[0].insertBefore(idHeaderCell, headerCells[nameCellIndex]);
}
function showPlayerUnitPointsAndId() {
let mainContentPane = document.getElementsByClassName("contentpane")[1];
let borderLists = mainContentPane.getElementsByClassName("borderlist");
let playerPropertiesTable = borderLists[0];
let playerPropertiesTbody = playerPropertiesTable.getElementsByTagName("tbody")[0];
let playerPropertiesRows = playerPropertiesTable.getElementsByTagName("tr");
let totalPoints = num(playerPropertiesRows[2].getElementsByTagName("td")[1].textContent);
let villagesCount = num(playerPropertiesRows[4].getElementsByTagName("td")[1].textContent);
let villagesTable = borderLists[1];
let villagesRows = villagesTable.getElementsByTagName("tr");
let villagesPoints = 0;
for (let i = 1; i < villagesRows.length; i += 1) {
villagesPoints += num(villagesRows[i].getElementsByTagName("td")[2].textContent);
}
let villagesBonus = 2250 * Math.max(0, villagesCount - 1);
let armyPoints = totalPoints - villagesPoints - villagesBonus;
let armyPercent = "-";
if (villagesCount > 0) {
armyPercent = (Math.round(armyPoints / villagesCount) / 100).toString() + " %";
}
let moduleMenu = mainContentPane.getElementsByTagName("table")[0];
let moduleHyperlink = moduleMenu.getElementsByTagName("a")[0];
let playerId = moduleHyperlink.getAttribute("href").replace(/^.*[?&]id=(\d+).*$/, "$1");
playerPropertiesTbody.appendChild(createKeyValueRow("Points troupes:", str(armyPoints)));
playerPropertiesTbody.appendChild(createKeyValueRow("% points troupes:", armyPercent));
playerPropertiesTbody.insertBefore(createKeyValueRow("Id:", playerId), playerPropertiesRows[2]);
}
function showVillageUnitPoints() {
let settlementElt = document.getElementById("settlement");
if (settlementElt === null) {
console.log("Settlement element not found => cannot show village points :(");
return;
}
let settlements = settlementElt.textContent.split("|");
let noBorderRows = document.getElementsByClassName("noborder");
let villagePointsRow = noBorderRows[0];
for (let i = 0; i < noBorderRows.length; i++) {
if (noBorderRows[i].textContent.startsWith("Points:")) {
villagePointsRow = noBorderRows[i];
break;
}
}
let unitPointsRow = villagePointsRow.cloneNode(true);
villagePointsRow.getElementsByTagName("td")[1].textContent = "Points village: " + settlements[3];
unitPointsRow.getElementsByTagName("td")[1].textContent = "Points troupes: " + settlements[4];
villagePointsRow.after(unitPointsRow);
}
function showBarrackSelectAllUnits() {
let sendCommandForm = document.getElementById("sendCommandForm");
let barracksCommands = sendCommandForm.getElementsByClassName("barracksCommand");
let borderListTables = sendCommandForm.getElementsByClassName("borderlist");
let unitCountBoxes = [];
if (barracksCommands.length === 1) {
unitCountBoxes = barracksCommands[0].getElementsByClassName("box");
} else if (borderListTables.length === 1) {
unitCountBoxes = borderListTables[0].getElementsByTagName("td");
}
for (let i = 0; i < unitCountBoxes.length; i ++) {
let unitCountInputs = unitCountBoxes[i].getElementsByTagName("input");
if (unitCountInputs.length === 0) {
continue;
}
let unitCountInput = unitCountInputs[0];
if (unitCountInput.getAttribute("type") === null) {
unitCountInput.setAttribute("type", "number");
unitCountInput.style.width = "65px";
}
}
let sendXInput = document.getElementById("send_x");
sendXInput.setAttribute("type", "number");
if (sendXInput.value === "0") {
sendXInput.value = "";
}
let sendYInput = document.getElementById("send_y");
sendYInput.setAttribute("type", "number");
if (sendYInput.value === "0") {
sendYInput.value = "";
}
let selectAllLabel = createCustomElement("label");
let selectAllInput = createCustomElement("input", {"type": "checkbox"});
selectAllInput.addEventListener("change", function () {
for (let i = 0; i < unitCountBoxes.length; i ++) {
let unitCountBox = unitCountBoxes[i];
let unitCountClicks = unitCountBox.getElementsByClassName("click");
if (unitCountClicks.length === 0) {
continue;
}
let unitCountClick = unitCountClicks[0];
if (unitCountClick.classList.contains("all")) {
continue;
}
let unitCountInput = unitCountBox.getElementsByTagName("input")[0];
if (this.checked && unitCountClick.textContent !== "(0)") {
unitCountInput.value = unitCountClick.textContent.replace(/^\(([^.]*)(\.([^.]*))?\)$/, "$1$3");
} else {
unitCountInput.value = "";
}
}
})
selectAllLabel.appendChild(selectAllInput);
let selectAllSpan = createCustomElement("span", {"class": "click all"}, "(Tout sélectionner)");
selectAllLabel.appendChild(selectAllSpan);
/* Modern style */
if (barracksCommands.length === 1) {
let boxCell = createCustomElement("div", {"class": "box"});
let backgroundCell = createCustomElement("div", {"class": "background"});
let backgroundImg = createCustomElement(
"img", {"src": "//s58-fr.kingsage.gameforge.com/img/modern/card_sendunit.png"}
);
backgroundCell.appendChild(backgroundImg);
boxCell.appendChild(backgroundCell);
let imageCell = createCustomElement("div", {"class": "image"});
let imageImg = createCustomElement(
"img", {"src": "//s58-fr.kingsage.gameforge.com/img/shortcut/barracks.png"}, null, {"width": "28px"}
);
imageCell.appendChild(imageImg);
boxCell.appendChild(imageCell);
let nameCell = createCustomElement("div", {"class": "name"});
let nameA = createCustomElement("a", {"href": "help.php?m=units", "target": "_help"});
let nameB = createCustomElement("b", null, "Tout");
nameA.appendChild(nameB);
nameCell.appendChild(nameA);
boxCell.appendChild(nameCell);
let selectAllCell = createCustomElement("div", {"class": "quantity"});
selectAllCell.appendChild(selectAllLabel);
boxCell.appendChild(selectAllCell);
let brTag = barracksCommands[0].getElementsByTagName("br")[1];
barracksCommands[0].insertBefore(boxCell, brTag);
/* Classic style */
} else if (borderListTables.length === 1) {
let borderListRows = borderListTables[0].getElementsByTagName("tr");
let selectAllCell = borderListRows[4].getElementsByTagName("td")[3];
let imageA = createCustomElement("a", {"href": "help.php?m=units", "target": "_help"});
let imageImg = createCustomElement(
"img", {"src": "//s58-fr.kingsage.gameforge.com/img/shortcut/barracks.png", "title": "Tout"}
);
imageA.appendChild(imageImg);
selectAllCell.appendChild(imageA);
selectAllCell.appendChild(selectAllLabel);
}
}
function showCountupTimeDecimals() {
let oldCell = document.getElementById("countup-time");
let hms = oldCell.parentElement.previousElementSibling.getElementsByTagName("td")[1].textContent.split(":");
movingDuration = parseInt(hms[0]) * 3600 + parseInt(hms[1]) * 60 + parseInt(hms[2]) ;
let newRow = createCustomElement("tr");
let newLeftCell = createCustomElement("td", null, "Arrivée:");
newRow.appendChild(newLeftCell);
let newRightCell = createCustomElement("td", {"id": "countup-time-ms"});
newRow.appendChild(newRightCell);
oldCell.parentElement.parentElement.insertBefore(newRow, oldCell.parentElement);
oldCell.parentElement.style.display = "none";
setInterval(countUpMs, 100);
}
function showOccurrencesInput() {
let table = createCustomElement("table", {"class": "borderlist"});
let tbody = createCustomElement("tbody");
let tr = createCustomElement("tr");
let th = createCustomElement("th", null, "Nombre d'occurrences:");
tr.appendChild(th)
let td = createCustomElement("td");
let input = createCustomElement("input", {"type": "number", "name": "occurrences", "value": "1"});
td.appendChild(input);
tr.appendChild(td);
tbody.appendChild(tr);
table.appendChild(tbody);
let form = document.getElementsByTagName("form")[0];
let firstInput = form.getElementsByTagName("input")[0];
form.insertBefore(table, firstInput);
form.addEventListener("submit", function (event) {
event.preventDefault();
let formData = new FormData(this);
let attackCount = parseInt(formData.get("occurrences").toString());
formData.delete("occurrences");
let sent = 0;
for (let i = 0; i < attackCount; i ++) {
let xhr = new XMLHttpRequest();
xhr.addEventListener("readystatechange", function () {
if (this.readyState === this.DONE) {
sent ++;
}
if (sent === attackCount) {
window.location.replace(xhr.responseURL);
}
})
xhr.open(this.method, this.action, true);
xhr.send(formData);
}
});
}
function fixSelectVillageBug() {
let select = document.getElementsByName("village_name")[0];
select.removeAttribute("onchange");
select.addEventListener("change", function () {
let sendX = document.getElementById("send_x");
let sendY = document.getElementById("send_y");
if (this.selectedIndex === 0) {
sendX.value = "";
sendY.value = "";
} else {
let xy = this.value.split("|");
sendX.value = xy[0];
sendY.value = xy[1];
}
});
}
function showThousandInputs() {
let sendForm = document.getElementsByTagName("form")[0]
sendForm.addEventListener("submit", function () {
let inputs = this.getElementsByTagName("input");
for (let i = 0; i < inputs.length; i ++) {
if (inputs[i].getAttribute("name").endsWith("_k")) {
inputs[i].setAttribute("name", "");
}
}
});
let sendFormTables = sendForm.getElementsByTagName("table");
let newTable = sendFormTables[0].cloneNode(true);
newTable.getElementsByTagName("th")[0].textContent = "Ressources par milliers";
let resCells = newTable.getElementsByTagName("td");
for (let i = 0; i < resCells.length; i ++) {
let resInput = resCells[i].getElementsByTagName("input")[0];
let resName = resInput.getAttribute("name");
let resNameK = resInput.getAttribute("name") + "_k";
resInput.setAttribute("name", resNameK);
resInput.addEventListener("change", function () {
document.getElementsByName(resName)[0].value = 1000 * parseInt(this.value);
});
let spanInput = resCells[i].getElementsByTagName("span")[0];
let resMax = spanInput.textContent.replace(/\(/, "").replace("\)", "").replace(/\./, "");
let rMax = Math.floor(parseInt(resMax) / 1000);
spanInput.setAttribute(
"onclick",
"insertNum('kingsage', '" + resNameK + "', '" + rMax.toString() + "'); " +
"insertNum('kingsage', '" + resName + "', '" + (1000 * rMax).toString() + "');"
)
spanInput.textContent = "(" + rMax.toString() + "K)";
}
sendForm.insertBefore(newTable, sendFormTables[0]);
sendForm.insertBefore(createCustomElement("br"), sendFormTables[1]);
}
function fixSendResourcesInputsTypes() {
let contentPane = document.getElementsByClassName("contentpane")[1]
let sendCommandForm = contentPane.getElementsByTagName("form")[0];
let sendInputs = sendCommandForm.getElementsByTagName("input");
for (let i = 0; i < sendInputs.length; i ++) {
if (sendInputs[i].name.startsWith("send_")) {
sendInputs[i].setAttribute("type", "number");
if (sendInputs[i].value === "0") {
sendInputs[i].value = "";
}
sendInputs[i].style.width = "65px";
}
}
}
function showSecondsAndCalculator() {
let serverTime = parseInt(document.getElementById("servertime").getAttribute("time"));
let contentPane = document.getElementsByClassName("contentpane")[1]
let table = contentPane.getElementsByClassName("borderlist")[0];
let rows = table.getElementsByTagName("tr");
let titleRowIndex = 0;
if (rows[titleRowIndex].getElementsByTagName("th").length === 0) {
titleRowIndex = 1;
}
console.log(titleRowIndex)
let headCell = createCustomElement("th", null, "Calcul", {"width": "45px"});
rows[titleRowIndex].appendChild(headCell);
for (let i = titleRowIndex + 1; i < rows.length; i ++) {
let cells = rows[i].getElementsByTagName("td");
let arrivalDateCell = cells[3]
let arrivalTimeCell = cells[4];
let seconds = parseInt(arrivalTimeCell.getElementsByTagName("span")[0].getAttribute("time"));
let arrival = new Date((serverTime + seconds) * 1000);
let hour = arrival.toLocaleTimeString("fr-FR");
arrivalDateCell.textContent = arrivalDateCell.textContent.replace(/(.*)\d\d:\d\d(.*)/, "$1" + hour + "$2");
let startPoint = searchPoint(cells[2].textContent);
let targetPoint = searchPoint(cells[1].textContent);
let calculatorCell = createCustomElement("td");
let calculatorForm = createCustomElement(
"form",
{
"method": "post",
"action": "/?s=tools&m=runtime_calculator&inta=calculate",
"title": "Calculateur de trajet",
},
null,
{
"display": "inline-block",
},
);
calculatorForm.appendChild(createCustomInput("hidden", "start_x", startPoint.x));
calculatorForm.appendChild(createCustomInput("hidden", "start_y", startPoint.y));
calculatorForm.appendChild(createCustomInput("hidden", "target_x", targetPoint.x));
calculatorForm.appendChild(createCustomInput("hidden", "target_y", targetPoint.y));
let calculatorImg = createCustomInput(
"image",
null,
null,
{"src": chrome.runtime.getURL("images/calculator.svg")},
{"width": "20px", "height": "20px", "border": "none"}
);
calculatorForm.appendChild(calculatorImg);
calculatorCell.appendChild(calculatorForm);
let calculatorFormBlank = calculatorForm.cloneNode(true);
calculatorFormBlank.setAttribute("target", "_blank");
calculatorFormBlank.setAttribute("title", "Calculateur de trajet dans nouvel onglet");
let calculatorBlankImg = calculatorFormBlank.getElementsByTagName("input")[4]
calculatorBlankImg.setAttribute("src", chrome.runtime.getURL("images/blank.svg"));
calculatorCell.appendChild(calculatorFormBlank);
rows[i].appendChild(calculatorCell);
}
}
function main() { function main() {
/* Exit immediately if not on game page */ /* Exit immediately if not on game page */
let layCastleTopElements = document.getElementsByClassName("lay_castle_top"); let layCastleTopElements = document.getElementsByClassName("lay_castle_top");
@@ -86,23 +529,20 @@ function main() {
return; return;
} }
/* Remove iframe banner */ /* Exit immediately if extension has already been loaded */
document.getElementById("banner_skyscraper").remove(); let kaplus = document.getElementById("kaplus-marker");
if (kaplus) {
return;
}
/* Improve navbar icons */ /* Set marker to prevent loading extension several times */
let shortcutElements = layCastleTopElements[0].getElementsByClassName("shortcut_element"); document.body.appendChild(createCustomElement("div", {"id": "kaplus-marker"}, null, {"display": "none"}));
shortcutElementReplace(shortcutElements[0], "ranking", shortcutElements[0].textContent.replace(/[^0-9]/g, ""));
shortcutElementReplace(shortcutElements[1], "ally", "");
shortcutElementReplace(shortcutElements[2], "profile", "");
shortcutElementReplace(shortcutElements[3], "premium", "");
shortcutElementReplace(shortcutElements[4], "messages", "");
shortcutElementReplace(shortcutElements[5], "tools", "");
shortcutElementReplace(shortcutElements[6], "favorites", "");
/* Center navbar */ /* Remove ads banner on dom content loaded */
let shortcutContainers = layCastleTopElements[0].getElementsByClassName("shortcut_container"); window.addEventListener("DOMContentLoaded", removeAdsBanner);
shortcutContainers[0].classList.add("shortcut_container_left");
shortcutContainers[2].classList.add("shortcut_container_right"); /* Customize navbar */
customizeNavbar(layCastleTopElements[0]); // test: OK
/* Parse url params and switch case */ /* Parse url params and switch case */
let urlParams = new URLSearchParams(window.location.search); let urlParams = new URLSearchParams(window.location.search);
@@ -110,152 +550,68 @@ function main() {
let module = urlParams.get("m"); let module = urlParams.get("m");
let sub = urlParams.get("sub"); let sub = urlParams.get("sub");
/* Display unit-points on user profile */ /* Choose action according to section, module and sub */
if (section === "info_player" && (module === "profile" || module === null)) { switch (section) {
let mainContentPane = document.getElementsByClassName("contentpane")[1]; case "ranking":
let borderLists = mainContentPane.getElementsByClassName("borderlist"); switch (module) {
case "player": case null:
let playerPropertiesTable = borderLists[0]; showPlayersId(); // test: OK
let playerPropertiesRows = playerPropertiesTable.getElementsByTagName("tr"); break;
let totalPoints = num(playerPropertiesRows[2].getElementsByTagName("td")[1].textContent);
let villagesCount = num(playerPropertiesRows[4].getElementsByTagName("td")[1].textContent);
let villagesTable = borderLists[1];
let villagesRows = villagesTable.getElementsByTagName("tr");
let villagesPoints = 0;
for (let i = 1; i < villagesRows.length; i += 1) {
villagesPoints += num(villagesRows[i].getElementsByTagName("td")[2].textContent);
}
let villagesBonus = 2250 * Math.max(0, villagesCount - 1);
let armyPoints = totalPoints - villagesPoints - villagesBonus;
let armyPercent = "-";
if (villagesCount > 0) {
armyPercent = (Math.round(armyPoints / villagesCount) / 100).toString() + " %";
}
playerPropertiesTable.appendChild(createRow("Points troupes:", str(armyPoints)));
playerPropertiesTable.appendChild(createRow("% points troupes:", armyPercent));
}
/* Display unit-points on village overview */
if (section === "overview") {
let settlements = document.getElementById("settlement").textContent.split("|");
let noBorderRows = document.getElementsByClassName("noborder");
let villagePointsRow = noBorderRows[0];
for (let i = 0; i < noBorderRows.length; i++) {
if (noBorderRows[i].textContent.startsWith("Points:")) {
villagePointsRow = noBorderRows[i];
break;
} }
} break;
let unitPointsRow = villagePointsRow.cloneNode(true);
villagePointsRow.getElementsByTagName("td")[1].textContent = "Points village: " + settlements[3];
unitPointsRow.getElementsByTagName("td")[1].textContent = "Points troupes: " + settlements[4];
villagePointsRow.after(unitPointsRow);
}
/* Allow multiple attacks */ case "ally":
if (section === "build_barracks" && module === "command" && sub === "send") { switch (module) {
let table = document.createElement("table"); case "members":
table.classList.add("borderlist"); showPlayersId(); // test: OK
let tbody = document.createElement("tbody"); break;
let tr = document.createElement("tr"); case "attacks":
let th = document.createElement("th"); showSecondsAndCalculator(); // test: OK
th.textContent = "Nombre d'attaques:"; break;
tr.appendChild(th) }
let td = document.createElement("td"); break;
let input = document.createElement("input");
input.setAttribute("type", "number");
input.setAttribute("name", "attack_count");
input.setAttribute("value", "1");
td.appendChild(input);
tr.appendChild(td);
tbody.appendChild(tr);
table.appendChild(tbody);
let form = document.getElementsByTagName("form")[0]; case "overview":
let firstInput = form.getElementsByTagName("input")[0]; showVillageUnitPoints(); // test: FAILED because settlement element has been removed
form.insertBefore(table, firstInput); break;
form.addEventListener("submit", function (event) {
event.preventDefault();
let formData = new FormData(this);
let attackCount = parseInt(formData.get("attack_count").toString());
formData.delete("attack_count");
let sent = 0; case "build_barracks":
for (let i = 0; i < attackCount; i++) { switch (module) {
let xhr = new XMLHttpRequest(); case "command": case null:
xhr.onload = function () { switch (sub) {
sent++; case null:
if (sent === attackCount) { showBarrackSelectAllUnits(); // test: OK
window.location.replace(xhr.responseURL); break;
case "send":
showCountupTimeDecimals(); // test: OK
showOccurrencesInput(); // test: OK
break;
} }
} break;
xhr.open(this.method, this.action, true);
xhr.send(formData);
} }
}); break;
}
/* Fix select bug in market */ case "build_market":
if (section === "build_market" && (module === "send" || module === null)) { switch (module) {
let select = document.getElementsByName("village_name")[0]; case "send": case null:
select.removeAttribute("onchange"); fixSelectVillageBug(); // test: OK
select.addEventListener("change", function () { showThousandInputs(); // test: OK
let sendX = document.getElementById("send_x"); fixSendResourcesInputsTypes(); // test: OK
let sendY = document.getElementById("send_y"); break;
if (this.selectedIndex === 0) {
sendX.value = "";
sendY.value = "";
} else {
let xy = this.value.split("|");
sendX.value = xy[0];
sendY.value = xy[1];
} }
}); break;
}
/* Improve attacks display */ case "info_player":
if (section === "ally" && module === "attacks") { switch (module) {
let serverTime = parseInt(document.getElementById("servertime").getAttribute("time")); case "profile": case null:
let contentPane = document.getElementsByClassName("contentpane")[1] showPlayerUnitPointsAndId(); // test: OK
let table = contentPane.getElementsByClassName("borderlist")[0]; break;
let rows = table.getElementsByTagName("tr"); }
break;
let headCell = document.createElement("th"); case "info_member":
rows[0].appendChild(headCell); showPlayersId(); // test: OK
break;
for (let i = 1; i < rows.length; i ++) {
let cells = rows[i].getElementsByTagName("td");
let arrivalDateCell = cells[3]
let arrivalTimeCell = cells[4];
let seconds = parseInt(arrivalTimeCell.getElementsByTagName("span")[0].getAttribute("time"));
let arrival = new Date((serverTime + seconds) * 1000);
let hour = arrival.toLocaleTimeString("fr-FR");
arrivalDateCell.textContent = arrivalDateCell.textContent.replace(/(.*)\d\d:\d\d(.*)/, "$1" + hour + "$2");
let startPoint = searchPoint(cells[2].textContent);
let targetPoint = searchPoint(cells[1].textContent);
let calculatorCell = document.createElement("td");
let calculatorForm = document.createElement("form");
calculatorForm.setAttribute("method", "post");
calculatorForm.setAttribute("action", "/?s=tools&m=runtime_calculator&inta=calculate");
calculatorForm.appendChild(createInput("hidden", "start_x", startPoint.x));
calculatorForm.appendChild(createInput("hidden", "start_y", startPoint.y));
calculatorForm.appendChild(createInput("hidden", "target_x", targetPoint.x));
calculatorForm.appendChild(createInput("hidden", "target_y", targetPoint.y));
let calculatorImg = document.createElement("input");
calculatorImg.setAttribute("type", "image");
calculatorImg.setAttribute("src", chrome.runtime.getURL("images/calculator.svg"));
calculatorImg.style.width = "20px";
calculatorImg.style.height = "20px";
calculatorImg.style.border = "none";
calculatorForm.appendChild(calculatorImg);
calculatorCell.appendChild(calculatorForm);
rows[i].appendChild(calculatorCell);
}
} }
} }