add admins from remote adminlist

This commit is contained in:
SeanWalsh95 2020-10-27 17:31:05 -04:00
parent a2793326b2
commit 41f9572986
3 changed files with 99 additions and 61 deletions

View File

@ -34,6 +34,7 @@ export default class SquadServer extends EventEmitter {
this.layerHistoryMaxLength = options.layerHistoryMaxLength || 20;
this.players = [];
this.admins = [];
this.plugins = [];
@ -41,6 +42,7 @@ export default class SquadServer extends EventEmitter {
this.setupRCON();
this.setupLogParser();
this.setupAdminList();
this.updatePlayerList = this.updatePlayerList.bind(this);
this.updatePlayerListInterval = 30 * 1000;
@ -232,6 +234,39 @@ export default class SquadServer extends EventEmitter {
await this.logParser.watch();
}
async setupAdminList() {
try {
for (const list of this.options.adminLists) {
const resp = await axios({
method: 'GET',
url: `${list}`
});
const rawData = resp.data;
const groupRgx = /(?<=Group=)(.*?):(.*)(?=\n)/g;
const adminRgx = /(?<=Admin=)(\d+):(\S+)(?=\s)/g;
const adminGroups = {};
for (const m of rawData.matchAll(groupRgx)) {
adminGroups[m[1]] = m[2].split(',');
}
/* eslint-disable no-unused-vars */
for (const [input, steamID, groupID] of rawData.matchAll(adminRgx)) {
const perms = adminGroups[groupID];
if (!(perms.includes('reserve') && perms.length === 1)) {
// exclude whitelist only
this.admins.push({ steamID: steamID, perms: perms });
}
}
/* eslint-enable no-unused-vars */
// console.log(this.admins)
}
} catch (err) {
console.log(err);
}
}
async updatePlayerList() {
if (this.updatePlayerListTimeout) clearTimeout(this.updatePlayerListTimeout);
@ -247,12 +282,12 @@ export default class SquadServer extends EventEmitter {
}));
for (const player of this.players) {
if(typeof oldPlayerInfo[player.steamID] == 'undefined')
continue;
if(player.teamID !== oldPlayerInfo[player.steamID].teamID) this.emit('PLAYER_TEAM_CHANGE', player);
if(player.squadID !== oldPlayerInfo[player.steamID].squadID) this.emit('PLAYER_SQUAD_CHANGE', player);
if (typeof oldPlayerInfo[player.steamID] === 'undefined') continue;
if (player.teamID !== oldPlayerInfo[player.steamID].teamID)
this.emit('PLAYER_TEAM_CHANGE', player);
if (player.squadID !== oldPlayerInfo[player.steamID].squadID)
this.emit('PLAYER_SQUAD_CHANGE', player);
}
} catch (err) {
Logger.verbose('SquadServer', 1, 'Failed to update player list.', err);
}

View File

