XFE Git
XFE Studio Git
Git 首页 全局搜索
XFE 主站 文档 NuGet

XFESpaceNinjaServer

A simple server for a small space ninja game

公开
关注 0 Fork 0 Star 0
返回提交历史

XFEstudio/XFESpaceNinjaServer

feat(webui): Vault MiscItems and ShipDecorations (#2889)

Closes #2874 Closes #2875 Reviewed-on: https://onlyg.it/OpenWF/SpaceNinjaServer/pulls/2889 Reviewed-by: Sainan <63328889+sainan@users.noreply.github.com> Co-authored-by: AMelonInsideLemon <166175391+AMelonInsideLemon@users.noreply.github.com> Co-committed-by: AMelonInsideLemon <166175391+AMelonInsideLemon@users.noreply.github.com>

c1c14b20
AMelonInsideLemon <166175391+AMelonInsideLemon@users.noreply.github.com>
提交于

代码差异

13 个文件 +233 -117
Deleted src/controllers/custom/addVaultDecoRecipeController.ts +0 -36
@@ -1,36 +0,0 @@
1 import { getAccountIdForRequest } from "../../services/loginService.ts";
2 import { getInventory } from "../../services/inventoryService.ts";
3 import type { RequestHandler } from "express";
4 import { getGuildForRequestEx, hasGuildPermission } from "../../services/guildService.ts";
5 import { GuildPermission } from "../../types/guildTypes.ts";
6 import type { ITypeCount } from "../../types/commonTypes.ts";
7
8 export const addVaultDecoRecipeController: RequestHandler = async (req, res) => {
9 const accountId = await getAccountIdForRequest(req);
10 const requests = req.body as ITypeCount[];
11 const inventory = await getInventory(accountId, "GuildId");
12 const guild = await getGuildForRequestEx(req, inventory);
13 if (!(await hasGuildPermission(guild, accountId, GuildPermission.Architect))) {
14 res.status(400).send("-1").end();
15 return;
16 }
17 guild.VaultDecoRecipes ??= [];
18 for (const request of requests) {
19 const index = guild.VaultDecoRecipes.findIndex(x => x.ItemType === request.ItemType);
20
21 if (index == -1) {
22 guild.VaultDecoRecipes.push({
23 ItemType: request.ItemType,
24 ItemCount: request.ItemCount
25 });
26 } else {
27 guild.VaultDecoRecipes[index].ItemCount += request.ItemCount;
28
29 if (guild.VaultDecoRecipes[index].ItemCount < 1) {
30 guild.VaultDecoRecipes.splice(index, 1);
31 }
32 }
33 }
34 await guild.save();
35 res.end();
36 };
Added src/controllers/custom/addVaultTypeCountController.ts +43 -0
@@ -0,0 +1,43 @@
1 import { getAccountIdForRequest } from "../../services/loginService.ts";
2 import { getInventory } from "../../services/inventoryService.ts";
3 import type { RequestHandler } from "express";
4 import { getGuildForRequestEx, hasGuildPermission } from "../../services/guildService.ts";
5 import { GuildPermission } from "../../types/guildTypes.ts";
6 import type { ITypeCount } from "../../types/commonTypes.ts";
7
8 export const addVaultTypeCountController: RequestHandler = async (req, res) => {
9 const accountId = await getAccountIdForRequest(req);
10 const { vaultType, items } = req.body as {
11 vaultType: keyof typeof vaultConfig;
12 items: ITypeCount[];
13 };
14 const inventory = await getInventory(accountId, "GuildId");
15 const guild = await getGuildForRequestEx(req, inventory);
16 if (!(await hasGuildPermission(guild, accountId, vaultConfig[vaultType]))) {
17 res.status(400).send("-1").end();
18 return;
19 }
20 guild[vaultType] ??= [];
21 for (const item of items) {
22 const index = guild[vaultType].findIndex(x => x.ItemType === item.ItemType);
23 if (index === -1) {
24 guild[vaultType].push({
25 ItemType: item.ItemType,
26 ItemCount: item.ItemCount
27 });
28 } else {
29 guild[vaultType][index].ItemCount += item.ItemCount;
30 if (guild[vaultType][index].ItemCount < 1) {
31 guild[vaultType].splice(index, 1);
32 }
33 }
34 }
35
36 await guild.save();
37 res.end();
38 };
39 const vaultConfig = {
40 VaultShipDecorations: GuildPermission.Treasurer,
41 VaultMiscItems: GuildPermission.Treasurer,
42 VaultDecoRecipes: GuildPermission.Architect
43 } as const;
Modified src/controllers/custom/getItemListsController.ts +9 -1
@@ -38,6 +38,7 @@ interface ListedItem {
38 38 parazon?: boolean;
39 39 alwaysAvailable?: boolean;
40 40 maxLevelCap?: number;
41 eligibleForVault?: boolean;
41 42 }
42 43
43 44 interface ItemLists {
@@ -141,6 +142,12 @@ const getItemListsController: RequestHandler = (req, response) => {
141 142 }
142 143 ]*/
143 144 };
145 const eligibleForVault = new Set<string>([
146 ...Object.values(ExportDojoRecipes.research).flatMap(r => r.ingredients.map(i => i.ItemType)),
147 ...Object.values(ExportDojoRecipes.fabrications).flatMap(f => f.ingredients.map(i => i.ItemType)),
148 ...Object.values(ExportDojoRecipes.rooms).flatMap(r => r.ingredients.map(i => i.ItemType)),
149 ...Object.values(ExportDojoRecipes.decos).flatMap(d => d.ingredients.map(i => i.ItemType))
150 ]);
144 151 for (const [uniqueName, item] of Object.entries(ExportWarframes)) {
145 152 res[item.productCategory].push({
146 153 uniqueName,
@@ -246,7 +253,8 @@ const getItemListsController: RequestHandler = (req, response) => {
246 253 res.miscitems.push({
247 254 uniqueName: uniqueName,
248 255 name: name,
249 subtype: "Resource"
256 subtype: "Resource",
257 ...(eligibleForVault.has(uniqueName) && { eligibleForVault: true })
250 258 });
251 259 }
252 260 }
Modified src/routes/custom.ts +2 -2
@@ -34,7 +34,7 @@ import {
34 34 fundTechProjectController,
35 35 removeTechProjectController
36 36 } from "../controllers/custom/techProjectController.ts";
37 import { addVaultDecoRecipeController } from "../controllers/custom/addVaultDecoRecipeController.ts";
37 import { addVaultTypeCountController } from "../controllers/custom/addVaultTypeCountController.ts";
38 38 import { addXpController } from "../controllers/custom/addXpController.ts";
39 39 import { importController } from "../controllers/custom/importController.ts";
40 40 import { manageQuestsController } from "../controllers/custom/manageQuestsController.ts";
@@ -81,7 +81,7 @@ customRouter.post("/addCurrency", addCurrencyController);
81 81 customRouter.post("/addItems", addItemsController);
82 82 customRouter.post("/addTechProject", addTechProjectController);
83 83 customRouter.post("/removeTechProject", removeTechProjectController);
84 customRouter.post("/addVaultDecoRecipe", addVaultDecoRecipeController);
84 customRouter.post("/addVaultTypeCount", addVaultTypeCountController);
85 85 customRouter.post("/fundTechProject", fundTechProjectController);
86 86 customRouter.post("/completeTechProject", completeTechProjectsController);
87 87 customRouter.post("/addXp", addXpController);
Modified static/webui/index.html +40 -2
@@ -624,7 +624,7 @@
624 624 <div class="card" style="height: 400px;">
625 625 <h5 class="card-header" data-loc="guildView_vaultDecoRecipes"></h5>
626 626 <div class="card-body d-flex flex-column">
627 <form id="vaultDecoRecipes-form" class="input-group mb-3 d-none" onsubmit="addVaultDecoRecipe();return false;">
627 <form id="vaultDecoRecipes-form" class="input-group mb-3 d-none" onsubmit="addVaultItem('VaultDecoRecipes');return false;">
628 628 <input class="form-control" id="acquire-type-VaultDecoRecipes" list="datalist-VaultDecoRecipes" />
629 629 <button class="btn btn-primary" type="submit" data-loc="general_addButton"></button>
630 630 </form>
@@ -637,6 +637,42 @@
637 637 </div>
638 638 </div>
639 639 </div>
640 <div class="row g-3 mb-3">
641 <div class="col-lg-6">
642 <div class="card" style="height: 400px;">
643 <h5 class="card-header" data-loc="guildView_vaultMiscItems"></h5>
644 <div class="card-body d-flex flex-column">
645 <form id="vaultMiscItems-form" class="input-group mb-3 d-none" onsubmit="addVaultItem('VaultMiscItems');return false;">
646 <input class="form-control" id="VaultMiscItems-count" type="number" value="1" />
647 <input class="form-control w-50" id="acquire-type-VaultMiscItems" list="datalist-VaultMiscItems" />
648 <button class="btn btn-primary" type="submit" data-loc="general_addButton"></button>
649 </form>
650 <div class="overflow-auto">
651 <table class="table table-hover w-100">
652 <tbody id="VaultMiscItems-list"></tbody>
653 </table>
654 </div>
655 </div>
656 </div>
657 </div>
658 <div class="col-lg-6">
659 <div class="card" style="height: 400px;">
660 <h5 class="card-header" data-loc="guildView_vaultShipDecorations"></h5>
661 <div class="card-body d-flex flex-column">
662 <form id="vaultShipDecorations-form" class="input-group mb-3 d-none" onsubmit="addVaultItem('VaultShipDecorations');return false;">
663 <input class="form-control" id="VaultShipDecorations-count" type="number" value="1" />
664 <input class="form-control w-50" id="acquire-type-VaultShipDecorations" list="datalist-ShipDecorations" />
665 <button class="btn btn-primary" type="submit" data-loc="general_addButton"></button>
666 </form>
667 <div class="overflow-auto">
668 <table class="table table-hover w-100">
669 <tbody id="VaultShipDecorations-list"></tbody>
670 </table>
671 </div>
672 </div>
673 </div>
674 </div>
675 </div>
640 676 <div class="row g-3 mb-3">
641 677 <div class="col-lg-6">
642 678 <div class="card" style="height: 400px;">
@@ -666,7 +702,8 @@
666 702 <div class="card-body" id="guild-actions">
667 703 <div class="mb-2 d-flex flex-wrap gap-2">
668 704 <button class="btn btn-primary" onclick="debounce(addMissingTechProjects);" data-loc="guildView_bulkAddTechProjects"></button>
669 <button class="btn btn-primary" onclick="debounce(addMissingVaultDecoRecipes);" data-loc="guildView_bulkAddVaultDecoRecipes"></button>
705 <button class="btn btn-primary" onclick="debounce(addMissingVaultItems, ['VaultDecoRecipes']);" data-loc="guildView_bulkAddVaultDecoRecipes"></button>
706 <button class="btn btn-primary" onclick="debounce(addMissingVaultItems, ['VaultShipDecorations']);" data-loc="guildView_bulkAddVaultShipDecorations"></button>
670 707 </div>
671 708 <div class="mb-2 d-flex flex-wrap gap-2">
672 709 <button class="btn btn-success" onclick="debounce(fundAllTechProjects);" data-loc="guildView_bulkFundTechProjects"></button>
@@ -1552,6 +1589,7 @@
1552 1589 <datalist id="datalist-FlavourItems"></datalist>
1553 1590 <datalist id="datalist-ShipDecorations"></datalist>
1554 1591 <datalist id="datalist-WeaponSkins"></datalist>
1592 <datalist id="datalist-VaultMiscItems"></datalist>
1555 1593 <datalist id="datalist-circuitGameModes">
1556 1594 <option>Survival</option>
1557 1595 <option>VoidFlood</option>
Modified static/webui/script.js +111 -69
@@ -711,6 +711,10 @@ function fetchItemList() {
711 711 option.value += " (" + item.subtype + ")";
712 712 }
713 713 document.getElementById("datalist-" + type).appendChild(option);
714 if (item.eligibleForVault) {
715 const vaultOption = option.cloneNode(true);
716 document.getElementById("datalist-VaultMiscItems").appendChild(vaultOption);
717 }
714 718 } else {
715 719 //console.log(`Not adding ${item.uniqueName} to datalist for ${type} due to duplicate display name: ${item.name}`);
716 720 }
@@ -1802,6 +1806,8 @@ function updateInventory() {
1802 1806 document.getElementById("VaultRegularCredits-owned").classList.remove("mb-0");
1803 1807 document.getElementById("vaultPremiumCredits-form").classList.remove("d-none");
1804 1808 document.getElementById("VaultPremiumCredits-owned").classList.remove("mb-0");
1809 document.getElementById("vaultMiscItems-form").classList.remove("d-none");
1810 document.getElementById("vaultShipDecorations-form").classList.remove("d-none");
1805 1811 }
1806 1812 if (userGuildMember.Rank <= 1) {
1807 1813 document.querySelectorAll("#guild-actions button").forEach(btn => {
@@ -1892,42 +1898,55 @@ function updateInventory() {
1892 1898 document.getElementById("TechProjects-list").appendChild(tr);
1893 1899 });
1894 1900
1895 document.getElementById("VaultDecoRecipes-list").innerHTML = "";
1896 guildData.VaultDecoRecipes ??= [];
1897 guildData.VaultDecoRecipes.forEach(item => {
1898 const datalist = document.getElementById("datalist-VaultDecoRecipes");
1899 const optionToRemove = datalist.querySelector(`option[data-key="${item.ItemType}"]`);
1900 if (optionToRemove) {
1901 datalist.removeChild(optionToRemove);
1902 }
1903 const tr = document.createElement("tr");
1904 tr.setAttribute("data-item-type", item.ItemType);
1905 {
1906 const td = document.createElement("td");
1907 td.textContent = itemMap[item.ItemType]?.name ?? item.ItemType;
1908 tr.appendChild(td);
1909 }
1910 {
1911 const td = document.createElement("td");
1912 td.classList = "text-end text-nowrap";
1913
1914 if (userGuildMember && userGuildMember.Rank <= 1) {
1915 const a = document.createElement("a");
1916 a.href = "#";
1917 a.onclick = function (event) {
1918 event.preventDefault();
1919 reAddToItemList(itemMap, "VaultDecoRecipes", item.ItemType);
1920 removeVaultDecoRecipe(item.ItemType);
1921 };
1922 a.title = loc("code_remove");
1923 a.innerHTML = `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 448 512"><!--!Font Awesome Free 6.5.2 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free Copyright 2024 Fonticons, Inc.--><path d="M135.2 17.7L128 32H32C14.3 32 0 46.3 0 64S14.3 96 32 96H416c17.7 0 32-14.3 32-32s-14.3-32-32-32H320l-7.2-14.3C307.4 6.8 296.3 0 284.2 0H163.8c-12.1 0-23.2 6.8-28.6 17.7zM416 128H32L53.2 467c1.6 25.3 22.6 45 47.9 45H346.9c25.3 0 46.3-19.7 47.9-45L416 128z"/></svg>`;
1924 td.appendChild(a);
1901 ["VaultDecoRecipes", "VaultMiscItems", "VaultShipDecorations"].forEach(vaultKey => {
1902 document.getElementById(vaultKey + "-list").innerHTML = "";
1903 (guildData[vaultKey] ??= []).forEach(item => {
1904 if (vaultKey == "VaultDecoRecipes") {
1905 const datalist = document.getElementById("datalist-VaultDecoRecipes");
1906 const optionToRemove = datalist.querySelector(
1907 `option[data-key="${item.ItemType}"]`
1908 );
1909 if (optionToRemove) {
1910 datalist.removeChild(optionToRemove);
1911 }
1925 1912 }
1926 1913
1927 tr.appendChild(td);
1928 }
1914 const tr = document.createElement("tr");
1915 tr.setAttribute("data-item-type", item.ItemType);
1916 {
1917 const td = document.createElement("td");
1918 td.textContent = itemMap[item.ItemType]?.name ?? item.ItemType;
1919 if (item.ItemCount > 1) {
1920 td.innerHTML += ` <span title='${loc("code_count")}'>🗍 ${parseInt(item.ItemCount)}</span>`;
1921 }
1922 tr.appendChild(td);
1923 }
1924 {
1925 const td = document.createElement("td");
1926 td.classList = "text-end text-nowrap";
1927 const canRemove =
1928 vaultKey === "VaultDecoRecipes"
1929 ? userGuildMember && userGuildMember.Rank <= 1
1930 : userGuildPermissions && userGuildPermissions & 64;
1931 if (canRemove) {
1932 const a = document.createElement("a");
1933 a.href = "#";
1934 a.title = loc("code_remove");
1935 a.onclick = e => {
1936 e.preventDefault();
1937 if (vaultKey == "VaultDecoRecipes") {
1938 reAddToItemList(itemMap, vaultKey, item.ItemType);
1939 }
1940 removeVaultItem(vaultKey, item.ItemType, item.ItemCount * -1);
1941 };
1942 a.innerHTML = `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 448 512"><path d="M135.2 17.7L128 32H32C14.3 32 0 46.3 0 64S14.3 96 32 96H416c17.7 0 32-14.3 32-32s-14.3-32-32-32H320l-7.2-14.3C307.4 6.8 296.3 0 284.2 0H163.8c-12.1 0-23.2 6.8-28.6 17.7zM416 128H32L53.2 467c1.6 25.3 22.6 45 47.9 45H346.9c25.3 0 46.3-19.7 47.9-45L416 128z"/></svg>`;
1943 td.appendChild(a);
1944 }
1945 tr.appendChild(td);
1946 }
1929 1947
1930 document.getElementById("VaultDecoRecipes-list").appendChild(tr);
1948 document.getElementById(vaultKey + "-list").appendChild(tr);
1949 });
1931 1950 });
1932 1951
1933 1952 document.getElementById("Members-list").innerHTML = "";
@@ -2346,41 +2365,52 @@ function addMissingEquipment(categories) {
2346 2365 }
2347 2366 }
2348 2367
2349 function addVaultDecoRecipe() {
2350 const uniqueName = getKey(document.getElementById("acquire-type-VaultDecoRecipes"));
2351 if (!uniqueName) {
2352 $("#acquire-type-VaultDecoRecipes").addClass("is-invalid").focus();
2368 function addVaultItem(vaultType) {
2369 const ItemType = getKey(document.getElementById(`acquire-type-${vaultType}`));
2370 if (!ItemType) {
2371 $(`#acquire-type-${vaultType}`).addClass("is-invalid").focus();
2353 2372 return;
2354 2373 }
2355 revalidateAuthz().then(() => {
2356 const req = $.post({
2357 url: "/custom/addVaultDecoRecipe?" + window.authz + "&guildId=" + window.guildId,
2358 contentType: "application/json",
2359 data: JSON.stringify([
2360 {
2361 ItemType: uniqueName,
2362 ItemCount: 1
2363 }
2364 ])
2365 });
2366 req.done(() => {
2367 document.getElementById("acquire-type-VaultDecoRecipes").value = "";
2368 updateInventory();
2374 const ItemCount = ["VaultMiscItems", "VaultShipDecorations"].includes(vaultType)
2375 ? parseInt($(`#${vaultType}-count`).val())
2376 : 1;
2377 if (ItemCount != 0) {
2378 revalidateAuthz().then(() => {
2379 const req = $.post({
2380 url: "/custom/addVaultTypeCount?" + window.authz + "&guildId=" + window.guildId,
2381 contentType: "application/json",
2382 data: JSON.stringify({
2383 vaultType,
2384 items: [
2385 {
2386 ItemType,
2387 ItemCount
2388 }
2389 ]
2390 })
2391 });
2392 req.done(() => {
2393 document.getElementById(`acquire-type-${vaultType}`).value = "";
2394 updateInventory();
2395 });
2369 2396 });
2370 });
2397 }
2371 2398 }
2372 2399
2373 function removeVaultDecoRecipe(uniqueName) {
2400 function removeVaultItem(vaultType, ItemType, ItemCount) {
2374 2401 revalidateAuthz().then(() => {
2375 2402 const req = $.post({
2376 url: "/custom/addVaultDecoRecipe?" + window.authz + "&guildId=" + window.guildId,
2403 url: "/custom/addVaultTypeCount?" + window.authz + "&guildId=" + window.guildId,
2377 2404 contentType: "application/json",
2378 data: JSON.stringify([
2379 {
2380 ItemType: uniqueName,
2381 ItemCount: -1
2382 }
2383 ])
2405 data: JSON.stringify({
2406 vaultType,
2407 items: [
2408 {
2409 ItemType,
2410 ItemCount
2411 }
2412 ]
2413 })
2384 2414 });
2385 2415 req.done(() => {
2386 2416 updateInventory();
@@ -2462,13 +2492,16 @@ function fundGuildTechProject(uniqueName) {
2462 2492 });
2463 2493 }
2464 2494
2465 function dispatchAddVaultDecoRecipesBatch(requests) {
2495 function dispatchAddVaultItemsBatch(requests, vaultType) {
2466 2496 return new Promise(resolve => {
2467 2497 revalidateAuthz().then(() => {
2468 2498 const req = $.post({
2469 url: "/custom/addVaultDecoRecipe?" + window.authz + "&guildId=" + window.guildId,
2499 url: "/custom/addVaultItems?" + window.authz + "&guildId=" + window.guildId,
2470 2500 contentType: "application/json",
2471 data: JSON.stringify(requests)
2501 data: JSON.stringify({
2502 vaultType,
2503 items: requests
2504 })
2472 2505 });
2473 2506 req.done(() => {
2474 2507 updateInventory();
@@ -2478,20 +2511,23 @@ function dispatchAddVaultDecoRecipesBatch(requests) {
2478 2511 });
2479 2512 }
2480 2513
2481 function addMissingVaultDecoRecipes() {
2514 function addMissingVaultItems(vaultType) {
2482 2515 const requests = [];
2483 2516
2484 document.querySelectorAll("#datalist-VaultDecoRecipes" + " option").forEach(elm => {
2485 if (!document.querySelector("#VaultDecoRecipes-list [data-item-type='" + elm.getAttribute("data-key") + "']")) {
2486 requests.push({ ItemType: elm.getAttribute("data-key"), ItemCount: 1 });
2517 document.querySelectorAll(`#datalist-${vaultType} option`).forEach(elm => {
2518 const datalist = vaultType === "VaultShipDecorations" ? "ShipDecorations" : vaultType;
2519 if (!document.querySelector(`#${datalist}-list [data-item-type='${elm.getAttribute("data-key")}']`)) {
2520 let ItemCount = 1;
2521 if (category == "VaultShipDecorations") ItemCount = 999999;
2522 requests.push({ ItemType: elm.getAttribute("data-key"), ItemCount });
2487 2523 }
2488 2524 });
2489 2525
2490 2526 if (
2491 2527 requests.length != 0 &&
2492 window.confirm(loc("code_addDecoRecipesConfirm").split("|COUNT|").join(requests.length))
2528 window.confirm(loc("code_addVaultItemsConfirm").split("|COUNT|").join(requests.length))
2493 2529 ) {
2494 return dispatchAddVaultDecoRecipesBatch(requests);
2530 return dispatchAddVaultItemsBatch(requests, vaultType);
2495 2531 }
2496 2532 }
2497 2533
@@ -3445,6 +3481,12 @@ single.getRoute("#guild-route").on("beforeload", function () {
3445 3481 document.getElementById("VaultDecoRecipes-list").innerHTML = "";
3446 3482 document.getElementById("vaultDecoRecipes-form").classList.add("d-none");
3447 3483 document.getElementById("acquire-type-VaultDecoRecipes").value = "";
3484 document.getElementById("VaultMiscItems-list").innerHTML = "";
3485 document.getElementById("vaultMiscItems-form").classList.add("d-none");
3486 document.getElementById("acquire-type-VaultMiscItems").value = "";
3487 document.getElementById("VaultShipDecorations-list").innerHTML = "";
3488 document.getElementById("vaultShipDecorations-form").classList.add("d-none");
3489 document.getElementById("acquire-type-VaultShipDecorations").value = "";
3448 3490 document.getElementById("Alliance-list").innerHTML = "";
3449 3491 document.getElementById("guildView-alliance").textContent = "";
3450 3492 document.getElementById("Members-list").innerHTML = "";
Modified static/webui/translations/de.js +4 -1
@@ -33,7 +33,7 @@ dict = {
33 33 code_remove: `Entfernen`,
34 34 code_addItemsConfirm: `Bist du sicher, dass du |COUNT| Gegenstände zu deinem Account hinzufügen möchtest?`,
35 35 code_addTechProjectsConfirm: `[UNTRANSLATED] Are you sure you want to add |COUNT| research to your clan?`,
36 code_addDecoRecipesConfirm: `[UNTRANSLATED] Are you sure you want to add |COUNT| deco recipes to your clan?`,
36 code_addVaultItemsConfirm: `[UNTRANSLATED] Are you sure you want to add |COUNT| items to your clan vault?`,
37 37 code_succRankUp: `Erfolgreich aufgestiegen.`,
38 38 code_noEquipmentToRankUp: `Keine Ausstattung zum Rangaufstieg verfügbar.`,
39 39 code_succAdded: `Erfolgreich hinzugefügt.`,
@@ -419,6 +419,8 @@ dict = {
419 419 guildView_cheats: `[UNTRANSLATED] Clan Cheats`,
420 420 guildView_techProjects: `Forschung`,
421 421 guildView_vaultDecoRecipes: `[UNTRANSLATED] Dojo Deco Recipes`,
422 guildView_vaultMiscItems: `[UNTRANSLATED] Resources in Vault`,
423 guildView_vaultShipDecorations: `[UNTRANSLATED] Decorations in Vault`,
422 424 guildView_alliance: `Allianz`,
423 425 guildView_members: `Mitglieder`,
424 426 guildView_pending: `Ausstehend`,
@@ -441,6 +443,7 @@ dict = {
441 443 guildView_currency_owned: `[UNTRANSLATED] |COUNT| in Vault.`,
442 444 guildView_bulkAddTechProjects: `[UNTRANSLATED] Add Missing Research`,
443 445 guildView_bulkAddVaultDecoRecipes: `[UNTRANSLATED] Add Missing Dojo Deco Recipes`,
446 guildView_bulkAddVaultShipDecorations: `[UNTRANSLATED] Add Missing Decorations in Vault`,
444 447 guildView_bulkFundTechProjects: `[UNTRANSLATED] Fund All Research`,
445 448 guildView_bulkCompleteTechProjects: `[UNTRANSLATED] Complete All Research`,
446 449 guildView_promote: `Befördern`,
Modified static/webui/translations/en.js +4 -1
@@ -32,7 +32,7 @@ dict = {
32 32 code_remove: `Remove`,
33 33 code_addItemsConfirm: `Are you sure you want to add |COUNT| items to your account?`,
34 34 code_addTechProjectsConfirm: `Are you sure you want to add |COUNT| research to your clan?`,
35 code_addDecoRecipesConfirm: `Are you sure you want to add |COUNT| deco recipes to your clan?`,
35 code_addVaultItemsConfirm: `Are you sure you want to add |COUNT| items to your clan vault?`,
36 36 code_succRankUp: `Successfully ranked up.`,
37 37 code_noEquipmentToRankUp: `No equipment to rank up.`,
38 38 code_succAdded: `Successfully added.`,
@@ -418,6 +418,8 @@ dict = {
418 418 guildView_cheats: `Clan Cheats`,
419 419 guildView_techProjects: `Research`,
420 420 guildView_vaultDecoRecipes: `Dojo Deco Recipes`,
421 guildView_vaultMiscItems: `Resources in Vault`,
422 guildView_vaultShipDecorations: `Decorations in Vault`,
421 423 guildView_alliance: `Alliance`,
422 424 guildView_members: `Members`,
423 425 guildView_pending: `Pending`,
@@ -440,6 +442,7 @@ dict = {
440 442 guildView_currency_owned: `|COUNT| in Vault.`,
441 443 guildView_bulkAddTechProjects: `Add Missing Research`,
442 444 guildView_bulkAddVaultDecoRecipes: `Add Missing Dojo Deco Recipes`,
445 guildView_bulkAddVaultShipDecorations: `Add Missing Decorations in Vault`,
443 446 guildView_bulkFundTechProjects: `Fund All Research`,
444 447 guildView_bulkCompleteTechProjects: `Complete All Research`,
445 448 guildView_promote: `Promote`,
Modified static/webui/translations/es.js +4 -1
@@ -33,7 +33,7 @@ dict = {
33 33 code_remove: `Quitar`,
34 34 code_addItemsConfirm: `¿Estás seguro de que deseas agregar |COUNT| objetos a tu cuenta?`,
35 35 code_addTechProjectsConfirm: `¿Estás seguro de que quieres añadir |COUNT| proyectos de investigación a tu clan?`,
36 code_addDecoRecipesConfirm: `¿Estás seguro de que quieres añadir |COUNT| planos de decoración a tu clan?`,
36 code_addVaultItemsConfirm: `[UNTRANSLATED] Are you sure you want to add |COUNT| items to your clan vault?`,
37 37 code_succRankUp: `Ascenso exitoso.`,
38 38 code_noEquipmentToRankUp: `No hay equipo para ascender.`,
39 39 code_succAdded: `Agregado exitosamente.`,
@@ -419,6 +419,8 @@ dict = {
419 419 guildView_cheats: `Trucos de Clan`,
420 420 guildView_techProjects: `Investigación`,
421 421 guildView_vaultDecoRecipes: `Planos de Decoración de Dojo`,
422 guildView_vaultMiscItems: `[UNTRANSLATED] Resources in Vault`,
423 guildView_vaultShipDecorations: `[UNTRANSLATED] Decorations in Vault`,
422 424 guildView_alliance: `Alianza`,
423 425 guildView_members: `Miembros`,
424 426 guildView_pending: `Pendiente`,
@@ -441,6 +443,7 @@ dict = {
441 443 guildView_currency_owned: `|COUNT| en la Bóveda.`,
442 444 guildView_bulkAddTechProjects: `Añadir proyectos de Investigación Faltantes`,
443 445 guildView_bulkAddVaultDecoRecipes: `Añadir planos de Decoración de Dojo Faltantes`,
446 guildView_bulkAddVaultShipDecorations: `[UNTRANSLATED] Add Missing Decorations in Vault`,
444 447 guildView_bulkFundTechProjects: `Financiar toda la Investigación`,
445 448 guildView_bulkCompleteTechProjects: `Completar toda la Investigación`,
446 449 guildView_promote: `Promover`,
Modified static/webui/translations/fr.js +4 -1
@@ -33,7 +33,7 @@ dict = {
33 33 code_remove: `Retirer`,
34 34 code_addItemsConfirm: `Ajouter |COUNT| items à l'inventaire ?`,
35 35 code_addTechProjectsConfirm: `Ajouter |COUNT| recherches au clan ?`,
36 code_addDecoRecipesConfirm: `Ajouter |COUNT| décorations au clan ?`,
36 code_addVaultItemsConfirm: `[UNTRANSLATED] Are you sure you want to add |COUNT| items to your clan vault?`,
37 37 code_succRankUp: `Montée de niveau effectuée.`,
38 38 code_noEquipmentToRankUp: `Aucun équipement à monter de niveau.`,
39 39 code_succAdded: `Ajouté.`,
@@ -419,6 +419,8 @@ dict = {
419 419 guildView_cheats: `[UNTRANSLATED] Clan Cheats`,
420 420 guildView_techProjects: `Recherche`,
421 421 guildView_vaultDecoRecipes: `Schémas de décorations de dojo`,
422 guildView_vaultMiscItems: `[UNTRANSLATED] Resources in Vault`,
423 guildView_vaultShipDecorations: `[UNTRANSLATED] Decorations in Vault`,
422 424 guildView_alliance: `Alliance`,
423 425 guildView_members: `Members`,
424 426 guildView_pending: `En Attente`,
@@ -441,6 +443,7 @@ dict = {
441 443 guildView_currency_owned: `|COUNT| dans le coffre.`,
442 444 guildView_bulkAddTechProjects: `Ajouter les recherches manquantes`,
443 445 guildView_bulkAddVaultDecoRecipes: `Ajouter les schémas de décorations de dojo manquantes`,
446 guildView_bulkAddVaultShipDecorations: `[UNTRANSLATED] Add Missing Decorations in Vault`,
444 447 guildView_bulkFundTechProjects: `Financer toutes les recherches`,
445 448 guildView_bulkCompleteTechProjects: `Compléter toutes les recherches`,
446 449 guildView_promote: `Promouvoir`,
Modified static/webui/translations/ru.js +4 -1
@@ -33,7 +33,7 @@ dict = {
33 33 code_remove: `Удалить`,
34 34 code_addItemsConfirm: `Вы уверены, что хотите добавить |COUNT| предметов на ваш аккаунт?`,
35 35 code_addTechProjectsConfirm: `Вы уверены, что хотите добавить |COUNT| исследований в свой клан?`,
36 code_addDecoRecipesConfirm: `Вы уверены, что хотите добавить |COUNT| рецептов декораций в свой клан?`,
36 code_addVaultItemsConfirm: `Вы уверены, что хотите добавить |COUNT| предметов в хранилище своего клана?`,
37 37 code_succRankUp: `Ранг успешно повышен.`,
38 38 code_noEquipmentToRankUp: `Нет снаряжения для повышения ранга.`,
39 39 code_succAdded: `Успешно добавлено.`,
@@ -419,6 +419,8 @@ dict = {
419 419 guildView_cheats: `Читы Клана`,
420 420 guildView_techProjects: `Исследовения`,
421 421 guildView_vaultDecoRecipes: `Рецепты декораций Додзё`,
422 guildView_vaultMiscItems: `Ресурсы в Хранилище`,
423 guildView_vaultShipDecorations: `Укращения в Хранилище`,
422 424 guildView_alliance: `Альянс`,
423 425 guildView_members: `Товарищи`,
424 426 guildView_pending: `Ожидание`,
@@ -441,6 +443,7 @@ dict = {
441 443 guildView_currency_owned: `В хранилище |COUNT|.`,
442 444 guildView_bulkAddTechProjects: `Добавить отсутствующие исследования`,
443 445 guildView_bulkAddVaultDecoRecipes: `Добавить отсутствующие рецепты декораций Дoдзё`,
446 guildView_bulkAddVaultShipDecorations: `Добавить отсутствующие укращения в Хранилище`,
444 447 guildView_bulkFundTechProjects: `Профинансировать все исследования`,
445 448 guildView_bulkCompleteTechProjects: `Завершить все исследования`,
446 449 guildView_promote: `Повысить`,
Modified static/webui/translations/uk.js +4 -1
@@ -33,7 +33,7 @@ dict = {
33 33 code_remove: `Видалити`,
34 34 code_addItemsConfirm: `Ви впевнені, що хочете додати |COUNT| предметів на ваш обліковий запис?`,
35 35 code_addTechProjectsConfirm: `Ви впевнені, що хочете додати |COUNT| досліджень до свого клану?`,
36 code_addDecoRecipesConfirm: `Ви впевнені, що хочете додати |COUNT| рецептів оздоблень до свого клану?`,
36 code_addVaultItemsConfirm: `[UNTRANSLATED] Are you sure you want to add |COUNT| items to your clan vault?`,
37 37 code_succRankUp: `Рівень успішно підвищено`,
38 38 code_noEquipmentToRankUp: `Немає спорядження для підвищення рівня.`,
39 39 code_succAdded: `Успішно додано.`,
@@ -419,6 +419,8 @@ dict = {
419 419 guildView_cheats: `Кланові чити`,
420 420 guildView_techProjects: `Дослідження`,
421 421 guildView_vaultDecoRecipes: `Рецепти оздоблень Доджьо`,
422 guildView_vaultMiscItems: `[UNTRANSLATED] Resources in Vault`,
423 guildView_vaultShipDecorations: `[UNTRANSLATED] Decorations in Vault`,
422 424 guildView_alliance: `Альянс`,
423 425 guildView_members: `Учасники`,
424 426 guildView_pending: `Очікування`,
@@ -441,6 +443,7 @@ dict = {
441 443 guildView_currency_owned: `В сховищі |COUNT|.`,
442 444 guildView_bulkAddTechProjects: `Додати відсутні дослідження`,
443 445 guildView_bulkAddVaultDecoRecipes: `Додати відсутні рецепти оздоблень Доджьо`,
446 guildView_bulkAddVaultShipDecorations: `[UNTRANSLATED] Add Missing Decorations in Vault`,
444 447 guildView_bulkFundTechProjects: `Фінансувати всі дослідження`,
445 448 guildView_bulkCompleteTechProjects: `Завершити всі дослідження`,
446 449 guildView_promote: `Підвищити звання`,
Modified static/webui/translations/zh.js +4 -1