function num(s) { return parseInt(s.replace(".", "")); } function str(n) { if (n === 0) { return "0"; } let s = ""; while (n > 0) { if (s !== "") { s = "." + s; } let r = n % 1000; s = r.toString().padStart(3, "0") + s; n = ~~(n/1000); } return s.replace(/^0+/, ""); } function createRow(key, value) { let keyCell = document.createElement("td"); keyCell.textContent = key; let valueCell = document.createElement("td"); valueCell.textContent = value; let row = document.createElement("tr"); row.appendChild(keyCell); row.appendChild(valueCell); return row; } function shortcutElementReplace(elt, img, text) { // If more than one hyperlink element found, // then keep the last one but with href of the first one. let aElements = elt.getElementsByTagName("a"); let imgElements = elt.getElementsByTagName("img"); if (aElements.length > 1 || imgElements.length > 0) { aElements[aElements.length - 1].classList.add("has_notif"); aElements[aElements.length - 1].setAttribute("href", aElements[0].getAttribute("href")); for (let i = imgElements.length - 1; i >= 0; i--) { imgElements[i].remove(); } for (let i = aElements.length - 2; i >= 0; i--) { aElements[i].remove(); } } let spanImageElement = document.createElement("span"); spanImageElement.classList.add("shortcut_element_image"); let imgElement = document.createElement("img"); imgElement.setAttribute("src", chrome.runtime.getURL("images/" + img + ".svg")); spanImageElement.appendChild(imgElement); aElements[0].textContent = ""; aElements[0].appendChild(spanImageElement); if (text) { let spanDescElement = document.createElement("span"); spanDescElement.classList.add("shortcut_element_desc"); spanDescElement.textContent = text; aElements[0].appendChild(spanDescElement); } } function main() { /* Exit immediately if not on game page */ let layCastleTopElements = document.getElementsByClassName("lay_castle_top"); if (layCastleTopElements.length === 0) { return; } /* Remove iframe banner */ document.getElementById("banner_skyscraper").remove(); /* Improve navbar icons */ let shortcutElements = layCastleTopElements[0].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 = layCastleTopElements[0].getElementsByClassName("shortcut_container"); shortcutContainers[0].classList.add("shortcut_container_left"); shortcutContainers[2].classList.add("shortcut_container_right"); /* Parse url params and switch case */ let urlParams = new URLSearchParams(window.location.search); let section = urlParams.get("s"); let module = urlParams.get("m"); let sub = urlParams.get("sub"); /* Display unit-points on user profile */ if (section === "info_player" && (module === "profile" || module === null)) { let mainContentPane = document.getElementsByClassName("contentpane")[1]; let borderLists = mainContentPane.getElementsByClassName("borderlist"); let playerPropertiesTable = borderLists[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() + " %"; } 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; } } 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 */ if (section === "build_barracks" && module === "command" && sub === "send") { let table = document.createElement("table"); table.classList.add("borderlist"); let tbody = document.createElement("tbody"); let tr = document.createElement("tr"); let th = document.createElement("th"); th.textContent = "Nombre d'attaques:"; tr.appendChild(th) let td = document.createElement("td"); 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]; 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("attack_count").toString()); formData.delete("attack_count"); let sent = 0; for (let i = 0; i < attackCount; i++) { let xhr = new XMLHttpRequest(); xhr.onload = function () { sent++; if (sent === attackCount) { window.location.replace(xhr.responseURL); } } xhr.open(this.method, this.action, true); xhr.send(formData); } }); } /* Fix select bug in market */ if (section === "build_market" && (module === "send" || module === null)) { 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]; } }); } /* Improve attacks display */ if (section === "ally" && module === "attacks") { let contentPane = document.getElementsByClassName("contentpane")[1] let table = contentPane.getElementsByClassName("borderlist")[0]; let rows = table.getElementsByTagName("tr"); for (let i = 1; i < rows.length; i ++) { let cells = rows[i].getElementsByTagName("td"); let arrivalDateCell = cells[3] let arrivalTimeCell = cells[4]; let interval = arrivalTimeCell.textContent.split(":"); let seconds = parseInt(interval[0]) * 3600 + parseInt(interval[1]) * 60 + parseInt(interval[2]); let arrival = new Date(Date.now() + seconds * 1000); let hour = arrival.toLocaleTimeString("fr-FR"); arrivalDateCell.textContent = arrivalDateCell.textContent.replace(/(.*)\d\d:\d\d(.*)/, "$1" + hour + "$2"); } } } main();