forked from OpenWF/SpaceNinjaServer
feat: initial stats save (#884)
Closes #203 Reviewed-on: http://209.141.38.3/OpenWF/SpaceNinjaServer/pulls/884 Reviewed-by: Sainan <sainan@calamity.inc> Co-authored-by: AMelonInsideLemon <166175391+AMelonInsideLemon@users.noreply.github.com> Co-committed-by: AMelonInsideLemon <166175391+AMelonInsideLemon@users.noreply.github.com>
This commit is contained in:
parent
8175deb023
commit
13c68a75c1
@ -6,6 +6,7 @@ import { Inventory } from "@/src/models/inventoryModels/inventoryModel";
|
|||||||
import { Loadout } from "@/src/models/inventoryModels/loadoutModel";
|
import { Loadout } from "@/src/models/inventoryModels/loadoutModel";
|
||||||
import { PersonalRooms } from "@/src/models/personalRoomsModel";
|
import { PersonalRooms } from "@/src/models/personalRoomsModel";
|
||||||
import { Ship } from "@/src/models/shipModel";
|
import { Ship } from "@/src/models/shipModel";
|
||||||
|
import { Stats } from "@/src/models/statsModel";
|
||||||
|
|
||||||
export const deleteAccountController: RequestHandler = async (req, res) => {
|
export const deleteAccountController: RequestHandler = async (req, res) => {
|
||||||
const accountId = await getAccountIdForRequest(req);
|
const accountId = await getAccountIdForRequest(req);
|
||||||
@ -15,7 +16,8 @@ export const deleteAccountController: RequestHandler = async (req, res) => {
|
|||||||
Inventory.deleteOne({ accountOwnerId: accountId }),
|
Inventory.deleteOne({ accountOwnerId: accountId }),
|
||||||
Loadout.deleteOne({ loadoutOwnerId: accountId }),
|
Loadout.deleteOne({ loadoutOwnerId: accountId }),
|
||||||
PersonalRooms.deleteOne({ personalRoomsOwnerId: accountId }),
|
PersonalRooms.deleteOne({ personalRoomsOwnerId: accountId }),
|
||||||
Ship.deleteOne({ ShipOwnerId: accountId })
|
Ship.deleteOne({ ShipOwnerId: accountId }),
|
||||||
|
Stats.deleteOne({ accountOwnerId: accountId })
|
||||||
]);
|
]);
|
||||||
res.end();
|
res.end();
|
||||||
};
|
};
|
||||||
|
@ -1,6 +1,14 @@
|
|||||||
|
import { getJSONfromString } from "@/src/helpers/stringHelpers";
|
||||||
|
import { getAccountIdForRequest } from "@/src/services/loginService";
|
||||||
|
import { getStats, uploadStats } from "@/src/services/statsService";
|
||||||
|
import { IStatsUpload } from "@/src/types/statTypes";
|
||||||
import { RequestHandler } from "express";
|
import { RequestHandler } from "express";
|
||||||
|
|
||||||
const uploadController: RequestHandler = (_req, res) => {
|
const uploadController: RequestHandler = async (req, res) => {
|
||||||
|
const payload = getJSONfromString<IStatsUpload>(String(req.body));
|
||||||
|
const accountId = await getAccountIdForRequest(req);
|
||||||
|
const playerStats = await getStats(accountId);
|
||||||
|
await uploadStats(playerStats, payload);
|
||||||
res.status(200).end();
|
res.status(200).end();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -1,31 +1,33 @@
|
|||||||
import { RequestHandler } from "express";
|
import { RequestHandler } from "express";
|
||||||
import { getAccountIdForRequest } from "@/src/services/loginService";
|
import { getAccountIdForRequest } from "@/src/services/loginService";
|
||||||
import { IStatsView } from "@/src/types/statTypes";
|
|
||||||
import { config } from "@/src/services/configService";
|
import { config } from "@/src/services/configService";
|
||||||
import allScans from "@/static/fixed_responses/allScans.json";
|
import allScans from "@/static/fixed_responses/allScans.json";
|
||||||
import { ExportEnemies } from "warframe-public-export-plus";
|
import { ExportEnemies } from "warframe-public-export-plus";
|
||||||
import { getInventory } from "@/src/services/inventoryService";
|
import { getInventory } from "@/src/services/inventoryService";
|
||||||
|
import { getStats } from "@/src/services/statsService";
|
||||||
|
import { IStatsView } from "@/src/types/statTypes";
|
||||||
|
|
||||||
const viewController: RequestHandler = async (req, res) => {
|
const viewController: RequestHandler = async (req, res) => {
|
||||||
const accountId = await getAccountIdForRequest(req);
|
const accountId = await getAccountIdForRequest(req);
|
||||||
const inventory = await getInventory(accountId, "XPInfo");
|
const inventory = await getInventory(accountId, "XPInfo");
|
||||||
|
const playerStats = await getStats(accountId);
|
||||||
|
|
||||||
const responseJson: IStatsView = {};
|
const responseJson: IStatsView = playerStats.toJSON();
|
||||||
responseJson.Weapons = [];
|
responseJson.Weapons ??= [];
|
||||||
for (const item of inventory.XPInfo) {
|
for (const item of inventory.XPInfo) {
|
||||||
responseJson.Weapons.push({
|
const weaponIndex = responseJson.Weapons.findIndex(element => element.type == item.ItemType);
|
||||||
type: item.ItemType,
|
if (weaponIndex !== -1) {
|
||||||
xp: item.XP
|
responseJson.Weapons[weaponIndex].xp == item.XP;
|
||||||
});
|
} else {
|
||||||
|
responseJson.Weapons.push({ type: item.ItemType, xp: item.XP });
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (config.unlockAllScans) {
|
if (config.unlockAllScans) {
|
||||||
const scans = new Set(allScans);
|
const scans = new Set(allScans);
|
||||||
for (const type of Object.keys(ExportEnemies.avatars)) {
|
for (const type of Object.keys(ExportEnemies.avatars)) {
|
||||||
if (!scans.has(type)) {
|
if (!scans.has(type)) scans.add(type);
|
||||||
scans.add(type);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
responseJson.Scans = [];
|
responseJson.Scans ??= [];
|
||||||
for (const type of scans) {
|
for (const type of scans) {
|
||||||
responseJson.Scans.push({ type: type, scans: 9999 });
|
responseJson.Scans.push({ type: type, scans: 9999 });
|
||||||
}
|
}
|
||||||
|
101
src/models/statsModel.ts
Normal file
101
src/models/statsModel.ts
Normal file
@ -0,0 +1,101 @@
|
|||||||
|
import { Document, Schema, Types, model } from "mongoose";
|
||||||
|
import { IEnemy, IMission, IScan, ITutorial, IAbility, IWeapon, IStatsDatabase } from "@/src/types/statTypes";
|
||||||
|
|
||||||
|
const abilitySchema = new Schema<IAbility>(
|
||||||
|
{
|
||||||
|
type: { type: String, required: true },
|
||||||
|
used: Number
|
||||||
|
},
|
||||||
|
{ _id: false }
|
||||||
|
);
|
||||||
|
|
||||||
|
const enemySchema = new Schema<IEnemy>(
|
||||||
|
{
|
||||||
|
type: { type: String, required: true },
|
||||||
|
executions: Number,
|
||||||
|
headshots: Number,
|
||||||
|
kills: Number,
|
||||||
|
assists: Number,
|
||||||
|
deaths: Number
|
||||||
|
},
|
||||||
|
{ _id: false }
|
||||||
|
);
|
||||||
|
|
||||||
|
const missionSchema = new Schema<IMission>(
|
||||||
|
{
|
||||||
|
type: { type: String, required: true },
|
||||||
|
highScore: Number
|
||||||
|
},
|
||||||
|
{ _id: false }
|
||||||
|
);
|
||||||
|
|
||||||
|
const scanSchema = new Schema<IScan>(
|
||||||
|
{
|
||||||
|
type: { type: String, required: true },
|
||||||
|
scans: Number
|
||||||
|
},
|
||||||
|
{ _id: false }
|
||||||
|
);
|
||||||
|
|
||||||
|
const tutorialSchema = new Schema<ITutorial>(
|
||||||
|
{
|
||||||
|
stage: Number
|
||||||
|
},
|
||||||
|
{ _id: false }
|
||||||
|
);
|
||||||
|
|
||||||
|
const weaponSchema = new Schema<IWeapon>(
|
||||||
|
{
|
||||||
|
type: { type: String, required: true },
|
||||||
|
equipTime: Number,
|
||||||
|
hits: Number,
|
||||||
|
kills: Number,
|
||||||
|
xp: Number,
|
||||||
|
assists: Number,
|
||||||
|
headshots: Number,
|
||||||
|
fired: Number
|
||||||
|
},
|
||||||
|
{ _id: false }
|
||||||
|
);
|
||||||
|
|
||||||
|
const statsSchema = new Schema<IStatsDatabase>({
|
||||||
|
accountOwnerId: { type: Schema.Types.ObjectId, required: true },
|
||||||
|
CiphersSolved: Number,
|
||||||
|
CiphersFailed: Number,
|
||||||
|
CipherTime: Number,
|
||||||
|
Weapons: { type: [weaponSchema], default: [] },
|
||||||
|
Enemies: { type: [enemySchema], default: [] },
|
||||||
|
MeleeKills: Number,
|
||||||
|
MissionsCompleted: Number,
|
||||||
|
MissionsQuit: Number,
|
||||||
|
MissionsFailed: Number,
|
||||||
|
TimePlayedSec: Number,
|
||||||
|
PickupCount: Number,
|
||||||
|
Tutorial: { type: Map, of: tutorialSchema, default: {} },
|
||||||
|
Abilities: { type: [abilitySchema], default: [] },
|
||||||
|
Rating: Number,
|
||||||
|
Income: Number,
|
||||||
|
Rank: Number,
|
||||||
|
PlayerLevel: Number,
|
||||||
|
Scans: { type: [scanSchema], default: [] },
|
||||||
|
Missions: { type: [missionSchema], default: [] },
|
||||||
|
Deaths: Number,
|
||||||
|
HealCount: Number,
|
||||||
|
ReviveCount: Number
|
||||||
|
});
|
||||||
|
|
||||||
|
statsSchema.set("toJSON", {
|
||||||
|
transform(_document, returnedObject) {
|
||||||
|
delete returnedObject._id;
|
||||||
|
delete returnedObject.__v;
|
||||||
|
delete returnedObject.accountOwnerId;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
export const Stats = model<IStatsDatabase>("Stats", statsSchema);
|
||||||
|
|
||||||
|
// eslint-disable-next-line @typescript-eslint/ban-types
|
||||||
|
export type TStatsDatabaseDocument = Document<unknown, {}, IStatsDatabase> & {
|
||||||
|
_id: Types.ObjectId;
|
||||||
|
__v: number;
|
||||||
|
} & IStatsDatabase;
|
@ -7,6 +7,7 @@ import { Loadout } from "@/src/models/inventoryModels/loadoutModel";
|
|||||||
import { PersonalRooms } from "@/src/models/personalRoomsModel";
|
import { PersonalRooms } from "@/src/models/personalRoomsModel";
|
||||||
import { Request } from "express";
|
import { Request } from "express";
|
||||||
import { config } from "@/src/services/configService";
|
import { config } from "@/src/services/configService";
|
||||||
|
import { createStats } from "@/src/services/statsService";
|
||||||
|
|
||||||
export const isCorrectPassword = (requestPassword: string, databasePassword: string): boolean => {
|
export const isCorrectPassword = (requestPassword: string, databasePassword: string): boolean => {
|
||||||
return requestPassword === databasePassword;
|
return requestPassword === databasePassword;
|
||||||
@ -24,6 +25,7 @@ export const createAccount = async (accountData: IDatabaseAccount): Promise<IDat
|
|||||||
const shipId = await createShip(account._id);
|
const shipId = await createShip(account._id);
|
||||||
await createInventory(account._id, { loadOutPresetId: loadoutId, ship: shipId });
|
await createInventory(account._id, { loadOutPresetId: loadoutId, ship: shipId });
|
||||||
await createPersonalRooms(account._id, shipId);
|
await createPersonalRooms(account._id, shipId);
|
||||||
|
await createStats(account._id.toString());
|
||||||
return account.toJSON();
|
return account.toJSON();
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
if (error instanceof Error) {
|
if (error instanceof Error) {
|
||||||
|
283
src/services/statsService.ts
Normal file
283
src/services/statsService.ts
Normal file
@ -0,0 +1,283 @@
|
|||||||
|
import { Stats, TStatsDatabaseDocument } from "@/src/models/statsModel";
|
||||||
|
import { IStatsUpload } from "@/src/types/statTypes";
|
||||||
|
|
||||||
|
export const createStats = async (accountId: string): Promise<TStatsDatabaseDocument> => {
|
||||||
|
const stats = new Stats({ accountOwnerId: accountId });
|
||||||
|
await stats.save();
|
||||||
|
return stats;
|
||||||
|
};
|
||||||
|
|
||||||
|
export const getStats = async (accountOwnerId: string): Promise<TStatsDatabaseDocument> => {
|
||||||
|
let stats = await Stats.findOne({ accountOwnerId: accountOwnerId });
|
||||||
|
|
||||||
|
if (!stats) stats = await createStats(accountOwnerId);
|
||||||
|
|
||||||
|
return stats;
|
||||||
|
};
|
||||||
|
|
||||||
|
export const uploadStats = async (playerStats: TStatsDatabaseDocument, payload: IStatsUpload): Promise<void> => {
|
||||||
|
if (payload.add) {
|
||||||
|
const {
|
||||||
|
MISSION_COMPLETE,
|
||||||
|
PICKUP_ITEM,
|
||||||
|
SCAN,
|
||||||
|
USE_ABILITY,
|
||||||
|
FIRE_WEAPON,
|
||||||
|
HIT_ENTITY_ITEM,
|
||||||
|
HEADSHOT_ITEM,
|
||||||
|
KILL_ENEMY_ITEM,
|
||||||
|
KILL_ENEMY,
|
||||||
|
EXECUTE_ENEMY,
|
||||||
|
HEADSHOT,
|
||||||
|
DIE,
|
||||||
|
MELEE_KILL,
|
||||||
|
INCOME,
|
||||||
|
CIPHER
|
||||||
|
} = payload.add;
|
||||||
|
|
||||||
|
if (MISSION_COMPLETE) {
|
||||||
|
for (const [key, value] of Object.entries(MISSION_COMPLETE)) {
|
||||||
|
switch (key) {
|
||||||
|
case "GS_SUCCESS":
|
||||||
|
playerStats.MissionsCompleted ??= 0;
|
||||||
|
playerStats.MissionsCompleted += value;
|
||||||
|
break;
|
||||||
|
case "GS_QUIT":
|
||||||
|
playerStats.MissionsQuit ??= 0;
|
||||||
|
playerStats.MissionsQuit += value;
|
||||||
|
break;
|
||||||
|
case "GS_FAILURE":
|
||||||
|
playerStats.MissionsFailed ??= 0;
|
||||||
|
playerStats.MissionsFailed += value;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (PICKUP_ITEM) {
|
||||||
|
for (const value of Object.values(PICKUP_ITEM)) {
|
||||||
|
playerStats.PickupCount ??= 0;
|
||||||
|
playerStats.PickupCount += value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (SCAN) {
|
||||||
|
playerStats.Scans ??= [];
|
||||||
|
for (const [key, scans] of Object.entries(SCAN)) {
|
||||||
|
const scan = playerStats.Scans.find(element => element.type === key);
|
||||||
|
if (scan) {
|
||||||
|
scan.scans ??= 0;
|
||||||
|
scan.scans += scans;
|
||||||
|
} else {
|
||||||
|
playerStats.Scans.push({ type: key, scans });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (USE_ABILITY) {
|
||||||
|
playerStats.Abilities ??= [];
|
||||||
|
for (const [key, used] of Object.entries(USE_ABILITY)) {
|
||||||
|
const ability = playerStats.Abilities.find(element => element.type === key);
|
||||||
|
if (ability) {
|
||||||
|
ability.used ??= 0;
|
||||||
|
ability.used += used;
|
||||||
|
} else {
|
||||||
|
playerStats.Abilities.push({ type: key, used });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (FIRE_WEAPON) {
|
||||||
|
playerStats.Weapons ??= [];
|
||||||
|
for (const [key, fired] of Object.entries(FIRE_WEAPON)) {
|
||||||
|
const weapon = playerStats.Weapons.find(element => element.type === key);
|
||||||
|
if (weapon) {
|
||||||
|
weapon.fired ??= 0;
|
||||||
|
weapon.fired += fired;
|
||||||
|
} else {
|
||||||
|
playerStats.Weapons.push({ type: key, fired });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (HIT_ENTITY_ITEM) {
|
||||||
|
playerStats.Weapons ??= [];
|
||||||
|
for (const [key, hits] of Object.entries(HIT_ENTITY_ITEM)) {
|
||||||
|
const weapon = playerStats.Weapons.find(element => element.type === key);
|
||||||
|
if (weapon) {
|
||||||
|
weapon.hits ??= 0;
|
||||||
|
weapon.hits += hits;
|
||||||
|
} else {
|
||||||
|
playerStats.Weapons.push({ type: key, hits });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (HEADSHOT_ITEM) {
|
||||||
|
playerStats.Weapons ??= [];
|
||||||
|
for (const [key, headshots] of Object.entries(HEADSHOT_ITEM)) {
|
||||||
|
const weapon = playerStats.Weapons.find(element => element.type === key);
|
||||||
|
if (weapon) {
|
||||||
|
weapon.headshots ??= 0;
|
||||||
|
weapon.headshots += headshots;
|
||||||
|
} else {
|
||||||
|
playerStats.Weapons.push({ type: key, headshots });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (KILL_ENEMY_ITEM) {
|
||||||
|
playerStats.Weapons ??= [];
|
||||||
|
for (const [key, kills] of Object.entries(KILL_ENEMY_ITEM)) {
|
||||||
|
const weapon = playerStats.Weapons.find(element => element.type === key);
|
||||||
|
if (weapon) {
|
||||||
|
weapon.kills ??= 0;
|
||||||
|
weapon.kills += kills;
|
||||||
|
} else {
|
||||||
|
playerStats.Weapons.push({ type: key, kills });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (KILL_ENEMY) {
|
||||||
|
playerStats.Enemies ??= [];
|
||||||
|
for (const [key, kills] of Object.entries(KILL_ENEMY)) {
|
||||||
|
const enemy = playerStats.Enemies.find(element => element.type === key);
|
||||||
|
if (enemy) {
|
||||||
|
enemy.kills ??= 0;
|
||||||
|
enemy.kills += kills;
|
||||||
|
} else {
|
||||||
|
playerStats.Enemies.push({ type: key, kills });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (EXECUTE_ENEMY) {
|
||||||
|
playerStats.Enemies ??= [];
|
||||||
|
for (const [key, executions] of Object.entries(EXECUTE_ENEMY)) {
|
||||||
|
const enemy = playerStats.Enemies.find(element => element.type === key);
|
||||||
|
if (enemy) {
|
||||||
|
enemy.executions ??= 0;
|
||||||
|
enemy.executions += executions;
|
||||||
|
} else {
|
||||||
|
playerStats.Enemies.push({ type: key, executions });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (HEADSHOT) {
|
||||||
|
playerStats.Enemies ??= [];
|
||||||
|
for (const [key, headshots] of Object.entries(HEADSHOT)) {
|
||||||
|
const enemy = playerStats.Enemies.find(element => element.type === key);
|
||||||
|
if (enemy) {
|
||||||
|
enemy.headshots ??= 0;
|
||||||
|
enemy.headshots += headshots;
|
||||||
|
} else {
|
||||||
|
playerStats.Enemies.push({ type: key, headshots });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (DIE) {
|
||||||
|
playerStats.Enemies ??= [];
|
||||||
|
for (const [key, deaths] of Object.entries(DIE)) {
|
||||||
|
playerStats.Deaths ??= 0;
|
||||||
|
playerStats.Deaths += deaths;
|
||||||
|
const enemy = playerStats.Enemies.find(element => element.type === key);
|
||||||
|
if (enemy) {
|
||||||
|
enemy.deaths ??= 0;
|
||||||
|
enemy.deaths += deaths;
|
||||||
|
} else {
|
||||||
|
playerStats.Enemies.push({ type: key, deaths });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (MELEE_KILL) {
|
||||||
|
playerStats.MeleeKills ??= 0;
|
||||||
|
for (const kills of Object.values(MELEE_KILL)) {
|
||||||
|
playerStats.MeleeKills += kills;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (INCOME) {
|
||||||
|
playerStats.Income ??= 0;
|
||||||
|
playerStats.Income += INCOME;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (CIPHER) {
|
||||||
|
if (CIPHER["0"] > 0) {
|
||||||
|
playerStats.CiphersFailed ??= 0;
|
||||||
|
playerStats.CiphersFailed += CIPHER["0"];
|
||||||
|
}
|
||||||
|
if (CIPHER["1"] > 0) {
|
||||||
|
playerStats.CiphersSolved ??= 0;
|
||||||
|
playerStats.CiphersSolved += CIPHER["1"];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (payload.timers) {
|
||||||
|
const { EQUIP_WEAPON, CURRENT_MISSION_TIME, CIPHER_TIME } = payload.timers;
|
||||||
|
|
||||||
|
if (EQUIP_WEAPON) {
|
||||||
|
playerStats.Weapons ??= [];
|
||||||
|
for (const [key, equipTime] of Object.entries(EQUIP_WEAPON)) {
|
||||||
|
const weapon = playerStats.Weapons.find(element => element.type === key);
|
||||||
|
if (weapon) {
|
||||||
|
weapon.equipTime ??= 0;
|
||||||
|
weapon.equipTime += equipTime;
|
||||||
|
} else {
|
||||||
|
playerStats.Weapons.push({ type: key, equipTime });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (CURRENT_MISSION_TIME) {
|
||||||
|
playerStats.TimePlayedSec ??= 0;
|
||||||
|
playerStats.TimePlayedSec += CURRENT_MISSION_TIME;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (CIPHER_TIME) {
|
||||||
|
playerStats.CipherTime ??= 0;
|
||||||
|
playerStats.CipherTime += CIPHER_TIME;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (payload.max) {
|
||||||
|
const { WEAPON_XP, MISSION_SCORE } = payload.max;
|
||||||
|
|
||||||
|
if (WEAPON_XP) {
|
||||||
|
playerStats.Weapons ??= [];
|
||||||
|
for (const [key, xp] of Object.entries(WEAPON_XP)) {
|
||||||
|
const weapon = playerStats.Weapons.find(element => element.type === key);
|
||||||
|
if (weapon) {
|
||||||
|
weapon.xp = xp;
|
||||||
|
} else {
|
||||||
|
playerStats.Weapons.push({ type: key, xp });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (MISSION_SCORE) {
|
||||||
|
playerStats.Missions ??= [];
|
||||||
|
for (const [key, highScore] of Object.entries(MISSION_SCORE)) {
|
||||||
|
const mission = playerStats.Missions.find(element => element.type === key);
|
||||||
|
if (mission) {
|
||||||
|
mission.highScore = highScore;
|
||||||
|
} else {
|
||||||
|
playerStats.Missions.push({ type: key, highScore });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (payload.set) {
|
||||||
|
const { ELO_RATING, RANK, PLAYER_LEVEL } = payload.set;
|
||||||
|
if (ELO_RATING) playerStats.Rating = ELO_RATING;
|
||||||
|
if (RANK) playerStats.Rank = RANK;
|
||||||
|
if (PLAYER_LEVEL) playerStats.PlayerLevel = PLAYER_LEVEL;
|
||||||
|
}
|
||||||
|
|
||||||
|
await playerStats.save();
|
||||||
|
};
|
@ -1,3 +1,5 @@
|
|||||||
|
import { Types } from "mongoose";
|
||||||
|
|
||||||
export interface IStatsView {
|
export interface IStatsView {
|
||||||
CiphersSolved?: number;
|
CiphersSolved?: number;
|
||||||
CiphersFailed?: number;
|
CiphersFailed?: number;
|
||||||
@ -23,28 +25,32 @@ export interface IStatsView {
|
|||||||
ReviveCount?: number;
|
ReviveCount?: number;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export interface IStatsDatabase extends IStatsView {
|
||||||
|
accountOwnerId: Types.ObjectId;
|
||||||
|
}
|
||||||
|
|
||||||
export interface IAbility {
|
export interface IAbility {
|
||||||
used: number;
|
|
||||||
type: string;
|
type: string;
|
||||||
|
used: number;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface IEnemy {
|
export interface IEnemy {
|
||||||
|
type: string;
|
||||||
executions?: number;
|
executions?: number;
|
||||||
headshots?: number;
|
headshots?: number;
|
||||||
kills?: number;
|
kills?: number;
|
||||||
type: string;
|
|
||||||
assists?: number;
|
assists?: number;
|
||||||
deaths?: number;
|
deaths?: number;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface IMission {
|
export interface IMission {
|
||||||
highScore: number;
|
|
||||||
type: string;
|
type: string;
|
||||||
|
highScore: number;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface IScan {
|
export interface IScan {
|
||||||
scans: number;
|
|
||||||
type: string;
|
type: string;
|
||||||
|
scans: number;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface ITutorial {
|
export interface ITutorial {
|
||||||
@ -52,12 +58,91 @@ export interface ITutorial {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export interface IWeapon {
|
export interface IWeapon {
|
||||||
|
type: string;
|
||||||
equipTime?: number;
|
equipTime?: number;
|
||||||
hits?: number;
|
hits?: number;
|
||||||
kills?: number;
|
kills?: number;
|
||||||
xp?: number;
|
xp?: number;
|
||||||
assists?: number;
|
assists?: number;
|
||||||
type: string;
|
|
||||||
headshots?: number;
|
headshots?: number;
|
||||||
fired?: number;
|
fired?: number;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export interface IStatsUpload {
|
||||||
|
displayName: string;
|
||||||
|
guildId?: string;
|
||||||
|
PS?: string;
|
||||||
|
add?: IStatsAdd;
|
||||||
|
set?: IStatsSet;
|
||||||
|
max?: IStatsMax;
|
||||||
|
timers?: IStatsTimers;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface IStatsAdd {
|
||||||
|
GEAR_USED?: IUploadEntry;
|
||||||
|
SCAN?: IUploadEntry;
|
||||||
|
MISSION_COMPLETE?: IUploadEntry;
|
||||||
|
HEADSHOT_ITEM?: IUploadEntry;
|
||||||
|
HEADSHOT?: IUploadEntry;
|
||||||
|
PLAYER_COUNT?: IUploadEntry;
|
||||||
|
HOST_MIGRATION?: IUploadEntry;
|
||||||
|
PICKUP_ITEM?: IUploadEntry;
|
||||||
|
FIRE_WEAPON?: IUploadEntry;
|
||||||
|
HIT_ENTITY_ITEM?: IUploadEntry;
|
||||||
|
DESTROY_DECORATION?: IUploadEntry;
|
||||||
|
KILL_ENEMY?: IUploadEntry;
|
||||||
|
TAKE_DAMAGE?: IUploadEntry;
|
||||||
|
SQUAD_KILL_ENEMY?: IUploadEntry;
|
||||||
|
RECEIVE_UPGRADE?: IUploadEntry;
|
||||||
|
USE_ABILITY?: IUploadEntry;
|
||||||
|
SQUAD_VIP_KILL?: IUploadEntry;
|
||||||
|
HEAL_BUDDY?: IUploadEntry;
|
||||||
|
INCOME?: number;
|
||||||
|
CIPHER?: IUploadEntry;
|
||||||
|
EQUIP_COSMETIC?: IUploadEntry;
|
||||||
|
EQUIP_UPGRADE?: IUploadEntry;
|
||||||
|
KILL_BOSS?: IUploadEntry;
|
||||||
|
MISSION_TYPE?: IUploadEntry;
|
||||||
|
MISSION_FACTION?: IUploadEntry;
|
||||||
|
MISSION_PLAYED?: IUploadEntry;
|
||||||
|
MISSION_PLAYED_TIME?: IUploadEntry;
|
||||||
|
MEDALS_TOP?: IUploadEntry;
|
||||||
|
INPUT_ACTIVITY_TIME?: IUploadEntry;
|
||||||
|
KILL_ENEMY_ITEM?: IUploadEntry;
|
||||||
|
TAKE_DAMAGE_ITEM?: IUploadEntry;
|
||||||
|
SQUAD_KILL_ENEMY_ITEM?: IUploadEntry;
|
||||||
|
MELEE_KILL?: IUploadEntry;
|
||||||
|
SQUAD_MELEE_KILL?: IUploadEntry;
|
||||||
|
MELEE_KILL_ITEM?: IUploadEntry;
|
||||||
|
SQUAD_MELEE_KILL_ITEM?: IUploadEntry;
|
||||||
|
DIE?: IUploadEntry;
|
||||||
|
DIE_ITEM?: IUploadEntry;
|
||||||
|
EXECUTE_ENEMY?: IUploadEntry;
|
||||||
|
EXECUTE_ENEMY_ITEM?: IUploadEntry;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface IUploadEntry {
|
||||||
|
[key: string]: number;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface IStatsMax {
|
||||||
|
WEAPON_XP?: IUploadEntry;
|
||||||
|
MISSION_SCORE?: IUploadEntry;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface IStatsSet {
|
||||||
|
ELO_RATING?: number;
|
||||||
|
RANK?: number;
|
||||||
|
PLAYER_LEVEL?: number;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface IStatsTimers {
|
||||||
|
IN_SHIP_TIME?: number;
|
||||||
|
IN_SHIP_VIEW_TIME?: IUploadEntry;
|
||||||
|
EQUIP_WEAPON?: IUploadEntry;
|
||||||
|
MISSION_TIME?: IUploadEntry;
|
||||||
|
REGION_TIME?: IUploadEntry;
|
||||||
|
PLATFORM_TIME?: IUploadEntry;
|
||||||
|
CURRENT_MISSION_TIME?: number;
|
||||||
|
CIPHER_TIME?: number;
|
||||||
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user