From b885d7766c247ee5cf35f7c02e905c8779508413 Mon Sep 17 00:00:00 2001 From: AMelonInsideLemon <166175391+AMelonInsideLemon@users.noreply.github.com> Date: Sun, 17 Aug 2025 13:11:55 -0700 Subject: [PATCH 1/4] feat: warframe anniversary goals (#2640) Also adds `useAnniversaryTagForOldGoals` to display old Goals in GUI Re #1103 Reviewed-on: https://onlyg.it/OpenWF/SpaceNinjaServer/pulls/2640 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> --- config-vanilla.json | 4 +- src/services/configService.ts | 2 + src/services/missionInventoryUpdateService.ts | 168 ++++++++++- src/services/worldStateService.ts | 267 +++++++++++++++++- static/webui/index.html | 53 ++-- static/webui/script.js | 6 +- static/webui/translations/de.js | 7 +- static/webui/translations/en.js | 7 +- static/webui/translations/es.js | 7 +- static/webui/translations/fr.js | 7 +- static/webui/translations/ru.js | 7 +- static/webui/translations/uk.js | 7 +- static/webui/translations/zh.js | 7 +- 13 files changed, 495 insertions(+), 54 deletions(-) diff --git a/config-vanilla.json b/config-vanilla.json index 49a66b44..7a72dc10 100644 --- a/config-vanilla.json +++ b/config-vanilla.json @@ -59,7 +59,8 @@ "nightwaveStandingMultiplier": 1, "unfaithfulBugFixes": { "ignore1999LastRegionPlayed": false, - "fixXtraCheeseTimer": false + "fixXtraCheeseTimer": false, + "useAnniversaryTagForOldGoals": true }, "worldState": { "creditBoost": false, @@ -70,6 +71,7 @@ "orphixVenom": false, "longShadow": false, "hallowedFlame": false, + "anniversary": null, "hallowedNightmares": false, "hallowedNightmaresRewardsOverride": 0, "proxyRebellion": false, diff --git a/src/services/configService.ts b/src/services/configService.ts index 72efe735..7d6a8337 100644 --- a/src/services/configService.ts +++ b/src/services/configService.ts @@ -71,6 +71,7 @@ export interface IConfig { unfaithfulBugFixes?: { ignore1999LastRegionPlayed?: boolean; fixXtraCheeseTimer?: boolean; + useAnniversaryTagForOldGoals?: boolean; }; worldState?: { creditBoost?: boolean; @@ -82,6 +83,7 @@ export interface IConfig { orphixVenom?: boolean; longShadow?: boolean; hallowedFlame?: boolean; + anniversary?: number; hallowedNightmares?: boolean; hallowedNightmaresRewardsOverride?: number; proxyRebellion?: boolean; diff --git a/src/services/missionInventoryUpdateService.ts b/src/services/missionInventoryUpdateService.ts index e1958a2a..a7219d7f 100644 --- a/src/services/missionInventoryUpdateService.ts +++ b/src/services/missionInventoryUpdateService.ts @@ -712,6 +712,20 @@ export const addMissionInventoryUpdates = async ( if (reward.credits) { message.RegularCredits = reward.credits; } + if (info.arg) { + const args: Record = { + PLAYER_NAME: account.DisplayName, + CREDIT_REWARD: reward.credits ?? 0 + }; + + info.arg.forEach(key => { + const value = args[key]; + if (value) { + message.arg ??= []; + message.arg.push({ Key: key, Tag: value }); + } + }); + } await createMessage(inventory.accountOwnerId, [message]); } @@ -2271,7 +2285,7 @@ const getHexBounties = (seed: number): { nodes: string[]; buddies: string[] } => return { nodes, buddies }; };*/ -const goalMessagesByKey: Record = { +const goalMessagesByKey: Record = { "/Lotus/Types/Keys/GalleonRobberyAlert": { sndr: "/Lotus/Language/Bosses/BossCouncilorVayHek", msg: "/Lotus/Language/Messages/GalleonRobbery2025RewardMsgA", @@ -2384,19 +2398,22 @@ const goalMessagesByKey: Record { Personal: true, Bounty: true, ClampNodeScores: true, - Node: "EventNode28", // Incompatible with Wolf Hunt (2025), Orphix Venom + Node: "EventNode28", // Incompatible with Wolf Hunt (2025), Orphix Venom, Warframe Anniversary MissionKeyName: "/Lotus/Types/Keys/GalleonRobberyAlertB", Desc: "/Lotus/Language/Events/GalleonRobberyEventMissionTitle", Icon: "/Lotus/Interface/Icons/Player/GalleonRobberiesEvent.png", @@ -1819,14 +1820,14 @@ export const getWorldState = (buildLabel?: string): IWorldState => { Personal: true, Bounty: true, ClampNodeScores: true, - Node: "EventNode25", // Incompatible with Hallowed Flame, Hallowed Nightmares + Node: "EventNode25", // Incompatible with Hallowed Flame, Hallowed Nightmares, Warframe Anniversary ConcurrentMissionKeyNames: [ "/Lotus/Types/Keys/TacAlertKeyWaterFightB", "/Lotus/Types/Keys/TacAlertKeyWaterFightC", "/Lotus/Types/Keys/TacAlertKeyWaterFightD" ], ConcurrentNodeReqs: [25, 50, 100], - ConcurrentNodes: ["EventNode24", "EventNode34", "EventNode35"], // Incompatible with Hallowed Flame, Hallowed Nightmares + ConcurrentNodes: ["EventNode24", "EventNode34", "EventNode35"], // Incompatible with Hallowed Flame, Hallowed Nightmares, Warframe Anniversary MissionKeyName: "/Lotus/Types/Keys/TacAlertKeyWaterFightA", Faction: "FC_CORPUS", Desc: "/Lotus/Language/Alerts/TacAlertWaterFight", @@ -1934,6 +1935,226 @@ export const getWorldState = (buildLabel?: string): IWorldState => { } } + if (config.worldState?.anniversary != undefined) { + // Incompatible with: Use Tag from Warframe Anniversary for old Events, Wolf Hunt (2025), Galleon Of Ghouls, Hallowed Flame, Hallowed Nightmares, Dog Days, Proxy Rebellion, Long Shadow + const goalsByWeek: Partial[][] = [ + [ + { + Node: "EventNode28", + MissionKeyName: "/Lotus/Types/Keys/TacAlertKeyAnniversary2019E", + Tag: "Anniversary2019TacAlert", + Reward: { + items: ["/Lotus/StoreItems/Upgrades/Skins/Excalibur/ExcaliburDexSkin"] + } + }, + { + Node: "EventNode26", + MissionKeyName: "/Lotus/Types/Keys/TacAlertKeyAnniversary2020F", + Tag: "Anniversary2020TacAlert", + Reward: { + items: ["/Lotus/StoreItems/Types/Items/ShipDecos/ExcaliburDexBobbleHead"] + } + }, + { + Node: "EventNode19", + MissionKeyName: "/Lotus/Types/Keys/TacAlertKeyAnniversary2024ChallengeModeA", + Tag: "Anniversary2024TacAlertCMA", + Reward: { + items: ["/Lotus/StoreItems/Types/Items/MiscItems/WeaponUtilityUnlocker"] + } + } + ], + [ + { + Node: "EventNode24", + MissionKeyName: "/Lotus/Types/Keys/TacAlertKeyAnniversary2017C", + Tag: "Anniversary2018TacAlert", + Reward: { + items: ["/Lotus/StoreItems/Weapons/Tenno/LongGuns/DexTheThird/DexTheThird"] + } + }, + { + Node: "EventNode18", + MissionKeyName: "/Lotus/Types/Keys/TacAlertKeyAnniversary2020H", + Tag: "Anniversary2020TacAlert", + Reward: { + items: ["/Lotus/StoreItems/Types/StoreItems/AvatarImages/ImageDexAnniversary"] + } + } + ], + [ + { + Node: "EventNode18", + MissionKeyName: "/Lotus/Types/Keys/TacAlertKeyAnniversary2022J", + Tag: "Anniversary2022TacAlert", + Reward: { + items: ["/Lotus/StoreItems/Upgrades/Skins/Rhino/RhinoDexSkin"] + } + }, + { + Node: "EventNode38", + MissionKeyName: "/Lotus/Types/Keys/TacAlertKeyAnniversary2025D", + Tag: "Anniversary2020TacAlert", + Reward: { + items: ["/Lotus/StoreItems/Types/Items/ShipDecos/RhinoDexBobbleHead"] + } + }, + { + Node: "EventNode27", + MissionKeyName: "/Lotus/Types/Keys/TacAlertKeyAnniversary2025ChallengeModeA", + Tag: "Anniversary2024TacAlertCMA", + Reward: { + items: ["/Lotus/StoreItems/Types/Items/MiscItems/OrokinCatalyst"] + } + } + ], + [ + { + Node: "EventNode2", + MissionKeyName: "/Lotus/Types/Keys/TacAlertKeyAnniversary2020G", + Tag: "Anniversary2020TacAlert", + Reward: { + items: ["/Lotus/StoreItems/Upgrades/Skins/Liset/DexLisetSkin"] + } + }, + { + Node: "EventNode17", + MissionKeyName: "/Lotus/Types/Keys/TacAlertKeyAnniversary2017B", + Tag: "Anniversary2018TacAlert", + Reward: { + items: ["/Lotus/StoreItems/Weapons/Tenno/Melee/Swords/DexTheSecond/DexTheSecond"] + } + } + ], + [ + { + Node: "EventNode18", + MissionKeyName: "/Lotus/Types/Keys/TacAlertKeyAnniversary2017A", + Tag: "Anniversary2018TacAlert", + Reward: { + items: ["/Lotus/StoreItems/Weapons/Tenno/Pistols/DexFuris/DexFuris"] + } + }, + { + Node: "EventNode26", + MissionKeyName: "/Lotus/Types/Keys/TacAlertKeyAnniversary2023K", + Tag: "Anniversary2025TacAlert", + Reward: { + items: ["/Lotus/StoreItems/Types/StoreItems/AvatarImages/AvatarImageCommunityClemComic"] + } + }, + { + Node: "EventNode12", + MissionKeyName: "/Lotus/Types/Keys/TacAlertKeyAnniversary2025ChallengeModeB", + Tag: "Anniversary2025TacAlertCMB", + Reward: { + items: ["/Lotus/StoreItems/Types/Items/MiscItems/WeaponPrimaryArcaneUnlocker"] + } + } + ], + [ + { + Node: "EventNode17", + MissionKeyName: "/Lotus/Types/Keys/TacAlertKeyAnniversary2025A", + Tag: "Anniversary2025TacAlert", + Reward: { + items: [ + "/Lotus/StoreItems/Weapons/Tenno/Melee/Swords/KatanaAndWakizashi/Dex2023Nikana/Dex2023Nikana" + ] + } + }, + { + Node: "EventNode27", + MissionKeyName: "/Lotus/Types/Keys/TacAlertKeyAnniversary2018D", + Tag: "Anniversary2018TacAlert", + Reward: { + items: ["/Lotus/StoreItems/Upgrades/Skins/Scarves/DexScarf"] + } + } + ], + [ + { + Node: "EventNode38", + MissionKeyName: "/Lotus/Types/Keys/TacAlertKeyAnniversary2025C", + Tag: "Anniversary2018TacAlert", + Reward: { + items: ["/Lotus/StoreItems/Upgrades/Skins/Wisp/DexWispSkin"] + } + }, + { + Node: "EventNode12", + MissionKeyName: "/Lotus/Types/Keys/TacAlertKeyAnniversary2024L", + Tag: "Anniversary2024TacAlert", + Reward: { + items: ["/Lotus/Types/StoreItems/Packages/OperatorDrifterDexBundle"] + } + }, + { + Node: "EventNode26", + MissionKeyName: "/Lotus/Types/Keys/TacAlertKeyAnniversary2024ChallengeModeB", + Tag: "Anniversary2024TacAlertCMB", + Reward: { + items: ["/Lotus/StoreItems/Types/Recipes/Components/UmbraFormaBlueprint"] + } + } + ], + [ + { + Node: "EventNode37", + MissionKeyName: "/Lotus/Types/Keys/TacAlertKeyAnniversary2021I", + Tag: "Anniversary2021TacAlert", + Reward: { + items: [ + "/Lotus/StoreItems/Upgrades/Skins/Armor/Dex2020Armor/Dex2020ArmorAArmor", + "/Lotus/StoreItems/Upgrades/Skins/Armor/Dex2020Armor/Dex2020ArmorCArmor", + "/Lotus/StoreItems/Upgrades/Skins/Armor/Dex2020Armor/Dex2020ArmorLArmor", + "/Lotus/StoreItems/Types/Game/CatbrowPet/CatbrowGeneticSignature" + ], + countedItems: [ + { + ItemType: "/Lotus/Types/Game/CatbrowPet/CatbrowGeneticSignature", + ItemCount: 10 + } + ] + } + }, + { + Node: "EventNode9", + MissionKeyName: "/Lotus/Types/Keys/TacAlertKeyAnniversary2025B", + Tag: "Anniversary2025TacAlert", + Reward: { + items: ["/Lotus/StoreItems/Types/StoreItems/SuitCustomizations/ColourPickerAnniversaryEleven"] + } + } + ] + ]; + goalsByWeek[config.worldState.anniversary].forEach((goal, i) => { + worldState.Goals.push({ + _id: { + $oid: + "67c6d8e725b23feb" + + config.worldState?.anniversary!.toString(16).padStart(4, "0") + + i.toString(16).padStart(4, "0") + }, + Activation: { $date: { $numberLong: "1745593200000" } }, + Expiry: { $date: { $numberLong: "2000000000000" } }, + Count: 0, + Goal: 1, + Success: 0, + Personal: true, + ClampNodeScores: true, + Node: goal.Node, + MissionKeyName: goal.MissionKeyName, + Desc: goal.Tag!.endsWith("CMB") + ? "/Lotus/Language/Events/Anniversary2024ChallengeMode" + : "/Lotus/Language/G1Quests/Anniversary2017MissionTitle", + Icon: "/Lotus/Interface/Icons/Player/GlyphLotus12Anniversary.png", + Tag: goal.Tag!, + Reward: goal.Reward + }); + }); + } + if (config.worldState?.wolfHunt) { worldState.Goals.push({ _id: { @@ -1964,7 +2185,7 @@ export const getWorldState = (buildLabel?: string): IWorldState => { "/Lotus/Types/Keys/WolfTacAlertReduxD" ], ConcurrentNodeReqs: [1, 2, 3], - ConcurrentNodes: ["EventNode28", "EventNode39", "EventNode40"], // Incompatible with Galleon Of Ghouls, Orphix Venom + ConcurrentNodes: ["EventNode28", "EventNode39", "EventNode40"], // Incompatible with Galleon Of Ghouls, Orphix Venom, Warframe Anniversary MissionKeyName: "/Lotus/Types/Keys/WolfTacAlertReduxA", Faction: "FC_GRINEER", Desc: "/Lotus/Language/Alerts/WolfAlert", @@ -1995,6 +2216,18 @@ export const getWorldState = (buildLabel?: string): IWorldState => { }); } + const tagsForOlderGoals: string[] = [ + "Anniversary2018TacAlert", + "Anniversary2019TacAlert", + "Anniversary2020TacAlert", + "Anniversary2021TacAlert", + "Anniversary2022TacAlert", + "Anniversary2024TacAlert", + "Anniversary2024TacAlertCMA", + "Anniversary2025TacAlert", + "Anniversary2025TacAlertCMB" + ]; + if (config.worldState?.hallowedFlame) { worldState.Goals.push( { @@ -2019,7 +2252,7 @@ export const getWorldState = (buildLabel?: string): IWorldState => { Faction: "FC_INFESTATION", Desc: "/Lotus/Language/Events/TacAlertHalloweenLantern", Icon: "/Lotus/Interface/Icons/JackOLanternColour.png", - Tag: "Halloween19", + Tag: config.unfaithfulBugFixes?.useAnniversaryTagForOldGoals ? tagsForOlderGoals[0] : "Halloween19", InterimRewards: [ { items: ["/Lotus/StoreItems/Types/Items/MiscItems/OrokinCatalyst"] }, { items: ["/Lotus/StoreItems/Types/Items/MiscItems/Forma"] } @@ -2045,7 +2278,9 @@ export const getWorldState = (buildLabel?: string): IWorldState => { Desc: "/Lotus/Language/Events/TacAlertHalloweenLanternEndless", Icon: "/Lotus/Interface/Icons/JackOLanternColour.png", Tag: "Halloween19Endless", - PrereqGoalTags: ["Halloween19"], + PrereqGoalTags: [ + config.unfaithfulBugFixes?.useAnniversaryTagForOldGoals ? tagsForOlderGoals[0] : "Halloween19" + ], Reward: { items: [ "/Lotus/StoreItems/Upgrades/Skins/Effects/BatsEphemera", @@ -2109,17 +2344,17 @@ export const getWorldState = (buildLabel?: string): IWorldState => { Success: 0, Personal: true, Bounty: true, - Tag: "Halloween", + Tag: config.unfaithfulBugFixes?.useAnniversaryTagForOldGoals ? tagsForOlderGoals[0] : "Halloween", Faction: "FC_INFESTATION", Desc: "/Lotus/Language/G1Quests/TacAlertHalloweenTitle", ToolTip: "/Lotus/Language/G1Quests/TacAlertHalloweenToolTip", Icon: "/Lotus/Interface/Icons/JackOLanternColour.png", ClampNodeScores: true, - Node: "EventNode2", + Node: "EventNode2", // Incompatible with Warframe Anniversary MissionKeyName: "/Lotus/Types/Keys/TacAlertKeyHalloween", ConcurrentMissionKeyNames: ["/Lotus/Types/Keys/TacAlertKeyHalloweenBonus"], ConcurrentNodeReqs: [1], - ConcurrentNodes: ["EventNode24"], // Incompatible with Hallowed Flame, Dog Days + ConcurrentNodes: ["EventNode24"], // Incompatible with Hallowed Flame, Dog Days, Warframe Anniversary InterimRewards: [rewards[year][0]], Reward: rewards[year][1] }); @@ -2135,7 +2370,9 @@ export const getWorldState = (buildLabel?: string): IWorldState => { Bounty: true, Best: true, Tag: "Halloween", - PrereqGoalTags: ["Halloween"], + PrereqGoalTags: [ + config.unfaithfulBugFixes?.useAnniversaryTagForOldGoals ? tagsForOlderGoals[0] : "Halloween" + ], Faction: "FC_INFESTATION", Desc: "Hallowed Nightmares - Time Attack", ToolTip: "/Lotus/Language/G1Quests/TacAlertHalloweenToolTip", @@ -2209,19 +2446,19 @@ export const getWorldState = (buildLabel?: string): IWorldState => { Personal: true, Bounty: true, ClampNodeScores: true, - Node: "EventNode18", + Node: "EventNode18", // Incompatible with Warframe Anniversary ConcurrentMissionKeyNames: [ "/Lotus/Types/Keys/TacAlertKeyProxyRebellionTwo", "/Lotus/Types/Keys/TacAlertKeyProxyRebellionThree", "/Lotus/Types/Keys/TacAlertKeyProxyRebellionFour" ], ConcurrentNodeReqs: [1, 2, 3], - ConcurrentNodes: ["EventNode7", "EventNode4", "EventNode17"], // Incompatible with Orphix venom + ConcurrentNodes: ["EventNode7", "EventNode4", "EventNode17"], // Incompatible with Orphix venom, Warframe Anniversary MissionKeyName: "/Lotus/Types/Keys/TacAlertKeyProxyRebellionOne", Faction: "FC_CORPUS", Desc: "/Lotus/Language/Alerts/TacAlertProxyRebellion", Icon: "/Lotus/Materials/Emblems/BountyBadge_e.png", - Tag: "ProxyRebellion", + Tag: config.unfaithfulBugFixes?.useAnniversaryTagForOldGoals ? tagsForOlderGoals[1] : "ProxyRebellion", InterimRewards: rewards[year].slice(0, 2), Reward: rewards[year][2], BonusReward: rewards[year][3] @@ -2240,12 +2477,12 @@ export const getWorldState = (buildLabel?: string): IWorldState => { Success: 0, Personal: true, Bounty: true, - Tag: "NightwatchTacAlert", + Tag: config.unfaithfulBugFixes?.useAnniversaryTagForOldGoals ? tagsForOlderGoals[2] : "NightwatchTacAlert", Faction: "FC_GRINEER", Desc: "/Lotus/Language/G1Quests/ProjectNightwatchTacAlertTitle", Icon: "/Lotus/Materials/Emblems/BountyBadge_e.png", ClampNodeScores: true, - Node: "EventNode9", + Node: "EventNode9", // Incompatible with Warframe Anniversary MissionKeyName: "/Lotus/Types/Keys/TacAlertKeyProjectNightwatchEasy", ConcurrentMissionKeyNames: [ "/Lotus/Types/Keys/TacAlertKeyProjectNightwatch", diff --git a/static/webui/index.html b/static/webui/index.html index 6b3caad9..83730e06 100644 --- a/static/webui/index.html +++ b/static/webui/index.html @@ -937,29 +937,35 @@ +
+ + + +
- +
- +
+
- +
- + - - - + + +
- + - - + +
- +
+
+ + + +
@@ -1039,10 +1060,10 @@
diff --git a/static/webui/script.js b/static/webui/script.js index 50aaf932..ebad506f 100644 --- a/static/webui/script.js +++ b/static/webui/script.js @@ -206,12 +206,12 @@ function updateLocElements() { const incWith = elm .getAttribute("data-loc-inc") .split("|") - .map(key => loc(key)) + .map(key => loc(key).replace(/<[^>]+>/g, "")) .join(", "); elm.title = `${loc("worldState_incompatibleWith")} ${incWith}`; }); - document.querySelectorAll("[data-loc-year]").forEach(elm => { - elm.innerHTML = elm.innerHTML.replace("|YEAR|", elm.getAttribute("data-loc-year")); + document.querySelectorAll("[data-loc-replace]").forEach(elm => { + elm.innerHTML = elm.innerHTML.replace("|VAL|", elm.getAttribute("data-loc-replace")); }); } diff --git a/static/webui/translations/de.js b/static/webui/translations/de.js index 50059328..9add8618 100644 --- a/static/webui/translations/de.js +++ b/static/webui/translations/de.js @@ -246,6 +246,8 @@ dict = { worldState_baroTennoConRelay: `Baros TennoCon Relais`, worldState_starDays: `Sternen-Tage`, worldState_galleonOfGhouls: `Galeone der Ghule`, + worldState_anniversary: `[UNTRANSLATED] Warframe Anniversary`, + worldState_useAnniversaryTagForOldGoals: `[UNTRANSLATED] Use Tag from Warframe Anniversary for old Events`, worldState_ghoulEmergence: `Ghul Ausrottung`, worldState_plagueStar: `Plagenstern`, worldState_dogDays: `Hitzefrei`, @@ -262,8 +264,9 @@ dict = { worldState_bellyOfTheBeastProgressOverride: `[UNTRANSLATED] Belly of the Beast Progress`, worldState_eightClaw: `Acht Klauen`, worldState_eightClawProgressOverride: `[UNTRANSLATED] Eight Claw Progress`, - worldState_from_year: `[UNTRANSLATED] from |YEAR|`, - worldState_pre_year: `[UNTRANSLATED] pre |YEAR|`, + worldState_from_year: `[UNTRANSLATED] from |VAL|`, + worldState_pre_year: `[UNTRANSLATED] pre |VAL|`, + worldState_week: `[UNTRANSLATED] Week |VAL|`, worldState_incompatibleWith: `[UNTRANSLATED] Incompatible with:`, enabled: `Aktiviert`, disabled: `Deaktiviert`, diff --git a/static/webui/translations/en.js b/static/webui/translations/en.js index ed5de064..101e28ea 100644 --- a/static/webui/translations/en.js +++ b/static/webui/translations/en.js @@ -245,6 +245,8 @@ dict = { worldState_baroTennoConRelay: `Baro's TennoCon Relay`, worldState_starDays: `Star Days`, worldState_galleonOfGhouls: `Galleon of Ghouls`, + worldState_anniversary: `Warframe Anniversary`, + worldState_useAnniversaryTagForOldGoals: `Use Tag from Warframe Anniversary for old Events`, worldState_ghoulEmergence: `Ghoul Purge`, worldState_plagueStar: `Plague Star`, worldState_dogDays: `Dog Days`, @@ -261,8 +263,9 @@ dict = { worldState_bellyOfTheBeastProgressOverride: `Belly of the Beast Progress`, worldState_eightClaw: `Eight Claw`, worldState_eightClawProgressOverride: `Eight Claw Progress`, - worldState_from_year: `from |YEAR|`, - worldState_pre_year: `pre |YEAR|`, + worldState_from_year: `from |VAL|`, + worldState_pre_year: `pre |VAL|`, + worldState_week: `Week |VAL|`, worldState_incompatibleWith: `Incompatible with:`, enabled: `Enabled`, disabled: `Disabled`, diff --git a/static/webui/translations/es.js b/static/webui/translations/es.js index f2ec9512..e22a8fe2 100644 --- a/static/webui/translations/es.js +++ b/static/webui/translations/es.js @@ -246,6 +246,8 @@ dict = { worldState_baroTennoConRelay: `Repetidor de Baro de la TennoCon`, worldState_starDays: `Días estelares`, worldState_galleonOfGhouls: `Galeón de Gules`, + worldState_anniversary: `[UNTRANSLATED] Warframe Anniversary`, + worldState_useAnniversaryTagForOldGoals: `[UNTRANSLATED] Use Tag from Warframe Anniversary for old Events`, worldState_ghoulEmergence: `Purga de Gules`, worldState_plagueStar: `Estrella Infestada`, worldState_dogDays: `Canícula`, @@ -262,8 +264,9 @@ dict = { worldState_bellyOfTheBeastProgressOverride: `[UNTRANSLATED] Belly of the Beast Progress`, worldState_eightClaw: `Octava Garra`, worldState_eightClawProgressOverride: `[UNTRANSLATED] Eight Claw Progress`, - worldState_from_year: `de |YEAR|`, - worldState_pre_year: `antes de |YEAR|`, + worldState_from_year: `de |VAL|`, + worldState_pre_year: `antes de |VAL|`, + worldState_week: `[UNTRANSLATED] Week |VAL|`, worldState_incompatibleWith: `No compatible con:`, enabled: `Activado`, disabled: `Desactivado`, diff --git a/static/webui/translations/fr.js b/static/webui/translations/fr.js index 22c60883..8a45cc08 100644 --- a/static/webui/translations/fr.js +++ b/static/webui/translations/fr.js @@ -246,6 +246,8 @@ dict = { worldState_baroTennoConRelay: `Relais Baro TennoCon`, worldState_starDays: `Jours Stellaires`, worldState_galleonOfGhouls: `Galion des Goules`, + worldState_anniversary: `[UNTRANSLATED] Warframe Anniversary`, + worldState_useAnniversaryTagForOldGoals: `[UNTRANSLATED] Use Tag from Warframe Anniversary for old Events`, worldState_ghoulEmergence: `Purge des Goules`, worldState_plagueStar: `Fléau Céleste`, worldState_dogDays: `Bataille d'Eau`, @@ -262,8 +264,9 @@ dict = { worldState_bellyOfTheBeastProgressOverride: `[UNTRANSLATED] Belly of the Beast Progress`, worldState_eightClaw: `Huitième Griffe`, worldState_eightClawProgressOverride: `[UNTRANSLATED] Eight Claw Progress`, - worldState_from_year: `[UNTRANSLATED] from |YEAR|`, - worldState_pre_year: `[UNTRANSLATED] pre |YEAR|`, + worldState_from_year: `[UNTRANSLATED] from |VAL|`, + worldState_pre_year: `[UNTRANSLATED] pre |VAL|`, + worldState_week: `[UNTRANSLATED] Week |VAL|`, worldState_incompatibleWith: `[UNTRANSLATED] Incompatible with:`, enabled: `Activé`, disabled: `Désactivé`, diff --git a/static/webui/translations/ru.js b/static/webui/translations/ru.js index c582b56b..69923f3b 100644 --- a/static/webui/translations/ru.js +++ b/static/webui/translations/ru.js @@ -246,6 +246,8 @@ dict = { worldState_baroTennoConRelay: `Реле Баро TennoCon`, worldState_starDays: `Звёздные дни`, worldState_galleonOfGhouls: `Галеон Гулей`, + worldState_anniversary: `Годовщина Warframe`, + worldState_useAnniversaryTagForOldGoals: `Использовать Tag из Годовщины Warframe для старых событий`, worldState_ghoulEmergence: `Избавление от гулей`, worldState_plagueStar: `Чумная звезда`, worldState_dogDays: `Знойные дни`, @@ -262,8 +264,9 @@ dict = { worldState_bellyOfTheBeastProgressOverride: `Прогресс Чрева зверя`, worldState_eightClaw: `Восемь когтей`, worldState_eightClawProgressOverride: `Прогресс Восьми когтей`, - worldState_from_year: `из |YEAR|`, - worldState_pre_year: `до |YEAR|`, + worldState_from_year: `из |VAL|`, + worldState_pre_year: `до |VAL|`, + worldState_week: `Неделя |VAL|`, worldState_incompatibleWith: `Несовместимо с:`, enabled: `Включено`, disabled: `Отключено`, diff --git a/static/webui/translations/uk.js b/static/webui/translations/uk.js index 1e9c0660..4271e5ee 100644 --- a/static/webui/translations/uk.js +++ b/static/webui/translations/uk.js @@ -246,6 +246,8 @@ dict = { worldState_baroTennoConRelay: `Реле Баро TennoCon`, worldState_starDays: `Зоряні дні`, worldState_galleonOfGhouls: `Гульський галеон`, + worldState_anniversary: `[UNTRANSLATED] Warframe Anniversary`, + worldState_useAnniversaryTagForOldGoals: `[UNTRANSLATED] Use Tag from Warframe Anniversary for old Events`, worldState_ghoulEmergence: `Зачищення від гулів`, worldState_plagueStar: `Морова зірка`, worldState_dogDays: `Спекотні дні`, @@ -262,8 +264,9 @@ dict = { worldState_bellyOfTheBeastProgressOverride: `Прогрес У лігві звіра`, worldState_eightClaw: `Вісім кігтів`, worldState_eightClawProgressOverride: `Прогрес Восьми кігтів`, - worldState_from_year: `з |YEAR|`, - worldState_pre_year: `до |YEAR|`, + worldState_from_year: `з |VAL|`, + worldState_pre_year: `до |VAL|`, + worldState_week: `[UNTRANSLATED] Week |VAL|`, worldState_incompatibleWith: `Несумісне з:`, enabled: `Увімкнено`, disabled: `Вимкнено`, diff --git a/static/webui/translations/zh.js b/static/webui/translations/zh.js index 43964537..bba7c870 100644 --- a/static/webui/translations/zh.js +++ b/static/webui/translations/zh.js @@ -246,6 +246,8 @@ dict = { worldState_baroTennoConRelay: `Baro的TennoCon中继站`, worldState_starDays: `活动:星日`, worldState_galleonOfGhouls: `战术警报:尸鬼的帆船战舰`, + worldState_anniversary: `[UNTRANSLATED] Warframe Anniversary`, + worldState_useAnniversaryTagForOldGoals: `[UNTRANSLATED] Use Tag from Warframe Anniversary for old Events`, worldState_ghoulEmergence: `尸鬼净化`, worldState_plagueStar: `瘟疫之星`, worldState_dogDays: `三伏天`, @@ -262,8 +264,9 @@ dict = { worldState_bellyOfTheBeastProgressOverride: `[UNTRANSLATED] Belly of the Beast Progress`, worldState_eightClaw: `八爪`, worldState_eightClawProgressOverride: `[UNTRANSLATED] Eight Claw Progress`, - worldState_from_year: `[UNTRANSLATED] from |YEAR|`, - worldState_pre_year: `[UNTRANSLATED] pre |YEAR|`, + worldState_from_year: `[UNTRANSLATED] from |VAL|`, + worldState_pre_year: `[UNTRANSLATED] pre |VAL|`, + worldState_week: `[UNTRANSLATED] Week |VAL|`, worldState_incompatibleWith: `[UNTRANSLATED] Incompatible with:`, enabled: `启用`, disabled: `关闭/取消配置`, From 024b806af1f0821f06b19230e8ee1e9243d5adb3 Mon Sep 17 00:00:00 2001 From: AMelonInsideLemon <166175391+AMelonInsideLemon@users.noreply.github.com> Date: Sun, 17 Aug 2025 13:12:06 -0700 Subject: [PATCH 2/4] feat(webui): display Favorite items first (#2656) Closes #2653 Reviewed-on: https://onlyg.it/OpenWF/SpaceNinjaServer/pulls/2656 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> --- static/webui/script.js | 302 +++++++++++++++++++++-------------------- 1 file changed, 155 insertions(+), 147 deletions(-) diff --git a/static/webui/script.js b/static/webui/script.js index ebad506f..33fae749 100644 --- a/static/webui/script.js +++ b/static/webui/script.js @@ -662,166 +662,174 @@ function updateInventory() { "KubrowPets" ].forEach(category => { document.getElementById(category + "-list").innerHTML = ""; - data[category].forEach(item => { - const tr = document.createElement("tr"); - tr.setAttribute("data-item-type", item.ItemType); - { - const td = document.createElement("td"); - td.textContent = itemMap[item.ItemType]?.name ?? item.ItemType; - if (item.ItemName) { - const pipeIndex = item.ItemName.indexOf("|"); - if (pipeIndex != -1) { - td.textContent = item.ItemName.substr(1 + pipeIndex) + " " + td.textContent; - } else { - td.textContent = item.ItemName + " (" + td.textContent + ")"; + data[category] + .sort((a, b) => (b.Favorite ? 1 : 0) - (a.Favorite ? 1 : 0)) + .forEach(item => { + const tr = document.createElement("tr"); + tr.setAttribute("data-item-type", item.ItemType); + { + const td = document.createElement("td"); + td.textContent = itemMap[item.ItemType]?.name ?? item.ItemType; + if (item.ItemName) { + const pipeIndex = item.ItemName.indexOf("|"); + if (pipeIndex != -1) { + td.textContent = item.ItemName.substr(1 + pipeIndex) + " " + td.textContent; + } else { + td.textContent = item.ItemName + " (" + td.textContent + ")"; + } } + if (item.Details?.Name) { + td.textContent = item.Details.Name + " (" + td.textContent + ")"; + } + if (item.ModularParts && item.ModularParts.length) { + td.textContent += " ["; + item.ModularParts.forEach(part => { + td.textContent += " " + (itemMap[part]?.name ?? part) + ","; + }); + td.textContent = td.textContent.slice(0, -1) + " ]"; + } + tr.appendChild(td); } - if (item.Details?.Name) { - td.textContent = item.Details.Name + " (" + td.textContent + ")"; - } - if (item.ModularParts && item.ModularParts.length) { - td.textContent += " ["; - item.ModularParts.forEach(part => { - td.textContent += " " + (itemMap[part]?.name ?? part) + ","; - }); - td.textContent = td.textContent.slice(0, -1) + " ]"; - } - tr.appendChild(td); - } - { - const td = document.createElement("td"); - td.classList = "text-end text-nowrap"; + { + const td = document.createElement("td"); + td.classList = "text-end text-nowrap"; - let maxXP = Math.pow(uniqueLevelCaps[item.ItemType] ?? 30, 2) * 1000; - if ( - category != "Suits" && - category != "SpaceSuits" && - category != "Sentinels" && - category != "Hoverboards" && - category != "MechSuits" && - category != "MoaPets" && - category != "KubrowPets" - ) { - maxXP /= 2; - } - let anyExaltedMissingXP = false; - if (item.XP >= maxXP && item.ItemType in itemMap && "exalted" in itemMap[item.ItemType]) { - for (const exaltedType of itemMap[item.ItemType].exalted) { - const exaltedItem = data.SpecialItems.find(x => x.ItemType == exaltedType); - if (exaltedItem) { - const exaltedCap = itemMap[exaltedType]?.type == "weapons" ? 800_000 : 1_600_000; - if (exaltedItem.XP < exaltedCap) { - anyExaltedMissingXP = true; - break; + let maxXP = Math.pow(uniqueLevelCaps[item.ItemType] ?? 30, 2) * 1000; + if ( + category != "Suits" && + category != "SpaceSuits" && + category != "Sentinels" && + category != "Hoverboards" && + category != "MechSuits" && + category != "MoaPets" && + category != "KubrowPets" + ) { + maxXP /= 2; + } + let anyExaltedMissingXP = false; + if (item.XP >= maxXP && item.ItemType in itemMap && "exalted" in itemMap[item.ItemType]) { + for (const exaltedType of itemMap[item.ItemType].exalted) { + const exaltedItem = data.SpecialItems.find(x => x.ItemType == exaltedType); + if (exaltedItem) { + const exaltedCap = + itemMap[exaltedType]?.type == "weapons" ? 800_000 : 1_600_000; + if (exaltedItem.XP < exaltedCap) { + anyExaltedMissingXP = true; + break; + } } } } - } - if (item.XP < maxXP || anyExaltedMissingXP) { - const a = document.createElement("a"); - a.href = "#"; - a.onclick = function (event) { - event.preventDefault(); - revalidateAuthz().then(() => { - const promises = []; - if (item.XP < maxXP) { - promises.push(addGearExp(category, item.ItemId.$oid, maxXP - item.XP)); - } - if ("exalted" in itemMap[item.ItemType]) { - for (const exaltedType of itemMap[item.ItemType].exalted) { - const exaltedItem = data.SpecialItems.find(x => x.ItemType == exaltedType); - if (exaltedItem) { - const exaltedCap = - itemMap[exaltedType]?.type == "weapons" ? 800_000 : 1_600_000; - if (exaltedItem.XP < exaltedCap) { - promises.push( - addGearExp( - "SpecialItems", - exaltedItem.ItemId.$oid, - exaltedCap - exaltedItem.XP - ) - ); + if (item.XP < maxXP || anyExaltedMissingXP) { + const a = document.createElement("a"); + a.href = "#"; + a.onclick = function (event) { + event.preventDefault(); + revalidateAuthz().then(() => { + const promises = []; + if (item.XP < maxXP) { + promises.push(addGearExp(category, item.ItemId.$oid, maxXP - item.XP)); + } + if ("exalted" in itemMap[item.ItemType]) { + for (const exaltedType of itemMap[item.ItemType].exalted) { + const exaltedItem = data.SpecialItems.find( + x => x.ItemType == exaltedType + ); + if (exaltedItem) { + const exaltedCap = + itemMap[exaltedType]?.type == "weapons" ? 800_000 : 1_600_000; + if (exaltedItem.XP < exaltedCap) { + promises.push( + addGearExp( + "SpecialItems", + exaltedItem.ItemId.$oid, + exaltedCap - exaltedItem.XP + ) + ); + } } } } - } - Promise.all(promises).then(() => { - updateInventory(); + Promise.all(promises).then(() => { + updateInventory(); + }); }); - }); - }; - a.title = loc("code_maxRank"); - a.innerHTML = ``; - td.appendChild(a); - } - - if ( - ["Suits", "LongGuns", "Pistols", "Melee", "SpaceGuns", "SpaceMelee"].includes(category) || - modularWeapons.includes(item.ItemType) - ) { - const a = document.createElement("a"); - a.href = "/webui/detailedView?productCategory=" + category + "&itemId=" + item.ItemId.$oid; - a.innerHTML = ``; - td.appendChild(a); - } - - if (!(item.Features & 8) && modularWeapons.includes(item.ItemType)) { - const a = document.createElement("a"); - a.href = "#"; - a.onclick = function (event) { - event.preventDefault(); - gildEquipment(category, item.ItemId.$oid); - }; - a.title = loc("code_gild"); - a.innerHTML = ``; - td.appendChild(a); - } - if (category == "KubrowPets") { - const a = document.createElement("a"); - a.href = "#"; - a.onclick = function (event) { - event.preventDefault(); - maturePet(item.ItemId.$oid, !item.Details.IsPuppy); - }; - if (item.Details.IsPuppy) { - a.title = loc("code_mature"); - a.innerHTML = ``; - } else { - a.title = loc("code_unmature"); - a.innerHTML = ``; + }; + a.title = loc("code_maxRank"); + a.innerHTML = ``; + td.appendChild(a); } - td.appendChild(a); - } - { - const a = document.createElement("a"); - a.href = "#"; - a.onclick = function (event) { - event.preventDefault(); - const name = prompt(loc("code_renamePrompt")); - if (name !== null) { - renameGear(category, item.ItemId.$oid, name); + + if ( + ["Suits", "LongGuns", "Pistols", "Melee", "SpaceGuns", "SpaceMelee"].includes( + category + ) || + modularWeapons.includes(item.ItemType) + ) { + const a = document.createElement("a"); + a.href = + "/webui/detailedView?productCategory=" + category + "&itemId=" + item.ItemId.$oid; + a.innerHTML = ``; + td.appendChild(a); + } + + if (!(item.Features & 8) && modularWeapons.includes(item.ItemType)) { + const a = document.createElement("a"); + a.href = "#"; + a.onclick = function (event) { + event.preventDefault(); + gildEquipment(category, item.ItemId.$oid); + }; + a.title = loc("code_gild"); + a.innerHTML = ``; + td.appendChild(a); + } + if (category == "KubrowPets") { + const a = document.createElement("a"); + a.href = "#"; + a.onclick = function (event) { + event.preventDefault(); + maturePet(item.ItemId.$oid, !item.Details.IsPuppy); + }; + if (item.Details.IsPuppy) { + a.title = loc("code_mature"); + a.innerHTML = ``; + } else { + a.title = loc("code_unmature"); + a.innerHTML = ``; } - }; - a.title = loc("code_rename"); - a.innerHTML = ``; - td.appendChild(a); + td.appendChild(a); + } + { + const a = document.createElement("a"); + a.href = "#"; + a.onclick = function (event) { + event.preventDefault(); + const name = prompt(loc("code_renamePrompt")); + if (name !== null) { + renameGear(category, item.ItemId.$oid, name); + } + }; + a.title = loc("code_rename"); + a.innerHTML = ``; + td.appendChild(a); + } + { + const a = document.createElement("a"); + a.href = "#"; + a.onclick = function (event) { + event.preventDefault(); + document.getElementById(category + "-list").removeChild(tr); + disposeOfGear(category, item.ItemId.$oid); + }; + a.title = loc("code_remove"); + a.innerHTML = ``; + td.appendChild(a); + } + tr.appendChild(td); } - { - const a = document.createElement("a"); - a.href = "#"; - a.onclick = function (event) { - event.preventDefault(); - document.getElementById(category + "-list").removeChild(tr); - disposeOfGear(category, item.ItemId.$oid); - }; - a.title = loc("code_remove"); - a.innerHTML = ``; - td.appendChild(a); - } - tr.appendChild(td); - } - document.getElementById(category + "-list").appendChild(tr); - }); + document.getElementById(category + "-list").appendChild(tr); + }); }); document.getElementById("EvolutionProgress-list").innerHTML = ""; From 660c3f3ddf12df87c5f086beeaaeb9a8e1f3fb01 Mon Sep 17 00:00:00 2001 From: Sainan <63328889+Sainan@users.noreply.github.com> Date: Sun, 17 Aug 2025 13:12:29 -0700 Subject: [PATCH 3/4] fix(webui): differentiate between nonce invalidation & forced logout (#2658) Closes #2642 Reviewed-on: https://onlyg.it/OpenWF/SpaceNinjaServer/pulls/2658 Co-authored-by: Sainan <63328889+Sainan@users.noreply.github.com> Co-committed-by: Sainan <63328889+Sainan@users.noreply.github.com> --- src/controllers/api/loginController.ts | 3 +-- src/controllers/api/logoutController.ts | 3 +-- src/services/wsService.ts | 3 ++- static/webui/script.js | 5 ++++- 4 files changed, 8 insertions(+), 6 deletions(-) diff --git a/src/controllers/api/loginController.ts b/src/controllers/api/loginController.ts index 1de6104f..05329be4 100644 --- a/src/controllers/api/loginController.ts +++ b/src/controllers/api/loginController.ts @@ -88,8 +88,7 @@ export const loginController: RequestHandler = async (request, response) => { account.LastLogin = new Date(); await account.save(); - // Tell WebUI its nonce has been invalidated - sendWsBroadcastTo(account._id.toString(), { logged_out: true }); + sendWsBroadcastTo(account._id.toString(), { nonce_updated: true }); response.json(createLoginResponse(myAddress, myUrlBase, account.toJSON(), buildLabel)); }; diff --git a/src/controllers/api/logoutController.ts b/src/controllers/api/logoutController.ts index d290b1ee..bf7328a4 100644 --- a/src/controllers/api/logoutController.ts +++ b/src/controllers/api/logoutController.ts @@ -21,8 +21,7 @@ export const logoutController: RequestHandler = async (req, res) => { } ); if (stat.modifiedCount) { - // Tell WebUI its nonce has been invalidated - sendWsBroadcastTo(req.query.accountId as string, { logged_out: true }); + sendWsBroadcastTo(req.query.accountId as string, { nonce_updated: true }); } res.writeHead(200, { diff --git a/src/services/wsService.ts b/src/services/wsService.ts index fb4bbee3..e55293cd 100644 --- a/src/services/wsService.ts +++ b/src/services/wsService.ts @@ -73,8 +73,9 @@ interface IWsMsgToClient { auth_fail?: { isRegister: boolean; }; - logged_out?: boolean; + nonce_updated?: boolean; update_inventory?: boolean; + logged_out?: boolean; } const wsOnConnect = (ws: ws, req: http.IncomingMessage): void => { diff --git a/static/webui/script.js b/static/webui/script.js index 33fae749..6d598ddd 100644 --- a/static/webui/script.js +++ b/static/webui/script.js @@ -81,12 +81,15 @@ function openWebSocket() { single.loadRoute("/webui/"); } } - if ("logged_out" in msg) { + if ("nonce_updated" in msg) { sendAuth(); } if ("update_inventory" in msg) { updateInventory(); } + if ("logged_out" in msg) { + logout(); + } }; window.ws.onclose = function () { ws_is_open = false; From 956ba38b7da65a68b9ac51de86e15dd6f77a7cb4 Mon Sep 17 00:00:00 2001 From: Sainan <63328889+Sainan@users.noreply.github.com> Date: Sun, 17 Aug 2025 13:12:40 -0700 Subject: [PATCH 4/4] fix(webui): handle name already being taken at rename (#2659) Closes #2643 Reviewed-on: https://onlyg.it/OpenWF/SpaceNinjaServer/pulls/2659 Co-authored-by: Sainan <63328889+Sainan@users.noreply.github.com> Co-committed-by: Sainan <63328889+Sainan@users.noreply.github.com> --- static/webui/script.js | 17 ++++++++++++----- static/webui/translations/de.js | 1 + static/webui/translations/en.js | 1 + static/webui/translations/es.js | 1 + static/webui/translations/fr.js | 1 + static/webui/translations/ru.js | 1 + static/webui/translations/uk.js | 1 + static/webui/translations/zh.js | 1 + 8 files changed, 19 insertions(+), 5 deletions(-) diff --git a/static/webui/script.js b/static/webui/script.js index 6d598ddd..6feb4020 100644 --- a/static/webui/script.js +++ b/static/webui/script.js @@ -148,13 +148,20 @@ function doLogout() { } } -function renameAccount() { - const newname = window.prompt(loc("code_changeNameConfirm")); +function renameAccount(taken_name) { + const newname = window.prompt( + (taken_name ? loc("code_changeNameRetry").split("|NAME|").join(taken_name) + " " : "") + + loc("code_changeNameConfirm") + ); if (newname) { revalidateAuthz().then(() => { - fetch("/custom/renameAccount?" + window.authz + "&newname=" + newname).then(() => { - $(".displayname").text(newname); - updateLocElements(); + fetch("/custom/renameAccount?" + window.authz + "&newname=" + newname).then(res => { + if (res.status == 409) { + renameAccount(newname); + } else { + $(".displayname").text(newname); + updateLocElements(); + } }); }); } diff --git a/static/webui/translations/de.js b/static/webui/translations/de.js index 9add8618..b1d45481 100644 --- a/static/webui/translations/de.js +++ b/static/webui/translations/de.js @@ -10,6 +10,7 @@ dict = { code_loginFail: `Anmeldung fehlgeschlagen. Bitte überprüfe deine Angaben.`, code_regFail: `Registrierung fehlgeschlagen. Account existiert bereits?`, code_changeNameConfirm: `In welchen Namen möchtest du deinen Account umbenennen?`, + code_changeNameRetry: `[UNTRANSLATED] |NAME| is already taken.`, code_deleteAccountConfirm: `Bist du sicher, dass du deinen Account |DISPLAYNAME| (|EMAIL|) löschen möchtest? Diese Aktion kann nicht rückgängig gemacht werden.`, code_archgun: `Arch-Gewehr`, code_melee: `Nahkampf`, diff --git a/static/webui/translations/en.js b/static/webui/translations/en.js index 101e28ea..0603dc75 100644 --- a/static/webui/translations/en.js +++ b/static/webui/translations/en.js @@ -9,6 +9,7 @@ dict = { code_loginFail: `Login failed. Double-check the email and password.`, code_regFail: `Registration failed. Account already exists?`, code_changeNameConfirm: `What would you like to change your account name to?`, + code_changeNameRetry: `|NAME| is already taken.`, code_deleteAccountConfirm: `Are you sure you want to delete your account |DISPLAYNAME| (|EMAIL|)? This action cannot be undone.`, code_archgun: `Archgun`, code_melee: `Melee`, diff --git a/static/webui/translations/es.js b/static/webui/translations/es.js index e22a8fe2..54fb50ce 100644 --- a/static/webui/translations/es.js +++ b/static/webui/translations/es.js @@ -10,6 +10,7 @@ dict = { code_loginFail: `Error al iniciar sesión. Verifica el correo electrónico y la contraseña.`, code_regFail: `Error al registrar la cuenta. ¿Ya existe una cuenta con este correo?`, code_changeNameConfirm: `¿Qué nombre te gustaría ponerle a tu cuenta?`, + code_changeNameRetry: `[UNTRANSLATED] |NAME| is already taken.`, code_deleteAccountConfirm: `¿Estás seguro de que deseas eliminar tu cuenta |DISPLAYNAME| (|EMAIL|)? Esta acción es permanente.`, code_archgun: `Archcañón`, code_melee: `Cuerpo a cuerpo`, diff --git a/static/webui/translations/fr.js b/static/webui/translations/fr.js index 8a45cc08..e48f0179 100644 --- a/static/webui/translations/fr.js +++ b/static/webui/translations/fr.js @@ -10,6 +10,7 @@ dict = { code_loginFail: `Connexion échouée. Vérifiez le mot de passe.`, code_regFail: `Enregistrement impossible. Compte existant?`, code_changeNameConfirm: `Nouveau nom du compte :`, + code_changeNameRetry: `[UNTRANSLATED] |NAME| is already taken.`, code_deleteAccountConfirm: `Supprimer |DISPLAYNAME| (|EMAIL|) ? Cette action est irreversible.`, code_archgun: `Archgun`, code_melee: `Melee`, diff --git a/static/webui/translations/ru.js b/static/webui/translations/ru.js index 69923f3b..119afa5b 100644 --- a/static/webui/translations/ru.js +++ b/static/webui/translations/ru.js @@ -10,6 +10,7 @@ dict = { code_loginFail: `Не удалось войти. Проверьте адрес электронной почты и пароль.`, code_regFail: `Не удалось зарегистрироваться. Учетная запись уже существует?`, code_changeNameConfirm: `Какое имя вы хотите установить для своей учетной записи?`, + code_changeNameRetry: `[UNTRANSLATED] |NAME| is already taken.`, code_deleteAccountConfirm: `Вы уверены, что хотите удалить аккаунт |DISPLAYNAME| (|EMAIL|)? Это действие нельзя отменить.`, code_archgun: `Арч-Пушка`, code_melee: `Ближний бой`, diff --git a/static/webui/translations/uk.js b/static/webui/translations/uk.js index 4271e5ee..ba0815cc 100644 --- a/static/webui/translations/uk.js +++ b/static/webui/translations/uk.js @@ -10,6 +10,7 @@ dict = { code_loginFail: `Не вдалося увійти. Перевірте адресу електронної пошти та пароль.`, code_regFail: `Не вдалося зареєструватися. Обліковий запис вже існує?`, code_changeNameConfirm: `Яке ім'я ви хочете встановити для свого облікового запису?`, + code_changeNameRetry: `[UNTRANSLATED] |NAME| is already taken.`, code_deleteAccountConfirm: `Ви впевнені, що хочете видалити обліковий запис |DISPLAYNAME| (|EMAIL|)? Цю дію не можна скасувати.`, code_archgun: `Арк-гармата`, code_melee: `Холодна зброя`, diff --git a/static/webui/translations/zh.js b/static/webui/translations/zh.js index bba7c870..98357ff7 100644 --- a/static/webui/translations/zh.js +++ b/static/webui/translations/zh.js @@ -10,6 +10,7 @@ dict = { code_loginFail: `登录失败。请检查邮箱和密码。`, code_regFail: `注册失败。账号是否已存在?`, code_changeNameConfirm: `您想将账户名称更改为?`, + code_changeNameRetry: `[UNTRANSLATED] |NAME| is already taken.`, code_deleteAccountConfirm: `确定要删除您的账户 |DISPLAYNAME|(|EMAIL|) 吗?此操作不可撤销。`, code_archgun: `空战`, code_melee: `近战`,