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

141 lines
5.4 KiB
TypeScript

import { DbInstance, SavePriority } from "../instance";
import consoleFactory from '@lib/console';
import { DatabasePlayerType, DatabaseWhitelistApprovalsType, DatabaseWhitelistRequestsType } from '../databaseTypes';
import { now } from '@lib/misc';
const console = consoleFactory('DatabaseDao');
/**
* Data access object for cleaning up the database.
*/
export default class CleanupDao {
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;
}
/**
* Cleans the database by removing every entry that matches the provided filter function.
* @returns {number} number of removed items
*/
bulkRemove(
tableName: 'players' | 'actions' | 'whitelistApprovals' | 'whitelistRequests',
filterFunc: Function
): number {
if (!Array.isArray(this.dbo.data[tableName])) throw new Error('Table selected isn\'t an array.');
if (typeof filterFunc !== 'function') throw new Error('filterFunc must be a function.');
try {
this.db.writeFlag(SavePriority.HIGH);
const removed = this.chain.get(tableName)
.remove(filterFunc as any)
.value();
return removed.length;
} catch (error) {
const msg = `Failed to clean database with error: ${(error as Error).message}`;
console.verbose.error(msg);
throw new Error(msg);
}
}
/**
* Cleans the hwids from the database.
* @returns {number} number of removed HWIDs
*/
wipeHwids(
fromPlayers: boolean,
fromBans: boolean,
): number {
if (!Array.isArray(this.dbo.data.players)) throw new Error('Players table isn\'t an array yet.');
if (!Array.isArray(this.dbo.data.players)) throw new Error('Actions table isn\'t an array yet.');
if (typeof fromPlayers !== 'boolean' || typeof fromBans !== 'boolean') throw new Error('The parameters should be booleans.');
try {
this.db.writeFlag(SavePriority.HIGH);
let removed = 0;
if (fromPlayers) {
this.chain.get('players')
.map(player => {
removed += player.hwids.length;
player.hwids = [];
return player;
})
.value();
}
if (fromBans)
this.chain.get('actions')
.map(action => {
if (action.type !== 'ban' || !action.hwids) {
return action;
} else {
removed += action.hwids.length;
action.hwids = [];
return action;
}
})
.value();
return removed;
} catch (error) {
const msg = `Failed to clean database with error: ${(error as Error).message}`;
console.verbose.error(msg);
throw new Error(msg);
}
}
/**
* Cron func to optimize the database removing players and whitelist reqs/approvals
*/
runDailyOptimizer() {
const oneDay = 24 * 60 * 60;
//Optimize players
//Players that have not joined the last 16 days, and have less than 2 hours of playtime
let playerRemoved;
try {
const sixteenDaysAgo = now() - (16 * oneDay);
const filter = (p: DatabasePlayerType) => {
return (p.tsLastConnection < sixteenDaysAgo && p.playTime < 120);
}
playerRemoved = this.bulkRemove('players', filter);
} catch (error) {
const msg = `Failed to optimize players database with error: ${(error as Error).message}`;
console.error(msg);
}
//Optimize whitelistRequests + whitelistApprovals
//Removing the ones older than 7 days
let wlRequestsRemoved, wlApprovalsRemoved;
const sevenDaysAgo = now() - (7 * oneDay);
try {
const wlRequestsFilter = (req: DatabaseWhitelistRequestsType) => {
return (req.tsLastAttempt < sevenDaysAgo);
}
wlRequestsRemoved = txCore.database.whitelist.removeManyRequests(wlRequestsFilter).length;
const wlApprovalsFilter = (req: DatabaseWhitelistApprovalsType) => {
return (req.tsApproved < sevenDaysAgo);
}
wlApprovalsRemoved = txCore.database.whitelist.removeManyApprovals(wlApprovalsFilter).length;
} catch (error) {
const msg = `Failed to optimize players database with error: ${(error as Error).message}`;
console.error(msg);
}
this.db.writeFlag(SavePriority.LOW);
console.ok(`Internal Database optimized. This applies only for the txAdmin internal database, and does not affect your MySQL or framework (ESX/QBCore/etc) databases.`);
console.ok(`- ${playerRemoved} players that haven't connected in the past 16 days and had less than 2 hours of playtime.`);
console.ok(`- ${wlRequestsRemoved} whitelist requests older than a week.`);
console.ok(`- ${wlApprovalsRemoved} whitelist approvals older than a week.`);
}
}