mirror of
https://github.com/AsgardEternal/SquadJS.git
synced 2024-09-28 17:34:25 -05:00
275 lines
9.0 KiB
JavaScript
275 lines
9.0 KiB
JavaScript
import axios from 'axios';
|
|
import didYouMean from 'didyoumean';
|
|
import fs from 'fs';
|
|
|
|
class SquadLayersBase {
|
|
get layerNames() {
|
|
return this.layers.map((layer) => layer.name);
|
|
}
|
|
|
|
getLayerByCondition(condition) {
|
|
const results = this.layers.filter(condition);
|
|
return results.length === 1 ? results[0] : null;
|
|
}
|
|
|
|
getLayerByLayerName(layerName) {
|
|
return this.getLayerByCondition((layer) => layer.layer === layerName);
|
|
}
|
|
|
|
getLayerByLayerClassname(layerClassname) {
|
|
return this.getLayerByCondition((layer) => layer.layerClassname === layerClassname);
|
|
}
|
|
|
|
getLayerByLayerNameAutoCorrection(layerName) {
|
|
return this.getLayerByLayerName(didYouMean(layerName, this.layerNames()));
|
|
}
|
|
|
|
getLayerByNumber(layerNumber) {
|
|
return this.getLayerByCondition((layer) => layer.layerNumber === layerNumber);
|
|
}
|
|
}
|
|
|
|
class SquadLayers extends SquadLayersBase {
|
|
constructor(source) {
|
|
super();
|
|
|
|
this.source =
|
|
source || 'https://raw.githubusercontent.com/Thomas-Smyth/squad-layers/master/layers.json';
|
|
this.pulled = false;
|
|
}
|
|
|
|
async pull(force = false) {
|
|
if (this.pulled && !force) return;
|
|
|
|
this.layers = (await axios.get(this.source)).data;
|
|
for (let i = 0; i < this.layers.length; i++) this.layers[i].layerNumber = i + 1;
|
|
}
|
|
|
|
buildPoolFromLayerNames(layerNames, activeFilter) {
|
|
return new SquadLayersPool(
|
|
this.layers.filter((layer) => layerNames.includes(layer.layer)),
|
|
activeFilter
|
|
);
|
|
}
|
|
|
|
buildPoolFromLayerNamesAutoCorrection(layerNames, activeFilter) {
|
|
return this.buildPoolFromLayerNames(
|
|
layerNames.map((layerName) => this.getLayerByLayerNameAutoCorrection(layerName)),
|
|
activeFilter
|
|
);
|
|
}
|
|
|
|
buildPoolFromFile(path, activeFilter, delimiter = '\n') {
|
|
return this.buildPoolFromLayerNames(
|
|
fs.readFileSync(path, 'utf8').split(delimiter),
|
|
activeFilter
|
|
);
|
|
}
|
|
|
|
buildPoolFromFilter(filter, activeFilter) {
|
|
const whitelistedLayers = filter.whitelistedLayers || null;
|
|
const blacklistedLayers = filter.blacklistedLayers || null;
|
|
const whitelistedMaps = filter.whitelistedMaps || null;
|
|
const blacklistedMaps = filter.blacklistedMaps || null;
|
|
const whitelistedGamemodes = filter.whitelistedGamemodes || null;
|
|
const blacklistedGamemodes = filter.blacklistedGamemodes || ['Training'];
|
|
const flagCountMin = filter.flagCountMin || null;
|
|
const flagCountMax = filter.flagCountMax || null;
|
|
const hasCommander = filter.hasCommander || null;
|
|
const hasTanks = filter.hasTanks || null;
|
|
const hasHelicopters = filter.hasHelicopters || null;
|
|
|
|
const layers = [];
|
|
|
|
for (const layer of this.layers) {
|
|
// Whitelist / Blacklist Layers
|
|
if (whitelistedLayers !== null && !whitelistedLayers.includes(layer.layer)) continue;
|
|
if (blacklistedLayers !== null && blacklistedLayers.includes(layer.layer)) continue;
|
|
|
|
// Whitelist / Blacklist Maps
|
|
if (whitelistedMaps !== null && !whitelistedMaps.includes(layer.map)) continue;
|
|
if (blacklistedMaps !== null && blacklistedMaps.includes(layer.map)) continue;
|
|
|
|
// Whitelist / Blacklist Gamemodes
|
|
if (whitelistedGamemodes !== null && !whitelistedGamemodes.includes(layer.gamemode)) continue;
|
|
if (blacklistedGamemodes !== null && blacklistedGamemodes.includes(layer.gamemode)) continue;
|
|
|
|
// Flag Count
|
|
if (flagCountMin !== null && layer.flagCount < flagCountMin) continue;
|
|
if (flagCountMax !== null && layer.flagCount > flagCountMax) continue;
|
|
|
|
// Other Properties
|
|
if (hasCommander !== null && layer.commander !== hasCommander) continue;
|
|
if (hasTanks !== null && (layer.tanks !== 'N/A') !== hasTanks) continue;
|
|
if (hasHelicopters !== null && (layer.helicopters !== 'N/A') !== hasHelicopters) continue;
|
|
|
|
layers.push(layer);
|
|
}
|
|
|
|
return new SquadLayersPool(layers, activeFilter);
|
|
}
|
|
}
|
|
|
|
class SquadLayersPool extends SquadLayersBase {
|
|
constructor(layers, activeFilter = null) {
|
|
super();
|
|
|
|
this.layers = layers;
|
|
for (let i = 0; i < this.layers.length; i++) this.layers[i].layerNumber = i + 1;
|
|
this.activeFilter = activeFilter;
|
|
}
|
|
|
|
inPool(layer) {
|
|
if (typeof layer === 'object') layer = layer.layer;
|
|
return super.layerNames.includes(layer);
|
|
}
|
|
|
|
isHistoryCompliant(layerHistory, layer) {
|
|
if (this.activeFilter === null) return true;
|
|
|
|
if (typeof layer === 'object') layer = layer.layer;
|
|
|
|
for (
|
|
let i = 0;
|
|
i < Math.min(layerHistory.length, this.activeFilter.layerHistoryTolerance);
|
|
i++
|
|
) {
|
|
if (new Date() - layerHistory[i].time > this.activeFilter.historyResetTime) return true;
|
|
if (layerHistory[i].layer === layer) return false;
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
isMapHistoryCompliant(layerHistory, layer) {
|
|
if (this.activeFilter === null) return true;
|
|
|
|
if (typeof layer === 'string') layer = this.getLayerByLayerName(layer);
|
|
|
|
for (let i = 0; i < Math.min(layerHistory.length, this.activeFilter.mapHistoryTolerance); i++) {
|
|
if (new Date() - layerHistory[i].time > this.activeFilter.historyResetTime) return true;
|
|
if (layerHistory[i].map === layer.map) return false;
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
isGamemodeHistoryCompliant(layerHistory, layer) {
|
|
if (this.activeFilter === null) return true;
|
|
|
|
if (typeof layer === 'string') layer = this.getLayerByLayerName(layer);
|
|
|
|
const gamemodeHistoryTolerance = this.activeFilter.gamemodeHistoryTolerance[layer.gamemode];
|
|
if (!gamemodeHistoryTolerance) return true;
|
|
|
|
for (let i = 0; i < Math.min(layerHistory.length, gamemodeHistoryTolerance); i++) {
|
|
if (new Date() - layerHistory[i].time > this.activeFilter.historyResetTime) return true;
|
|
if (layerHistory[i].gamemode === layer.gamemode) return false;
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
isGamemodeRepetitiveCompliant(layerHistory, layer) {
|
|
if (this.activeFilter === null) return true;
|
|
|
|
if (typeof layer === 'string') layer = this.getLayerByLayerName(layer);
|
|
|
|
const gamemodeRepetitiveTolerance = this.activeFilter.gamemodeRepetitiveTolerance[
|
|
layer.gamemode
|
|
];
|
|
if (!gamemodeRepetitiveTolerance) return true;
|
|
|
|
for (let i = 0; i < Math.min(layerHistory.length, gamemodeRepetitiveTolerance); i++) {
|
|
if (new Date() - layerHistory[i].time > this.activeFilter.historyResetTime) return true;
|
|
|
|
if (layerHistory[i].gamemode.gamemode !== layer.gamemode) return true;
|
|
}
|
|
return false;
|
|
}
|
|
|
|
isFactionCompliant(layerHistory, layer) {
|
|
if (this.activeFilter === null || this.activeFilter.factionComplianceEnabled === false)
|
|
return true;
|
|
|
|
if (layerHistory.length === 0) return true;
|
|
|
|
if (typeof layer === 'string') layer = this.getLayerByLayerName(layer);
|
|
|
|
return (
|
|
!layerHistory[0] ||
|
|
(layerHistory[0].teamOne.faction !== layer.teamTwo.faction &&
|
|
layerHistory[0].teamTwo.faction !== layer.teamOne.faction)
|
|
);
|
|
}
|
|
|
|
isFactionHistoryCompliant(layerHistory, layer, faction = null) {
|
|
if (this.activeFilter === null) return true;
|
|
|
|
if (typeof layer === 'string') layer = SquadLayers.getLayerByLayerName(layer);
|
|
|
|
if (faction === null) {
|
|
return (
|
|
this.isFactionHistoryCompliant(layerHistory, layer, layer.teamOne.faction) &&
|
|
this.isFactionHistoryCompliant(layerHistory, layer, layer.teamTwo.faction)
|
|
);
|
|
} else {
|
|
const factionThreshold = this.activeFilter.factionHistoryTolerance[faction];
|
|
if (!factionThreshold) return true;
|
|
|
|
for (let i = 0; i < Math.min(layerHistory.length, factionThreshold); i++) {
|
|
if (new Date() - layerHistory[i].time > this.activeFilter.historyResetTime) return true;
|
|
if (
|
|
layerHistory[i].teamOne.faction === faction ||
|
|
layerHistory[i].teamTwo.faction === faction
|
|
)
|
|
return false;
|
|
}
|
|
|
|
return true;
|
|
}
|
|
}
|
|
|
|
isFactionRepetitiveCompliant(layerHistory, layer, faction = null) {
|
|
if (this.activeFilter === null) return true;
|
|
|
|
if (typeof layer === 'string') layer = SquadLayers.getLayerByLayerName(layer);
|
|
|
|
if (faction === null) {
|
|
return (
|
|
this.isFactionRepetitiveCompliant(layerHistory, layer, layer.teamOne.faction) &&
|
|
this.isFactionRepetitiveCompliant(layerHistory, layer, layer.teamTwo.faction)
|
|
);
|
|
} else {
|
|
const factionThreshold = this.activeFilter.factionRepetitiveTolerance[faction];
|
|
if (!factionThreshold) return true;
|
|
|
|
for (let i = 0; i < Math.min(layerHistory.length, factionThreshold); i++) {
|
|
if (new Date() - layerHistory[i].time > this.activeFilter.historyResetTime) return true;
|
|
|
|
if (
|
|
layerHistory[i].teamOne.faction !== faction &&
|
|
layerHistory[i].teamTwo.faction !== faction
|
|
)
|
|
return true;
|
|
}
|
|
|
|
return false;
|
|
}
|
|
}
|
|
|
|
isPlayerCountCompliant(server, layer) {
|
|
if (this.activeFilter === null || this.activeFilter.playerCountComplianceEnabled === false)
|
|
return true;
|
|
|
|
if (typeof layer === 'string') layer = this.getLayerByLayerName(layer);
|
|
|
|
return !(
|
|
server.players.length > layer.estimatedSuitablePlayerCount.max ||
|
|
server.players.length < layer.estimatedSuitablePlayerCount.min
|
|
);
|
|
}
|
|
}
|
|
|
|
export { SquadLayers, SquadLayersPool };
|