返回提交历史
Modified
config-vanilla.json
+2
-0
Modified
src/controllers/api/inboxController.ts
+14
-0
Modified
src/controllers/custom/getItemListsController.ts
+1
-1
Modified
src/models/inboxModel.ts
+2
-0
Modified
src/models/loginModel.ts
+2
-1
Modified
src/services/configService.ts
+8
-0
Modified
src/services/guildService.ts
+15
-0
Modified
src/services/missionInventoryUpdateService.ts
+32
-0
Modified
src/services/worldStateService.ts
+26
-0
Modified
src/types/loginTypes.ts
+1
-0
Modified
static/webui/index.html
+18
-0
Modified
static/webui/translations/de.js
+2
-0
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
XFEstudio/SpaceNinjaServer
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
代码差异
18 个文件
+135
-2
@@ -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,
@@ -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
}
@@ -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,
@@ -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,
@@ -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
);
@@ -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 } => {
@@ -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
};
@@ -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}`);
@@ -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({
@@ -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
@@ -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>
@@ -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`,