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

SpaceNinjaServer

A simple server for a small space ninja game

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

XFEstudio/SpaceNinjaServer

feat: community synthesis settings (#4063)

Closes #3298 Reviewed-on: https://onlyg.it/OpenWF/SpaceNinjaServer/pulls/4063 Co-authored-by: Sainan <63328889+Sainan@users.noreply.github.com> Co-committed-by: Sainan <63328889+Sainan@users.noreply.github.com>

d3b4d56d
Sainan <63328889+Sainan@users.noreply.github.com>
提交于

代码差异

16 个文件 +94 -27
Modified config-vanilla.json +3 -1
@@ -112,7 +112,9 @@
112 112 "allTheFissures": "",
113 113 "varziaOverride": "",
114 114 "circuitGameModes": null,
115 "darvoStockMultiplier": 1
115 "darvoStockMultiplier": 1,
116 "communitySynthesisTarget": 0,
117 "communitySynthesisProgress": 0
116 118 },
117 119 "tunables": {
118 120 "useLoginToken": false,
Added src/constants/synthesis.ts +21 -0
@@ -0,0 +1,21 @@
1 export const libraryTargetToAvatar: Record<string, string> = {
2 "/Lotus/Types/Game/Library/Targets/DragonframeQuestTarget":
3 "/Lotus/Types/Enemies/Grineer/Desert/Avatars/RifleLancerAvatar",
4 "/Lotus/Types/Game/Library/Targets/Research1Target":
5 "/Lotus/Types/Enemies/Grineer/Desert/Avatars/RifleLancerAvatar",
6 "/Lotus/Types/Game/Library/Targets/Research2Target":
7 "/Lotus/Types/Enemies/Corpus/BipedRobot/AIWeek/LaserDiscBipedAvatar",
8 "/Lotus/Types/Game/Library/Targets/Research3Target":
9 "/Lotus/Types/Enemies/Grineer/Desert/Avatars/EvisceratorLancerAvatar",
10 "/Lotus/Types/Game/Library/Targets/Research4Target": "/Lotus/Types/Enemies/Orokin/OrokinHealingAncientAvatar",
11 "/Lotus/Types/Game/Library/Targets/Research5Target":
12 "/Lotus/Types/Enemies/Corpus/Spaceman/AIWeek/ShotgunSpacemanAvatar",
13 "/Lotus/Types/Game/Library/Targets/Research6Target": "/Lotus/Types/Enemies/Infested/AiWeek/Runners/RunnerAvatar",
14 "/Lotus/Types/Game/Library/Targets/Research7Target":
15 "/Lotus/Types/Enemies/Grineer/AIWeek/Avatars/GrineerMeleeStaffAvatar",
16 "/Lotus/Types/Game/Library/Targets/Research8Target": "/Lotus/Types/Enemies/Orokin/OrokinHeavyFemaleAvatar",
17 "/Lotus/Types/Game/Library/Targets/Research9Target":
18 "/Lotus/Types/Enemies/Infested/AiWeek/Quadrupeds/QuadrupedAvatar",
19 "/Lotus/Types/Game/Library/Targets/Research10Target":
20 "/Lotus/Types/Enemies/Corpus/Spaceman/AIWeek/NullifySpacemanAvatar"
21 };
Modified src/services/configService.ts +2 -0
@@ -116,6 +116,8 @@ export interface IConfig {
116 116 varziaOverride?: string;
117 117 circuitGameModes?: string[];
118 118 darvoStockMultiplier?: number;
119 communitySynthesisTarget?: number;
120 communitySynthesisProgress?: number;
119 121 };
120 122 tunables?: {
121 123 useLoginToken?: boolean;
Modified src/services/configWatcherService.ts +8 -1
@@ -15,6 +15,7 @@ import {
15 15 bootNonAdminsFromWebui,
16 16 forEachWsClient,
17 17 sendWsBroadcast,
18 sendWsBroadcastToGame,
18 19 sendWsBroadcastToWebui,
19 20 type IWsMsgToClient
20 21 } from "./wsService.ts";
@@ -27,6 +28,7 @@ import { createMessage } from "./inboxService.ts";
27 28 chokidar.watch(configPath).on("change", () => {
28 29 if (shouldReloadConfig()) {
29 30 const prevLogFormat = config.logger.format ?? "%timestamp% [%level%] %message%";
31 const prevWorldState = JSON.stringify(config.worldState);
30 32 const prevTunables = JSON.stringify(config.tunables);
31 33 const prevWebParams = JSON.stringify(getWebServerParams());
32 34
@@ -45,8 +47,13 @@ chokidar.watch(configPath).on("change", () => {
45 47 logger.debug("Here's some text to feast your eyes upon.");
46 48 }
47 49
50 if (JSON.stringify(config.worldState) != prevWorldState) {
51 logger.debug(`config.worldState changed, informing clients`);
52 sendWsBroadcastToGame(undefined, { sync_world_state: true });
53 }
54
48 55 if (JSON.stringify(config.tunables) != prevTunables) {
49 logger.debug(`tunables changed, informing clients`);
56 logger.debug(`config.tunables changed, informing clients`);
50 57 forEachWsClient(client => {
51 58 if (client.isGame) {
52 59 client.send(
Modified src/services/missionInventoryUpdateService.ts +2 -23
@@ -114,6 +114,7 @@ import { handleGuildGoalProgress } from "./guildService.ts";
114 114 import { importLoadOutConfig } from "./importService.ts";
115 115 import gameToBuildVersion from "../constants/gameToBuildVersion.ts";
116 116 import { corpusDeathSquadInfo, grineerDeathSquadInfo } from "./invasionService.ts";
117 import { libraryTargetToAvatar } from "../constants/synthesis.ts";
117 118
118 119 const getRotations = async (
119 120 rewardInfo: IRewardInfo,
@@ -509,7 +510,7 @@ export const addMissionInventoryUpdates = async (
509 510 value.forEach(scan => {
510 511 let synthesisIgnored = true;
511 512 if (inventory.LibraryPersonalTarget) {
512 const taskAvatar = libraryPersonalTargetToAvatar[inventory.LibraryPersonalTarget];
513 const taskAvatar = libraryTargetToAvatar[inventory.LibraryPersonalTarget];
513 514 const taskAvatars = libraryDailyTasks.find(x => x.indexOf(taskAvatar) != -1)!;
514 515 if (taskAvatars.indexOf(scan.EnemyType) != -1) {
515 516 let progress = inventory.LibraryPersonalProgress.find(
@@ -2904,28 +2905,6 @@ const corruptedMods = [
2904 2905 "/Lotus/StoreItems/Upgrades/Mods/Warframe/DualStat/FixedShieldAndShieldGatingDuration" // Catalyzing Shields
2905 2906 ];
2906 2907
2907 const libraryPersonalTargetToAvatar: Record<string, string> = {
2908 "/Lotus/Types/Game/Library/Targets/DragonframeQuestTarget":
2909 "/Lotus/Types/Enemies/Grineer/Desert/Avatars/RifleLancerAvatar",
2910 "/Lotus/Types/Game/Library/Targets/Research1Target":
2911 "/Lotus/Types/Enemies/Grineer/Desert/Avatars/RifleLancerAvatar",
2912 "/Lotus/Types/Game/Library/Targets/Research2Target":
2913 "/Lotus/Types/Enemies/Corpus/BipedRobot/AIWeek/LaserDiscBipedAvatar",
2914 "/Lotus/Types/Game/Library/Targets/Research3Target":
2915 "/Lotus/Types/Enemies/Grineer/Desert/Avatars/EvisceratorLancerAvatar",
2916 "/Lotus/Types/Game/Library/Targets/Research4Target": "/Lotus/Types/Enemies/Orokin/OrokinHealingAncientAvatar",
2917 "/Lotus/Types/Game/Library/Targets/Research5Target":
2918 "/Lotus/Types/Enemies/Corpus/Spaceman/AIWeek/ShotgunSpacemanAvatar",
2919 "/Lotus/Types/Game/Library/Targets/Research6Target": "/Lotus/Types/Enemies/Infested/AiWeek/Runners/RunnerAvatar",
2920 "/Lotus/Types/Game/Library/Targets/Research7Target":
2921 "/Lotus/Types/Enemies/Grineer/AIWeek/Avatars/GrineerMeleeStaffAvatar",
2922 "/Lotus/Types/Game/Library/Targets/Research8Target": "/Lotus/Types/Enemies/Orokin/OrokinHeavyFemaleAvatar",
2923 "/Lotus/Types/Game/Library/Targets/Research9Target":
2924 "/Lotus/Types/Enemies/Infested/AiWeek/Quadrupeds/QuadrupedAvatar",
2925 "/Lotus/Types/Game/Library/Targets/Research10Target":
2926 "/Lotus/Types/Enemies/Corpus/Spaceman/AIWeek/NullifySpacemanAvatar"
2927 };
2928
2929 2908 const chemistryBuddies: readonly string[] = [
2930 2909 "/Lotus/Types/Gameplay/1999Wf/Dialogue/JabirDialogue_rom.dialogue",
2931 2910 "/Lotus/Types/Gameplay/1999Wf/Dialogue/AoiDialogue_rom.dialogue",
Modified src/services/worldStateService.ts +18 -0
@@ -47,6 +47,7 @@ import gameToBuildVersion from "../constants/gameToBuildVersion.ts";
47 47 import { getDescent } from "./descentService.ts";
48 48 import { catBreadHash } from "../helpers/stringHelpers.ts";
49 49 import { Guild } from "../models/guildModel.ts";
50 import { libraryTargetToAvatar } from "../constants/synthesis.ts";
50 51
51 52 const sortieBosses = [
52 53 "SORTIE_BOSS_HYENA",
@@ -1893,6 +1894,7 @@ export const getWorldState = (buildLabel?: string): IWorldState => {
1893 1894 PrimeVaultTraders: [],
1894 1895 VoidStorms: [],
1895 1896 DailyDeals: [],
1897 //LibraryInfo: {},
1896 1898 EndlessXpChoices: [],
1897 1899 KnownCalendarSeasons: [],
1898 1900 PVPChallengeInstances: [],
@@ -4277,6 +4279,22 @@ export const getWorldState = (buildLabel?: string): IWorldState => {
4277 4279 pushSyndicateMissions(worldState, sdy, rng.randomInt(0, 100_000), "ba6f84724fa48061", "SteelMeridianSyndicate");
4278 4280 }
4279 4281
4282 if (config.worldState?.communitySynthesisTarget) {
4283 const targetType = `/Lotus/Types/Game/Library/Targets/Research${config.worldState.communitySynthesisTarget}Target`;
4284 worldState.LibraryInfo = {
4285 CurrentTarget: {
4286 StartTime: toMongoDate2(0, buildLabel),
4287 TargetType: targetType,
4288 EnemyType: libraryTargetToAvatar[targetType],
4289 PersonalScansRequired: 10,
4290 ProgressPercent: config.worldState.communitySynthesisProgress ?? 0
4291 }
4292 };
4293 if (config.worldState.communitySynthesisTarget != 1) {
4294 worldState.LibraryInfo.LastCompletedTargetType = `/Lotus/Types/Game/Library/Targets/Research${config.worldState.communitySynthesisTarget - 1}Target`;
4295 }
4296 }
4297
4280 4298 if (!buildLabel || version_compare(buildLabel, gameToBuildVersion["17.7.1"]) >= 0) {
4281 4299 if (!buildLabel || version_compare(buildLabel, gameToBuildVersion["18.0.2"]) >= 0) {
4282 4300 const conclaveWeekStart = weekStart + 40 * unixTimesInMs.minute - 2 * unixTimesInMs.day;
Modified src/services/wsService.ts +2 -2
@@ -317,10 +317,10 @@ export const sendWsBroadcastTo = (accountId: string, data: IWsMsgToClient): void
317 317 });
318 318 };
319 319
320 export const sendWsBroadcastToGame = (accountId: string, data: IWsMsgToClientGame): void => {
320 export const sendWsBroadcastToGame = (accountId: string | undefined, data: IWsMsgToClientGame): void => {
321 321 const msg = JSON.stringify(data);
322 322 forEachWsClient(client => {
323 if (client.isGame && client.accountId == accountId) {
323 if (client.isGame && (!accountId || client.accountId == accountId)) {
324 324 client.send(msg);
325 325 }
326 326 });
Modified src/types/worldStateTypes.ts +10 -0
@@ -24,6 +24,16 @@ export interface IWorldState {
24 24 PrimeVaultTraders: IPrimeVaultTrader[];
25 25 VoidStorms: IVoidStorm[];
26 26 DailyDeals: IDailyDeal[];
27 LibraryInfo?: {
28 CurrentTarget?: {
29 StartTime: IMongoDateWithLegacySupport;
30 TargetType: string;
31 EnemyType: string;
32 PersonalScansRequired: number;
33 ProgressPercent: number;
34 };
35 LastCompletedTargetType?: string;
36 };
27 37 PVPChallengeInstances: IPVPChallengeInstance[];
28 38 EndlessXpChoices: IEndlessXpChoice[];
29 39 FeaturedGuilds: IFeaturedGuild[];
Modified static/webui/index.html +14 -0
@@ -1696,6 +1696,20 @@
1696 1696 <button class="btn btn-secondary" type="submit" data-loc="cheats_save"></button>
1697 1697 </div>
1698 1698 </form>
1699 <form class="form-group mt-2" onsubmit="doSaveConfigInt('worldState.communitySynthesisTarget'); return false;">
1700 <label class="form-label" for="worldState.communitySynthesisTarget" data-loc="worldState_communitySynthesisTarget"></label>
1701 <div class="input-group">
1702 <input id="worldState.communitySynthesisTarget" class="form-control" type="number" data-default="0" />
1703 <button class="btn btn-secondary" type="submit" data-loc="cheats_save"></button>
1704 </div>
1705 </form>
1706 <form class="form-group mt-2" onsubmit="doSaveConfigFloat('worldState.communitySynthesisProgress'); return false;">
1707 <label class="form-label" for="worldState.communitySynthesisProgress" data-loc="worldState_communitySynthesisProgress"></label>
1708 <div class="input-group">
1709 <input id="worldState.communitySynthesisProgress" class="form-control" type="number" min="0" max="100" step="0.1" data-default="0" />
1710 <button class="btn btn-secondary" type="submit" data-loc="cheats_save"></button>
1711 </div>
1712 </form>
1699 1713 </div>
1700 1714 </div>
1701 1715 </div>
Modified static/webui/translations/de.js +2 -0
@@ -434,6 +434,8 @@ dict = {
434 434 worldState_allAtOnceSteelPath: `Alle gleichzeitig, Stählerne Pfad`,
435 435 worldState_theCircuitOverride: `Der Rundkurs-Überschreibung`,
436 436 worldState_darvoStockMultiplier: `Darvo-Vorratsmultiplikator`,
437 worldState_communitySynthesisTarget: `[UNTRANSLATED] Community Synthesis Target (0 to disable)`,
438 worldState_communitySynthesisProgress: `[UNTRANSLATED] Community Synthesis Progress`,
437 439 worldState_varziaFullyStocked: `Varzia hat volles Inventar`,
438 440 worldState_varziaOverride: `Varzia-Angebotsüberschreibung`,
439 441 worldState_vanguardVaultRelics: `Vanguard-Relikte`,
Modified static/webui/translations/en.js +2 -0
@@ -433,6 +433,8 @@ dict = {
433 433 worldState_allAtOnceSteelPath: `All At Once, Steel Path`,
434 434 worldState_theCircuitOverride: `The Circuit Override`,
435 435 worldState_darvoStockMultiplier: `Darvo Stock Multiplier`,
436 worldState_communitySynthesisTarget: `Community Synthesis Target (0 to disable)`,
437 worldState_communitySynthesisProgress: `Community Synthesis Progress`,
436 438 worldState_varziaFullyStocked: `Varzia Fully Stocked`,
437 439 worldState_varziaOverride: `Varzia Rotation Override`,
438 440 worldState_vanguardVaultRelics: `Vanguard Relics`,
Modified static/webui/translations/es.js +2 -0
@@ -434,6 +434,8 @@ dict = {
434 434 worldState_allAtOnceSteelPath: `Todo a la vez, Camino de Acero`,
435 435 worldState_theCircuitOverride: `Cambio del Circuito`,
436 436 worldState_darvoStockMultiplier: `Multiplicador de stock de Darvo`,
437 worldState_communitySynthesisTarget: `[UNTRANSLATED] Community Synthesis Target (0 to disable)`,
438 worldState_communitySynthesisProgress: `[UNTRANSLATED] Community Synthesis Progress`,
437 439 worldState_varziaFullyStocked: `Varzia con stock completo`,
438 440 worldState_varziaOverride: `Cambio en rotación de Varzia`,
439 441 worldState_vanguardVaultRelics: `Reliquias de Vanguardia`,
Modified static/webui/translations/fr.js +2 -0
Modified static/webui/translations/ru.js +2 -0
Modified static/webui/translations/uk.js +2 -0
Modified static/webui/translations/zh.js +2 -0