From e2c378b6a9157d47df146b3e12334274af067a11 Mon Sep 17 00:00:00 2001 From: Sainan Date: Fri, 3 May 2024 10:37:24 +0200 Subject: [PATCH 1/5] feat: Clan creation & persistence --- src/controllers/api/createGuildController.ts | 31 ++++++++++++++++++++ src/controllers/api/getGuildController.ts | 21 ++++++++++++- src/models/guildModel.ts | 8 +++++ src/models/inventoryModels/inventoryModel.ts | 3 ++ src/routes/api.ts | 2 ++ src/types/guildTypes.ts | 20 +++++++++++++ src/types/inventoryTypes/inventoryTypes.ts | 3 ++ 7 files changed, 87 insertions(+), 1 deletion(-) create mode 100644 src/controllers/api/createGuildController.ts create mode 100644 src/models/guildModel.ts create mode 100644 src/types/guildTypes.ts diff --git a/src/controllers/api/createGuildController.ts b/src/controllers/api/createGuildController.ts new file mode 100644 index 00000000..fe041d4a --- /dev/null +++ b/src/controllers/api/createGuildController.ts @@ -0,0 +1,31 @@ +import { RequestHandler } from "express"; +import { getJSONfromString } from "@/src/helpers/stringHelpers"; +import { Inventory } from "@/src/models/inventoryModels/inventoryModel"; +import { Guild } from "@/src/models/guildModel"; +import { IGuild, guildDbToResponse } from "@/src/types/guildTypes"; + +const createGuildController: RequestHandler = async (req, res) => { + let payload = getJSONfromString(req.body.toString()); + + if (!payload.guildName) { + res.status(400); + return; + } + + // Create guild on database + let guild = new Guild({ + Name: payload.guildName as string + } satisfies IGuild); + await guild.save(); + + // Update account's guild + let inventory = await Inventory.findOne({ accountOwnerId: req.query.accountId }); + if (inventory) { + inventory.GuildId = guild._id; + await inventory.save(); + } + + res.json(guildDbToResponse(guild)); +}; + +export { createGuildController }; diff --git a/src/controllers/api/getGuildController.ts b/src/controllers/api/getGuildController.ts index 99cfb3f0..bc6e17ef 100644 --- a/src/controllers/api/getGuildController.ts +++ b/src/controllers/api/getGuildController.ts @@ -1,6 +1,25 @@ import { RequestHandler } from "express"; +import { Inventory } from "@/src/models/inventoryModels/inventoryModel"; +import { Guild } from "@/src/models/guildModel"; +import { guildDbToResponse } from "@/src/types/guildTypes"; -const getGuildController: RequestHandler = (_req, res) => { +const getGuildController: RequestHandler = async (req, res) => { + if (!req.query.accountId) { + res.status(400).json({ error: "accountId was not provided" }); + return; + } + const inventory = await Inventory.findOne({ accountOwnerId: req.query.accountId }); + if (!inventory) { + res.status(400).json({ error: "inventory was undefined" }); + return; + } + if (inventory.GuildId) { + const guild = await Guild.findOne({ _id: inventory.GuildId }); + if (guild) { + res.json(guildDbToResponse(guild)); + return; + } + } res.json({}); }; diff --git a/src/models/guildModel.ts b/src/models/guildModel.ts new file mode 100644 index 00000000..ba305338 --- /dev/null +++ b/src/models/guildModel.ts @@ -0,0 +1,8 @@ +import { IGuild, IDatabaseGuild } from "@/src/types/guildTypes"; +import { model, Schema } from "mongoose"; + +const guildSchema = new Schema({ + Name: { type: String, required: true } +}); + +export const Guild = model("Guild", guildSchema); diff --git a/src/models/inventoryModels/inventoryModel.ts b/src/models/inventoryModels/inventoryModel.ts index d7f3ae81..1e0d7984 100644 --- a/src/models/inventoryModels/inventoryModel.ts +++ b/src/models/inventoryModels/inventoryModel.ts @@ -874,6 +874,9 @@ const inventorySchema = new Schema( //You first Dialog with NPC or use new Item NodeIntrosCompleted: [String], + //Current guild id, if applicable. + GuildId: { type: Schema.Types.ObjectId, ref: "Guild" }, + //https://warframe.fandom.com/wiki/Heist //ProfitTaker(1-4) Example:"LocationTag": "EudicoHeists", "Jobs":Mission name CompletedJobChains: [completedJobChainsSchema], diff --git a/src/routes/api.ts b/src/routes/api.ts index 537e245e..3f68a958 100644 --- a/src/routes/api.ts +++ b/src/routes/api.ts @@ -43,6 +43,7 @@ import { setActiveShipController } from "@/src/controllers/api/setActiveShipCont import { updateThemeController } from "../controllers/api/updateThemeController"; import { getGuildController } from "@/src/controllers/api/getGuildController"; import { addFriendImageController } from "@/src/controllers/api/addFriendImageController"; +import { createGuildController } from "@/src/controllers/api/createGuildController"; const apiRouter = express.Router(); @@ -96,5 +97,6 @@ apiRouter.post("/saveLoadout.php", saveLoadoutController); apiRouter.post("/trainingResult.php", trainingResultController); apiRouter.post("/updateTheme.php", updateThemeController); apiRouter.post("/addFriendImage.php", addFriendImageController); +apiRouter.post("/createGuild.php", createGuildController); export { apiRouter }; diff --git a/src/types/guildTypes.ts b/src/types/guildTypes.ts new file mode 100644 index 00000000..211cdbf9 --- /dev/null +++ b/src/types/guildTypes.ts @@ -0,0 +1,20 @@ +import { Types } from "mongoose"; +import { IOid } from "@/src/types/commonTypes"; +import { toOid } from "@/src/helpers/inventoryHelpers"; + +export interface IGuild { + Name: string; +} + +export interface IDatabaseGuild extends IGuild { + _id: Types.ObjectId; +} + +export interface IGuildResponse extends IGuild { + _id: IOid; +} + +export function guildDbToResponse(guild: IDatabaseGuild): IGuildResponse { + (guild as IGuild as IGuildResponse)._id = toOid(guild._id); + return guild as IGuild as IGuildResponse; +} diff --git a/src/types/inventoryTypes/inventoryTypes.ts b/src/types/inventoryTypes/inventoryTypes.ts index 71f5ebac..0bec69da 100644 --- a/src/types/inventoryTypes/inventoryTypes.ts +++ b/src/types/inventoryTypes/inventoryTypes.ts @@ -21,6 +21,7 @@ export interface IInventoryDatabase | "TrainingDate" | "LoadOutPresets" | "Mailbox" + | "GuildId" | "PendingRecipes" | "Created" | "QuestKeys" @@ -32,6 +33,7 @@ export interface IInventoryDatabase TrainingDate: Date; // TrainingDate changed from IMongoDate to Date LoadOutPresets: Types.ObjectId; // LoadOutPresets changed from ILoadOutPresets to Types.ObjectId for population Mailbox: Types.ObjectId; // Mailbox changed from IMailbox to Types.ObjectId + GuildId?: Types.ObjectId; // GuildId changed from ?IOid to ?Types.ObjectId PendingRecipes: IPendingRecipe[]; QuestKeys: IQuestKeyDatabase[]; BlessingCooldown: Date; @@ -232,6 +234,7 @@ export interface IInventoryResponse { RecentVendorPurchases: Array; Hoverboards: IHoverboard[]; NodeIntrosCompleted: string[]; + GuildId?: IOid; CompletedJobChains: ICompletedJobChain[]; SeasonChallengeHistory: ISeasonChallengeHistory[]; MoaPets: IMoaPet[]; -- 2.47.2 From 2c0f69abbb5854219d8b3b5ff5974c9dbfb8cf2d Mon Sep 17 00:00:00 2001 From: Sainan Date: Fri, 3 May 2024 14:32:25 +0200 Subject: [PATCH 2/5] feat: Give user a clan key when creating a clan --- src/controllers/api/createGuildController.ts | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/src/controllers/api/createGuildController.ts b/src/controllers/api/createGuildController.ts index fe041d4a..ed679668 100644 --- a/src/controllers/api/createGuildController.ts +++ b/src/controllers/api/createGuildController.ts @@ -18,10 +18,19 @@ const createGuildController: RequestHandler = async (req, res) => { } satisfies IGuild); await guild.save(); - // Update account's guild + // Update inventory let inventory = await Inventory.findOne({ accountOwnerId: req.query.accountId }); if (inventory) { + // Set GuildId inventory.GuildId = guild._id; + + // Give clan key + inventory.LevelKeys ??= []; + inventory.LevelKeys.push({ + ItemType: "/Lotus/Types/Keys/DojoKey", + ItemCount: 1 + }); + await inventory.save(); } -- 2.47.2 From 029fcb754086a9e00649860d989d4786fa37e0dc Mon Sep 17 00:00:00 2001 From: Sainan Date: Fri, 3 May 2024 14:36:15 +0200 Subject: [PATCH 3/5] fix: Transform inventory's GuildId to IOid --- src/models/inventoryModels/inventoryModel.ts | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/models/inventoryModels/inventoryModel.ts b/src/models/inventoryModels/inventoryModel.ts index 1e0d7984..547c56aa 100644 --- a/src/models/inventoryModels/inventoryModel.ts +++ b/src/models/inventoryModels/inventoryModel.ts @@ -974,6 +974,9 @@ inventorySchema.set("toJSON", { inventoryResponse.TrainingDate = toMongoDate(inventoryDatabase.TrainingDate); inventoryResponse.Created = toMongoDate(inventoryDatabase.Created); + if (inventoryDatabase.GuildId) { + inventoryResponse.GuildId = toOid(inventoryDatabase.GuildId); + } if (inventoryResponse.BlessingCooldown) { inventoryResponse.BlessingCooldown = toMongoDate(inventoryDatabase.BlessingCooldown); } -- 2.47.2 From 6c5020ac1bef22732b120683fe15427d909d53ac Mon Sep 17 00:00:00 2001 From: Sainan Date: Fri, 3 May 2024 14:56:51 +0200 Subject: [PATCH 4/5] Add ICreateGuildRequest, assume the client formats it correctly --- src/controllers/api/createGuildController.ts | 11 +++-------- src/types/guildTypes.ts | 4 ++++ 2 files changed, 7 insertions(+), 8 deletions(-) diff --git a/src/controllers/api/createGuildController.ts b/src/controllers/api/createGuildController.ts index ed679668..22ec05b2 100644 --- a/src/controllers/api/createGuildController.ts +++ b/src/controllers/api/createGuildController.ts @@ -2,19 +2,14 @@ import { RequestHandler } from "express"; import { getJSONfromString } from "@/src/helpers/stringHelpers"; import { Inventory } from "@/src/models/inventoryModels/inventoryModel"; import { Guild } from "@/src/models/guildModel"; -import { IGuild, guildDbToResponse } from "@/src/types/guildTypes"; +import { IGuild, guildDbToResponse, ICreateGuildRequest } from "@/src/types/guildTypes"; const createGuildController: RequestHandler = async (req, res) => { - let payload = getJSONfromString(req.body.toString()); - - if (!payload.guildName) { - res.status(400); - return; - } + let payload: ICreateGuildRequest = getJSONfromString(req.body.toString()); // Create guild on database let guild = new Guild({ - Name: payload.guildName as string + Name: payload.guildName } satisfies IGuild); await guild.save(); diff --git a/src/types/guildTypes.ts b/src/types/guildTypes.ts index 211cdbf9..5aefda9e 100644 --- a/src/types/guildTypes.ts +++ b/src/types/guildTypes.ts @@ -18,3 +18,7 @@ export function guildDbToResponse(guild: IDatabaseGuild): IGuildResponse { (guild as IGuild as IGuildResponse)._id = toOid(guild._id); return guild as IGuild as IGuildResponse; } + +export interface ICreateGuildRequest { + guildName: string; +} -- 2.47.2 From 8bf25515658ef56d48730cbfcae3acedc81e358f Mon Sep 17 00:00:00 2001 From: Sainan Date: Sat, 4 May 2024 15:33:16 +0200 Subject: [PATCH 5/5] =?UTF-8?q?improve:=20Replace=20guildDbToResponse=20wi?= =?UTF-8?q?th=20=E2=9C=A8=E2=9C=A8=E2=9C=A8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/controllers/api/createGuildController.ts | 4 ++-- src/controllers/api/getGuildController.ts | 3 +-- src/models/guildModel.ts | 8 ++++++++ src/types/guildTypes.ts | 6 ------ 4 files changed, 11 insertions(+), 10 deletions(-) diff --git a/src/controllers/api/createGuildController.ts b/src/controllers/api/createGuildController.ts index 22ec05b2..c8828b03 100644 --- a/src/controllers/api/createGuildController.ts +++ b/src/controllers/api/createGuildController.ts @@ -2,7 +2,7 @@ import { RequestHandler } from "express"; import { getJSONfromString } from "@/src/helpers/stringHelpers"; import { Inventory } from "@/src/models/inventoryModels/inventoryModel"; import { Guild } from "@/src/models/guildModel"; -import { IGuild, guildDbToResponse, ICreateGuildRequest } from "@/src/types/guildTypes"; +import { IGuild, ICreateGuildRequest } from "@/src/types/guildTypes"; const createGuildController: RequestHandler = async (req, res) => { let payload: ICreateGuildRequest = getJSONfromString(req.body.toString()); @@ -29,7 +29,7 @@ const createGuildController: RequestHandler = async (req, res) => { await inventory.save(); } - res.json(guildDbToResponse(guild)); + res.json(guild); }; export { createGuildController }; diff --git a/src/controllers/api/getGuildController.ts b/src/controllers/api/getGuildController.ts index bc6e17ef..81dfde24 100644 --- a/src/controllers/api/getGuildController.ts +++ b/src/controllers/api/getGuildController.ts @@ -1,7 +1,6 @@ import { RequestHandler } from "express"; import { Inventory } from "@/src/models/inventoryModels/inventoryModel"; import { Guild } from "@/src/models/guildModel"; -import { guildDbToResponse } from "@/src/types/guildTypes"; const getGuildController: RequestHandler = async (req, res) => { if (!req.query.accountId) { @@ -16,7 +15,7 @@ const getGuildController: RequestHandler = async (req, res) => { if (inventory.GuildId) { const guild = await Guild.findOne({ _id: inventory.GuildId }); if (guild) { - res.json(guildDbToResponse(guild)); + res.json(guild); return; } } diff --git a/src/models/guildModel.ts b/src/models/guildModel.ts index ba305338..3d8cbc3b 100644 --- a/src/models/guildModel.ts +++ b/src/models/guildModel.ts @@ -1,8 +1,16 @@ import { IGuild, IDatabaseGuild } from "@/src/types/guildTypes"; import { model, Schema } from "mongoose"; +import { toOid } from "@/src/helpers/inventoryHelpers"; const guildSchema = new Schema({ Name: { type: String, required: true } }); +guildSchema.set("toJSON", { + virtuals: true, + transform(_document, guild) { + guild._id = toOid(guild._id); + } +}); + export const Guild = model("Guild", guildSchema); diff --git a/src/types/guildTypes.ts b/src/types/guildTypes.ts index 5aefda9e..30350ff4 100644 --- a/src/types/guildTypes.ts +++ b/src/types/guildTypes.ts @@ -1,6 +1,5 @@ import { Types } from "mongoose"; import { IOid } from "@/src/types/commonTypes"; -import { toOid } from "@/src/helpers/inventoryHelpers"; export interface IGuild { Name: string; @@ -14,11 +13,6 @@ export interface IGuildResponse extends IGuild { _id: IOid; } -export function guildDbToResponse(guild: IDatabaseGuild): IGuildResponse { - (guild as IGuild as IGuildResponse)._id = toOid(guild._id); - return guild as IGuild as IGuildResponse; -} - export interface ICreateGuildRequest { guildName: string; } -- 2.47.2