diff --git a/CHANGELOG.md b/CHANGELOG.md
index 6d313b0..3de4e5b 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,5 +1,9 @@
# Changelog
+## 1.12.4 (2026-12-07)
+
+- ajout du planificateur autonome d'attaques
+
## 1.11.4 (2026-12-03)
- correction du bug sur le calculateur
diff --git a/images/cancel.svg b/images/cancel.svg
new file mode 100644
index 0000000..2067162
--- /dev/null
+++ b/images/cancel.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/images/clock.svg b/images/clock.svg
new file mode 100644
index 0000000..5f74ce2
--- /dev/null
+++ b/images/clock.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/images/play.svg b/images/play.svg
new file mode 100644
index 0000000..1cfff35
--- /dev/null
+++ b/images/play.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/manifest.json b/manifest.json
index 61b56f6..f5fe469 100644
--- a/manifest.json
+++ b/manifest.json
@@ -1,7 +1,7 @@
{
"manifest_version": 3,
"name": "KAplus",
- "version": "1.11.4",
+ "version": "1.12.1",
"developer": {
"name": "Samuel Campos",
diff --git a/metadata.json b/metadata.json
index bb6b108..0e806ca 100644
--- a/metadata.json
+++ b/metadata.json
@@ -5,8 +5,8 @@
"firefox"
],
"release_notes": {
- "fr": "- correction du bug sur le calculateur",
- "en-US": "- fix bug on attack calculator"
+ "fr": "- ajout du planificateur autonome d'attaques",
+ "en-US": "- add autonomous attack planer"
}
}
}
\ No newline at end of file
diff --git a/src/kaplus.css b/src/kaplus.css
index bca460f..6884d0a 100644
--- a/src/kaplus.css
+++ b/src/kaplus.css
@@ -1,3 +1,17 @@
+@keyframes blink {
+ 0% {
+ opacity: 1;
+ }
+
+ 50% {
+ opacity: 0;
+ }
+
+ 100% {
+ opacity: 1;
+ }
+}
+
#inner_footer {
.inner_subcolumns {
left: 0 !important;
@@ -6,6 +20,16 @@
#content_wrapper > table {
width: auto !important;
+ cursor: default;
+}
+
+.borderlist {
+ .autonomous:disabled {
+ opacity: 0.3;
+ }
+ .autonomous.blink {
+ animation: blink 2s infinite;
+ }
}
.lay_castle_top {
diff --git a/src/kaplus.js b/src/kaplus.js
index 9907aaa..187baf2 100644
--- a/src/kaplus.js
+++ b/src/kaplus.js
@@ -1,7 +1,42 @@
-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;
+const AUTHORIZED_ALLIANCES = {
+ "s58-fr": ["NAZGUL"]
+};
+
+const MOVING_FACTOR = {
+ "s56-fr": 3,
+ "s57-fr": 4,
+ "s58-fr": 1.98,
+}
+
+const BUILDINGS = {
+ "main": "Château",
+ "stone": "Carrière",
+ "wood": "Scierie",
+ "iron": "Mine de minerai",
+ "storage": "Entrepôt",
+ "hide": "Cachette",
+ "farm": "Moulin",
+ "barracks": "Caserne",
+ "wall": "Remparts",
+ "stable": "Élevage d'ânes",
+ "snob": "Résidence",
+ "smith": "Orfèvrerie",
+ "statue": "Mémorial",
+}
+
+const UNITS = {
+ "farmer": "Milice de paysans",
+ "sword": "Templier",
+ "spear": "Écuyer",
+ "axe": "Sauvage",
+ "bow": "Grand Arc",
+ "spy": "Éclaireur",
+ "light": "Croisé",
+ "heavy": "Chevalier Noir",
+ "ram": "Bélier",
+ "kata": "Trébuchet",
+ "snob": "Comte",
+}
function num(s) {
return parseInt(s.replace(".", ""));
@@ -73,6 +108,144 @@ function searchPoint(text) {
return {x: point[0], y: point[1]}
}
+function selectVillage(selectRef, inputXRef, inputYRef) {
+ let select = document.getElementById(selectRef);
+ let inputX = document.getElementById(inputXRef);
+ let inputY = document.getElementById(inputYRef);
+ if (select.selectedIndex === 0) {
+ inputX.value = "";
+ inputY.value = "";
+ } else {
+ let xy = select.value.split("|");
+ inputX.value = xy[0];
+ inputY.value = xy[1];
+ }
+}
+
+function storeOrderToken(ownVillages, targetVillage) {
+ let orderToken = sessionStorage.getItem("orderToken");
+ if (orderToken !== null) {
+ return;
+ }
+
+ let breakLoop = false;
+ for (let villageId in ownVillages) {
+ if (breakLoop === true) {
+ return;
+ }
+ let xhrOrder = new XMLHttpRequest();
+ xhrOrder.addEventListener("readystatechange", function () {
+ if (xhrOrder.readyState === xhrOrder.DONE) {
+ let parser = new DOMParser();
+ let doc = parser.parseFromString(xhrOrder.responseText, "text/html");
+ let quantityDivs = doc.getElementsByClassName("quantity");
+ let unit = null;
+ for (let i = 0; i < quantityDivs.length; i ++) {
+ let quantityInput = quantityDivs[i].getElementsByTagName("input")[0];
+ let quantityClick = quantityDivs[i].getElementsByClassName("click")[0];
+ if (quantityClick.textContent !== "(0)") {
+ unit = quantityInput.getAttribute("name");
+ break;
+ }
+ }
+ if (unit === null) {
+ return;
+ }
+
+ let xhrSend = new XMLHttpRequest();
+ let formData = new FormData();
+ formData.set(unit, "1");
+ formData.set("send_x", targetVillage.x);
+ formData.set("send_y", targetVillage.y);
+ formData.set("support", "Envoyer du renfort");
+ let formParams = new URLSearchParams(formData);
+ xhrSend.addEventListener("readystatechange", function () {
+ if (xhrSend.readyState === xhrSend.DONE) {
+ let parser = new DOMParser();
+ let doc = parser.parseFromString(xhrSend.responseText, "text/html");
+ let form = doc.getElementsByTagName("form")[0];
+ let action = form.getAttribute("action");
+ let orderToken = action.replace(/^.*p=([a-z0-9]+).*$/, "$1");
+ sessionStorage.setItem("orderToken", orderToken);
+ breakLoop = true;
+ }
+ });
+ xhrSend.open("POST", "/?village=" + villageId + "&s=build_barracks&m=command&sub=send");
+ xhrSend.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
+ xhrSend.send(formParams.toString());
+ }
+ });
+ xhrOrder.open("GET", "/?village=" + villageId + "&s=build_barracks");
+ xhrOrder.send();
+ }
+}
+
+function storeTargetVillage(ownVillages) {
+ let targetVillage = sessionStorage.getItem("targetVillage");
+ if (targetVillage !== null) {
+ storeOrderToken(ownVillages, JSON.parse(targetVillage));
+ return;
+ }
+
+ let xhr = new XMLHttpRequest();
+ targetVillage = {};
+ xhr.addEventListener("readystatechange", function () {
+ if (xhr.readyState === xhr.DONE) {
+ let parser = new DOMParser();
+ let doc = parser.parseFromString(xhr.responseText, "text/html");
+ let cells = doc.getElementsByClassName("occupied range");
+ for (let i = 0; i < cells.length; i ++) {
+ let links = cells[i].getElementsByTagName("a");
+ if (links.length === 0) {
+ continue;
+ }
+ let villageId = links[0].getAttribute("href").replace(/^.*id=(\d{4}).*$/, "$1");
+ if (villageId in ownVillages) {
+ continue;
+ }
+ let villageXY = links[0].getAttribute("onmouseover").replace(/^.*(\d{3}\|\d{3}).*$/, "$1").split("|");
+ targetVillage = {x: parseInt(villageXY[0]), y: parseInt(villageXY[1])};
+ sessionStorage.setItem("targetVillage", JSON.stringify(targetVillage));
+ storeOrderToken(ownVillages, targetVillage);
+ break;
+ }
+ }
+ });
+ xhr.open("GET", "/?s=map");
+ xhr.send();
+}
+
+function storeOwnVillages() {
+ let ownVillages = sessionStorage.getItem("ownVillages");
+ if (ownVillages !== null) {
+ storeTargetVillage(JSON.parse(ownVillages));
+ return;
+ }
+
+ let xhr = new XMLHttpRequest();
+ xhr.addEventListener("readystatechange", function () {
+ if (xhr.readyState === xhr.DONE) {
+ let parser = new DOMParser();
+ let doc = parser.parseFromString(xhr.responseText, "text/html");
+ let mainContentPane = doc.getElementsByClassName("contentpane")[1];
+ let table = mainContentPane.getElementsByClassName("borderlist")[1];
+ let rows = table.getElementsByTagName("tr");
+ let ownVillages = {};
+ for (let i = 1; i < rows.length; i ++) {
+ let cells = rows[i].getElementsByTagName("td");
+ let link = cells[0].getElementsByTagName("a")[0];
+ let villageId = link.getAttribute("href").replace(/^.*id=(\d{4}).*$/, "$1");
+ let villageXY = cells[1].textContent.split("|");
+ ownVillages[villageId] = {x: parseInt(villageXY[0]), y: parseInt(villageXY[1]), name: link.textContent};
+ }
+ sessionStorage.setItem("ownVillages", JSON.stringify(ownVillages));
+ storeTargetVillage(ownVillages);
+ }
+ });
+ xhr.open("GET", "/?s=info_player");
+ xhr.send();
+}
+
function shortcutElementReplace(elt, img, text) {
// If more than one hyperlink element found,
// then keep the last one but with href of the first one.
@@ -119,7 +292,7 @@ function customizeNavbar(layCastleElement) {
shortcutContainers[2].classList.add("shortcut_container_right");
}
-function countUpMs() {
+function countUpMs(tomorrow, afterTomorrow, movingDuration) {
let arrivalDate = new Date(new Date().getTime() + movingDuration * 1000);
let prefix = "";
if (arrivalDate >= afterTomorrow) {
@@ -138,6 +311,49 @@ function countUpMs() {
+ Math.floor(arrivalDate.getMilliseconds() / 100);
}
+function convertTimestamp(timestamp) {
+ let now = new Date();
+ let tomorrow = new Date(now.getTime() + 24*3600*1000);
+ tomorrow.setHours(0);
+ tomorrow.setMinutes(0);
+ tomorrow.setSeconds(0);
+ tomorrow.setMilliseconds(0);
+ let afterTomorrow = new Date(tomorrow.getTime() + 24*3600*1000);
+ let date = new Date(timestamp);
+
+ let prefix = "";
+ if (date >= afterTomorrow) {
+ prefix = "le " + date.getDate() + "." + date.getMonth() + " ";
+ } else if (date > tomorrow) {
+ prefix = "demain ";
+ }
+ return prefix
+ + "à "
+ + date.getHours().toString().padStart(2, "0")
+ + ":"
+ + date.getMinutes().toString().padStart(2, "0")
+ + ":"
+ + date.getSeconds().toString().padStart(2, "0")
+ + "."
+ + Math.floor(date.getMilliseconds() / 100);
+}
+
+function convertDurationUntil(timestamp) {
+ let now = new Date();
+ let duration = timestamp - now.getTime();
+ let hours = Math.floor(duration / (3600*1000));
+ duration -= hours * 3600 * 1000;
+ let minutes = Math.floor(duration / (60*1000));
+ duration -= minutes * 60 * 1000;
+ let seconds = Math.floor(duration / 1000);
+ duration -= seconds * 1000;
+ let tenth = Math.floor(duration / 100);
+ return hours.toString().padStart(2, "0") + ":"
+ + minutes.toString().padStart(2, "0") + ":"
+ + seconds.toString().padStart(2, "0") + "."
+ + tenth.toString();
+}
+
function removeAdsBanner() {
/* Remove iframe banner */
document.getElementById("banner_skyscraper").remove();
@@ -207,6 +423,777 @@ function showPlayerUnitPointsAndId() {
playerPropertiesTbody.insertBefore(createKeyValueRow("Id:", playerId), playerPropertiesRows[2]);
}
+function showAutoPlanerMenu(village, module) {
+ let mainContentPane = document.getElementsByClassName("contentpane")[1];
+ let navTable = mainContentPane.getElementsByTagName("table")[0];
+ let navRow = navTable.getElementsByTagName("tr")[0];
+ let navCells = navRow.getElementsByTagName("td");
+ let separatorCell = createCustomElement("td");
+ let separatorImg = createCustomElement("img");
+ separatorCell.appendChild(separatorImg);
+ let autonomousCell = createCustomElement("td");
+ let autonomousLink = createCustomElement(
+ "a", {"href": "/?village=" + village + "&s=tools&m=auto_planer"}, "Planificateur autonome d'attaques"
+ );
+ let rightImg = navCells[6].getElementsByTagName("img")[0];
+ switch (module) {
+ case "runtime_calculator":
+ separatorImg.setAttribute("src", "/img/tabs/menue_sn_center.png");
+ autonomousCell.setAttribute("background", "/img/tabs/menue_n_back.png");
+ rightImg.setAttribute("src", "/img/tabs/menue_n_right.png");
+ break;
+ case "auto_planer":
+ separatorImg.setAttribute("src", "/img/tabs/menue_ns_center.png");
+ autonomousCell.setAttribute("background", "/img/tabs/menue_s_back.png");
+ rightImg.setAttribute("src", "/img/tabs/menue_s_right.png");
+ break;
+ default:
+ separatorImg.setAttribute("src", "/img/tabs/menue_nn_center.png");
+ autonomousCell.setAttribute("background", "/img/tabs/menue_n_back.png");
+ rightImg.setAttribute("src", "/img/tabs/menue_n_right.png");
+ break;
+ }
+ autonomousCell.appendChild(autonomousLink);
+ navRow.insertBefore(autonomousCell, navCells[6]);
+ navRow.insertBefore(separatorCell, navCells[6]);
+}
+
+function insertAutoPlanedOrder(table, orderId, order) {
+ let row = createCustomElement(
+ "tr",
+ {
+ "data-id": orderId,
+ "data-time": order.start_time,
+ "data-order": JSON.stringify(order),
+ "data-status": "waiting",
+ }
+ );
+
+ let kindCell = createCustomElement("td");
+ let kindImg = createCustomElement("img");
+ switch (order.kind) {
+ case "attack":
+ kindImg.setAttribute("src", "/img/command/attack.png");
+ kindImg.setAttribute("title", "Attaque");
+ break;
+ case "support":
+ kindImg.setAttribute("src", "/img/command/support.png");
+ kindImg.setAttribute("title", "Renfort");
+ break
+ case "spying":
+ kindImg.setAttribute("src", "/img/units/unit_spy-slow.png");
+ kindImg.setAttribute("title", "Espionnage");
+ break;
+ }
+ kindCell.appendChild(kindImg);
+ row.appendChild(kindCell);
+
+ let unitCounts = [];
+ for (let unit in UNITS) {
+ unitCounts.push(order[unit]);
+ }
+ let labelCell = createCustomElement(
+ "td",
+ {"title": "Programmé " + order.occurrences.toString() + " fois"},
+ "(x" + order.occurrences + ") " + order.label,
+ );
+ row.appendChild(labelCell);
+
+ let headCell = createCustomElement(
+ "td",
+ {
+ "onmouseover":
+ "Tip(tipUnitDetails('/img', '" + Object.keys(UNITS).join(":") + "', '" + unitCounts.join(":") + "'))",
+ "onmouseout": "UnTip()",
+ },
+ );
+ let headImg = createCustomElement("img", {"src": "/img/units/unit_" + order.head + ".png"});
+ headCell.appendChild(headImg);
+ row.appendChild(headCell);
+
+ let originCell = createCustomElement("td");
+ let originInfoLink = createCustomElement(
+ "a",
+ {"href": "/?s=info_village&id=" + order.start_id, "title": order.start_name},
+ order.start_name,
+ );
+ let originMapLink = createCustomElement(
+ "a",
+ {"href": "/?s=map&x=" + order.start_x + "&y=" + order.start_y},
+ "(" + order.start_x + "|" + order.start_y + ")",
+ )
+ originCell.appendChild(originInfoLink);
+ originCell.appendChild(originMapLink);
+ row.appendChild(originCell);
+
+ let targetCell = createCustomElement("td");
+ let targetInfoLink = createCustomElement(
+ "a",
+ {"href": "/?s=info_village&id=" + order.target_id, "title": order.target_name},
+ order.target_name,
+ );
+ let targetMapLink = createCustomElement(
+ "a",
+ {"href": "/?s=map&x=" + order.target_x + "&y=" + order.target_y},
+ " (" + order.target_x + "|" + order.target_y + ")",
+ )
+ targetCell.appendChild(targetInfoLink);
+ targetCell.appendChild(targetMapLink);
+ row.appendChild(targetCell);
+
+ row.appendChild(createCustomElement("td", null, convertTimestamp(parseInt(order.start_time))));
+ row.appendChild(createCustomElement("td", null, convertTimestamp(parseInt(order.target_time))));
+ row.appendChild(createCustomElement("td", null, convertDurationUntil(parseInt(order.start_time))));
+
+ let playCell = createCustomElement("td");
+ let playLink = createCustomElement(
+ "a",
+ {
+ "href": "/?village=" + order.start_id + "&s=build_barracks&m=command" +
+ "&send_x=" + order.target_x + "&send_y=" + order.target_y + "&farmer=" + order.farmer +
+ "&sword=" + order.sword + "&spear=" + order.spear + "&axe=" + order.axe + "&bow=" + order.bow +
+ "&spy=" + order.spy + "&light=" + order.light + "&heavy=" + order.heavy + "&ram=" + order.ram +
+ "&kata=" + order.kata + "&snob=" + order.snob,
+ "title": "Lancer manuellement",
+ },
+ );
+ let playImg = createCustomElement(
+ "img", {"src": chrome.runtime.getURL("/images/play.svg")}, null, {"width": "18px"}
+ );
+ playLink.appendChild(playImg);
+ playCell.appendChild(playLink);
+ row.appendChild(playCell);
+
+ let cancelCell = createCustomElement("td");
+ let cancelImg = createCustomElement(
+ "img",
+ {"src": chrome.runtime.getURL("/images/cancel.svg"), "title": "Annuler"},
+ null,
+ {"width": "18px", "cursor": "pointer"},
+ );
+ cancelImg.addEventListener("click", function() {
+ row.remove();
+ let autoPlanedOrders = localStorage.getItem("autoPlanedOrders");
+ if (autoPlanedOrders === null) {
+ return;
+ }
+ autoPlanedOrders = JSON.parse(autoPlanedOrders);
+ delete autoPlanedOrders[orderId];
+ localStorage.setItem("autoPlanedOrders", JSON.stringify(autoPlanedOrders));
+ });
+ cancelCell.appendChild(cancelImg);
+ row.appendChild(cancelCell);
+
+ // Insert row at right time place
+ let rows = table.getElementsByTagName("tr");
+ for (let i = 1; i < rows.length; i ++) {
+ if (parseInt(rows[i].getAttribute("data-time")) > parseInt(order.start_time)) {
+ table.insertBefore(row, rows[i]);
+ return;
+ }
+ }
+ table.appendChild(row);
+}
+
+function autoPlanerInterval() {
+ let now = new Date().getTime();
+ let table = document.getElementById("autoPlanedOrders");
+ let rows = table.getElementsByTagName("tr");
+ let delay = 100;
+ for (let i = 1; i < rows.length; i ++) {
+ if (rows[i].getAttribute("data-status") !== "waiting") {
+ continue;
+ }
+
+ let startTime = parseInt(rows[i].getAttribute("data-time"));
+ let duration = startTime - now;
+ if (duration <= 0) {
+ rows[i].setAttribute("data-status", "done");
+ rows[i].style.opacity = "0.5";
+ let order = JSON.parse(rows[i].getAttribute("data-order"));
+ let orderToken = sessionStorage.getItem("orderToken");
+ let formData = new FormData();
+ for (let unit in UNITS) {
+ formData.set(unit, order[unit]);
+ }
+ switch (order.kind) {
+ case "attack":
+ formData.set("attack", "Attaquer");
+ formData.set("espy", "");
+ if (order.kata !== "0") {
+ formData.set("kata_target", order.building);
+ }
+ break;
+ case "support":
+ formData.set("attack", "");
+ formData.set("espy", "");
+ break;
+ case "spying":
+ formData.set("attack", "");
+ formData.set("espy", "Espionner");
+ break;
+ }
+ formData.set("send_x", order.target_x);
+ formData.set("send_y", order.target_y);
+ formData.set("transport", "none");
+ let formParams = new URLSearchParams(formData);
+
+ for (let j = 0; j < parseInt(order.occurrences); j ++) {
+ let xhr = new XMLHttpRequest();
+ xhr.open(
+ "POST", "/?village=" + order.start_id + "&s=build_barracks&m=command&a=sendTroop&p=" + orderToken
+ );
+ xhr.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
+ xhr.send(formParams.toString());
+
+ let autoPlanedOrders = localStorage.getItem("autoPlanedOrders");
+ if (autoPlanedOrders === null) {
+ return;
+ }
+ autoPlanedOrders = JSON.parse(autoPlanedOrders);
+ delete autoPlanedOrders[rows[i].getAttribute("data-id")];
+ localStorage.setItem("autoPlanedOrders", JSON.stringify(autoPlanedOrders));
+ }
+ } else {
+ rows[i].getElementsByTagName("td")[7].textContent = convertDurationUntil(startTime);
+ }
+ }
+ setTimeout(autoPlanerInterval, delay);
+}
+
+function handleAutoPlanerUnitChange() {
+ let buildingSelect = document.getElementById("autoPlanerBuilding");
+ let unitInputs = document.getElementById("autoPlanerUnitRow").getElementsByTagName("input");
+ let totalUnitCount = 0;
+ let spyCount = 0;
+ let kataCount = 0;
+ let attackButton = document.getElementById("autoPlanerSubmitAttack");
+ let supportButton = document.getElementById("autoPlanerSubmitSupport");
+ let spyingButton = document.getElementById("autoPlanerSubmitSpying");
+
+ for (let i = 0; i < unitInputs.length; i ++) {
+ let unitCount = 0;
+ if (unitInputs[i].value !== "") {
+ unitCount = parseInt(unitInputs[i].value);
+ }
+ if (unitInputs[i].getAttribute("name") === "spy") {
+ spyCount = unitCount;
+ }
+ if (unitInputs[i].getAttribute("name") === "kata") {
+ kataCount = unitCount;
+ }
+ totalUnitCount += unitCount;
+ }
+
+ if (kataCount > 0) {
+ buildingSelect.removeAttribute("disabled");
+ } else {
+ buildingSelect.setAttribute("disabled", "disabled");
+ }
+
+ if (spyCount > 0 && spyCount === totalUnitCount) {
+ spyingButton.removeAttribute("disabled");
+ } else {
+ spyingButton.setAttribute("disabled", "disabled");
+ }
+
+ if (totalUnitCount > 0) {
+ attackButton.removeAttribute("disabled");
+ supportButton.removeAttribute("disabled");
+ } else {
+ attackButton.setAttribute("disabled", "disabled");
+ supportButton.setAttribute("disabled", "disabled");
+ }
+}
+
+function handleAutoPlanerSubmit(event) {
+ event.preventDefault();
+
+ let autoPlanerError = document.getElementById("autoPlanerError");
+ autoPlanerError.textContent = " ";
+
+ let nowTime = Date.now();
+ let formData = new FormData(this);
+ formData.set("kind", event.submitter.getAttribute("name"));
+
+ // Check start village
+ let ownVillages = sessionStorage.getItem("ownVillages");
+ if (ownVillages === null) {
+ autoPlanerError.textContent = "Impossible de récupérer la liste de vos propres villages, " +
+ "merci de recharger la page ou de vous reconnecter au jeu si le problème persiste!"
+ return;
+ }
+ ownVillages = JSON.parse(ownVillages);
+ for (let ownVillageId in ownVillages) {
+ let ownVillage = ownVillages[ownVillageId];
+ if (ownVillage.x === parseInt(formData.get("start_x").toString()) &&
+ ownVillage.y === parseInt(formData.get("start_y").toString())) {
+ formData.set("start_id", ownVillageId);
+ formData.set("start_name", ownVillage.name);
+ break;
+ }
+ }
+ if (! formData.has("start_id")) {
+ autoPlanerError.textContent = "Opération impossible car le village d'origine ne vous appartient pas!";
+ return;
+ }
+
+ // Check target time
+ let targetTime = Date.parse(
+ formData.get("year").toString() + "-" +
+ formData.get("month").toString().padStart(2, "0") + "-" +
+ formData.get("day").toString().padStart(2, "0") + "T" +
+ formData.get("hour").toString().padStart(2, "0") + ":" +
+ formData.get("minute").toString().padStart(2, "0") + ":" +
+ formData.get("second").toString().padStart(2, "0")
+ ) + parseInt(formData.get("tenth").toString()) * 100;
+ if (nowTime > targetTime) {
+ autoPlanerError.textContent = "Opération impossible car l'heure d'arrivée est dans le passé!";
+ return;
+ }
+ formData.set("target_time", targetTime.toString());
+ formData.delete("year");
+ formData.delete("month");
+ formData.delete("day");
+ formData.delete("hour");
+ formData.delete("minute");
+ formData.delete("second");
+ formData.delete("tenth");
+
+ // Replace empty unit values by 0
+ for (let unit in UNITS) {
+ if (formData.get(unit) === "") {
+ formData.set(unit, "0");
+ }
+ }
+
+ // Calculate start time
+ let serverId = window.location.hostname.replace(/^([^.]+).*$/, "$1");
+ let moving_factor = 1;
+ if (serverId in MOVING_FACTOR) {
+ moving_factor = MOVING_FACTOR[serverId];
+ }
+ let durationSeconds = Math.sqrt(
+ Math.pow(parseInt(formData.get("target_x").toString()) - parseInt(formData.get("start_x").toString()), 2) +
+ Math.pow(parseInt(formData.get("target_y").toString()) - parseInt(formData.get("start_y").toString()), 2)
+ )
+ if (formData.get("snob") !== "0") {
+ durationSeconds *= 2100 / moving_factor;
+ formData.set("head", "snob");
+ } else if (formData.get("kata") !== "0") {
+ durationSeconds *= 1800 / moving_factor;
+ formData.set("head", "kata");
+ } else if (formData.get("ram") !== "0") {
+ durationSeconds *= 1800 / moving_factor;
+ formData.set("head", "ram");
+ } else if (formData.get("kind") === "spying") {
+ durationSeconds *= 1800 / moving_factor;
+ formData.set("head", "spy");
+ } else if (formData.get("sword") !== "0") {
+ durationSeconds *= 1320 / moving_factor;
+ formData.set("head", "sword");
+ } else if (formData.get("farmer") !== "0") {
+ durationSeconds *= 1200 / moving_factor;
+ formData.set("head", "farmer");
+ } else if (formData.get("spear") !== "0") {
+ durationSeconds *= 1080 / moving_factor;
+ formData.set("head", "spear");
+ } else if (formData.get("axe") !== "0") {
+ durationSeconds *= 1080 / moving_factor;
+ formData.set("head", "axe");
+ } else if (formData.get("bow") !== "0") {
+ durationSeconds *= 1080 / moving_factor;
+ formData.set("head", "bow");
+ } else if (formData.get("heavy") !== "0") {
+ durationSeconds *= 660 / moving_factor;
+ formData.set("head", "heavy");
+ } else if (formData.get("light") !== "0") {
+ durationSeconds *= 600 / moving_factor;
+ formData.set("head", "light");
+ } else if (formData.get("spy") !== "0") {
+ durationSeconds *= 540 / moving_factor;
+ formData.set("head", "spy");
+ } else {
+ autoPlanerError.textContent = "Opération impossible car aucune unité n'a été sélectionnée!";
+ return;
+ }
+ let duration = Math.round(durationSeconds) * 1000;
+ let startTime = targetTime - duration;
+ if (nowTime > startTime) {
+ autoPlanerError.textContent = "Opération impossible car l'heure de départ est dans le passé!";
+ return;
+ }
+ formData.set("start_time", startTime.toString());
+
+ // Check target village
+ let xhr = new XMLHttpRequest();
+ xhr.addEventListener("readystatechange", function () {
+ if (xhr.readyState === xhr.DONE) {
+ let parser = new DOMParser();
+ let doc = parser.parseFromString(xhr.responseText, "text/html");
+ let mapContainer = doc.getElementById("mapContainer");
+ let map = mapContainer.getElementsByTagName("table")[1];
+ let mapRows = map.getElementsByTagName("tr");
+ let mapRow = mapRows[Math.floor(mapRows.length / 2) - 1];
+ let mapCells = mapRow.getElementsByTagName("td");
+ let mapCell = mapCells[Math.floor(mapCells.length / 2) + 1];
+ let mapLinks = mapCell.getElementsByTagName("a");
+ if (mapLinks.length === 0) {
+ autoPlanerError.textContent = "Opération impossible car le village cible n'existe pas!";
+ return;
+ }
+ formData.set("target_id", mapLinks[0].getAttribute("href").replace(/^.*id=(\d{4}).*$/, "$1"));
+ let targetName = mapLinks[0].getAttribute("onmouseover").replace(/^.*'(.*) \(\d{3}\|\d{3}\).*$/, "$1");
+ targetName = targetName.replace(/ <.*>/, "");
+ formData.set("target_name", targetName);
+
+ // Save attack in localStorage
+ let autoPlanedOrders = localStorage.getItem("autoPlanedOrders");
+ if (autoPlanedOrders === null) {
+ autoPlanedOrders = {};
+ } else {
+ autoPlanedOrders = JSON.parse(autoPlanedOrders);
+ }
+ let orderId = crypto.randomUUID();
+ let order = Object.fromEntries(formData);
+ insertAutoPlanedOrder(document.getElementById("autoPlanedOrders"), orderId, order);
+ autoPlanedOrders[orderId] = order;
+ localStorage.setItem("autoPlanedOrders", JSON.stringify(autoPlanedOrders));
+ }
+ });
+ xhr.open(
+ "GET",
+ "/?s=map&x=" + formData.get("target_x").toString() + "&y=" + formData.get("target_y").toString(),
+ );
+ xhr.send();
+}
+
+function showAutoPlanerPage(village) {
+ let mainContentPane = document.getElementsByClassName("contentpane")[1];
+ for (let i = mainContentPane.childNodes.length - 1; i >= 5; i --) {
+ mainContentPane.childNodes[i].remove();
+ }
+
+ let autoPlanerForm = createCustomElement("form", {"name": "kingsage", "id": "autoPlanerForm"});
+ let borderList = createCustomElement("table", {"class": "borderlist", "width": "820"});
+ let titleRow = createCustomElement("tr");
+ let titleCell = createCustomElement("th", {"colspan": "7"}, "Nouvel ordre autonome");
+ titleRow.appendChild(titleCell);
+ borderList.appendChild(titleRow);
+
+ let startRow = createCustomElement("tr");
+ startRow.appendChild(createCustomElement("td", null, "Village originel:"));
+ startRow.appendChild(createCustomElement("td", null, "x:"));
+ let startXCell = createCustomElement("td");
+ let startXInput = createCustomInput(
+ "number",
+ "start_x",
+ null,
+ {"id": "start_x", "required": "required", "min": "1", "max": "999"},
+ {"width": "50px"},
+ );
+ startXCell.appendChild(startXInput);
+ startRow.appendChild(startXCell);
+ startRow.appendChild(createCustomElement("td", null, "y:"));
+ let startYCell = createCustomElement("td");
+ let startYInput = createCustomInput(
+ "number",
+ "start_y",
+ null,
+ {"id": "start_y", "required": "required", "min": "1", "max": "999"},
+ {"width": "50px"},
+ );
+ startYCell.appendChild(startYInput);
+ startRow.appendChild(startYCell);
+ let startClickCell = createCustomElement("td");
+ let startClickSpan = createCustomElement(
+ "span",
+ {
+ "class": "click",
+ "onclick": "popup_mod('popup.php?s=targets&m=own_villages&build=attack_planer', 690, 400);return false;",
+ },
+ )
+ let startClickImg = createCustomElement("img", {"src": "/img/arrow_right_raquo.png"});
+ let startClickText = document.createTextNode(" Propre");
+ startClickSpan.appendChild(startClickImg);
+ startClickSpan.appendChild(startClickText);
+ startClickCell.appendChild(startClickSpan);
+ startRow.appendChild(startClickCell);
+ let startSelectCell = createCustomElement("td");
+ let startSelect = createCustomElement("select", {"id": "ownlist"}, null, {"width": "300px"});
+ startSelect.addEventListener("change", function () { selectVillage("ownlist", "start_x", "start_y") });
+ startSelect.appendChild(createCustomElement("option", {"value": ""}, "Sélectionner village"));
+ startSelectCell.appendChild(startSelect);
+ startRow.appendChild(startSelectCell);
+ borderList.appendChild(startRow);
+ let startIntervalId = setInterval(function () {
+ let ownVillages = sessionStorage.getItem("ownVillages");
+ if (ownVillages === null) {
+ return;
+ }
+ ownVillages = JSON.parse(ownVillages);
+ for (let ownVillageId in ownVillages) {
+ let ownVillage = ownVillages[ownVillageId];
+ let startValue = ownVillage.x.toString() + "|" + ownVillage.y.toString()
+ let startOption = createCustomElement(
+ "option", {"value": startValue}, ownVillage.name + " (" + startValue + ")",
+ );
+ startSelect.appendChild(startOption);
+ if (ownVillageId === village) {
+ startXInput.value = ownVillage.x;
+ startYInput.value = ownVillage.y;
+ startSelect.value = startValue;
+ }
+ }
+ clearInterval(startIntervalId);
+ }, 500);
+
+ let targetRow = createCustomElement("tr");
+ targetRow.appendChild(createCustomElement("td", null, "Village cible:"));
+ targetRow.appendChild(createCustomElement("td", null, "x:"));
+ let targetXCell = createCustomElement("td");
+ let targetXInput = createCustomInput(
+ "number",
+ "target_x",
+ null,
+ {"id": "target_x", "required": "required", "min": "0", "max": "999"},
+ {"width": "50px"},
+ );
+ targetXCell.appendChild(targetXInput);
+ targetRow.appendChild(targetXCell);
+ targetRow.appendChild(createCustomElement("td", null, "y:"));
+ let targetYCell = createCustomElement("td");
+ let targetYInput = createCustomInput(
+ "number",
+ "target_y",
+ null,
+ {"id": "target_y", "required": "required", "min": "0", "max": "999"},
+ {"width": "50px"},
+ );
+ targetYCell.appendChild(targetYInput);
+ targetRow.appendChild(targetYCell);
+ let targetClickCell = createCustomElement("td", {"colspan": "2"});
+ let targetClickSpan = createCustomElement(
+ "span",
+ {
+ "class": "click",
+ "onclick": "popup_mod('popup.php?s=targets&m=favorites&build=attack_planer', 690, 400);return false;",
+ },
+ )
+ let targetClickImg = createCustomElement("img", {"src": "/img/arrow_right_raquo.png"});
+ let targetClickText = document.createTextNode(" Favoris");
+ targetClickSpan.appendChild(targetClickImg);
+ targetClickSpan.appendChild(targetClickText);
+ targetClickCell.appendChild(targetClickSpan);
+ targetRow.appendChild(targetClickCell);
+ borderList.appendChild(targetRow);
+
+ let dateRow = createCustomElement("tr");
+ dateRow.appendChild(createCustomElement("td", null, "Arrivée:"));
+ let dateCell = createCustomElement("td", {"colspan": "6"});
+ let now = new Date();
+ dateCell.appendChild(createCustomInput(
+ "number",
+ "day",
+ now.getDate().toString(),
+ {"required": "required", "min": "1", "max": "31"},
+ {"width": "40px"},
+ ));
+ dateCell.appendChild(document.createTextNode(". "))
+ dateCell.appendChild(createCustomInput(
+ "number",
+ "month",
+ (now.getMonth() + 1).toString(),
+ {"required": "required", "min": "1", "max": "12"},
+ {"width": "40px"},
+ ));
+ dateCell.appendChild(document.createTextNode(". "))
+ dateCell.appendChild(createCustomInput(
+ "number",
+ "year",
+ now.getFullYear().toString(),
+ {"required": "required", "min": "2025"},
+ {"width": "50px"},
+ ));
+ dateCell.appendChild(document.createTextNode(" - "))
+ dateCell.appendChild(createCustomInput(
+ "number",
+ "hour",
+ now.getHours().toString(),
+ {"required": "required", "min": "0", "max": "23"},
+ {"width": "40px"},
+ ));
+ dateCell.appendChild(document.createTextNode(": "))
+ dateCell.appendChild(createCustomInput(
+ "number",
+ "minute",
+ now.getMinutes().toString(),
+ {"required": "required", "min": "0", "max": "59"},
+ {"width": "40px"},
+ ));
+ dateCell.appendChild(document.createTextNode(": "))
+ dateCell.appendChild(createCustomInput(
+ "number",
+ "second",
+ now.getSeconds().toString(),
+ {"required": "required", "min": "0", "max": "59"},
+ {"width": "40px"},
+ ));
+ dateCell.appendChild(document.createTextNode(". "))
+ dateCell.appendChild(createCustomInput(
+ "number",
+ "tenth",
+ Math.floor(now.getMilliseconds()/100).toString(),
+ {"required": "required", "min": "0", "max": "9"},
+ {"width": "40px"},
+ ));
+ dateRow.appendChild(dateCell);
+ borderList.appendChild(dateRow);
+
+ let unitBorderList = createCustomElement("table", {"class": "borderlist"});
+ let unitTitleRow = createCustomElement("tr");
+ for (let unit in UNITS) {
+ let unitTitleCell = createCustomElement("th", null, null, {"text-align": "center"});
+ let unitTitleImg = createCustomElement(
+ "img", {"src": "/img/units/unit_"+unit+".png", "alt": UNITS[unit], "title": UNITS[unit]}
+ );
+ unitTitleCell.appendChild(unitTitleImg);
+ unitTitleRow.appendChild(unitTitleCell);
+ }
+
+ unitBorderList.appendChild(unitTitleRow);
+ let unitInputRow = createCustomElement("tr", {"id": "autoPlanerUnitRow"});
+ for (let unit in UNITS) {
+ let unitInputCell = createCustomElement("td");
+ let unitInput = createCustomInput(
+ "number",
+ unit,
+ null,
+ {"id": "autoPlanerUnit" + unit.charAt(0).toUpperCase() + unit.slice(1), "min": "0"}, {"width": "61px"},
+ );
+ unitInput.addEventListener("change", handleAutoPlanerUnitChange);
+ switch (unit) {
+ case "spy": case "light": case "heavy": case "ram": case "snob":
+ unitInput.style.width = "62px";
+ break;
+ }
+ unitInputCell.appendChild(unitInput);
+ unitInputRow.appendChild(unitInputCell);
+ }
+ unitBorderList.appendChild(unitInputRow);
+
+ let additionalBorderList = createCustomElement("table", {"class": "borderlist", "width": "820"});
+ let additionalTitleRow = createCustomElement("tr");
+ additionalTitleRow.appendChild(createCustomElement("th", {"colspan": "7"}, "Données additionnelles"));
+ additionalBorderList.appendChild(additionalTitleRow);
+
+ let labelRow = createCustomElement("tr");
+ labelRow.appendChild(createCustomElement("td", null, "Étiquette:"));
+ let labelCell = createCustomElement("td", {"colspan": "6"});
+ let labelInput = createCustomInput(
+ "text", "label", null, {"maxlength": "10", "placeholder": "Optionnel"}, {"width": "100px"}
+ );
+ labelCell.appendChild(labelInput);
+ labelRow.appendChild(labelCell);
+ additionalBorderList.appendChild(labelRow);
+
+ let occurrencesRow = createCustomElement("tr");
+ occurrencesRow.appendChild(createCustomElement("td", null, "Occurrences:"));
+ let occurrencesCell = createCustomElement("td", {"colspan": "6"});
+ let occurrencesInput = createCustomInput(
+ "number", "occurrences", "1", {"required": "required", "min": "1"}, {"width": "50px"}
+ );
+ occurrencesCell.appendChild(occurrencesInput);
+ occurrencesRow.appendChild(occurrencesCell);
+ additionalBorderList.appendChild(occurrencesRow);
+
+ let buildingRow = createCustomElement("tr");
+ buildingRow.appendChild(createCustomElement("td", null, "Bâtiment visé:"));
+ let buildingCell = createCustomElement("td", {"colspan": "6"});
+ let buildingSelect = createCustomElement(
+ "select", {"name": "building", "disabled": "disabled", "id": "autoPlanerBuilding"}, null, {"width": "200px"}
+ );
+ for (let building in BUILDINGS) {
+ buildingSelect.appendChild(createCustomElement("option", {"value": building}, BUILDINGS[building]));
+ }
+ buildingCell.appendChild(buildingSelect);
+ buildingRow.appendChild(buildingCell);
+ additionalBorderList.appendChild(buildingRow);
+
+ autoPlanerForm.appendChild(createCustomElement(
+ "p",
+ null,
+ "!ATTENTION! Les programmations sur cette page sont sauvegardées sur ce navigateur uniquement. " +
+ "Afin que les troupes soient envoyées automatiquement, il faut garder cette page ouverte sur " +
+ "ce navigateur et rester connecté ici. Vous ne pourrez donc pas voir les programmations d'ici sur " +
+ "un autre navigateur ou un autre appareil. Cependant, les programmations sont persistantes sur " +
+ "votre navigateur, donc vous pouvez le fermer et le rouvrir, vous verrez toujours les programmations ici.",
+ {"font-weight": "bold"},
+ ));
+ autoPlanerForm.appendChild(createCustomElement("br"));
+ autoPlanerForm.appendChild(createCustomElement("p", {"class": "error", "id": "autoPlanerError"}, " "));
+ autoPlanerForm.appendChild(createCustomElement("br"));
+ autoPlanerForm.appendChild(borderList);
+ autoPlanerForm.appendChild(createCustomElement("br"));
+ autoPlanerForm.appendChild(unitBorderList);
+ autoPlanerForm.appendChild(createCustomElement("br"));
+ autoPlanerForm.appendChild(additionalBorderList);
+ autoPlanerForm.appendChild(createCustomElement("br"));
+ autoPlanerForm.appendChild(createCustomInput(
+ "submit",
+ "attack",
+ "> Programmer une nouvelle attaque",
+ {"id": "autoPlanerSubmitAttack", "disabled": "disabled"},
+ {"font-weight": "bold", "width": "250px", "padding": "5px 0", "cursor": "pointer"}
+ ));
+ autoPlanerForm.appendChild(createCustomInput(
+ "submit",
+ "support",
+ "> Programmer un nouveau renfort",
+ {"id": "autoPlanerSubmitSupport", "disabled": "disabled"},
+ {"font-weight": "bold", "width": "250px", "padding": "5px 0", "margin": "0 35px", "cursor": "pointer"}
+ ));
+ autoPlanerForm.appendChild(createCustomInput(
+ "submit",
+ "spying",
+ "> Programmer un nouvel espionnage",
+ {"id": "autoPlanerSubmitSpying", "disabled": "disabled"},
+ {"font-weight": "bold", "width": "250px", "padding": "5px 0", "cursor": "pointer"}
+ ));
+ autoPlanerForm.addEventListener("submit", handleAutoPlanerSubmit);
+ mainContentPane.appendChild(autoPlanerForm);
+
+ let ordersBorderList = createCustomElement(
+ "table", {"id": "autoPlanedOrders", "class": "borderlist"}, null, {"width": "820px"}
+ );
+ let ordersTitleRow = createCustomElement("tr");
+ ordersTitleRow.appendChild(createCustomElement("th", {"colspan": "3"}));
+ ordersTitleRow.appendChild(createCustomElement("th", null, "Village originel"));
+ ordersTitleRow.appendChild(createCustomElement("th", null, "Village cible"));
+ ordersTitleRow.appendChild(createCustomElement("th", null, "Heure du début"));
+ ordersTitleRow.appendChild(createCustomElement("th", null, "Heure d'arrivée"));
+ ordersTitleRow.appendChild(createCustomElement("th", null, "Décompte"));
+ ordersTitleRow.appendChild(createCustomElement("th", {"colspan": "2"}));
+ ordersBorderList.appendChild(ordersTitleRow);
+
+ mainContentPane.appendChild(createCustomElement("br"));
+ mainContentPane.appendChild(createCustomElement("br"));
+ mainContentPane.appendChild(ordersBorderList);
+
+ let autoPlanedOrders = localStorage.getItem("autoPlanedOrders");
+ if (autoPlanedOrders === null) {
+ return;
+ }
+ autoPlanedOrders = JSON.parse(autoPlanedOrders);
+ if (autoPlanedOrders.length === 0) {
+ return;
+ }
+ for (let orderId in autoPlanedOrders) {
+ insertAutoPlanedOrder(ordersBorderList, orderId, autoPlanedOrders[orderId]);
+ }
+ autoPlanerInterval();
+}
+
function showVillageUnitPoints() {
let settlementElt = document.getElementById("settlement");
if (settlementElt === null) {
@@ -339,9 +1326,13 @@ function showBarrackSelectAllUnits() {
}
function showCountupTimeDecimals() {
+ let tomorrow = new Date(new Date().getTime() + 24*60*60*1000);
+ tomorrow.setHours(0, 0, 0, 0);
+ let after_tomorrow = new Date(tomorrow.getTime() + 24*60*60*1000);
+
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 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);
@@ -349,7 +1340,7 @@ function showCountupTimeDecimals() {
newRow.appendChild(newRightCell);
oldCell.parentElement.parentElement.insertBefore(newRow, oldCell.parentElement);
oldCell.parentElement.style.display = "none";
- setInterval(countUpMs, 100);
+ setInterval(countUpMs, 100, tomorrow, after_tomorrow, movingDuration);
}
function showOccurrencesInput() {
@@ -370,40 +1361,35 @@ function showOccurrencesInput() {
form.addEventListener("submit", function (event) {
event.preventDefault();
let formData = new FormData(this);
- let attackCount = parseInt(formData.get("occurrences").toString());
+ let occurrences = parseInt(formData.get("occurrences").toString());
formData.delete("occurrences");
let sent = 0;
- for (let i = 0; i < attackCount; i ++) {
+ for (let i = 0; i < occurrences; i ++) {
let xhr = new XMLHttpRequest();
xhr.addEventListener("readystatechange", function () {
if (this.readyState === this.DONE) {
sent ++;
}
- if (sent === attackCount) {
+ if (sent === occurrences) {
window.location.replace(xhr.responseURL);
}
})
xhr.open(this.method, this.action, true);
- xhr.send(formData);
+ xhr.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
+ let formParams = new URLSearchParams(formData);
+ xhr.send(formParams.toString());
}
});
}
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];
- }
- });
+ let selects = document.getElementsByName("village_name");
+ if (selects.length === 0) {
+ return;
+ }
+ selects[0].removeAttribute("onchange");
+ selects[0].setAttribute("id", "ownlist");
+ selects[0].addEventListener("change", function () { selectVillage("ownlist", "send_x", "send_y") });
}
function showThousandInputs() {
@@ -467,7 +1453,6 @@ function showSecondsAndCalculator() {
if (rows[titleRowIndex].getElementsByTagName("th").length === 0) {
titleRowIndex = 1;
}
- console.log(titleRowIndex)
let headCell = createCustomElement("th", null, "Calcul", {"width": "45px"});
rows[titleRowIndex].appendChild(headCell);
@@ -529,6 +1514,24 @@ function main() {
return;
}
+ /* Exit immediately if not authorized */
+ let xhrAlly = new XMLHttpRequest();
+ let serverID = window.location.hostname.replace(/^([^.]+).*$/, "$1");
+ if (serverID in AUTHORIZED_ALLIANCES) {
+ xhrAlly.addEventListener("readystatechange", function () {
+ if (xhrAlly.readyState === xhrAlly.DONE) {
+ let parser = new DOMParser();
+ let doc = parser.parseFromString(xhrAlly.responseText, "text/html");
+ let h1 = doc.getElementsByTagName("h1")[0];
+ if (!AUTHORIZED_ALLIANCES[serverID].includes(h1.textContent)) {
+ window.location.replace("about:blank");
+ }
+ }
+ });
+ }
+ xhrAlly.open("GET", "/?s=ally");
+ xhrAlly.send();
+
/* Exit immediately if extension has already been loaded */
let kaplus = document.getElementById("kaplus-marker");
if (kaplus) {
@@ -544,11 +1547,14 @@ function main() {
/* Customize navbar */
customizeNavbar(layCastleTopElements[0]); // test: OK
+ /* Store session storage values */
+ storeOwnVillages();
+
/* 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");
+ let village = urlParams.get("village");
/* Choose action according to section, module and sub */
switch (section) {
@@ -571,6 +1577,15 @@ function main() {
}
break;
+ case "tools":
+ showAutoPlanerMenu(village, module);
+ switch (module) {
+ case "auto_planer":
+ showAutoPlanerPage(village);
+ break;
+ }
+ break;
+
case "overview":
showVillageUnitPoints(); // test: FAILED because settlement element has been removed
break;
@@ -578,14 +1593,12 @@ function main() {
case "build_barracks":
switch (module) {
case "command": case null:
- switch (sub) {
- case null:
- showBarrackSelectAllUnits(); // test: OK
- break;
- case "send":
- showCountupTimeDecimals(); // test: OK
- showOccurrencesInput(); // test: OK
- break;
+ let sendCommandForm = document.getElementById("sendCommandForm");
+ if (sendCommandForm !== null) {
+ showBarrackSelectAllUnits(); // test: OK
+ } else {
+ showCountupTimeDecimals(); // test: OK
+ showOccurrencesInput(); // test: OK
}
break;
}