feat: view clan contributions (#1340)

Reviewed-on: OpenWF/SpaceNinjaServer#1340
This commit is contained in:
Sainan 2025-03-27 03:33:08 -07:00
parent 36c7b6f8f8
commit d9b944175a
9 changed files with 80 additions and 12 deletions

View File

@ -1,4 +1,4 @@
import { TGuildDatabaseDocument } from "@/src/models/guildModel"; import { GuildMember, TGuildDatabaseDocument } from "@/src/models/guildModel";
import { TInventoryDatabaseDocument } from "@/src/models/inventoryModels/inventoryModel"; import { TInventoryDatabaseDocument } from "@/src/models/inventoryModels/inventoryModel";
import { import {
getDojoClient, getDojoClient,
@ -10,7 +10,7 @@ import {
} from "@/src/services/guildService"; } from "@/src/services/guildService";
import { addMiscItems, getInventory, updateCurrency } from "@/src/services/inventoryService"; import { addMiscItems, getInventory, updateCurrency } from "@/src/services/inventoryService";
import { getAccountIdForRequest } from "@/src/services/loginService"; import { getAccountIdForRequest } from "@/src/services/loginService";
import { IDojoContributable } from "@/src/types/guildTypes"; import { IDojoContributable, IGuildMemberDatabase } from "@/src/types/guildTypes";
import { IMiscItem } from "@/src/types/inventoryTypes/inventoryTypes"; import { IMiscItem } from "@/src/types/inventoryTypes/inventoryTypes";
import { IInventoryChanges } from "@/src/types/purchaseTypes"; import { IInventoryChanges } from "@/src/types/purchaseTypes";
import { RequestHandler } from "express"; import { RequestHandler } from "express";
@ -35,6 +35,10 @@ export const contributeToDojoComponentController: RequestHandler = async (req, r
return; return;
} }
const guild = await getGuildForRequestEx(req, inventory); const guild = await getGuildForRequestEx(req, inventory);
const guildMember = (await GuildMember.findOne(
{ accountId, guildId: guild._id },
"RegularCreditsContributed MiscItemsContributed"
))!;
const request = JSON.parse(String(req.body)) as IContributeToDojoComponentRequest; const request = JSON.parse(String(req.body)) as IContributeToDojoComponentRequest;
const component = guild.DojoComponents.id(request.ComponentId)!; const component = guild.DojoComponents.id(request.ComponentId)!;
@ -45,7 +49,7 @@ export const contributeToDojoComponentController: RequestHandler = async (req, r
throw new Error("attempt to contribute to a deco in an unfinished room?!"); throw new Error("attempt to contribute to a deco in an unfinished room?!");
} }
const meta = Object.values(ExportDojoRecipes.rooms).find(x => x.resultType == component.pf)!; const meta = Object.values(ExportDojoRecipes.rooms).find(x => x.resultType == component.pf)!;
processContribution(guild, request, inventory, inventoryChanges, meta, component); processContribution(guild, guildMember, request, inventory, inventoryChanges, meta, component);
// eslint-disable-next-line @typescript-eslint/no-unnecessary-condition // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
if (component.CompletionTime) { if (component.CompletionTime) {
setDojoRoomLogFunded(guild, component); setDojoRoomLogFunded(guild, component);
@ -55,12 +59,13 @@ export const contributeToDojoComponentController: RequestHandler = async (req, r
if (request.DecoId) { if (request.DecoId) {
const deco = component.Decos!.find(x => x._id.equals(request.DecoId))!; const deco = component.Decos!.find(x => x._id.equals(request.DecoId))!;
const meta = Object.values(ExportDojoRecipes.decos).find(x => x.resultType == deco.Type)!; const meta = Object.values(ExportDojoRecipes.decos).find(x => x.resultType == deco.Type)!;
processContribution(guild, request, inventory, inventoryChanges, meta, deco); processContribution(guild, guildMember, request, inventory, inventoryChanges, meta, deco);
} }
} }
await guild.save(); await guild.save();
await inventory.save(); await inventory.save();
await guildMember.save();
res.json({ res.json({
...(await getDojoClient(guild, 0, component._id)), ...(await getDojoClient(guild, 0, component._id)),
InventoryChanges: inventoryChanges InventoryChanges: inventoryChanges
@ -69,6 +74,7 @@ export const contributeToDojoComponentController: RequestHandler = async (req, r
const processContribution = ( const processContribution = (
guild: TGuildDatabaseDocument, guild: TGuildDatabaseDocument,
guildMember: IGuildMemberDatabase,
request: IContributeToDojoComponentRequest, request: IContributeToDojoComponentRequest,
inventory: TInventoryDatabaseDocument, inventory: TInventoryDatabaseDocument,
inventoryChanges: IInventoryChanges, inventoryChanges: IInventoryChanges,
@ -80,6 +86,9 @@ const processContribution = (
component.RegularCredits += request.RegularCredits; component.RegularCredits += request.RegularCredits;
inventoryChanges.RegularCredits = -request.RegularCredits; inventoryChanges.RegularCredits = -request.RegularCredits;
updateCurrency(inventory, request.RegularCredits, false); updateCurrency(inventory, request.RegularCredits, false);
guildMember.RegularCreditsContributed ??= 0;
guildMember.RegularCreditsContributed += request.RegularCredits;
} }
if (request.VaultCredits) { if (request.VaultCredits) {
component.RegularCredits += request.VaultCredits; component.RegularCredits += request.VaultCredits;
@ -133,6 +142,9 @@ const processContribution = (
ItemType: ingredientContribution.ItemType, ItemType: ingredientContribution.ItemType,
ItemCount: ingredientContribution.ItemCount * -1 ItemCount: ingredientContribution.ItemCount * -1
}); });
guildMember.MiscItemsContributed ??= [];
guildMember.MiscItemsContributed.push(ingredientContribution);
} }
addMiscItems(inventory, miscItemChanges); addMiscItems(inventory, miscItemChanges);
inventoryChanges.MiscItems = miscItemChanges; inventoryChanges.MiscItems = miscItemChanges;

View File

@ -1,3 +1,4 @@
import { GuildMember } from "@/src/models/guildModel";
import { getGuildForRequestEx } from "@/src/services/guildService"; import { getGuildForRequestEx } from "@/src/services/guildService";
import { addFusionTreasures, addMiscItems, addShipDecorations, getInventory } from "@/src/services/inventoryService"; import { addFusionTreasures, addMiscItems, addShipDecorations, getInventory } from "@/src/services/inventoryService";
import { getAccountIdForRequest } from "@/src/services/loginService"; import { getAccountIdForRequest } from "@/src/services/loginService";
@ -8,23 +9,34 @@ export const contributeToVaultController: RequestHandler = async (req, res) => {
const accountId = await getAccountIdForRequest(req); const accountId = await getAccountIdForRequest(req);
const inventory = await getInventory(accountId); const inventory = await getInventory(accountId);
const guild = await getGuildForRequestEx(req, inventory); const guild = await getGuildForRequestEx(req, inventory);
const guildMember = (await GuildMember.findOne(
{ accountId, guildId: guild._id },
"RegularCreditsContributed MiscItemsContributed ShipDecorationsContributed"
))!;
const request = JSON.parse(String(req.body)) as IContributeToVaultRequest; const request = JSON.parse(String(req.body)) as IContributeToVaultRequest;
if (request.RegularCredits) { if (request.RegularCredits) {
guild.VaultRegularCredits ??= 0; guild.VaultRegularCredits ??= 0;
guild.VaultRegularCredits += request.RegularCredits; guild.VaultRegularCredits += request.RegularCredits;
guildMember.RegularCreditsContributed ??= 0;
guildMember.RegularCreditsContributed += request.RegularCredits;
} }
if (request.MiscItems.length) { if (request.MiscItems.length) {
guild.VaultMiscItems ??= []; guild.VaultMiscItems ??= [];
guildMember.MiscItemsContributed ??= [];
for (const item of request.MiscItems) { for (const item of request.MiscItems) {
guild.VaultMiscItems.push(item); guild.VaultMiscItems.push(item);
guildMember.MiscItemsContributed.push(item);
addMiscItems(inventory, [{ ...item, ItemCount: item.ItemCount * -1 }]); addMiscItems(inventory, [{ ...item, ItemCount: item.ItemCount * -1 }]);
} }
} }
if (request.ShipDecorations.length) { if (request.ShipDecorations.length) {
guild.VaultShipDecorations ??= []; guild.VaultShipDecorations ??= [];
guildMember.ShipDecorationsContributed ??= [];
for (const item of request.ShipDecorations) { for (const item of request.ShipDecorations) {
guild.VaultShipDecorations.push(item); guild.VaultShipDecorations.push(item);
guildMember.ShipDecorationsContributed.push(item);
addShipDecorations(inventory, [{ ...item, ItemCount: item.ItemCount * -1 }]); addShipDecorations(inventory, [{ ...item, ItemCount: item.ItemCount * -1 }]);
} }
} }
@ -38,6 +50,7 @@ export const contributeToVaultController: RequestHandler = async (req, res) => {
await guild.save(); await guild.save();
await inventory.save(); await inventory.save();
await guildMember.save();
res.end(); res.end();
}; };

View File

@ -1,3 +1,4 @@
import { GuildMember } from "@/src/models/guildModel";
import { getDojoClient, getGuildForRequestEx, hasAccessToDojo, scaleRequiredCount } from "@/src/services/guildService"; import { getDojoClient, getGuildForRequestEx, hasAccessToDojo, scaleRequiredCount } from "@/src/services/guildService";
import { getInventory, updateCurrency } from "@/src/services/inventoryService"; import { getInventory, updateCurrency } from "@/src/services/inventoryService";
import { getAccountIdForRequest } from "@/src/services/loginService"; import { getAccountIdForRequest } from "@/src/services/loginService";
@ -48,6 +49,12 @@ export const dojoComponentRushController: RequestHandler = async (req, res) => {
await guild.save(); await guild.save();
await inventory.save(); await inventory.save();
const guildMember = (await GuildMember.findOne({ accountId, guildId: guild._id }, "PremiumCreditsContributed"))!;
guildMember.PremiumCreditsContributed ??= 0;
guildMember.PremiumCreditsContributed += request.Amount;
await guildMember.save();
res.json({ res.json({
...(await getDojoClient(guild, 0, component._id)), ...(await getDojoClient(guild, 0, component._id)),
InventoryChanges: inventoryChanges InventoryChanges: inventoryChanges

View File

@ -0,0 +1,18 @@
import { GuildMember } from "@/src/models/guildModel";
import { getInventory } from "@/src/services/inventoryService";
import { getAccountIdForRequest } from "@/src/services/loginService";
import { RequestHandler } from "express";
export const getGuildContributionsController: RequestHandler = async (req, res) => {
const accountId = await getAccountIdForRequest(req);
const guildId = (await getInventory(accountId, "GuildId")).GuildId;
const guildMember = (await GuildMember.findOne({ guildId, accountId: req.query.buddyId }))!;
res.json({
_id: { $oid: req.query.buddyId },
RegularCreditsContributed: guildMember.RegularCreditsContributed,
PremiumCreditsContributed: guildMember.PremiumCreditsContributed,
MiscItemsContributed: guildMember.MiscItemsContributed,
ConsumablesContributed: [], // ???
ShipDecorationsContributed: guildMember.ShipDecorationsContributed
});
};

View File

@ -21,7 +21,7 @@ import { IMiscItem } from "@/src/types/inventoryTypes/inventoryTypes";
import { IInventoryChanges } from "@/src/types/purchaseTypes"; import { IInventoryChanges } from "@/src/types/purchaseTypes";
import { config } from "@/src/services/configService"; import { config } from "@/src/services/configService";
import { GuildPermission, ITechProjectClient, ITechProjectDatabase } from "@/src/types/guildTypes"; import { GuildPermission, ITechProjectClient, ITechProjectDatabase } from "@/src/types/guildTypes";
import { TGuildDatabaseDocument } from "@/src/models/guildModel"; import { GuildMember, TGuildDatabaseDocument } from "@/src/models/guildModel";
import { toMongoDate } from "@/src/helpers/inventoryHelpers"; import { toMongoDate } from "@/src/helpers/inventoryHelpers";
import { logger } from "@/src/utils/logger"; import { logger } from "@/src/utils/logger";
@ -90,6 +90,12 @@ export const guildTechController: RequestHandler = async (req, res) => {
res.status(400).send("-1").end(); res.status(400).send("-1").end();
return; return;
} }
const guildMember = (await GuildMember.findOne(
{ accountId, guildId: guild._id },
"RegularCreditsContributed MiscItemsContributed"
))!;
const contributions = data; const contributions = data;
const techProject = guild.TechProjects!.find(x => x.ItemType == contributions.RecipeType)!; const techProject = guild.TechProjects!.find(x => x.ItemType == contributions.RecipeType)!;
@ -106,6 +112,9 @@ export const guildTechController: RequestHandler = async (req, res) => {
} }
techProject.ReqCredits -= contributions.RegularCredits; techProject.ReqCredits -= contributions.RegularCredits;
guildMember.RegularCreditsContributed ??= 0;
guildMember.RegularCreditsContributed += contributions.RegularCredits;
if (contributions.VaultMiscItems.length) { if (contributions.VaultMiscItems.length) {
for (const miscItem of contributions.VaultMiscItems) { for (const miscItem of contributions.VaultMiscItems) {
const reqItem = techProject.ReqItems.find(x => x.ItemType == miscItem.ItemType); const reqItem = techProject.ReqItems.find(x => x.ItemType == miscItem.ItemType);
@ -133,6 +142,9 @@ export const guildTechController: RequestHandler = async (req, res) => {
ItemType: miscItem.ItemType, ItemType: miscItem.ItemType,
ItemCount: miscItem.ItemCount * -1 ItemCount: miscItem.ItemCount * -1
}); });
guildMember.MiscItemsContributed ??= [];
guildMember.MiscItemsContributed.push(miscItem);
} }
} }
addMiscItems(inventory, miscItemChanges); addMiscItems(inventory, miscItemChanges);
@ -151,6 +163,7 @@ export const guildTechController: RequestHandler = async (req, res) => {
await guild.save(); await guild.save();
await inventory.save(); await inventory.save();
await guildMember.save();
res.json({ res.json({
InventoryChanges: inventoryChanges, InventoryChanges: inventoryChanges,
Vault: getGuildVault(guild) Vault: getGuildVault(guild)

View File

@ -215,7 +215,11 @@ const guildMemberSchema = new Schema<IGuildMemberDatabase>({
accountId: Types.ObjectId, accountId: Types.ObjectId,
guildId: Types.ObjectId, guildId: Types.ObjectId,
status: { type: Number, required: true }, status: { type: Number, required: true },
rank: { type: Number, default: 7 } rank: { type: Number, default: 7 },
RegularCreditsContributed: Number,
PremiumCreditsContributed: Number,
MiscItemsContributed: { type: [typeCountSchema], default: undefined },
ShipDecorationsContributed: { type: [typeCountSchema], default: undefined }
}); });
guildMemberSchema.index({ accountId: 1, guildId: 1 }, { unique: true }); guildMemberSchema.index({ accountId: 1, guildId: 1 }, { unique: true });

View File

@ -42,6 +42,7 @@ import { genericUpdateController } from "@/src/controllers/api/genericUpdateCont
import { getAllianceController } from "@/src/controllers/api/getAllianceController"; import { getAllianceController } from "@/src/controllers/api/getAllianceController";
import { getDailyDealStockLevelsController } from "@/src/controllers/api/getDailyDealStockLevelsController"; import { getDailyDealStockLevelsController } from "@/src/controllers/api/getDailyDealStockLevelsController";
import { getFriendsController } from "@/src/controllers/api/getFriendsController"; import { getFriendsController } from "@/src/controllers/api/getFriendsController";
import { getGuildContributionsController } from "@/src/controllers/api/getGuildContributionsController";
import { getGuildController } from "@/src/controllers/api/getGuildController"; import { getGuildController } from "@/src/controllers/api/getGuildController";
import { getGuildDojoController } from "@/src/controllers/api/getGuildDojoController"; import { getGuildDojoController } from "@/src/controllers/api/getGuildDojoController";
import { getGuildLogController } from "@/src/controllers/api/getGuildLogController"; import { getGuildLogController } from "@/src/controllers/api/getGuildLogController";
@ -139,6 +140,7 @@ apiRouter.get("/drones.php", dronesController);
apiRouter.get("/getDailyDealStockLevels.php", getDailyDealStockLevelsController); apiRouter.get("/getDailyDealStockLevels.php", getDailyDealStockLevelsController);
apiRouter.get("/getFriends.php", getFriendsController); apiRouter.get("/getFriends.php", getFriendsController);
apiRouter.get("/getGuild.php", getGuildController); apiRouter.get("/getGuild.php", getGuildController);
apiRouter.get("/getGuildContributions.php", getGuildContributionsController);
apiRouter.get("/getGuildDojo.php", getGuildDojoController); apiRouter.get("/getGuildDojo.php", getGuildDojoController);
apiRouter.get("/getGuildLog.php", getGuildLogController); apiRouter.get("/getGuildLog.php", getGuildLogController);
apiRouter.get("/getIgnoredUsers.php", getIgnoredUsersController); apiRouter.get("/getIgnoredUsers.php", getIgnoredUsersController);

View File

@ -58,12 +58,7 @@ export const getGuildClient = async (guild: TGuildDatabaseDocument, accountId: s
if (guildMember.accountId.equals(accountId)) { if (guildMember.accountId.equals(accountId)) {
missingEntry = false; missingEntry = false;
} else { } else {
member.DisplayName = (await Account.findOne( member.DisplayName = (await Account.findById(guildMember.accountId, "DisplayName"))!.DisplayName;
{
_id: guildMember.accountId
},
"DisplayName"
))!.DisplayName;
await fillInInventoryDataForGuildMember(member); await fillInInventoryDataForGuildMember(member);
} }
members.push(member); members.push(member);

View File

@ -88,6 +88,10 @@ export interface IGuildMemberDatabase {
guildId: Types.ObjectId; guildId: Types.ObjectId;
status: number; status: number;
rank: number; rank: number;
RegularCreditsContributed?: number;
PremiumCreditsContributed?: number;
MiscItemsContributed?: IMiscItem[];
ShipDecorationsContributed?: ITypeCount[];
} }
export interface IGuildMemberClient { export interface IGuildMemberClient {