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: Kinematic Instant Messaging (#801)

a8fb9095
Sainan <sainan@calamity.inc>
提交于

代码差异

5 个文件 +219 -2
Added src/controllers/api/clearDialogueHistoryController.ts +23 -0
@@ -0,0 +1,23 @@
1 import { getInventory } from "@/src/services/inventoryService";
2 import { getAccountIdForRequest } from "@/src/services/loginService";
3 import { RequestHandler } from "express";
4
5 export const clearDialogueHistoryController: RequestHandler = async (req, res) => {
6 const accountId = await getAccountIdForRequest(req);
7 const inventory = await getInventory(accountId);
8 const request = JSON.parse(String(req.body)) as IClearDialogueRequest;
9 if (inventory.DialogueHistory && inventory.DialogueHistory.Dialogues) {
10 for (const dialogueName of request.Dialogues) {
11 const index = inventory.DialogueHistory.Dialogues.findIndex(x => x.DialogueName == dialogueName);
12 if (index != -1) {
13 inventory.DialogueHistory.Dialogues.splice(index, 1);
14 }
15 }
16 }
17 await inventory.save();
18 res.end();
19 };
20
21 interface IClearDialogueRequest {
22 Dialogues: string[];
23 }
Added src/controllers/api/saveDialogueController.ts +85 -0
@@ -0,0 +1,85 @@
1 import { getInventory } from "@/src/services/inventoryService";
2 import { getAccountIdForRequest } from "@/src/services/loginService";
3 import { ICompletedDialogue } from "@/src/types/inventoryTypes/inventoryTypes";
4 import { logger } from "@/src/utils/logger";
5 import { RequestHandler } from "express";
6
7 export const saveDialogueController: RequestHandler = async (req, res) => {
8 const accountId = await getAccountIdForRequest(req);
9 const request = JSON.parse(String(req.body)) as SaveDialogueRequest;
10 if ("YearIteration" in request) {
11 const inventory = await getInventory(accountId);
12 if (inventory.DialogueHistory) {
13 inventory.DialogueHistory.YearIteration = request.YearIteration;
14 } else {
15 inventory.DialogueHistory = { YearIteration: request.YearIteration };
16 }
17 await inventory.save();
18 res.end();
19 } else {
20 const inventory = await getInventory(accountId);
21 if (!inventory.DialogueHistory) {
22 throw new Error("bad inventory state");
23 }
24 if (request.QueuedDialogues.length != 0 || request.OtherDialogueInfos.length != 0) {
25 logger.error(`saveDialogue request not fully handled: ${String(req.body)}`);
26 }
27 inventory.DialogueHistory.Dialogues ??= [];
28 let dialogue = inventory.DialogueHistory.Dialogues.find(x => x.DialogueName == request.DialogueName);
29 if (!dialogue) {
30 dialogue =
31 inventory.DialogueHistory.Dialogues[
32 inventory.DialogueHistory.Dialogues.push({
33 Rank: 0,
34 Chemistry: 0,
35 AvailableDate: new Date(0),
36 AvailableGiftDate: new Date(0),
37 RankUpExpiry: new Date(0),
38 BountyChemExpiry: new Date(0),
39 Gifts: [],
40 Booleans: [],
41 Completed: [],
42 DialogueName: request.DialogueName
43 }) - 1
44 ];
45 }
46 dialogue.Rank = request.Rank;
47 dialogue.Chemistry = request.Chemistry;
48 //dialogue.QueuedDialogues = request.QueuedDialogues;
49 for (const bool of request.Booleans) {
50 dialogue.Booleans.push(bool);
51 }
52 for (const bool of request.ResetBooleans) {
53 const index = dialogue.Booleans.findIndex(x => x == bool);
54 if (index != -1) {
55 dialogue.Booleans.splice(index, 1);
56 }
57 }
58 dialogue.Completed.push(request.Data);
59 const tomorrowAt0Utc = (Math.trunc(Date.now() / (86400 * 1000)) + 1) * 86400 * 1000;
60 dialogue.AvailableDate = new Date(tomorrowAt0Utc);
61 await inventory.save();
62 res.json({
63 InventoryChanges: [],
64 AvailableDate: { $date: { $numberLong: tomorrowAt0Utc.toString() } }
65 });
66 }
67 };
68
69 type SaveDialogueRequest = SaveYearIterationRequest | SaveCompletedDialogueRequest;
70
71 interface SaveYearIterationRequest {
72 YearIteration: number;
73 }
74
75 interface SaveCompletedDialogueRequest {
76 DialogueName: string;
77 Rank: number;
78 Chemistry: number;
79 CompletionType: number;
80 QueuedDialogues: string[]; // unsure
81 Booleans: string[];
82 ResetBooleans: string[];
83 Data: ICompletedDialogue;
84 OtherDialogueInfos: string[]; // unsure
85 }
Modified src/models/inventoryModels/inventoryModel.ts +63 -2
@@ -47,7 +47,12 @@ import {
47 47 ICrewShipPilotWeapon,
48 48 IShipExterior,
49 49 IHelminthFoodRecord,
50 ICrewShipMembersDatabase
50 ICrewShipMembersDatabase,
51 IDialogueHistoryDatabase,
52 IDialogueDatabase,
53 IDialogueGift,
54 ICompletedDialogue,
55 IDialogueClient
51 56 } from "../../types/inventoryTypes/inventoryTypes";
52 57 import { IOid } from "../../types/commonTypes";
53 58 import {
@@ -710,6 +715,60 @@ crewShipSchema.set("toJSON", {
710 715 }
711 716 });
712 717
718 const dialogueGiftSchema = new Schema<IDialogueGift>(
719 {
720 Item: String,
721 GiftedQuantity: Number
722 },
723 { _id: false }
724 );
725
726 const completedDialogueSchema = new Schema<ICompletedDialogue>(
727 {
728 Id: { type: String, required: true },
729 Booleans: { type: [String], required: true },
730 Choices: { type: [Number], required: true }
731 },
732 { _id: false }
733 );
734
735 const dialogueSchema = new Schema<IDialogueDatabase>(
736 {
737 Rank: Number,
738 Chemistry: Number,
739 AvailableDate: Date,
740 AvailableGiftDate: Date,
741 RankUpExpiry: Date,
742 BountyChemExpiry: Date,
743 //QueuedDialogues: ???
744 Gifts: { type: [dialogueGiftSchema], default: [] },
745 Booleans: { type: [String], default: [] },
746 Completed: { type: [completedDialogueSchema], default: [] },
747 DialogueName: String
748 },
749 { _id: false }
750 );
751 dialogueSchema.set("toJSON", {
752 virtuals: true,
753 transform(_doc, ret) {
754 const db = ret as IDialogueDatabase;
755 const client = ret as IDialogueClient;
756
757 client.AvailableDate = toMongoDate(db.AvailableDate);
758 client.AvailableGiftDate = toMongoDate(db.AvailableGiftDate);
759 client.RankUpExpiry = toMongoDate(db.RankUpExpiry);
760 client.BountyChemExpiry = toMongoDate(db.BountyChemExpiry);
761 }
762 });
763
764 const dialogueHistorySchema = new Schema<IDialogueHistoryDatabase>(
765 {
766 YearIteration: { type: Number, required: true },
767 Dialogues: { type: [dialogueSchema], required: false }
768 },
769 { _id: false }
770 );
771
713 772 const inventorySchema = new Schema<IInventoryDatabase, InventoryDocumentProps>(
714 773 {
715 774 accountOwnerId: Schema.Types.ObjectId,
@@ -1069,7 +1128,9 @@ const inventorySchema = new Schema<IInventoryDatabase, InventoryDocumentProps>(
1069 1128 //Grustag three
1070 1129 DeathSquadable: Boolean,
1071 1130
1072 EndlessXP: { type: [endlessXpProgressSchema], default: undefined }
1131 EndlessXP: { type: [endlessXpProgressSchema], default: undefined },
1132
1133 DialogueHistory: dialogueHistorySchema
1073 1134 },
1074 1135 { timestamps: { createdAt: "Created" } }
1075 1136 );
Modified src/routes/api.ts +4 -0
@@ -6,6 +6,7 @@ import { archonFusionController } from "@/src/controllers/api/archonFusionContro
6 6 import { artifactsController } from "../controllers/api/artifactsController";
7 7 import { checkDailyMissionBonusController } from "@/src/controllers/api/checkDailyMissionBonusController";
8 8 import { claimCompletedRecipeController } from "@/src/controllers/api/claimCompletedRecipeController";
9 import { clearDialogueHistoryController } from "@/src/controllers/api/clearDialogueHistoryController";
9 10 import { createGuildController } from "@/src/controllers/api/createGuildController";
10 11 import { creditsController } from "@/src/controllers/api/creditsController";
11 12 import { deleteSessionController } from "@/src/controllers/api/deleteSessionController";
@@ -52,6 +53,7 @@ import { projectionManagerController } from "../controllers/api/projectionManage
52 53 import { purchaseController } from "@/src/controllers/api/purchaseController";
53 54 import { queueDojoComponentDestructionController } from "@/src/controllers/api/queueDojoComponentDestructionController";
54 55 import { rerollRandomModController } from "@/src/controllers/api/rerollRandomModController";
56 import { saveDialogueController } from "@/src/controllers/api/saveDialogueController";
55 57 import { saveLoadoutController } from "@/src/controllers/api/saveLoadout";
56 58 import { sellController } from "@/src/controllers/api/sellController";
57 59 import { setActiveQuestController } from "@/src/controllers/api/setActiveQuestController";
@@ -118,6 +120,7 @@ apiRouter.post("/arcaneCommon.php", arcaneCommonController);
118 120 apiRouter.post("/archonFusion.php", archonFusionController);
119 121 apiRouter.post("/artifacts.php", artifactsController);
120 122 apiRouter.post("/claimCompletedRecipe.php", claimCompletedRecipeController);
123 apiRouter.post("/clearDialogueHistory.php", clearDialogueHistoryController);
121 124 apiRouter.post("/createGuild.php", createGuildController);
122 125 apiRouter.post("/endlessXp.php", endlessXpController);
123 126 apiRouter.post("/evolveWeapon.php", evolveWeaponController);
@@ -142,6 +145,7 @@ apiRouter.post("/playerSkills.php", playerSkillsController);
142 145 apiRouter.post("/projectionManager.php", projectionManagerController);
143 146 apiRouter.post("/purchase.php", purchaseController);
144 147 apiRouter.post("/rerollRandomMod.php", rerollRandomModController);
148 apiRouter.post("/saveDialogue.php", saveDialogueController);
145 149 apiRouter.post("/saveLoadout.php", saveLoadoutController);
146 150 apiRouter.post("/sell.php", sellController);
147 151 apiRouter.post("/setEquippedInstrument.php", setEquippedInstrumentController);
Modified src/types/inventoryTypes/inventoryTypes.ts +44 -0
@@ -306,6 +306,7 @@ export interface IInventoryResponse extends IDailyAffiliations {
306 306 Harvestable: boolean;
307 307 DeathSquadable: boolean;
308 308 EndlessXP?: IEndlessXpProgress[];
309 DialogueHistory?: IDialogueHistoryDatabase;
309 310 }
310 311
311 312 export interface IAffiliation {
@@ -948,3 +949,46 @@ export interface IEndlessXpProgress {
948 949 Category: TEndlessXpCategory;
949 950 Choices: string[];
950 951 }
952
953 export interface IDialogueHistoryClient {
954 YearIteration: number;
955 Dialogues?: IDialogueClient[];
956 }
957
958 export interface IDialogueHistoryDatabase {
959 YearIteration: number;
960 Dialogues?: IDialogueDatabase[];
961 }
962
963 export interface IDialogueClient {
964 Rank: number;
965 Chemistry: number;
966 AvailableDate: IMongoDate;
967 AvailableGiftDate: IMongoDate;
968 RankUpExpiry: IMongoDate;
969 BountyChemExpiry: IMongoDate;
970 //QueuedDialogues: any[];
971 Gifts: IDialogueGift[];
972 Booleans: string[];
973 Completed: ICompletedDialogue[];
974 DialogueName: string;
975 }
976
977 export interface IDialogueDatabase
978 extends Omit<IDialogueClient, "AvailableDate" | "AvailableGiftDate" | "RankUpExpiry" | "BountyChemExpiry"> {
979 AvailableDate: Date;
980 AvailableGiftDate: Date;
981 RankUpExpiry: Date;
982 BountyChemExpiry: Date;
983 }
984
985 export interface IDialogueGift {
986 Item: string;
987 GiftedQuantity: number;
988 }
989
990 export interface ICompletedDialogue {
991 Id: string;
992 Booleans: string[];
993 Choices: number[];
994 }