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: operation Atramentum (#3706)

Reviewed-on: https://onlyg.it/OpenWF/SpaceNinjaServer/pulls/3706 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>

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

代码差异

18 个文件 +135 -2
Modified config-vanilla.json +2 -0
@@ -80,6 +80,8 @@
80 80 "lunarNewYear": null,
81 81 "dogDaysOverride": null,
82 82 "dogDaysRewardsOverride": null,
83 "operationAtramentum": false,
84 "operationAtramentumProgressOverride": 0,
83 85 "bellyOfTheBeast": false,
84 86 "bellyOfTheBeastProgressOverride": 0,
85 87 "eightClaw": false,
Modified src/controllers/api/inboxController.ts +14 -0
@@ -279,6 +279,20 @@ const createNewEventMessages = async (account: TAccountDocument): Promise<void>
279 279 });
280 280 }
281 281
282 if (config.worldState?.operationAtramentum && !account.receivedEventMessage_operationAtramentum) {
283 account.receivedEventMessage_operationAtramentum = true;
284 newEventMessages.push({
285 sndr: "/Lotus/Language/Shadowgrapher/ZorbaName",
286 sub: "/Lotus/Language/Shadowgrapher/ShadowgrapherEventInboxSubject",
287 msg: "/Lotus/Language/Shadowgrapher/ShadowgrapherEventInboxBody",
288 icon: "/Lotus/Interface/Icons/Npcs/Syndicates/Zorba.png",
289 transmission: "/Lotus/Sounds/Dialog/Shadowgrapher/Vendor/DSGInbox0011AspirantZorba",
290 startDate: new Date(),
291 QuestReq: "/Lotus/Types/Keys/PriestFrameQuest/PriestQuestKeyChain",
292 CrossPlatform: true
293 });
294 }
295
282 296 if (newEventMessages.length === 0) {
283 297 return;
284 298 }
Modified src/controllers/custom/getItemListsController.ts +1 -1
@@ -548,7 +548,7 @@ const getItemListsController: RequestHandler = (req, response) => {
548 548 if (uniqueName.startsWith("/Lotus/Levels/ClanDojo/ComponentPropRecipes/GradivusDilemma")) {
549 549 const factionTag = uniqueName.includes("Corpus") ? "FC_CORPUS" : "FC_GRINEER";
550 550 const faction = ExportFactions[factionTag].name;
551 name += ` [${getString(faction, lang)}]`;
551 name += ` [${getString(faction || factionTag, lang)}]`;
552 552 }
553 553 res.VaultDecoRecipes.push({
554 554 uniqueName,
Modified src/models/inboxModel.ts +2 -0
@@ -38,6 +38,7 @@ export interface IMessage {
38 38 countedAtt?: ITypeCount[];
39 39 startDate?: Date;
40 40 endDate?: Date;
41 QuestReq?: string;
41 42 goalTag?: string;
42 43 CrossPlatform?: boolean;
43 44 arg?: Arg[];
@@ -115,6 +116,7 @@ const messageSchema = new Schema<IMessageDatabase>(
115 116 customData: String,
116 117 icon: String,
117 118 highPriority: Boolean,
119 QuestReq: String,
118 120 lowPrioNewPlayers: Boolean,
119 121 startDate: Date,
120 122 endDate: Date,
Modified src/models/loginModel.ts +2 -1
@@ -34,7 +34,8 @@ const databaseAccountSchema = new Schema<IDatabaseAccountJson>(
34 34 receivedEventMessage_affinityBoost: Boolean,
35 35 receivedEventMessage_resourceBoost: Boolean,
36 36 receivedEventMessage_galleonOfGhouls: Boolean,
37 receivedEventMessage_longShadow: Boolean
37 receivedEventMessage_longShadow: Boolean,
38 receivedEventMessage_operationAtramentum: Boolean
38 39 },
39 40 opts
40 41 );
Modified src/services/configService.ts +8 -0
@@ -93,6 +93,8 @@ export interface IConfig {
93 93 lunarNewYear?: string;
94 94 dogDaysOverride?: boolean;
95 95 dogDaysRewardsOverride?: number;
96 operationAtramentum?: boolean;
97 operationAtramentumProgressOverride?: number;
96 98 bellyOfTheBeast?: boolean;
97 99 bellyOfTheBeastProgressOverride?: number;
98 100 eightClaw?: boolean;
@@ -250,6 +252,12 @@ export const syncConfigWithDatabase = (): void => {
250 252 void Account.updateMany({}, { $unset: { receivedEventMessage_longShadow: 1 } }).then(() => {});
251 253 void Inbox.deleteMany({ goalTag: "NightwatchTacAlert" }).then(() => {});
252 254 }
255 if (!config.worldState?.operationAtramentum) {
256 void Account.updateMany({}, { $unset: { receivedEventMessage_operationAtramentum: 1 } }).then(() => {});
257 void Inbox.deleteMany({
258 transmission: "/Lotus/Sounds/Dialog/Shadowgrapher/Vendor/DSGInbox0011AspirantZorba"
259 }).then(() => {});
260 }
253 261 };
254 262
255 263 export const getReflexiveAddress = (request: Request): { myAddress: string; myUrlBase: string } => {
Modified src/services/guildService.ts +15 -0
@@ -979,5 +979,20 @@ export const goalGuildRewardByTag: Record<string, { guildGoals: number[][]; rewa
979 979 "/Lotus/Levels/ClanDojo/ComponentPropRecipes/MechEventTrophySilverRecipe",
980 980 "/Lotus/Levels/ClanDojo/ComponentPropRecipes/MechEventTrophyGoldRecipe"
981 981 ]
982 },
983 ShadowgrapherEvent: {
984 guildGoals: [
985 [84, 168, 252, 336],
986 [252, 504, 756, 1008],
987 [840, 1680, 2520, 3360],
988 [2520, 5040, 7560, 10080],
989 [8400, 16800, 25200, 33600]
990 ],
991 rewards: [
992 "/Lotus/Levels/ClanDojo/ComponentPropRecipes/ShadowgrapherEventPewterTrophyRecipe",
993 "/Lotus/Levels/ClanDojo/ComponentPropRecipes/ShadowgrapherEventBronzeTrophyRecipe",
994 "/Lotus/Levels/ClanDojo/ComponentPropRecipes/ShadowgrapherEventSilverTrophyRecipe",
995 "/Lotus/Levels/ClanDojo/ComponentPropRecipes/ShadowgrapherEventGoldTrophyRecipe"
996 ]
982 997 }
983 998 };
Modified src/services/missionInventoryUpdateService.ts +32 -0
@@ -711,6 +711,13 @@ export const addMissionInventoryUpdates = async (
711 711 const goal = getWorldState(account.BuildLabel).Goals.find(
712 712 x => x._id.$oid == uploadProgress._id.$oid
713 713 );
714 if (goal && goal.Tag == "ShadowgrapherEvent") {
715 if (inventoryUpdates.RewardInfo!.node == goal.Node) {
716 const extraCount = inventoryUpdates.Missions?.Tier ? 4 : 3;
717 uploadProgress.Best += extraCount;
718 uploadProgress.Count += extraCount;
719 }
720 }
714 721 if (goal && goal.Personal) {
715 722 inventory.PersonalGoalProgress ??= [];
716 723 const goalProgress = inventory.PersonalGoalProgress.find(x => x.goalId.equals(goal._id.$oid));
@@ -1363,6 +1370,31 @@ export const addMissionRewards = async (
1363 1370 }
1364 1371 }
1365 1372
1373 if (
1374 config.worldState?.operationAtramentum &&
1375 inventory.QuestKeys.some(x => x.ItemType.endsWith("PriestQuestKeyChain") && x.Completed) &&
1376 (!account.BuildLabel || version_compare(account.BuildLabel, gameToBuildVersion["42.0.0"]) >= 0) &&
1377 rewardInfo.nightmareMode
1378 ) {
1379 if (inventory.GuildId) {
1380 const goal = getWorldState(account.BuildLabel).Goals.find(x => x.Tag == "ShadowgrapherEvent");
1381 if (goal && goal.ClanGoal) {
1382 const guild = await Guild.findById(inventory.GuildId, "GoalProgress Tier VaultDecoRecipes");
1383 if (guild) {
1384 await handleGuildGoalProgress(guild, {
1385 Count: 10,
1386 Tag: goal.Tag,
1387 goalId: new Types.ObjectId(goal._id.$oid)
1388 });
1389 }
1390 }
1391 }
1392 MissionRewards.push({
1393 StoreItem: "/Lotus/StoreItems/Types/Gameplay/Shadowgrapher/Resources/ShadowgrapherEventResource",
1394 ItemCount: 10
1395 });
1396 }
1397
1366 1398 if (levelKeyName) {
1367 1399 const fixedLevelRewards = getLevelKeyRewards(levelKeyName, account.BuildLabel);
1368 1400 //logger.debug(`fixedLevelRewards ${fixedLevelRewards}`);
Modified src/services/worldStateService.ts +26 -0
@@ -3272,6 +3272,32 @@ export const getWorldState = (buildLabel?: string): IWorldState => {
3272 3272 pushGoalAlerts(worldState, "JadeShadows", buildLabel);
3273 3273 }
3274 3274
3275 if (
3276 config.worldState?.operationAtramentum &&
3277 (!buildLabel || version_compare(buildLabel, gameToBuildVersion["42.0.0"]) >= 0)
3278 ) {
3279 worldState.Goals.push({
3280 _id: { $oid: "69ce8b780000000000000000" },
3281 Activation: { $date: { $numberLong: "1738868400000" } },
3282 Expiry: { $date: { $numberLong: "2000000000000" } },
3283 Count: config.worldState.operationAtramentumProgressOverride ?? 0,
3284 HealthPct: (config.worldState.operationAtramentumProgressOverride ?? 0) / 100,
3285 Goal: 0,
3286 Personal: true,
3287 Community: true,
3288 ClanGoal: [72, 216, 648, 1944, 5832],
3289 Tag: "ShadowgrapherEvent",
3290 Faction: "FC_TENNO",
3291 Desc: "/Lotus/Language/Shadowgrapher/ShadowgrapherEventName",
3292 ToolTip: "/Lotus/Language/Shadowgrapher/ShadowgrapherShortEventDesc",
3293 Icon: "/Lotus/Interface/Icons/WorldStatePanel/OperationAntramentumIcon.png",
3294 ScoreLocTag: "/Lotus/Language/Shadowgrapher/ShadowgrapherEventScore",
3295 Node: "SolNode239",
3296 MissionKeyName: "/Lotus/Types/Keys/ShadowgrapherEventMission",
3297 ItemType: "/Lotus/Types/Gameplay/Shadowgrapher/Resources/ShadowgrapherEventResource"
3298 });
3299 }
3300
3275 3301 // <U39
3276 3302 if (config.worldState?.eightClaw && (!buildLabel || version_compare(buildLabel, "2025.06.23.11.39") >= 0)) {
3277 3303 worldState.Goals.push({
Modified src/types/loginTypes.ts +1 -0
@@ -40,6 +40,7 @@ export interface IDatabaseAccount extends IDatabaseAccountRequiredFields {
40 40 receivedEventMessage_resourceBoost?: boolean;
41 41 receivedEventMessage_galleonOfGhouls?: boolean;
42 42 receivedEventMessage_longShadow?: boolean;
43 receivedEventMessage_operationAtramentum?: boolean;
43 44 }
44 45
45 46 // Includes virtual ID
Modified static/webui/index.html +18 -0
@@ -1514,6 +1514,24 @@
1514 1514 </select>
1515 1515 </div>
1516 1516 </div>
1517 <div class="form-group mt-2 d-flex gap-2">
1518 <div class="flex-fill">
1519 <label class="form-label" for="worldState.operationAtramentum" data-loc="worldState_operationAtramentum"></label>
1520 <select class="form-control" id="worldState.operationAtramentum" data-default="false">
1521 <option value="true" data-loc="enabled"></option>
1522 <option value="false" data-loc="disabled"></option>
1523 </select>
1524 </div>
1525 <div class="flex-fill">
1526 <form class="form-group" onsubmit="doSaveConfigInt('worldState.operationAtramentumProgressOverride'); return false;">
1527 <label class="form-label" for="worldState.operationAtramentumProgressOverride" data-loc="worldState_operationAtramentumProgressOverride"></label>
1528 <div class="input-group">
1529 <input id="worldState.operationAtramentumProgressOverride" class="form-control" type="number" min="0" max="100" data-default="0" />
1530 <button class="btn btn-secondary" type="submit" data-loc="cheats_save"></button>
1531 </div>
1532 </form>
1533 </div>
1534 </div>
1517 1535 <div class="form-group mt-2 d-flex gap-2">
1518 1536 <div class="flex-fill">
1519 1537 <label class="form-label" for="worldState.bellyOfTheBeast" data-loc="worldState_bellyOfTheBeast"></label>
Modified static/webui/translations/de.js +2 -0
@@ -364,6 +364,8 @@ dict = {
364 364 worldState_eightClawProgressOverride: `Acht Klauen-Fortschritt`,
365 365 worldState_thermiaFractures: `Thermische Risse`,
366 366 worldState_thermiaFracturesProgressOverride: `Thermische Risse-Fortschritt`,
367 worldState_operationAtramentum: `Operation: Atramentum`,
368 worldState_operationAtramentumProgressOverride: `[UNTRANSLATED] Operation: Atramentum Progress`,
367 369 worldState_qtccAlerts: `Quest zum Kampf gegen Krebs-Alarmierungen`,
368 370 worldState_evilBaroStage: `Böser Baro`,
369 371 worldState_baroRelayOverride: `Baro Relais-Überschreibung`,
Modified static/webui/translations/en.js +2 -0
Modified static/webui/translations/es.js +2 -0
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