111 lines
3.5 KiB
TypeScript
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;
|
|
}
|
|
}
|