monitor/core/modules/Database/dao/players.ts
2025-04-16 22:30:27 +07:00

111 lines
3.5 KiB
TypeScript

import { cloneDeep } from 'lodash-es';
import { DbInstance, SavePriority } from "../instance";
import { DatabasePlayerType } from "../databaseTypes";
import { DuplicateKeyError } from "../dbUtils";
import consoleFactory from '@lib/console';
const console = consoleFactory('DatabaseDao');
/**
* Data access object for the database "players" collection.
*/
export default class PlayersDao {
constructor(private readonly db: DbInstance) { }
private get dbo() {
if (!this.db.obj || !this.db.isReady) throw new Error(`database not ready yet`);
return this.db.obj;
}
private get chain() {
if (!this.db.obj || !this.db.isReady) throw new Error(`database not ready yet`);
return this.db.obj.chain;
}
/**
* Searches for a player in the database by the license, returns null if not found or false in case of error
*/
findOne(license: string): DatabasePlayerType | null {
//Performing search
const p = this.chain.get('players')
.find({ license })
.cloneDeep()
.value();
return (typeof p === 'undefined') ? null : p;
}
/**
* Register a player to the database
*/
findMany(filter: object | Function): DatabasePlayerType[] {
return this.chain.get('players')
.filter(filter as any)
.cloneDeep()
.value();
}
/**
* Register a player to the database
*/
register(player: DatabasePlayerType): void {
//TODO: validate player data vs DatabasePlayerType props
//Check for duplicated license
const found = this.chain.get('players')
.filter({ license: player.license })
.value();
if (found.length) throw new DuplicateKeyError(`this license is already registered`);
this.db.writeFlag(SavePriority.LOW);
this.chain.get('players')
.push(player)
.value();
}
/**
* Updates a player setting assigning srcData props to the database player.
* The source data object is deep cloned to prevent weird side effects.
*/
update(license: string, srcData: object, srcUniqueId: Symbol): DatabasePlayerType {
if (typeof (srcData as any).license !== 'undefined') {
throw new Error(`cannot license field`);
}
const playerDbObj = this.chain.get('players').find({ license });
if (!playerDbObj.value()) throw new Error('Player not found in database');
this.db.writeFlag(SavePriority.LOW);
const newData = playerDbObj
.assign(cloneDeep(srcData))
.cloneDeep()
.value();
txCore.fxPlayerlist.handleDbDataSync(newData, srcUniqueId);
return newData;
}
/**
* Revokes whitelist status of all players that match a filter function
* @returns the number of revoked whitelists
*/
bulkRevokeWhitelist(filterFunc: Function): number {
if (typeof filterFunc !== 'function') throw new Error('filterFunc must be a function.');
let cntChanged = 0;
const srcSymbol = Symbol('bulkRevokePlayerWhitelist');
this.dbo.data!.players.forEach((player) => {
if (player.tsWhitelisted && filterFunc(player)) {
cntChanged++;
player.tsWhitelisted = undefined;
txCore.fxPlayerlist.handleDbDataSync(cloneDeep(player), srcSymbol);
}
});
this.db.writeFlag(SavePriority.HIGH);
return cntChanged;
}
}