diff --git a/src/controllers/custom/configController.ts b/src/controllers/custom/configController.ts new file mode 100644 index 00000000..2c1e10ac --- /dev/null +++ b/src/controllers/custom/configController.ts @@ -0,0 +1,42 @@ +import { RequestHandler } from "express"; +import { config } from "@/src/services/configService"; +import { getAccountForRequest, isAdministrator } from "@/src/services/loginService"; +import { saveConfig } from "@/src/services/configWatcherService"; + +export const getConfigController: RequestHandler = async (req, res) => { + const account = await getAccountForRequest(req); + if (isAdministrator(account)) { + const responseData: Record = {}; + for (const id of req.body as string[]) { + const [obj, idx] = configIdToIndexable(id); + responseData[id] = obj[idx] ?? null; + } + res.json(responseData); + } else { + res.status(401).end(); + } +}; + +export const setConfigController: RequestHandler = async (req, res) => { + const account = await getAccountForRequest(req); + if (isAdministrator(account)) { + for (const [id, value] of Object.entries(req.body as Record)) { + const [obj, idx] = configIdToIndexable(id); + obj[idx] = value; + } + await saveConfig(); + res.end(); + } else { + res.status(401).end(); + } +}; + +const configIdToIndexable = (id: string): [Record, string] => { + let obj = config as unknown as Record; + const arr = id.split("."); + while (arr.length > 1) { + obj = obj[arr[0]]; + arr.splice(0, 1); + } + return [obj, arr[0]]; +}; diff --git a/src/controllers/custom/getConfigDataController.ts b/src/controllers/custom/getConfigDataController.ts deleted file mode 100644 index 12208527..00000000 --- a/src/controllers/custom/getConfigDataController.ts +++ /dev/null @@ -1,14 +0,0 @@ -import { RequestHandler } from "express"; -import { config } from "@/src/services/configService"; -import { getAccountForRequest, isAdministrator } from "@/src/services/loginService"; - -const getConfigDataController: RequestHandler = async (req, res) => { - const account = await getAccountForRequest(req); - if (isAdministrator(account)) { - res.json(config); - } else { - res.status(401).end(); - } -}; - -export { getConfigDataController }; diff --git a/src/controllers/custom/updateConfigDataController.ts b/src/controllers/custom/updateConfigDataController.ts deleted file mode 100644 index 7c87c372..00000000 --- a/src/controllers/custom/updateConfigDataController.ts +++ /dev/null @@ -1,21 +0,0 @@ -import { RequestHandler } from "express"; -import { saveConfig } from "@/src/services/configWatcherService"; -import { getAccountForRequest, isAdministrator } from "@/src/services/loginService"; -import { config, IConfig } from "@/src/services/configService"; - -export const updateConfigDataController: RequestHandler = async (req, res) => { - const account = await getAccountForRequest(req); - if (isAdministrator(account)) { - const data = req.body as IUpdateConfigDataRequest; - config[data.key] = data.value; - await saveConfig(); - res.end(); - } else { - res.status(401).end(); - } -}; - -interface IUpdateConfigDataRequest { - key: keyof IConfig; - value: never; -} diff --git a/src/routes/custom.ts b/src/routes/custom.ts index 5ed4906e..e10bc721 100644 --- a/src/routes/custom.ts +++ b/src/routes/custom.ts @@ -25,8 +25,7 @@ import { manageQuestsController } from "@/src/controllers/custom/manageQuestsCon import { setEvolutionProgressController } from "@/src/controllers/custom/setEvolutionProgressController"; import { setBoosterController } from "@/src/controllers/custom/setBoosterController"; -import { getConfigDataController } from "@/src/controllers/custom/getConfigDataController"; -import { updateConfigDataController } from "@/src/controllers/custom/updateConfigDataController"; +import { getConfigController, setConfigController } from "@/src/controllers/custom/configController"; const customRouter = express.Router(); @@ -55,7 +54,7 @@ customRouter.post("/manageQuests", manageQuestsController); customRouter.post("/setEvolutionProgress", setEvolutionProgressController); customRouter.post("/setBooster", setBoosterController); -customRouter.get("/config", getConfigDataController); -customRouter.post("/config", updateConfigDataController); +customRouter.post("/getConfig", getConfigController); +customRouter.post("/setConfig", setConfigController); export { customRouter }; diff --git a/static/webui/index.html b/static/webui/index.html index caf7be01..befa3e1d 100644 --- a/static/webui/index.html +++ b/static/webui/index.html @@ -568,10 +568,10 @@
-
+