@ -1,7 +1,6 @@
import BasePlugin from './base-plugin.js';
import Logger from 'core/logger';
export default class AutoKickAFK extends BasePlugin {
static get description() {
return 'The <code>AutoKickAFK</code> plugin will automatically kick players that are not in a squad after a specified ammount of time.';
@ -23,7 +22,7 @@ export default class AutoKickAFK extends BasePlugin {
description: 'Message to send to players when they are kicked',
default: 'Unassigned - automatically removed'
},
frequencyOfWarnings : {
frequencyOfWarnings: {
required: false,
description: 'How often in seconds should we warn the player about being AFK?',
default: 30
@ -33,33 +32,36 @@ export default class AutoKickAFK extends BasePlugin {
description: 'How long in minutes to wait before a player that is AFK is kicked',
default: 6
},
playerThreshold:{
playerThreshold: {
required: false,
description: 'Player count required for Auto Kick to start kicking players to disable set to -1 to disable',
description:
'Player count required for Auto Kick to start kicking players to disable set to -1 to disable',
default: 93
},
queueThreshold:{
queueThreshold: {
required: false,
description: 'The number of players in the queue before Auto Kick starts kicking players set to -1 to disable',
description:
'The number of players in the queue before Auto Kick starts kicking players set to -1 to disable',
default: -1
},
roundStartDelay:{
roundStartDelay: {
required: false,
description: 'Time delay in minutes from start of the round before auto AFK starts kicking again',
description:
'Time delay in minutes from start of the round before auto AFK starts kicking again',
default: 15
}/*, to be added in future when we can track admins better
} /*, to be added in future when we can track admins better
ignoreAdmins:{
required: false,
description: 'Whether or not admins will be auto kicked for being unassigned',
default: false
}*/
} */
};
}
constructor(server, options) {
super();
this.kickTimeout = options.afkTimer * 60 * 1000;
this.kickTimeout = options.afkTimer * 60 * 1000;
this.warningInterval = options.frequencyOfWarnings * 1000;
this.gracePeriod = options.roundStartDelay * 60 * 1000;
@ -70,87 +72,87 @@ export default class AutoKickAFK extends BasePlugin {
server.on('NEW_GAME', async (info) => {
this.betweenRounds = true;
updateTrackingList();
setTimeout(async ()=>{
setTimeout(async () => {
this.betweenRounds = false;
}, this.gracePeriod);
});
server.on('PLAYER_SQUAD_CHANGE', async (player) =>{
if (player.steamID in this.trackedPlayers && player.squadID !== null){
server.on('PLAYER_SQUAD_CHANGE', async (player) => {
if (player.steamID in this.trackedPlayers && player.squadID !== null) {
untrackPlayer(player.steamID);
}
});
const runConditions = ()=>{
return true; // force run for testing TODO: remove
return ( !this.betweenRounds || (0 < options.playerCountThreshold < server.players.count) || (0 < options.queueThreshold < (server.publicQueue + server.reserveQueue)) )
}
const runConditions = () => {
// return true; // force run for testing TODO: remove
return (
!this.betweenRounds ||
options.playerCountThreshold > 0 < server.players.count ||
options.queueThreshold > 0 < server.publicQueue + server.reserveQueue
);
};
const updateTrackingList = async ()=>{
if( !runConditions() ){
const updateTrackingList = async () => {
if (!runConditions()) {
// clear all tracked players if run conditions are not met.
for(const steamID of Object.keys(this.trackedPlayers))
untrackPlayer(steamID);
for (const steamID of Object.keys(this.trackedPlayers)) untrackPlayer(steamID);
return;
}
//await server.updatePlayerList(); //possibly unneeded as updates to player list are already common
// await server.updatePlayerList(); //possibly unneeded as updates to player list are already common
// loop through players on server and start tracking players not in a squad
for (const player of server.players) {
let isTracked = (player.steamID in this.trackedPlayers);
let isUnassigned = (player.squadID === null);
let isAdmin = false; //to be implemented
const isTracked = player.steamID in this.trackedPlayers;
const isUnassigned = player.squadID === null;
const isAdmin = player.steamID in server.admins.map((a) => a.steamID);
if(isUnassigned && !isTracked && !isAdmin)
if (isUnassigned && !isTracked && !isAdmin)
this.trackedPlayers[player.steamID] = trackPlayer(player); // start tracking player
if(!isUnassigned && isTracked)
untrackPlayer(player.steamID); // tracked player joined a squad remove them (redundant afer addming PLAYER_SQUAD_CHANGE, keeping for now)
if (!isUnassigned && isTracked) untrackPlayer(player.steamID); // tracked player joined a squad remove them (redundant afer addming PLAYER_SQUAD_CHANGE, keeping for now)
}
}
};
const msFormat = (ms)=>{
let min = Math.floor((ms/1000/60) << 0);
let sec = Math.floor((ms/1000) % 60);
const msFormat = (ms) => {
const min = Math.floor((ms / 1000 / 60) << 0);
const sec = Math.floor((ms / 1000) % 60);
return `${min}:${sec}`;
}
};
const trackPlayer = (player)=>{
const trackPlayer = (player) => {
Logger.verbose('AutoAFK', 1, `Tracking: ${player.name}`);
let tracker = {};
tracker.player = player
const tracker = {};
tracker.player = player;
tracker.startTime = Date.now();
tracker.warnTimerID = setInterval( async ()=> {
let timeLeft = msFormat(this.kickTimeout-(Date.now()-tracker.startTime));
tracker.warnTimerID = setInterval(async () => {
const timeLeft = msFormat(this.kickTimeout - (Date.now() - tracker.startTime));
Logger.verbose('AutoAFK', 1, `Warning: ${player.name} (${timeLeft})`);
server.rcon.warn(player.steamID, `${options.warningMessage} - ${timeLeft}`);
}, this.warningInterval);
tracker.kickTimerID = setTimeout(async ()=>{
tracker.kickTimerID = setTimeout(async () => {
Logger.verbose('AutoAFK', 1, `Kicked: ${player.name}`);
server.rcon.kick(player.steamID, options.kickMessage);
untrackPlayer(player.steamID);
}, this.kickTimeout);
return tracker;
}
};
const untrackPlayer = (steamID)=>{
let tracker = this.trackedPlayers[steamID];
const untrackPlayer = (steamID) => {
const tracker = this.trackedPlayers[steamID];
Logger.verbose('AutoAFK', 1, `[AutoAFK] unTrack: ${tracker.player.name}`);
clearInterval(tracker.warnTimerID); // clears warning interval
clearTimeout(tracker.kickTimerID); // clears kick timeout
delete this.trackedPlayers[steamID];
}
};
setInterval(updateTrackingList , 1*60*1000); //tracking list update loop
setInterval(updateTrackingList, 1 * 60 * 1000); // tracking list update loop
//clean up every 20 minutes, removes players no longer on the server that may be stuck in the tracking dict
const cleanupMS = 20*60*1000;
setInterval( ()=>{
for(const steamID of Object.keys(this.trackedPlayers))
if(!steamID in server.players.map(p => p.steamID))
untrackPlayer(steamID);
// clean up every 20 minutes, removes players no longer on the server that may be stuck in the tracking dict
const cleanupMS = 20 * 60 * 1000;
setInterval(() => {
for (const steamID of Object.keys(this.trackedPlayers))
if (!(steamID in server.players.map((p) => p.steamID))) untrackPlayer(steamID);
}, cleanupMS);
}
}

View File

@ -13,7 +13,8 @@
"ftpPort": 21,
"ftpUser": "FTP Username",
"ftpPassword": "FTP Password",
"ftpUseListForSize": false
"ftpUseListForSize": false,
"adminLists": []
},
"connectors": {
"discord": "Discord Login Token",