feat(stats): log unknown categories in updateStats (#947)
Reviewed-on: #947 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
cf50738d34
commit
2dade02f3e
@ -1,14 +1,15 @@
|
||||
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 { getStats, updateStats } from "@/src/services/statsService";
|
||||
import { IStatsUpdate } from "@/src/types/statTypes";
|
||||
import { RequestHandler } from "express";
|
||||
|
||||
const uploadController: RequestHandler = async (req, res) => {
|
||||
const payload = getJSONfromString<IStatsUpload>(String(req.body));
|
||||
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
||||
const { PS, ...payload } = getJSONfromString<IStatsUpdate>(String(req.body));
|
||||
const accountId = await getAccountIdForRequest(req);
|
||||
const playerStats = await getStats(accountId);
|
||||
await uploadStats(playerStats, payload);
|
||||
await updateStats(playerStats, payload);
|
||||
res.status(200).end();
|
||||
};
|
||||
|
||||
|
@ -5,14 +5,14 @@ import allScans from "@/static/fixed_responses/allScans.json";
|
||||
import { ExportEnemies } from "warframe-public-export-plus";
|
||||
import { getInventory } from "@/src/services/inventoryService";
|
||||
import { getStats } from "@/src/services/statsService";
|
||||
import { IStatsView } from "@/src/types/statTypes";
|
||||
import { IStatsClient } from "@/src/types/statTypes";
|
||||
|
||||
const viewController: RequestHandler = async (req, res) => {
|
||||
const accountId = await getAccountIdForRequest(req);
|
||||
const inventory = await getInventory(accountId, "XPInfo");
|
||||
const playerStats = await getStats(accountId);
|
||||
|
||||
const responseJson: IStatsView = playerStats.toJSON();
|
||||
const responseJson = playerStats.toJSON() as IStatsClient;
|
||||
responseJson.Weapons ??= [];
|
||||
for (const item of inventory.XPInfo) {
|
||||
const weaponIndex = responseJson.Weapons.findIndex(element => element.type == item.ItemType);
|
||||
|
@ -1,5 +1,5 @@
|
||||
import { Document, Schema, Types, model } from "mongoose";
|
||||
import { IEnemy, IMission, IScan, ITutorial, IAbility, IWeapon, IStatsDatabase } from "@/src/types/statTypes";
|
||||
import { IEnemy, IMission, IScan, ITutorial, IAbility, IWeapon, IStatsDatabase, IRace } from "@/src/types/statTypes";
|
||||
|
||||
const abilitySchema = new Schema<IAbility>(
|
||||
{
|
||||
@ -58,6 +58,13 @@ const weaponSchema = new Schema<IWeapon>(
|
||||
{ _id: false }
|
||||
);
|
||||
|
||||
const raceSchema = new Schema<IRace>(
|
||||
{
|
||||
highScore: Number
|
||||
},
|
||||
{ _id: false }
|
||||
);
|
||||
|
||||
const statsSchema = new Schema<IStatsDatabase>({
|
||||
accountOwnerId: { type: Schema.Types.ObjectId, required: true },
|
||||
CiphersSolved: Number,
|
||||
@ -69,6 +76,8 @@ const statsSchema = new Schema<IStatsDatabase>({
|
||||
MissionsCompleted: Number,
|
||||
MissionsQuit: Number,
|
||||
MissionsFailed: Number,
|
||||
MissionsInterrupted: Number,
|
||||
MissionsDumped: Number,
|
||||
TimePlayedSec: Number,
|
||||
PickupCount: Number,
|
||||
Tutorial: { type: Map, of: tutorialSchema, default: {} },
|
||||
@ -81,7 +90,8 @@ const statsSchema = new Schema<IStatsDatabase>({
|
||||
Missions: { type: [missionSchema], default: [] },
|
||||
Deaths: Number,
|
||||
HealCount: Number,
|
||||
ReviveCount: Number
|
||||
ReviveCount: Number,
|
||||
Races: { type: Map, of: raceSchema, default: {} }
|
||||
});
|
||||
|
||||
statsSchema.set("toJSON", {
|
||||
|
@ -1,5 +1,15 @@
|
||||
import { Stats, TStatsDatabaseDocument } from "@/src/models/statsModel";
|
||||
import { IStatsUpload } from "@/src/types/statTypes";
|
||||
import {
|
||||
IEnemy,
|
||||
IStatsAdd,
|
||||
IStatsMax,
|
||||
IStatsSet,
|
||||
IStatsTimers,
|
||||
IStatsUpdate,
|
||||
IUploadEntry,
|
||||
IWeapon
|
||||
} from "@/src/types/statTypes";
|
||||
import { logger } from "../utils/logger";
|
||||
|
||||
export const createStats = async (accountId: string): Promise<TStatsDatabaseDocument> => {
|
||||
const stats = new Stats({ accountOwnerId: accountId });
|
||||
@ -15,28 +25,16 @@ export const getStats = async (accountOwnerId: string): Promise<TStatsDatabaseDo
|
||||
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;
|
||||
export const updateStats = async (playerStats: TStatsDatabaseDocument, payload: IStatsUpdate): Promise<void> => {
|
||||
const unknownCategories: Record<string, string[]> = {};
|
||||
|
||||
if (MISSION_COMPLETE) {
|
||||
for (const [key, value] of Object.entries(MISSION_COMPLETE)) {
|
||||
for (const [action, actionData] of Object.entries(payload)) {
|
||||
switch (action) {
|
||||
case "add":
|
||||
for (const [category, data] of Object.entries(actionData as IStatsAdd)) {
|
||||
switch (category) {
|
||||
case "MISSION_COMPLETE":
|
||||
for (const [key, value] of Object.entries(data as IUploadEntry)) {
|
||||
switch (key) {
|
||||
case "GS_SUCCESS":
|
||||
playerStats.MissionsCompleted ??= 0;
|
||||
@ -50,234 +48,360 @@ export const uploadStats = async (playerStats: TStatsDatabaseDocument, payload:
|
||||
playerStats.MissionsFailed ??= 0;
|
||||
playerStats.MissionsFailed += value;
|
||||
break;
|
||||
case "GS_INTERRUPTED":
|
||||
playerStats.MissionsInterrupted ??= 0;
|
||||
playerStats.MissionsInterrupted += value;
|
||||
break;
|
||||
case "GS_DUMPED":
|
||||
playerStats.MissionsDumped ??= 0;
|
||||
playerStats.MissionsDumped += value;
|
||||
break;
|
||||
default:
|
||||
if (!ignoredCategories.includes(category)) {
|
||||
if (!unknownCategories[action]) {
|
||||
unknownCategories[action] = [];
|
||||
}
|
||||
unknownCategories[action].push(category);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
if (PICKUP_ITEM) {
|
||||
for (const value of Object.values(PICKUP_ITEM)) {
|
||||
case "PICKUP_ITEM":
|
||||
playerStats.PickupCount ??= 0;
|
||||
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
||||
for (const [_key, value] of Object.entries(data as IUploadEntry)) {
|
||||
playerStats.PickupCount += value;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
if (SCAN) {
|
||||
case "SCAN":
|
||||
playerStats.Scans ??= [];
|
||||
for (const [key, scans] of Object.entries(SCAN)) {
|
||||
const scan = playerStats.Scans.find(element => element.type === key);
|
||||
for (const [type, scans] of Object.entries(data as IUploadEntry)) {
|
||||
const scan = playerStats.Scans.find(element => element.type === type);
|
||||
if (scan) {
|
||||
scan.scans ??= 0;
|
||||
scan.scans += scans;
|
||||
} else {
|
||||
playerStats.Scans.push({ type: key, scans });
|
||||
}
|
||||
playerStats.Scans.push({ type: type, scans });
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
if (USE_ABILITY) {
|
||||
case "USE_ABILITY":
|
||||
playerStats.Abilities ??= [];
|
||||
for (const [key, used] of Object.entries(USE_ABILITY)) {
|
||||
const ability = playerStats.Abilities.find(element => element.type === key);
|
||||
for (const [type, used] of Object.entries(data as IUploadEntry)) {
|
||||
const ability = playerStats.Abilities.find(element => element.type === type);
|
||||
if (ability) {
|
||||
ability.used ??= 0;
|
||||
ability.used += used;
|
||||
} else {
|
||||
playerStats.Abilities.push({ type: key, used });
|
||||
}
|
||||
playerStats.Abilities.push({ type: type, used });
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
if (FIRE_WEAPON) {
|
||||
case "FIRE_WEAPON":
|
||||
case "HIT_ENTITY_ITEM":
|
||||
case "HEADSHOT_ITEM":
|
||||
case "KILL_ENEMY_ITEM":
|
||||
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 });
|
||||
}
|
||||
}
|
||||
}
|
||||
const statKey = {
|
||||
FIRE_WEAPON: "fired",
|
||||
HIT_ENTITY_ITEM: "hits",
|
||||
HEADSHOT_ITEM: "headshots",
|
||||
KILL_ENEMY_ITEM: "kills"
|
||||
}[category] as "fired" | "hits" | "headshots" | "kills";
|
||||
|
||||
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);
|
||||
for (const [type, count] of Object.entries(data as IUploadEntry)) {
|
||||
const weapon = playerStats.Weapons.find(element => element.type === type);
|
||||
if (weapon) {
|
||||
weapon.hits ??= 0;
|
||||
weapon.hits += hits;
|
||||
weapon[statKey] ??= 0;
|
||||
weapon[statKey] += count;
|
||||
} else {
|
||||
playerStats.Weapons.push({ type: key, hits });
|
||||
}
|
||||
const newWeapon: IWeapon = { type: type };
|
||||
newWeapon[statKey] = count;
|
||||
playerStats.Weapons.push(newWeapon);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
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) {
|
||||
case "KILL_ENEMY":
|
||||
case "EXECUTE_ENEMY":
|
||||
case "HEADSHOT":
|
||||
playerStats.Enemies ??= [];
|
||||
for (const [key, kills] of Object.entries(KILL_ENEMY)) {
|
||||
const enemy = playerStats.Enemies.find(element => element.type === key);
|
||||
const enemyStatKey = {
|
||||
KILL_ENEMY: "kills",
|
||||
EXECUTE_ENEMY: "executions",
|
||||
HEADSHOT: "headshots"
|
||||
}[category] as "kills" | "executions" | "headshots";
|
||||
|
||||
for (const [type, count] of Object.entries(data as IUploadEntry)) {
|
||||
const enemy = playerStats.Enemies.find(element => element.type === type);
|
||||
if (enemy) {
|
||||
enemy.kills ??= 0;
|
||||
enemy.kills += kills;
|
||||
enemy[enemyStatKey] ??= 0;
|
||||
enemy[enemyStatKey] += count;
|
||||
} else {
|
||||
playerStats.Enemies.push({ type: key, kills });
|
||||
}
|
||||
const newEnemy: IEnemy = { type: type };
|
||||
newEnemy[enemyStatKey] = count;
|
||||
playerStats.Enemies.push(newEnemy);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
if (EXECUTE_ENEMY) {
|
||||
case "DIE":
|
||||
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;
|
||||
for (const [type, deaths] of Object.entries(data as IUploadEntry)) {
|
||||
playerStats.Deaths += deaths;
|
||||
const enemy = playerStats.Enemies.find(element => element.type === key);
|
||||
const enemy = playerStats.Enemies.find(element => element.type === type);
|
||||
if (enemy) {
|
||||
enemy.deaths ??= 0;
|
||||
enemy.deaths += deaths;
|
||||
} else {
|
||||
playerStats.Enemies.push({ type: key, deaths });
|
||||
}
|
||||
playerStats.Enemies.push({ type: type, deaths });
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
if (MELEE_KILL) {
|
||||
case "MELEE_KILL":
|
||||
playerStats.MeleeKills ??= 0;
|
||||
for (const kills of Object.values(MELEE_KILL)) {
|
||||
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
||||
for (const [_key, kills] of Object.entries(data as IUploadEntry)) {
|
||||
playerStats.MeleeKills += kills;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
if (INCOME) {
|
||||
case "INCOME":
|
||||
playerStats.Income ??= 0;
|
||||
playerStats.Income += INCOME;
|
||||
}
|
||||
playerStats.Income += data;
|
||||
break;
|
||||
|
||||
if (CIPHER) {
|
||||
if (CIPHER["0"] > 0) {
|
||||
case "CIPHER":
|
||||
if (data["0"] > 0) {
|
||||
playerStats.CiphersFailed ??= 0;
|
||||
playerStats.CiphersFailed += CIPHER["0"];
|
||||
playerStats.CiphersFailed += data["0"];
|
||||
}
|
||||
if (CIPHER["1"] > 0) {
|
||||
if (data["1"] > 0) {
|
||||
playerStats.CiphersSolved ??= 0;
|
||||
playerStats.CiphersSolved += CIPHER["1"];
|
||||
}
|
||||
}
|
||||
playerStats.CiphersSolved += data["1"];
|
||||
}
|
||||
break;
|
||||
|
||||
if (payload.timers) {
|
||||
const { EQUIP_WEAPON, CURRENT_MISSION_TIME, CIPHER_TIME } = payload.timers;
|
||||
default:
|
||||
if (!ignoredCategories.includes(category)) {
|
||||
if (!unknownCategories[action]) {
|
||||
unknownCategories[action] = [];
|
||||
}
|
||||
unknownCategories[action].push(category);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
if (EQUIP_WEAPON) {
|
||||
case "timers":
|
||||
for (const [category, data] of Object.entries(actionData as IStatsTimers)) {
|
||||
switch (category) {
|
||||
case "EQUIP_WEAPON":
|
||||
playerStats.Weapons ??= [];
|
||||
for (const [key, equipTime] of Object.entries(EQUIP_WEAPON)) {
|
||||
const weapon = playerStats.Weapons.find(element => element.type === key);
|
||||
for (const [type, equipTime] of Object.entries(data as IUploadEntry)) {
|
||||
const weapon = playerStats.Weapons.find(element => element.type === type);
|
||||
if (weapon) {
|
||||
weapon.equipTime ??= 0;
|
||||
weapon.equipTime += equipTime;
|
||||
} else {
|
||||
playerStats.Weapons.push({ type: key, equipTime });
|
||||
}
|
||||
playerStats.Weapons.push({ type: type, equipTime });
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
if (CURRENT_MISSION_TIME) {
|
||||
case "CURRENT_MISSION_TIME":
|
||||
playerStats.TimePlayedSec ??= 0;
|
||||
playerStats.TimePlayedSec += CURRENT_MISSION_TIME;
|
||||
}
|
||||
playerStats.TimePlayedSec += data;
|
||||
break;
|
||||
|
||||
if (CIPHER_TIME) {
|
||||
case "CIPHER_TIME":
|
||||
playerStats.CipherTime ??= 0;
|
||||
playerStats.CipherTime += CIPHER_TIME;
|
||||
playerStats.CipherTime += data;
|
||||
break;
|
||||
|
||||
default:
|
||||
if (!ignoredCategories.includes(category)) {
|
||||
if (!unknownCategories[action]) {
|
||||
unknownCategories[action] = [];
|
||||
}
|
||||
unknownCategories[action].push(category);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
if (payload.max) {
|
||||
const { WEAPON_XP, MISSION_SCORE } = payload.max;
|
||||
|
||||
if (WEAPON_XP) {
|
||||
case "max":
|
||||
for (const [category, data] of Object.entries(actionData as IStatsMax)) {
|
||||
switch (category) {
|
||||
case "WEAPON_XP":
|
||||
playerStats.Weapons ??= [];
|
||||
for (const [key, xp] of Object.entries(WEAPON_XP)) {
|
||||
const weapon = playerStats.Weapons.find(element => element.type === key);
|
||||
for (const [type, xp] of Object.entries(data as IUploadEntry)) {
|
||||
const weapon = playerStats.Weapons.find(element => element.type === type);
|
||||
if (weapon) {
|
||||
if (xp > (weapon.xp ?? 0)) {
|
||||
weapon.xp = xp;
|
||||
}
|
||||
} else {
|
||||
playerStats.Weapons.push({ type: key, xp });
|
||||
}
|
||||
playerStats.Weapons.push({ type: type, xp });
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
if (MISSION_SCORE) {
|
||||
case "MISSION_SCORE":
|
||||
playerStats.Missions ??= [];
|
||||
for (const [key, highScore] of Object.entries(MISSION_SCORE)) {
|
||||
const mission = playerStats.Missions.find(element => element.type === key);
|
||||
for (const [type, highScore] of Object.entries(data as IUploadEntry)) {
|
||||
const mission = playerStats.Missions.find(element => element.type === type);
|
||||
if (mission) {
|
||||
if (highScore > mission.highScore) {
|
||||
mission.highScore = highScore;
|
||||
}
|
||||
} else {
|
||||
playerStats.Missions.push({ type: key, highScore });
|
||||
playerStats.Missions.push({ type: type, highScore });
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case "RACE_SCORE":
|
||||
playerStats.Races ??= new Map();
|
||||
|
||||
for (const [race, highScore] of Object.entries(data as Record<string, number>)) {
|
||||
const currentRace = playerStats.Races.get(race);
|
||||
|
||||
if (currentRace) {
|
||||
if (highScore > currentRace.highScore) {
|
||||
playerStats.Races.set(race, { highScore });
|
||||
}
|
||||
} else {
|
||||
playerStats.Races.set(race, { 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;
|
||||
break;
|
||||
|
||||
default:
|
||||
if (!ignoredCategories.includes(category)) {
|
||||
if (!unknownCategories[action]) {
|
||||
unknownCategories[action] = [];
|
||||
}
|
||||
unknownCategories[action].push(category);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case "set":
|
||||
for (const [category, value] of Object.entries(actionData as IStatsSet)) {
|
||||
switch (category) {
|
||||
case "ELO_RATING":
|
||||
playerStats.Rating = value;
|
||||
break;
|
||||
|
||||
case "RANK":
|
||||
playerStats.Rank = value;
|
||||
break;
|
||||
|
||||
case "PLAYER_LEVEL":
|
||||
playerStats.PlayerLevel = value;
|
||||
break;
|
||||
|
||||
default:
|
||||
if (!ignoredCategories.includes(category)) {
|
||||
if (!unknownCategories[action]) {
|
||||
unknownCategories[action] = [];
|
||||
}
|
||||
unknownCategories[action].push(category);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case "displayName":
|
||||
case "guildId":
|
||||
break;
|
||||
|
||||
default:
|
||||
logger.debug(`Unknown updateStats action: ${action}`);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
for (const [action, categories] of Object.entries(unknownCategories)) {
|
||||
logger.debug(`Unknown updateStats ${action} action categories: ${categories.join(", ")}`);
|
||||
}
|
||||
|
||||
await playerStats.save();
|
||||
};
|
||||
|
||||
const ignoredCategories = [
|
||||
//add action
|
||||
"MISSION_STARTED",
|
||||
"HOST_OS",
|
||||
"CPU_CORES",
|
||||
"CPU_MODEL",
|
||||
"CPU_VENDOR",
|
||||
"GPU_CLASS",
|
||||
"GFX_DRIVER",
|
||||
"GFX_RESOLUTION",
|
||||
"GFX_ASPECT",
|
||||
"GFX_WINDOW",
|
||||
"GPU_VENDOR",
|
||||
"GFX_HDR",
|
||||
"SPEAKER_COUNT",
|
||||
"MISSION_MATCHMAKING",
|
||||
"PLAYER_COUNT",
|
||||
"HOST_MIGRATION",
|
||||
"DESTROY_DECORATION",
|
||||
"MOVEMENT",
|
||||
"RECEIVE_UPGRADE",
|
||||
"EQUIP_COSMETIC",
|
||||
"EQUIP_UPGRADE",
|
||||
"MISSION_TYPE",
|
||||
"MISSION_FACTION",
|
||||
"MISSION_PLAYED",
|
||||
"MISSION_PLAYED_TIME",
|
||||
"CPU_CLOCK",
|
||||
"CPU_FEATURE",
|
||||
"RAM",
|
||||
"ADDR_SPACE",
|
||||
"GFX_SCALE",
|
||||
"LOGINS",
|
||||
"GPU_MODEL",
|
||||
"MEDALS_TOP",
|
||||
"STATS_TIMERS_RESET",
|
||||
"INPUT_ACTIVITY_TIME",
|
||||
"LOGINS_ITEM",
|
||||
"TAKE_DAMAGE",
|
||||
"SQUAD_KILL_ENEMY",
|
||||
"SQUAD_HEADSHOT",
|
||||
"SQUAD_MELEE_KILL",
|
||||
"MELEE_KILL_ITEM",
|
||||
"TAKE_DAMAGE_ITEM",
|
||||
"SQUAD_KILL_ENEMY_ITEM",
|
||||
"SQUAD_HEADSHOT_ITEM",
|
||||
"SQUAD_MELEE_KILL_ITEM",
|
||||
"PRE_DIE",
|
||||
"PRE_DIE_ITEM",
|
||||
"GEAR_USED",
|
||||
"DIE_ITEM",
|
||||
|
||||
// timers action
|
||||
"IN_SHIP_TIME",
|
||||
"IN_SHIP_VIEW_TIME",
|
||||
"MISSION_LOAD_TIME",
|
||||
"MISSION_TIME",
|
||||
"REGION_TIME",
|
||||
"PLATFORM_TIME",
|
||||
"PRE_DIE_TIME",
|
||||
"VEHICLE_TIME"
|
||||
];
|
||||
|
@ -1,6 +1,6 @@
|
||||
import { Types } from "mongoose";
|
||||
|
||||
export interface IStatsView {
|
||||
export interface IStatsClient {
|
||||
CiphersSolved?: number;
|
||||
CiphersFailed?: number;
|
||||
CipherTime?: number;
|
||||
@ -10,9 +10,11 @@ export interface IStatsView {
|
||||
MissionsCompleted?: number;
|
||||
MissionsQuit?: number;
|
||||
MissionsFailed?: number;
|
||||
MissionsInterrupted?: number;
|
||||
MissionsDumped?: number;
|
||||
TimePlayedSec?: number;
|
||||
PickupCount?: number;
|
||||
Tutorial?: { [key: string]: ITutorial };
|
||||
Tutorial?: Map<string, ITutorial>;
|
||||
Abilities?: IAbility[];
|
||||
Rating?: number;
|
||||
Income?: number;
|
||||
@ -23,9 +25,10 @@ export interface IStatsView {
|
||||
Deaths?: number;
|
||||
HealCount?: number;
|
||||
ReviveCount?: number;
|
||||
Races?: Map<string, IRace>;
|
||||
}
|
||||
|
||||
export interface IStatsDatabase extends IStatsView {
|
||||
export interface IStatsDatabase extends IStatsClient {
|
||||
accountOwnerId: Types.ObjectId;
|
||||
}
|
||||
|
||||
@ -68,7 +71,11 @@ export interface IWeapon {
|
||||
fired?: number;
|
||||
}
|
||||
|
||||
export interface IStatsUpload {
|
||||
export interface IRace {
|
||||
highScore: number;
|
||||
}
|
||||
|
||||
export interface IStatsUpdate {
|
||||
displayName: string;
|
||||
guildId?: string;
|
||||
PS?: string;
|
||||
@ -128,6 +135,7 @@ export interface IUploadEntry {
|
||||
export interface IStatsMax {
|
||||
WEAPON_XP?: IUploadEntry;
|
||||
MISSION_SCORE?: IUploadEntry;
|
||||
RACE_SCORE?: IUploadEntry;
|
||||
}
|
||||
|
||||
export interface IStatsSet {
|
||||
|
Loading…
x
Reference in New Issue
Block a user