-
+
@@ -807,6 +807,27 @@
+
+
+
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+
diff --git a/static/webui/script.js b/static/webui/script.js index 91cc54a1..59e011a8 100644 --- a/static/webui/script.js +++ b/static/webui/script.js @@ -1847,16 +1847,16 @@ function doAcquireMod() { } } -const uiConfigs = [...$("#server-settings input[id]")].map(x => x.id); +const uiConfigs = [...$(".config-form input[id]")].map(x => x.id); for (const id of uiConfigs) { const elm = document.getElementById(id); if (elm.type == "checkbox") { elm.onchange = function () { $.post({ - url: "/custom/config?" + window.authz, + url: "/custom/setConfig?" + window.authz, contentType: "application/json", - data: JSON.stringify({ key: id, value: this.checked }) + data: JSON.stringify({ [id]: this.checked }) }).then(() => { if (["infiniteCredits", "infinitePlatinum", "infiniteEndo", "infiniteRegalAya"].indexOf(id) != -1) { updateInventory(); @@ -1869,9 +1869,9 @@ for (const id of uiConfigs) { function doSaveConfig(id) { const elm = document.getElementById(id); $.post({ - url: "/custom/config?" + window.authz, + url: "/custom/setConfig?" + window.authz, contentType: "application/json", - data: JSON.stringify({ key: id, value: parseInt(elm.value) }) + data: JSON.stringify({ [id]: parseInt(elm.value) }) }); } @@ -1882,36 +1882,36 @@ single.getRoute("/webui/cheats").on("beforeload", function () { interval = setInterval(() => { if (window.authz) { clearInterval(interval); - fetch("/custom/config?" + window.authz).then(async res => { - if (res.status == 200) { - //window.is_admin = true; - $("#server-settings-no-perms").addClass("d-none"); - $("#server-settings").removeClass("d-none"); - res.json().then(json => - Object.entries(json).forEach(entry => { - const [key, value] = entry; - var x = document.getElementById(`${key}`); - if (x != null) { - if (x.type == "checkbox") { - x.checked = value; - } else if (x.type == "number") { - x.setAttribute("value", `${value}`); - } - } - }) - ); - } else { - if ((await res.text()) == "Log-in expired") { - revalidateAuthz().then(() => { - if (single.getCurrentPath() == "/webui/cheats") { - single.loadRoute("/webui/cheats"); - } - }); - } else { - //window.is_admin = false; - $("#server-settings-no-perms").removeClass("d-none"); - $("#server-settings").addClass("d-none"); + $.post({ + url: "/custom/getConfig?" + window.authz, + contentType: "application/json", + data: JSON.stringify(uiConfigs) + }).done(json => { + //window.is_admin = true; + $(".config-admin-hide").addClass("d-none"); + $(".config-admin-show").removeClass("d-none"); + Object.entries(json).forEach(entry => { + const [key, value] = entry; + var x = document.getElementById(`${key}`); + if (x != null) { + if (x.type == "checkbox") { + x.checked = value; + } else if (x.type == "number") { + x.setAttribute("value", `${value}`); + } } + }); + }).fail(res => { + if (res.responseText == "Log-in expired") { + revalidateAuthz().then(() => { + if (single.getCurrentPath() == "/webui/cheats") { + single.loadRoute("/webui/cheats"); + } + }); + } else { + //window.is_admin = false; + $(".config-admin-hide").removeClass("d-none"); + $(".config-admin-show").addClass("d-none"); } }); } diff --git a/static/webui/translations/de.js b/static/webui/translations/de.js index a56103b6..2df6337f 100644 --- a/static/webui/translations/de.js +++ b/static/webui/translations/de.js @@ -186,6 +186,13 @@ dict = { cheats_changeSupportedSyndicate: `Unterstütztes Syndikat`, cheats_changeButton: `Ändern`, cheats_none: `Keines`, + + worldState: `[UNTRANSLATED] World State`, + worldState_creditBoost: `[UNTRANSLATED] Credit Boost`, + worldState_affinityBoost: `[UNTRANSLATED] Affinity Boost`, + worldState_resourceBoost: `[UNTRANSLATED] Resource Boost`, + worldState_starDays: `[UNTRANSLATED] Star Days`, + import_importNote: `Du kannst hier eine vollständige oder teilweise Inventarantwort (Client-Darstellung) einfügen. Alle Felder, die vom Importer unterstützt werden, werden in deinem Account überschrieben.`, import_submit: `Absenden`, import_samples: `[UNTRANSLATED] Samples:`, diff --git a/static/webui/translations/en.js b/static/webui/translations/en.js index 36d38301..e3ef116c 100644 --- a/static/webui/translations/en.js +++ b/static/webui/translations/en.js @@ -185,6 +185,13 @@ dict = { cheats_changeSupportedSyndicate: `Supported syndicate`, cheats_changeButton: `Change`, cheats_none: `None`, + + worldState: `World State`, + worldState_creditBoost: `Credit Boost`, + worldState_affinityBoost: `Affinity Boost`, + worldState_resourceBoost: `Resource Boost`, + worldState_starDays: `Star Days`, + import_importNote: `You can provide a full or partial inventory response (client respresentation) here. All fields that are supported by the importer will be overwritten in your account.`, import_submit: `Submit`, import_samples: `Samples:`, diff --git a/static/webui/translations/es.js b/static/webui/translations/es.js index 3fbb7bf1..11512ea0 100644 --- a/static/webui/translations/es.js +++ b/static/webui/translations/es.js @@ -186,6 +186,13 @@ dict = { cheats_changeSupportedSyndicate: `Sindicatos disponibles`, cheats_changeButton: `Cambiar`, cheats_none: `Ninguno`, + + worldState: `[UNTRANSLATED] World State`, + worldState_creditBoost: `[UNTRANSLATED] Credit Boost`, + worldState_affinityBoost: `[UNTRANSLATED] Affinity Boost`, + worldState_resourceBoost: `[UNTRANSLATED] Resource Boost`, + worldState_starDays: `[UNTRANSLATED] Star Days`, + import_importNote: `Puedes proporcionar una respuesta de inventario completa o parcial (representación del cliente) aquí. Todos los campos compatibles con el importador serán sobrescritos en tu cuenta.`, import_submit: `Enviar`, import_samples: `Muestras:`, diff --git a/static/webui/translations/fr.js b/static/webui/translations/fr.js index a52f5bef..a74aa010 100644 --- a/static/webui/translations/fr.js +++ b/static/webui/translations/fr.js @@ -186,6 +186,13 @@ dict = { cheats_changeSupportedSyndicate: `Allégeance`, cheats_changeButton: `Changer`, cheats_none: `Aucun`, + + worldState: `[UNTRANSLATED] World State`, + worldState_creditBoost: `[UNTRANSLATED] Credit Boost`, + worldState_affinityBoost: `[UNTRANSLATED] Affinity Boost`, + worldState_resourceBoost: `[UNTRANSLATED] Resource Boost`, + worldState_starDays: `[UNTRANSLATED] Star Days`, + import_importNote: `Import manuel. Toutes les modifcations supportées par l'inventaire écraseront celles présentes dans la base de données.`, import_submit: `Soumettre`, import_samples: `Echantillons :`, diff --git a/static/webui/translations/ru.js b/static/webui/translations/ru.js index 26fef974..609ab4f5 100644 --- a/static/webui/translations/ru.js +++ b/static/webui/translations/ru.js @@ -186,6 +186,13 @@ dict = { cheats_changeSupportedSyndicate: `Поддерживаемый синдикат`, cheats_changeButton: `Изменить`, cheats_none: `Отсутствует`, + + worldState: `[UNTRANSLATED] World State`, + worldState_creditBoost: `[UNTRANSLATED] Credit Boost`, + worldState_affinityBoost: `[UNTRANSLATED] Affinity Boost`, + worldState_resourceBoost: `[UNTRANSLATED] Resource Boost`, + worldState_starDays: `[UNTRANSLATED] Star Days`, + import_importNote: `Вы можете загрузить полный или частичный ответ инвентаря (клиентское представление) здесь. Все поддерживаемые поля будут перезаписаны в вашем аккаунте.`, import_submit: `Отправить`, import_samples: `[UNTRANSLATED] Samples:`, diff --git a/static/webui/translations/zh.js b/static/webui/translations/zh.js index ca7f726a..051eef94 100644 --- a/static/webui/translations/zh.js +++ b/static/webui/translations/zh.js @@ -186,6 +186,13 @@ dict = { cheats_changeSupportedSyndicate: `支持的集团`, cheats_changeButton: `更改`, cheats_none: `无`, + + worldState: `[UNTRANSLATED] World State`, + worldState_creditBoost: `[UNTRANSLATED] Credit Boost`, + worldState_affinityBoost: `[UNTRANSLATED] Affinity Boost`, + worldState_resourceBoost: `[UNTRANSLATED] Resource Boost`, + worldState_starDays: `[UNTRANSLATED] Star Days`, + import_importNote: `您可以在此处提供完整或部分库存响应(客户端表示)。支持的所有字段将被覆盖到您的账户中。`, import_submit: `提交`, import_samples: `示例:`,