chore(webui): update German translation #2587

Merged
Sainan merged 5 commits from Animan8000/SpaceNinjaServer:animan8000-patch-1 into main 2025-08-05 09:47:25 -07:00
22 changed files with 279 additions and 60 deletions
Showing only changes of commit cc7bd86811 - Show all commits

View File

@ -14,7 +14,7 @@ jobs:
with:
node-version: ">=20.6.0"
- run: npm ci
- run: cp config.json.example config.json
- run: cp config-vanilla.json config.json
- run: npm run verify
- run: npm run lint:ci
- run: npm run prettier

View File

@ -2,4 +2,4 @@ src/routes/api.ts
static/webui/libs/
*.html
*.md
config.json.example
config-vanilla.json

View File

@ -10,7 +10,7 @@ To get an idea of what functionality you can expect to be missing [have a look t
## config.json
SpaceNinjaServer requires a `config.json`. To set it up, you can copy the [config.json.example](config.json.example), which has most cheats disabled.
SpaceNinjaServer requires a `config.json`. To set it up, you can copy the [config-vanilla.json](config-vanilla.json), which has most cheats disabled.
- `logger.level` can be `fatal`, `error`, `warn`, `info`, `http`, `debug`, or `trace`.
- `myIrcAddresses` can be used to point to an IRC server. If not provided, defaults to `[ myAddress ]`.

View File

@ -70,8 +70,9 @@
"creditBoost": false,
"affinityBoost": false,
"resourceBoost": false,
"starDays": true,
"tennoLiveRelay": false,
"galleonOfGhouls": 0,
"starDaysOverride": null,
"eidolonOverride": "",
"vallisOverride": "",
"duviriOverride": "",

View File

@ -2,7 +2,7 @@
set -e
if [ ! -f conf/config.json ]; then
jq --arg value "mongodb://openwfagent:spaceninjaserver@mongodb:27017/" '.mongodbUrl = $value' /app/config.json.example > /app/conf/config.json
jq --arg value "mongodb://openwfagent:spaceninjaserver@mongodb:27017/" '.mongodbUrl = $value' /app/config-vanilla.json > /app/conf/config.json
fi
exec npm run start -- --configPath conf/config.json

View File

@ -335,6 +335,17 @@ export const getInventoryResponse = async (
for (const uniqueName in ExportFlavour) {
inventoryResponse.FlavourItems.push({ ItemType: uniqueName });
}
} else if (config.worldState?.baroTennoConRelay) {
[
"/Lotus/Types/Items/Events/TennoConRelay2022EarlyAccess",
"/Lotus/Types/Items/Events/TennoConRelay2023EarlyAccess",
"/Lotus/Types/Items/Events/TennoConRelay2024EarlyAccess",
"/Lotus/Types/Items/Events/TennoConRelay2025EarlyAccess"
].forEach(uniqueName => {
if (!inventoryResponse.FlavourItems.some(x => x.ItemType == uniqueName)) {
inventoryResponse.FlavourItems.push({ ItemType: uniqueName });
}
});
}
if (config.unlockAllSkins) {

View File

@ -10,6 +10,7 @@ import { logger } from "@/src/utils/logger";
export const updateChallengeProgressController: RequestHandler = async (req, res) => {
const challenges = getJSONfromString<IUpdateChallengeProgressRequest>(String(req.body));
const account = await getAccountForRequest(req);
logger.debug(`challenge report:`, challenges);
const inventory = await getInventory(
account._id.toString(),
@ -17,7 +18,7 @@ export const updateChallengeProgressController: RequestHandler = async (req, res
);
let affiliationMods: IAffiliationMods[] = [];
if (challenges.ChallengeProgress) {
affiliationMods = addChallenges(
affiliationMods = await addChallenges(
account,
inventory,
challenges.ChallengeProgress,

View File

@ -7,7 +7,7 @@ try {
if (fs.existsSync("config.json")) {
console.log("Failed to load " + configPath + ": " + (e as Error).message);
} else {
console.log("Failed to load " + configPath + ". You can copy config.json.example to create your config file.");
console.log("Failed to load " + configPath + ". You can copy config-vanilla.json to create your config file.");
}
process.exit(1);
}

View File

@ -81,8 +81,10 @@ export interface IConfig {
creditBoost?: boolean;
affinityBoost?: boolean;
resourceBoost?: boolean;
starDays?: boolean;
tennoLiveRelay?: boolean;
baroTennoConRelay?: boolean;
galleonOfGhouls?: number;
starDaysOverride?: boolean;
eidolonOverride?: string;
vallisOverride?: string;
duviriOverride?: string;

View File

@ -25,7 +25,8 @@ import {
INemesisWeaponTargetFingerprint,
INemesisPetTargetFingerprint,
IDialogueDatabase,
IKubrowPetPrintClient
IKubrowPetPrintClient,
equipmentKeys
} from "@/src/types/inventoryTypes/inventoryTypes";
import { IGenericUpdate, IUpdateNodeIntrosResponse } from "@/src/types/genericUpdate";
import { IKeyChainRequest, IMissionInventoryUpdateRequest } from "@/src/types/requestTypes";
@ -1341,7 +1342,7 @@ export const addStanding = (
// TODO: AffiliationMods support (Nightwave).
export const updateGeneric = async (data: IGenericUpdate, accountId: string): Promise<IUpdateNodeIntrosResponse> => {
const inventory = await getInventory(accountId, "NodeIntrosCompleted MiscItems");
const inventory = await getInventory(accountId, "NodeIntrosCompleted MiscItems ShipDecorations");
// Make it an array for easier parsing.
if (typeof data.NodeIntrosCompleted === "string") {
@ -1350,7 +1351,15 @@ export const updateGeneric = async (data: IGenericUpdate, accountId: string): Pr
const inventoryChanges: IInventoryChanges = {};
for (const node of data.NodeIntrosCompleted) {
if (node == "KayaFirstVisitPack") {
if (node == "TC2025") {
inventoryChanges.ShipDecorations = [
{
ItemType: "/Lotus/Types/Items/ShipDecos/TauGrineerLancerBobbleHead",
ItemCount: 1
}
];
addShipDecorations(inventory, inventoryChanges.ShipDecorations);
} else if (node == "KayaFirstVisitPack") {
inventoryChanges.MiscItems = [
{
ItemType: "/Lotus/Types/Items/MiscItems/1999FixedStickersPack",
@ -1903,25 +1912,87 @@ export const addLoreFragmentScans = (inventory: TInventoryDatabaseDocument, arr:
});
};
export const addChallenges = (
const challengeRewardsInboxMessages: Record<string, IMessageCreationTemplate> = {
SentEvoEphemeraRankOne: {
sub: "/Lotus/Language/Inbox/EvolvingEphemeraUnlockAName",
sndr: "/Lotus/Language/Bosses/Ordis",
msg: "/Lotus/Language/Inbox/EvolvingEphemeraUnlockADesc",
icon: "/Lotus/Interface/Icons/Npcs/Ordis.png",
att: ["/Lotus/Upgrades/Skins/Effects/NarmerEvolvingEphemeraB"]
},
SentEvoEphemeraRankTwo: {
sub: "/Lotus/Language/Inbox/EvolvingEphemeraUnlockBName",
sndr: "/Lotus/Language/Bosses/Ordis",
msg: "/Lotus/Language/Inbox/EvolvingEphemeraUnlockBDesc",
icon: "/Lotus/Interface/Icons/Npcs/Ordis.png",
att: ["/Lotus/Upgrades/Skins/Effects/NarmerEvolvingEphemeraC"]
},
SentEvoSyandanaRankOne: {
sub: "/Lotus/Language/Inbox/EvolvingSyandanaUnlockAName",
sndr: "/Lotus/Language/Bosses/Ordis",
msg: "/Lotus/Language/Inbox/EvolvingSyandanaUnlockADesc",
icon: "/Lotus/Interface/Icons/Npcs/Ordis.png",
att: ["/Lotus/Upgrades/Skins/Scarves/NarmerEvolvingSyandanaBCape"]
},
SentEvoSyandanaRankTwo: {
sub: "/Lotus/Language/Inbox/EvolvingSyandanaUnlockBName",
sndr: "/Lotus/Language/Bosses/Ordis",
msg: "/Lotus/Language/Inbox/EvolvingSyandanaUnlockBDesc",
icon: "/Lotus/Interface/Icons/Npcs/Ordis.png",
att: ["/Lotus/Upgrades/Skins/Scarves/NarmerEvolvingSyandanaCCape"]
},
SentEvoSekharaRankOne: {
sub: "/Lotus/Language/Inbox/EvolvingSekharaUnlockAName",
sndr: "/Lotus/Language/Bosses/Ordis",
msg: "/Lotus/Language/Inbox/EvolvingSekharaUnlockADesc",
icon: "/Lotus/Interface/Icons/Npcs/Ordis.png",
att: ["/Lotus/Upgrades/Skins/Clan/ZarimanEvolvingSekharaBadgeItemB"]
},
SentEvoSekharaRankTwo: {
sub: "/Lotus/Language/Inbox/EvolvingSekharaUnlockBName",
sndr: "/Lotus/Language/Bosses/Ordis",
msg: "/Lotus/Language/Inbox/EvolvingSekharaUnlockBDesc",
icon: "/Lotus/Interface/Icons/Npcs/Ordis.png",
att: ["/Lotus/Upgrades/Skins/Clan/ZarimanEvolvingSekharaBadgeItemC"]
}
};
export const addChallenges = async (
account: TAccountDocument,
inventory: TInventoryDatabaseDocument,
ChallengeProgress: IChallengeProgress[],
SeasonChallengeCompletions: ISeasonChallenge[] | undefined
): IAffiliationMods[] => {
ChallengeProgress.forEach(({ Name, Progress }) => {
const itemIndex = inventory.ChallengeProgress.findIndex(i => i.Name === Name);
if (itemIndex !== -1) {
inventory.ChallengeProgress[itemIndex].Progress = Progress;
): Promise<IAffiliationMods[]> => {
for (const { Name, Progress, Completed } of ChallengeProgress) {
let dbChallenge = inventory.ChallengeProgress.find(x => x.Name == Name);
if (dbChallenge) {
dbChallenge.Progress = Progress;
} else {
inventory.ChallengeProgress.push({ Name, Progress });
dbChallenge = { Name, Progress };
inventory.ChallengeProgress.push(dbChallenge);
}
if (Name.startsWith("Calendar")) {
addString(getCalendarProgress(inventory).SeasonProgress.ActivatedChallenges, Name);
}
});
if ((Completed?.length ?? 0) > (dbChallenge.Completed?.length ?? 0)) {
dbChallenge.Completed ??= [];
for (const completion of Completed!) {
if (dbChallenge.Completed.indexOf(completion) == -1) {
if (completion == "challengeRewards") {
if (Name in challengeRewardsInboxMessages) {
await createMessage(account._id, [challengeRewardsInboxMessages[Name]]);
dbChallenge.Completed.push(completion);
// Would love to somehow let the client know about inbox or inventory changes, but there doesn't seem to anything for updateChallengeProgress.
continue;
}
}
logger.warn(`ignoring unknown challenge completion`, { challenge: Name, completion });
}
}
}
}
const affiliationMods: IAffiliationMods[] = [];
if (SeasonChallengeCompletions) {
@ -2117,6 +2188,21 @@ export const cleanupInventory = (inventory: TInventoryDatabaseDocument): void =>
inventory.LotusCustomization.syancol = {};
}
}
{
let numFixed = 0;
for (const equipmentKey of equipmentKeys) {
for (const item of inventory[equipmentKey]) {
if (item.ModularParts?.length === 0) {
item.ModularParts = undefined;
++numFixed;
}
}
}
if (numFixed != 0) {
logger.debug(`removed ModularParts from ${numFixed} non-modular items`);
}
}
};
export const getDialogue = (inventory: TInventoryDatabaseDocument, dialogueName: string): IDialogueDatabase => {

View File

@ -292,7 +292,7 @@ export const addMissionInventoryUpdates = async (
addRecipes(inventory, value);
break;
case "ChallengeProgress":
addChallenges(account, inventory, value, inventoryUpdates.SeasonChallengeCompletions);
await addChallenges(account, inventory, value, inventoryUpdates.SeasonChallengeCompletions);
break;
case "FusionTreasures":
addFusionTreasures(inventory, value);

View File

@ -1038,13 +1038,13 @@ const pushVoidStorms = (arr: IVoidStorm[], hour: number): void => {
};
interface ITimeConstraint {
//name: string;
name: string;
isValidTime: (timeSecs: number) => boolean;
getIdealTimeBefore: (timeSecs: number) => number;
}
const eidolonDayConstraint: ITimeConstraint = {
//name: "eidolon day",
name: "eidolon day",
isValidTime: (timeSecs: number): boolean => {
const eidolonEpoch = 1391992660;
const eidolonCycle = Math.trunc((timeSecs - eidolonEpoch) / 9000);
@ -1062,7 +1062,7 @@ const eidolonDayConstraint: ITimeConstraint = {
};
const eidolonNightConstraint: ITimeConstraint = {
//name: "eidolon night",
name: "eidolon night",
isValidTime: (timeSecs: number): boolean => {
const eidolonEpoch = 1391992660;
const eidolonCycle = Math.trunc((timeSecs - eidolonEpoch) / 9000);
@ -1089,7 +1089,7 @@ const eidolonNightConstraint: ITimeConstraint = {
};
const venusColdConstraint: ITimeConstraint = {
//name: "venus cold",
name: "venus cold",
isValidTime: (timeSecs: number): boolean => {
const vallisEpoch = 1541837628;
const vallisCycle = Math.trunc((timeSecs - vallisEpoch) / 1600);
@ -1115,7 +1115,7 @@ const venusColdConstraint: ITimeConstraint = {
};
const venusWarmConstraint: ITimeConstraint = {
//name: "venus warm",
name: "venus warm",
isValidTime: (timeSecs: number): boolean => {
const vallisEpoch = 1541837628;
const vallisCycle = Math.trunc((timeSecs - vallisEpoch) / 1600);
@ -1157,6 +1157,25 @@ const getIdealTimeSatsifyingConstraints = (constraints: ITimeConstraint[]): numb
return timeSecs;
};
const fullyStockBaro = (vt: IVoidTrader): void => {
for (const armorSet of baro.armorSets) {
if (Array.isArray(armorSet[0])) {
for (const set of armorSet as IVoidTraderOffer[][]) {
for (const item of set) {
vt.Manifest.push(item);
}
}
} else {
for (const item of armorSet as IVoidTraderOffer[]) {
vt.Manifest.push(item);
}
}
}
for (const item of baro.rest) {
vt.Manifest.push(item);
}
};
const getVarziaRotation = (week: number): string => {
const seed = new SRng(week).randomInt(0, 100_000);
const rng = new SRng(seed);
@ -1321,7 +1340,7 @@ export const getWorldState = (buildLabel?: string): IWorldState => {
});
} else {
constraints.push({
//name: `duviri ${config.worldState.duviriOverride}`,
name: `duviri ${config.worldState.duviriOverride}`,
isValidTime: (timeSecs: number): boolean => {
const moodIndex = Math.trunc(timeSecs / 7200);
return moodIndex % 5 == desiredMood;
@ -1336,11 +1355,20 @@ export const getWorldState = (buildLabel?: string): IWorldState => {
}
}
const timeSecs = getIdealTimeSatsifyingConstraints(constraints);
if (constraints.length != 0) {
const delta = Math.trunc(Date.now() / 1000) - timeSecs;
if (delta > 1) {
logger.debug(
`reported time is ${delta} seconds behind real time to satisfy selected constraints (${constraints.map(x => x.name).join(", ")})`
);
}
}
const timeMs = timeSecs * 1000;
const day = Math.trunc((timeMs - EPOCH) / 86400000);
const week = Math.trunc(day / 7);
const weekStart = EPOCH + week * 604800000;
const weekEnd = weekStart + 604800000;
const date = new Date(timeMs);
const worldState: IWorldState = {
BuildLabel: typeof buildLabel == "string" ? buildLabel.split(" ").join("+") : buildConfig.buildLabel,
@ -1367,11 +1395,77 @@ export const getWorldState = (buildLabel?: string): IWorldState => {
worldState.PVPChallengeInstances = [];
}
if (config.worldState?.starDays) {
if (config.worldState?.tennoLiveRelay) {
worldState.Goals.push({
_id: {
$oid: "687bf9400000000000000000"
},
Activation: {
$date: {
$numberLong: "1752955200000"
}
},
Expiry: {
$date: {
$numberLong: "2000000000000"
}
},
Count: 0,
Goal: 0,
Success: 0,
Personal: true,
Desc: "/Lotus/Language/Locations/RelayStationTennoConB",
ToolTip: "/Lotus/Language/Locations/RelayStationTennoConDescB",
Icon: "/Lotus/Interface/Icons/Categories/IconTennoLive.png",
Tag: "TennoConRelayB",
Node: "TennoConBHUB6"
});
}
if (config.worldState?.baroTennoConRelay) {
worldState.Goals.push({
_id: { $oid: "687bb2f00000000000000000" },
Activation: { $date: { $numberLong: "1752937200000" } },
Expiry: { $date: { $numberLong: "2000000000000" } },
Count: 0,
Goal: 0,
Success: 0,
Personal: true,
//"Faction": "FC_GRINEER",
Desc: "/Lotus/Language/Locations/RelayStationTennoCon",
ToolTip: "/Lotus/Language/Locations/RelayStationTennoConDesc",
Icon: "/Lotus/Interface/Icons/Categories/IconTennoConSigil.png",
Tag: "TennoConRelay",
Node: "TennoConHUB2"
});
const vt: IVoidTrader = {
_id: { $oid: "687809030379266d790495c6" },
Activation: { $date: { $numberLong: "1752937200000" } },
Expiry: { $date: { $numberLong: "2000000000000" } },
Character: "Baro'Ki Teel",
Node: "TennoConHUB2",
Manifest: []
};
worldState.VoidTraders.push(vt);
fullyStockBaro(vt);
}
const isFebruary = date.getUTCMonth() == 1;
if (config.worldState?.starDaysOverride ?? isFebruary) {
worldState.Goals.push({
_id: { $oid: "67a4dcce2a198564d62e1647" },
Activation: { $date: { $numberLong: "1738868400000" } },
Expiry: { $date: { $numberLong: "2000000000000" } },
Activation: {
$date: {
$numberLong: config.worldState?.starDaysOverride
? "1738868400000"
: Date.UTC(date.getUTCFullYear(), date.getUTCMonth(), 1).toString()
}
},
Expiry: {
$date: {
$numberLong: config.worldState?.starDaysOverride
? "2000000000000"
: Date.UTC(date.getUTCFullYear(), date.getUTCMonth() + 1, 1).toString()
}
},
Count: 0,
Goal: 0,
Success: 0,
@ -1585,24 +1679,8 @@ export const getWorldState = (buildLabel?: string): IWorldState => {
};
worldState.VoidTraders.push(vt);
if (isBeforeNextExpectedWorldStateRefresh(timeMs, baroActualStart)) {
vt.Manifest = [];
if (config.baroFullyStocked) {
for (const armorSet of baro.armorSets) {
if (Array.isArray(armorSet[0])) {
for (const set of armorSet as IVoidTraderOffer[][]) {
for (const item of set) {
vt.Manifest.push(item);
}
}
} else {
for (const item of armorSet as IVoidTraderOffer[]) {
vt.Manifest.push(item);
}
}
}
for (const item of baro.rest) {
vt.Manifest.push(item);
}
fullyStockBaro(vt);
} else {
const rng = new SRng(new SRng(baroIndex).randomInt(0, 100_000));
// TOVERIFY: Constraint for upgrades amount?
@ -1823,7 +1901,10 @@ export const populateFissures = async (worldState: IWorldState): Promise<void> =
_id: toOid(fissure._id),
Region: meta.systemIndex + 1,
Seed: 1337,
Activation: toMongoDate(fissure.Activation),
Activation:
fissure.Activation.getTime() < Date.now() // Activation is in the past?
? { $date: { $numberLong: "1000000000000" } } // Let the client know 'explicitly' to avoid interference from time constraints.
: toMongoDate(fissure.Activation),
Expiry: toMongoDate(fissure.Expiry),
Node: fissure.Node,
MissionType: eMissionType[meta.missionIndex].tag,

View File

@ -74,6 +74,7 @@ export type IInventoryChanges = {
InfestedFoundry?: IInfestedFoundryClient;
Drones?: IDroneClient[];
MiscItems?: IMiscItem[];
ShipDecorations?: ITypeCount[];
EmailItems?: ITypeCount[];
CrewShipRawSalvage?: ITypeCount[];
Nemesis?: Partial<INemesisClient>;

View File

@ -431,7 +431,7 @@
{ "ItemType": "/Lotus/StoreItems/Types/Items/SongItems/KuvaLichLoginSongItem", "PrimePrice": 140, "RegularPrice": 170000 },
{ "ItemType": "/Lotus/StoreItems/Types/Items/ShipDecos/Plushies/PlushyBaro", "PrimePrice": 100, "RegularPrice": 125000 },
{ "ItemType": "/Lotus/StoreItems/Types/Items/ShipDecos/Plushies/PlushyInaros", "PrimePrice": 120, "RegularPrice": 90000 },
{ "ItemType": "/Lotus/Upgrades/Mods/Pistol/Expert/WeaponPistolFactionDamageMurmursExpert", "PrimePrice": 375, "RegularPrice": 130000 }
{ "ItemType": "/Lotus/StoreItems/Upgrades/Mods/Pistol/Expert/WeaponPistolFactionDamageMurmursExpert", "PrimePrice": 375, "RegularPrice": 130000 }
],
"allIfAny": [
[

View File

@ -926,8 +926,12 @@
<label class="form-check-label" for="worldState.resourceBoost" data-loc="worldState_resourceBoost"></label>
</div>
<div class="form-check">
<input class="form-check-input" type="checkbox" id="worldState.starDays" />
<label class="form-check-label" for="worldState.starDays" data-loc="worldState_starDays"></label>
<input class="form-check-input" type="checkbox" id="worldState.tennoLiveRelay" />
<label class="form-check-label" for="worldState.tennoLiveRelay" data-loc="worldState_tennoLiveRelay"></label>
</div>
<div class="form-check">
<input class="form-check-input" type="checkbox" id="worldState.baroTennoConRelay" />
<label class="form-check-label" for="worldState.baroTennoConRelay" data-loc="worldState_baroTennoConRelay"></label>
</div>
<div class="form-check">
<input class="form-check-input" type="checkbox" id="worldState.varziaFullyStocked" />
@ -942,6 +946,14 @@
<option value="3" data-loc="worldState_we3"></option>
</select>
</div>
<div class="form-group mt-2">
<label class="form-label" for="worldState.starDaysOverride" data-loc="worldState_starDays"></label>
<select class="form-control" id="worldState.starDaysOverride" data-default="null">
<option value="null" data-loc="normal"></option>
<option value="true" data-loc="enabled"></option>
<option value="false" data-loc="disabled"></option>
</select>
</div>
<div class="form-group mt-2">
<label class="form-label" for="worldState.eidolonOverride" data-loc="worldState_eidolonOverride"></label>
<select class="form-control" id="worldState.eidolonOverride" data-default="">

View File

@ -2098,7 +2098,13 @@ for (const id of uiConfigs) {
if (elm.tagName == "SELECT") {
elm.onchange = function () {
let value = this.value;
if (!isNaN(parseInt(value))) {
if (value == "true") {
value = true;
} else if (value == "false") {
value = false;
} else if (value == "null") {
value = null;
} else if (!isNaN(parseInt(value))) {
value = parseInt(value);
}
$.post({

View File

@ -242,8 +242,11 @@ dict = {
worldState_creditBoost: `Event Booster: Credit`,
worldState_affinityBoost: `Event Booster: Erfahrung`,
worldState_resourceBoost: `Event Booster: Ressourcen`,
worldState_tennoLiveRelay: `[UNTRANSLATED] TennoLive Relay`,
worldState_baroTennoConRelay: `[UNTRANSLATED] Baro's TennoCon Relay`,
worldState_starDays: `Sternen-Tage`,
worldState_galleonOfGhouls: `Galeone der Ghule`,
enabled: `[UNTRANSLATED] Enabled`,
disabled: `Deaktiviert`,
worldState_we1: `Wochenende 1`,
worldState_we2: `Wochenende 2`,

View File

@ -241,15 +241,18 @@ dict = {
worldState_creditBoost: `Credit Boost`,
worldState_affinityBoost: `Affinity Boost`,
worldState_resourceBoost: `Resource Boost`,
worldState_tennoLiveRelay: `TennoLive Relay`,
worldState_baroTennoConRelay: `Baro's TennoCon Relay`,
worldState_starDays: `Star Days`,
worldState_galleonOfGhouls: `Galleon of Ghouls`,
enabled: `Enabled`,
disabled: `Disabled`,
worldState_we1: `Weekend 1`,
worldState_we2: `Weekend 2`,
worldState_we3: `Weekend 3`,
worldState_eidolonOverride: `Eidolon Override`,
worldState_day: `Day`,
worldState_night: `Night`,
worldState_eidolonOverride: `Eidolon/Deimos Override`,
worldState_day: `Day/Fass`,
worldState_night: `Night/Vome`,
worldState_vallisOverride: `Orb Vallis Override`,
worldState_warm: `Warm`,
worldState_cold: `Cold`,

View File

@ -242,8 +242,11 @@ dict = {
worldState_creditBoost: `Potenciador de Créditos`,
worldState_affinityBoost: `Potenciador de Afinidad`,
worldState_resourceBoost: `Potenciador de Recursos`,
worldState_tennoLiveRelay: `[UNTRANSLATED] TennoLive Relay`,
worldState_baroTennoConRelay: `[UNTRANSLATED] Baro's TennoCon Relay`,
worldState_starDays: `Días estelares`,
worldState_galleonOfGhouls: `Galeón de Gules`,
enabled: `[UNTRANSLATED] Enabled`,
disabled: `Desactivado`,
worldState_we1: `Semana 1`,
worldState_we2: `Semana 2`,

View File

@ -242,8 +242,11 @@ dict = {
worldState_creditBoost: `Booster de Crédit`,
worldState_affinityBoost: `Booster d'Affinité`,
worldState_resourceBoost: `Booster de Ressource`,
worldState_tennoLiveRelay: `[UNTRANSLATED] TennoLive Relay`,
worldState_baroTennoConRelay: `[UNTRANSLATED] Baro's TennoCon Relay`,
worldState_starDays: `Jours Stellaires`,
worldState_galleonOfGhouls: `Galion des Goules`,
enabled: `[UNTRANSLATED] Enabled`,
disabled: `Désactivé`,
worldState_we1: `Weekend 1`,
worldState_we2: `Weekend 2`,

View File

@ -242,15 +242,18 @@ dict = {
worldState_creditBoost: `[UNTRANSLATED] Credit Boost`,
worldState_affinityBoost: `[UNTRANSLATED] Affinity Boost`,
worldState_resourceBoost: `[UNTRANSLATED] Resource Boost`,
worldState_tennoLiveRelay: `[UNTRANSLATED] TennoLive Relay`,
worldState_baroTennoConRelay: `[UNTRANSLATED] Baro's TennoCon Relay`,
worldState_starDays: `[UNTRANSLATED] Star Days`,
worldState_galleonOfGhouls: `[UNTRANSLATED] Galleon of Ghouls`,
enabled: `[UNTRANSLATED] Enabled`,
disabled: `[UNTRANSLATED] Disabled`,
worldState_we1: `[UNTRANSLATED] Weekend 1`,
worldState_we2: `[UNTRANSLATED] Weekend 2`,
worldState_we3: `[UNTRANSLATED] Weekend 3`,
worldState_eidolonOverride: `[UNTRANSLATED] Eidolon Override`,
worldState_day: `[UNTRANSLATED] Day`,
worldState_night: `[UNTRANSLATED] Night`,
worldState_eidolonOverride: `[UNTRANSLATED] Eidolon/Deimos Override`,
worldState_day: `[UNTRANSLATED] Day/Fass`,
worldState_night: `[UNTRANSLATED] Night/Vome`,
worldState_vallisOverride: `[UNTRANSLATED] Orb Vallis Override`,
worldState_warm: `[UNTRANSLATED] Warm`,
worldState_cold: `[UNTRANSLATED] Cold`,

View File

@ -156,8 +156,8 @@ dict = {
invigorations_defensiveLabel: `功能型属性`,
invigorations_expiryLabel: `活化时效(可选)`,
abilityOverride_label: `[UNTRANSLATED] Ability Override`,
abilityOverride_onSlot: `[UNTRANSLATED] on slot`,
abilityOverride_label: `技能替换`,
abilityOverride_onSlot: `槽位`,
mods_addRiven: `添加裂罅MOD`,
mods_fingerprint: `印记`,
@ -242,8 +242,11 @@ dict = {
worldState_creditBoost: `现金加成`,
worldState_affinityBoost: `经验加成`,
worldState_resourceBoost: `资源加成`,
worldState_tennoLiveRelay: `TennoLive 中继站`,
worldState_baroTennoConRelay: `[UNTRANSLATED] Baro's TennoCon Relay`,
worldState_starDays: `活动:星日`,
worldState_galleonOfGhouls: `战术警报:尸鬼的帆船战舰`,
enabled: `启用`,
disabled: `关闭/取消配置`,
worldState_we1: `活动阶段:第一周`,
worldState_we2: `活动阶段:第二周`,