Merge pull request #24 from Thomas-Smyth/alpha

SquadJS v1.0.11 Release
This commit is contained in:
Thomas Smyth 2020-06-14 12:59:38 +01:00 committed by GitHub
commit d401ee3561
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
29 changed files with 431 additions and 365 deletions

View File

@ -1,4 +1,4 @@
{
"singleQuote": true,
"printWidth": 80
"printWidth": 100
}

View File

@ -209,7 +209,11 @@
},
"tanks": "x1 for INS, 30 min delay",
"helicopters": "N/A",
"newForVersion": false
"newForVersion": false,
"estimatedSuitablePlayerCount": {
"min": 45,
"max": 80
}
},
{
"layer": "Al Basrah TC v2",
@ -232,7 +236,11 @@
},
"tanks": "x1 for INS, 20 min delay",
"helicopters": "N/A",
"newForVersion": false
"newForVersion": false,
"estimatedSuitablePlayerCount": {
"min": 45,
"max": 80
}
},
{
"layer": "Belaya AAS v1",
@ -471,7 +479,11 @@
},
"tanks": "x1 per team, 20min delay",
"helicopters": "N/A",
"newForVersion": false
"newForVersion": false,
"estimatedSuitablePlayerCount": {
"min": 45,
"max": 80
}
},
{
"layer": "Chora AAS v1",
@ -710,12 +722,16 @@
},
"tanks": "N/A",
"helicopters": "N/A",
"newForVersion": false
"newForVersion": false,
"estimatedSuitablePlayerCount": {
"min": 36,
"max": 80
}
},
{
"layer": "Fool's Road AAS v1",
"map": "Fool's Road",
"layerClassname": "FoolsRoad_AAS_v1",
"layerClassname": "Fools_Road_AAS_v1",
"mapSize": "2x2 km",
"gamemode": "AAS",
"version": "v1",
@ -742,7 +758,7 @@
{
"layer": "Fool's Road AAS v2",
"map": "Fool's Road",
"layerClassname": "FoolsRoad_AAS_v2",
"layerClassname": "Fools_Road_AAS_v2",
"mapSize": "2x2 km",
"gamemode": "AAS",
"version": "v2",
@ -769,7 +785,7 @@
{
"layer": "Fool's Road Destruction v1",
"map": "Fool's Road",
"layerClassname": "FoolsRoad_Destruction_v1",
"layerClassname": "Fools_Road_Destruction_v1",
"mapSize": "2x2 km",
"gamemode": "Destruction",
"version": "v1",
@ -796,7 +812,7 @@
{
"layer": "Fool's Road Invasion v1",
"map": "Fool's Road",
"layerClassname": "FoolsRoad_Invasion_v1",
"layerClassname": "Fools_Road_Invasion_v1",
"mapSize": "2x2 km",
"gamemode": "Invasion",
"version": "v1",
@ -823,7 +839,7 @@
{
"layer": "Fool's Road RAAS v1",
"map": "Fool's Road",
"layerClassname": "FoolsRoad_RAAS_v1",
"layerClassname": "Fools_Road_RAAS_v1",
"mapSize": "2x2 km",
"gamemode": "RAAS",
"version": "v1",
@ -850,7 +866,7 @@
{
"layer": "Fool's Road RAAS v2",
"map": "Fool's Road",
"layerClassname": "FoolsRoad_RAAS_v2",
"layerClassname": "Fools_Road_RAAS_v2",
"mapSize": "2x2 km",
"gamemode": "RAAS",
"version": "v2",
@ -877,7 +893,7 @@
{
"layer": "Fool's Road RAAS v3",
"map": "Fool's Road",
"layerClassname": "FoolsRoad_RAAS_v3",
"layerClassname": "Fools_Road_RAAS_v3",
"mapSize": "2x2 km",
"gamemode": "RAAS",
"version": "v3",
@ -904,7 +920,7 @@
{
"layer": "Fool's Road Skirmish v1",
"map": "Fool's Road",
"layerClassname": "FoolsRoad_Skirmish_v1",
"layerClassname": "Fools_Road_Skirmish_v1",
"mapSize": "2x2 km",
"gamemode": "Skirmish",
"version": "v1",
@ -931,7 +947,7 @@
{
"layer": "Fool's Road Skirmish v2",
"map": "Fool's Road",
"layerClassname": "FoolsRoad_Skirmish_v2",
"layerClassname": "Fools_Road_Skirmish_v2",
"mapSize": "2x2 km",
"gamemode": "Skirmish",
"version": "v2",
@ -958,7 +974,7 @@
{
"layer": "Fool's Road TC v1",
"map": "Fool's Road",
"layerClassname": "FoolsRoad_TC_v1",
"layerClassname": "Fools_Road_TC_v1",
"mapSize": "2x2 km",
"gamemode": "TC",
"version": "v1",
@ -976,7 +992,11 @@
},
"tanks": "N/A",
"helicopters": "N/A",
"newForVersion": false
"newForVersion": false,
"estimatedSuitablePlayerCount": {
"min": 36,
"max": 80
}
},
{
"layer": "Gorodok AAS v1",
@ -1296,7 +1316,11 @@
},
"tanks": "N/A",
"helicopters": "x1 per team",
"newForVersion": false
"newForVersion": false,
"estimatedSuitablePlayerCount": {
"min": 45,
"max": 80
}
},
{
"layer": "Jensen's Range Training v1",
@ -1697,7 +1721,11 @@
},
"tanks": "N/A",
"helicopters": "x1 per team",
"newForVersion": false
"newForVersion": false,
"estimatedSuitablePlayerCount": {
"min": 45,
"max": 80
}
},
{
"layer": "Kamdesh TC v2",
@ -1720,7 +1748,11 @@
},
"tanks": "N/A",
"helicopters": "N/A",
"newForVersion": false
"newForVersion": false,
"estimatedSuitablePlayerCount": {
"min": 54,
"max": 80
}
},
{
"layer": "Kohat AAS v1",
@ -1986,7 +2018,11 @@
},
"tanks": "N/A",
"helicopters": "x2 per team",
"newForVersion": false
"newForVersion": false,
"estimatedSuitablePlayerCount": {
"min": 45,
"max": 80
}
},
{
"layer": "Kokan AAS v1",
@ -2171,7 +2207,11 @@
},
"tanks": "N/A",
"helicopters": "N/A",
"newForVersion": false
"newForVersion": false,
"estimatedSuitablePlayerCount": {
"min": 36,
"max": 80
}
},
{
"layer": "Logar Valley AAS v1",
@ -2329,7 +2369,11 @@
},
"tanks": "N/A",
"helicopters": "N/A",
"newForVersion": false
"newForVersion": false,
"estimatedSuitablePlayerCount": {
"min": 36,
"max": 80
}
},
{
"layer": "Mestia AAS v1",
@ -2487,7 +2531,11 @@
},
"tanks": "N/A",
"helicopters": "N/A",
"newForVersion": false
"newForVersion": false,
"estimatedSuitablePlayerCount": {
"min": 36,
"max": 80
}
},
{
"layer": "Mutaha AAS v1",
@ -2618,7 +2666,11 @@
},
"tanks": "N/A",
"helicopters": "N/A",
"newForVersion": false
"newForVersion": false,
"estimatedSuitablePlayerCount": {
"min": 36,
"max": 80
}
},
{
"layer": "Mutaha TC v2",
@ -2641,7 +2693,11 @@
},
"tanks": "x1 per team, 20min delay",
"helicopters": "x1 per team",
"newForVersion": false
"newForVersion": false,
"estimatedSuitablePlayerCount": {
"min": 54,
"max": 80
}
},
{
"layer": "Narva AAS v1",
@ -2880,7 +2936,11 @@
},
"tanks": "N/A",
"helicopters": "N/A",
"newForVersion": false
"newForVersion": false,
"estimatedSuitablePlayerCount": {
"min": 36,
"max": 80
}
},
{
"layer": "Narva TC v2",
@ -2903,7 +2963,11 @@
},
"tanks": "x1 per team, 30min delay",
"helicopters": "N/A",
"newForVersion": false
"newForVersion": false,
"estimatedSuitablePlayerCount": {
"min": 45,
"max": 80
}
},
{
"layer": "Skorpo AAS v1",
@ -3142,7 +3206,11 @@
},
"tanks": "N/A",
"helicopters": "N/A",
"newForVersion": false
"newForVersion": false,
"estimatedSuitablePlayerCount": {
"min": 54,
"max": 80
}
},
{
"layer": "Skorpo TC v2",
@ -3165,7 +3233,11 @@
},
"tanks": "N/A",
"helicopters": "N/A",
"newForVersion": false
"newForVersion": false,
"estimatedSuitablePlayerCount": {
"min": 54,
"max": 80
}
},
{
"layer": "Skorpo TC v3",
@ -3188,7 +3260,11 @@
},
"tanks": "x1 per team, 20min delay",
"helicopters": "N/A",
"newForVersion": false
"newForVersion": false,
"estimatedSuitablePlayerCount": {
"min": 45,
"max": 80
}
},
{
"layer": "Sumari AAS v1",
@ -3373,7 +3449,11 @@
},
"tanks": "N/A",
"helicopters": "N/A",
"newForVersion": false
"newForVersion": false,
"estimatedSuitablePlayerCount": {
"min": 36,
"max": 80
}
},
{
"layer": "Tallil Outskirts AAS v1",
@ -3739,7 +3819,11 @@
},
"tanks": "x2 per team, 20min delay",
"helicopters": "x2 per team",
"newForVersion": false
"newForVersion": false,
"estimatedSuitablePlayerCount": {
"min": 54,
"max": 80
}
},
{
"layer": "Tutorials Infantry Training Tutorial",
@ -4159,7 +4243,11 @@
},
"tanks": "x2 per team, 20min delay",
"helicopters": "x1 per team",
"newForVersion": false
"newForVersion": false,
"estimatedSuitablePlayerCount": {
"min": 54,
"max": 80
}
},
{
"layer": "Yehorivka TC v2",
@ -4182,7 +4270,11 @@
},
"tanks": "x1 per team",
"helicopters": "x1 per team",
"newForVersion": false
"newForVersion": false,
"estimatedSuitablePlayerCount": {
"min": 54,
"max": 80
}
},
{
"layer": "CAF_Albasrah_Invasion_v1",
@ -4313,7 +4405,11 @@
},
"tanks": "N/A",
"helicopters": "x1 per team",
"newForVersion": false
"newForVersion": false,
"estimatedSuitablePlayerCount": {
"min": 45,
"max": 80
}
},
{
"layer": "CAF_Jensens_Range_v4",
@ -4417,7 +4513,11 @@
},
"tanks": "N/A",
"helicopters": "N/A",
"newForVersion": false
"newForVersion": false,
"estimatedSuitablePlayerCount": {
"min": 40,
"max": 80
}
},
{
"layer": "CAF_Kohat_Invasion_v1",
@ -4447,7 +4547,7 @@
}
},
{
"layer": "CAF_Manic_AAS_v1",
"layer": "CAF_Manic-5_AAS_v1",
"map": "CAF Manic-5",
"layerClassname": "CAF_Manic_AAS_v1",
"gamemode": "AAS",
@ -4474,7 +4574,7 @@
}
},
{
"layer": "CAF_Manic_Invasion_v1",
"layer": "CAF_Manic-5_Invasion_v1",
"map": "CAF Manic-5",
"layerClassname": "CAF_Manic_Invasion_v1",
"gamemode": "Invasion",
@ -4501,7 +4601,7 @@
}
},
{
"layer": "CAF_Manic_Invasion_v2",
"layer": "CAF_Manic-5_Invasion_v2",
"map": "CAF Manic-5",
"layerClassname": "CAF_Manic_Invasion_v2",
"gamemode": "Invasion",
@ -4528,7 +4628,7 @@
}
},
{
"layer": "CAF_Manic_RAAS_v1",
"layer": "CAF_Manic-5_RAAS_v1",
"map": "CAF Manic-5",
"layerClassname": "CAF_Manic_RAAS_v1",
"gamemode": "RAAS",
@ -4555,7 +4655,7 @@
}
},
{
"layer": "CAF_Manic_RAAS_v2",
"layer": "CAF_Manic-5_RAAS_v2",
"map": "CAF Manic-5",
"layerClassname": "CAF_Manic_RAAS_v2",
"gamemode": "RAAS",
@ -4582,7 +4682,7 @@
}
},
{
"layer": "CAF_Manic_RAAS_v3",
"layer": "CAF_Manic-5_RAAS_v3",
"map": "CAF Manic-5",
"layerClassname": "CAF_Manic_RAAS_v3",
"gamemode": "RAAS",
@ -4609,7 +4709,7 @@
}
},
{
"layer": "CAF_Manic_RAAS_v4",
"layer": "CAF_Manic-5_RAAS_v4",
"map": "CAF Manic-5",
"layerClassname": "CAF_Manic_RAAS_v4",
"gamemode": "RAAS",
@ -4636,7 +4736,7 @@
}
},
{
"layer": "CAF_Manic_Skirmish_v1",
"layer": "CAF_Manic-5_Skirmish_v1",
"map": "CAF Manic-5",
"layerClassname": "CAF_Manic_Skirmish_v1",
"gamemode": "Skirmish",
@ -4663,7 +4763,7 @@
}
},
{
"layer": "CAF_Manic_Skirmish_v2",
"layer": "CAF_Manic-5_Skirmish_v2",
"map": "CAF Manic-5",
"layerClassname": "CAF_Manic_Skirmish_v2",
"gamemode": "Skirmish",
@ -4690,7 +4790,7 @@
}
},
{
"layer": "CAF_Manic_TC_v1",
"layer": "CAF_Manic-5_TC_v1",
"map": "CAF Manic-5",
"layerClassname": "CAF_Manic_TC_v1",
"gamemode": "TC",
@ -4710,7 +4810,11 @@
},
"tanks": "N/A",
"helicopters": "x1 per team",
"newForVersion": false
"newForVersion": false,
"estimatedSuitablePlayerCount": {
"min": 45,
"max": 80
}
},
{
"layer": "CAF_Mestia_RAAS_v1",
@ -4949,6 +5053,10 @@
},
"tanks": "N/A",
"helicopters": "x1 per team",
"newForVersion": false
"newForVersion": false,
"estimatedSuitablePlayerCount": {
"min": 45,
"max": 80
}
}
]

View File

@ -1,7 +1,5 @@
import fs from 'fs';
import SquadLayers, {
SquadLayers as SquadLayersClass
} from './squad-layers.js';
import SquadLayers, { SquadLayers as SquadLayersClass } from './squad-layers.js';
export default class SquadLayerFilter extends SquadLayersClass {
constructor(layers, activeLayerFilter = null) {
@ -18,7 +16,20 @@ export default class SquadLayerFilter extends SquadLayersClass {
// defaults as off
...activeLayerFilter.gamemodeHistoryTolerance
},
gamemodeRepetitiveTolerance: {
// defaults as off
...activeLayerFilter.gamemodeRepetitiveTolerance
},
playerCountComplianceEnabled: true,
factionComplianceEnabled: true,
factionHistoryTolerance: {
// defaults as off
...activeLayerFilter.factionHistoryTolerance
},
factionRepetitiveTolerance: {
// defaults as off
...activeLayerFilter.factionRepetitiveTolerance
},
...activeLayerFilter
};
}
@ -31,26 +42,20 @@ export default class SquadLayerFilter extends SquadLayersClass {
static buildFromDidYouMeanList(layerNames, activeLayerFilter) {
const layers = [];
for (const layerName of layerNames) {
const layer = SquadLayers.getLayerByDidYouMean(
layerName,
SquadLayers.getLayerNames()
);
const layer = SquadLayers.getLayerByDidYouMean(layerName, SquadLayers.getLayerNames());
if (layer) layers.push(layer);
}
return new SquadLayerFilter(layers, activeLayerFilter);
}
static buildFromFile(filename, activeLayerFilter, delimiter = '\n') {
const lines = fs
.readFileSync('./connectors/data/layers.json', 'utf8')
.split(delimiter);
const lines = fs.readFileSync('./connectors/data/layers.json', 'utf8').split(delimiter);
const layers = [];
const validLayerNames = SquadLayers.getLayerNames();
for (const line of lines) {
if (validLayerNames.contains(line))
layers.push(SquadLayers.getLayerByLayerName(line));
if (validLayerNames.contains(line)) layers.push(SquadLayers.getLayerByLayerName(line));
}
return new SquadLayerFilter(layers, activeLayerFilter);
}
@ -72,31 +77,16 @@ export default class SquadLayerFilter extends SquadLayersClass {
for (const layer of SquadLayers.getLayers()) {
// Whitelist / Blacklist Layers
if (
whitelistedLayers !== null &&
!whitelistedLayers.includes(layer.layer)
)
continue;
if (blacklistedLayers !== null && blacklistedLayers.includes(layer.layer))
continue;
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;
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;
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;
@ -105,11 +95,7 @@ export default class SquadLayerFilter extends SquadLayersClass {
// 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;
if (hasHelicopters !== null && (layer.helicopters !== 'N/A') !== hasHelicopters) continue;
layers.push(layer);
}
@ -129,17 +115,10 @@ export default class SquadLayerFilter extends SquadLayersClass {
for (
let i = 0;
i <
Math.min(
server.layerHistory.length,
this.activeLayerFilter.layerHistoryTolerance
);
i < Math.min(server.layerHistory.length, this.activeLayerFilter.layerHistoryTolerance);
i++
) {
if (
new Date() - server.layerHistory[i].time >
this.activeLayerFilter.historyResetTime
)
if (new Date() - server.layerHistory[i].time > this.activeLayerFilter.historyResetTime)
return true;
if (server.layerHistory[i].layer === layer) return false;
}
@ -149,23 +128,16 @@ export default class SquadLayerFilter extends SquadLayersClass {
isMapHistoryCompliant(server, layer) {
if (this.activeLayerFilter === null) return true;
if (typeof layer === 'string')
layer = SquadLayers.getLayerByLayerName(layer);
if (typeof layer === 'string') layer = SquadLayers.getLayerByLayerName(layer);
for (
let i = 0;
i <
Math.min(
server.layerHistory.length,
this.activeLayerFilter.mapHistoryTolerance
);
i < Math.min(server.layerHistory.length, this.activeLayerFilter.mapHistoryTolerance);
i++
) {
if (
new Date() - server.layerHistory[i].time >
this.activeLayerFilter.historyResetTime
)
if (new Date() - server.layerHistory[i].time > this.activeLayerFilter.historyResetTime)
return true;
if (server.layerHistory[i].map === layer.map) return false;
}
return true;
@ -174,42 +146,134 @@ export default class SquadLayerFilter extends SquadLayersClass {
isGamemodeHistoryCompliant(server, layer) {
if (this.activeLayerFilter === null) return true;
if (typeof layer === 'string')
layer = SquadLayers.getLayerByLayerName(layer);
if (typeof layer === 'string') layer = SquadLayers.getLayerByLayerName(layer);
const gamemodeHistoryTolerance = this.activeLayerFilter
.gamemodeHistoryTolerance[layer.gamemode];
const gamemodeHistoryTolerance = this.activeLayerFilter.gamemodeHistoryTolerance[
layer.gamemode
];
if (!gamemodeHistoryTolerance) return true;
for (
let i = 0;
i < Math.min(server.layerHistory.length, gamemodeHistoryTolerance);
i++
) {
if (
new Date() - server.layerHistory[i].time >
this.activeLayerFilter.historyResetTime
)
for (let i = 0; i < Math.min(server.layerHistory.length, gamemodeHistoryTolerance); i++) {
if (new Date() - server.layerHistory[i].time > this.activeLayerFilter.historyResetTime)
return true;
const historyLayer = SquadLayers.getLayerByLayerName(
server.layerHistory[i].layer
);
if (historyLayer && historyLayer.gamemode === layer.gamemode)
return false;
const historyLayer = SquadLayers.getLayerByLayerName(server.layerHistory[i].layer);
if (!historyLayer) continue;
if (historyLayer.gamemode === layer.gamemode) return false;
}
return true;
}
isGamemodeRepetitiveCompliant(server, layer) {
if (this.activeLayerFilter === null) return true;
if (typeof layer === 'string') layer = SquadLayers.getLayerByLayerName(layer);
const gamemodeRepetitiveTolerance = this.activeLayerFilter.gamemodeRepetitiveTolerance[
layer.gamemode
];
if (!gamemodeRepetitiveTolerance) return true;
for (let i = 0; i < Math.min(server.layerHistory.length, gamemodeRepetitiveTolerance); i++) {
if (new Date() - server.layerHistory[i].time > this.activeLayerFilter.historyResetTime)
return true;
const historyLayer = SquadLayers.getLayerByLayerName(server.layerHistory[i].layer);
if (!historyLayer) return true;
if (historyLayer.gamemode !== layer.gamemode) return true;
}
return false;
}
isFactionCompliant(server, layer) {
if (
this.activeLayerFilter === null ||
this.activeLayerFilter.factionComplianceEnabled === false
)
return true;
if (server.layerHistory.length === 0) return true;
if (typeof layer === 'string') layer = SquadLayers.getLayerByLayerName(layer);
const historyLayer = SquadLayers.getLayerByLayerName(server.layerHistory[0].layer);
return (
!historyLayer ||
(
historyLayer.teamOne.faction !== layer.teamTwo.faction &&
historyLayer.teamTwo.faction !== layer.teamOne.faction
)
);
}
isFactionHistoryCompliant(server, layer, faction = null) {
if (this.activeLayerFilter === null) return true;
if (typeof layer === 'string') layer = SquadLayers.getLayerByLayerName(layer);
if (faction === null) {
return (
this.isFactionHistoryCompliant(server, layer, layer.teamOne.faction) &&
this.isFactionHistoryCompliant(server, layer, layer.teamTwo.faction)
);
} else {
const factionThreshold = this.activeLayerFilter.factionHistoryTolerance[faction];
if (!factionThreshold) return true;
for (let i = 0; i < Math.min(server.layerHistory.length, factionThreshold); i++) {
if (new Date() - server.layerHistory[i].time > this.activeLayerFilter.historyResetTime)
return true;
const historyLayer = SquadLayers.getLayerByLayerName(server.layerHistory[i].layer);
if (!historyLayer) continue;
if (historyLayer.teamOne.faction === faction || historyLayer.teamTwo.faction === faction)
return false;
}
return true;
}
}
isFactionRepetitiveCompliant(server, layer, faction = null) {
if (this.activeLayerFilter === null) return true;
if (typeof layer === 'string') layer = SquadLayers.getLayerByLayerName(layer);
if (faction === null) {
return (
this.isFactionRepetitiveCompliant(server, layer, layer.teamOne.faction) &&
this.isFactionRepetitiveCompliant(server, layer, layer.teamTwo.faction)
);
} else {
const factionThreshold = this.activeLayerFilter.factionRepetitiveTolerance[faction];
if (!factionThreshold) return true;
for (let i = 0; i < Math.min(server.layerHistory.length, factionThreshold); i++) {
if (new Date() - server.layerHistory[i].time > this.activeLayerFilter.historyResetTime)
return true;
const historyLayer = SquadLayers.getLayerByLayerName(server.layerHistory[i].layer);
if (!historyLayer) return true;
if (historyLayer.teamOne.faction !== faction && historyLayer.teamTwo.faction !== faction)
return true;
}
return false;
}
}
isPlayerCountCompliant(server, layer) {
if (
this.activeLayerFilter === null ||
this.playerCountComplianceEnabled === false
this.activeLayerFilter.playerCountComplianceEnabled === false
)
return true;
if (typeof layer === 'string')
layer = SquadLayers.getLayerByLayerName(layer);
if (typeof layer === 'string') layer = SquadLayers.getLayerByLayerName(layer);
return !(
server.players.length > layer.estimatedSuitablePlayerCount.max ||

View File

@ -7,9 +7,7 @@ class SquadLayers {
if (Array.isArray(layers)) {
this.layers = layers;
} else {
this.layers = JSON.parse(
fs.readFileSync('./connectors/data/layers.json', 'utf8')
);
this.layers = JSON.parse(fs.readFileSync('./connectors/data/layers.json', 'utf8'));
}
for (let i = 0; i < this.layers.length; i++) {
@ -34,9 +32,7 @@ class SquadLayers {
}
getLayerByLayerClassname(layerClassname) {
const layer = this.layers.filter(
layer => layer.layerClassname === layerClassname
);
const layer = this.layers.filter(layer => layer.layerClassname === layerClassname);
return layer.length === 1 ? layer[0] : null;
}

View File

@ -1,6 +1,6 @@
{
"name": "SquadJS",
"version": "1.0.10",
"version": "1.0.11",
"repository": "https://github.com/Thomas-Smyth/SquadJS.git",
"author": "Thomas Smyth <https://github.com/Thomas-Smyth>",
"license": "MIT",

View File

@ -2,9 +2,7 @@ import { LOG_PARSER_TEAMKILL } from 'squad-server/events/log-parser';
export default async function(server, options = {}) {
if (!server)
throw new Error(
'DiscordAdminCamLogs must be provided with a reference to the server.'
);
throw new Error('DiscordAdminCamLogs must be provided with a reference to the server.');
server.on(LOG_PARSER_TEAMKILL, info => {
// ignore suicides

View File

@ -6,17 +6,12 @@ import {
export default async function(server, discordClient, channelID, options = {}) {
if (!server)
throw new Error(
'DiscordAdminCamLogs must be provided with a reference to the server.'
);
throw new Error('DiscordAdminCamLogs must be provided with a reference to the server.');
if (!discordClient)
throw new Error(
'DiscordAdminCamLogs must be provided with a Discord.js client.'
);
throw new Error('DiscordAdminCamLogs must be provided with a Discord.js client.');
if (!channelID)
throw new Error('DiscordAdminCamLogs must be provided with a channel ID.');
if (!channelID) throw new Error('DiscordAdminCamLogs must be provided with a channel ID.');
options = {
color: 16761867,
@ -57,8 +52,7 @@ export default async function(server, discordClient, channelID, options = {}) {
});
server.on(LOG_PARSER_PLAYER_UNPOSSESS, info => {
if (info.switchPossess === true || !(info.player.steamID in adminsInCam))
return;
if (info.switchPossess === true || !(info.player.steamID in adminsInCam)) return;
channel.send({
embed: {
@ -78,9 +72,7 @@ export default async function(server, discordClient, channelID, options = {}) {
{
name: 'Time in Admin Camera',
value: `${Math.round(
(info.time.getTime() -
adminsInCam[info.player.steamID].getTime()) /
60000
(info.time.getTime() - adminsInCam[info.player.steamID].getTime()) / 60000
)} mins`
}
],

View File

@ -2,16 +2,11 @@ import { COPYRIGHT_MESSAGE } from 'core/config';
import { RCON_CHAT_MESSAGE } from 'squad-server/events/rcon';
export default async function(server, discordClient, channelID, options = {}) {
if (!server)
throw new Error(
'DiscordChat must be provided with a reference to the server.'
);
if (!server) throw new Error('DiscordChat must be provided with a reference to the server.');
if (!discordClient)
throw new Error('DiscordChat must be provided with a Discord.js client.');
if (!discordClient) throw new Error('DiscordChat must be provided with a Discord.js client.');
if (!channelID)
throw new Error('DiscordChat must be provided with a channel ID.');
if (!channelID) throw new Error('DiscordChat must be provided with a channel ID.');
const ignoreChats = options.ignoreChats || ['ChatSquad', 'ChatAdmin'];
@ -44,8 +39,7 @@ export default async function(server, discordClient, channelID, options = {}) {
},
{
name: 'Team & Squad',
value: `Team: ${playerInfo.teamID}, Squad: ${playerInfo.squadID ||
'Unassigned'}`
value: `Team: ${playerInfo.teamID}, Squad: ${playerInfo.squadID || 'Unassigned'}`
},
{
name: 'Message',

View File

@ -1,14 +1,9 @@
export default async function(server, discordClient, channelID, events = []) {
if (!server)
throw new Error(
'DiscordDebug must be provided with a reference to the server.'
);
if (!server) throw new Error('DiscordDebug must be provided with a reference to the server.');
if (!discordClient)
throw new Error('DiscordDebug must be provided with a Discord.js client.');
if (!discordClient) throw new Error('DiscordDebug must be provided with a Discord.js client.');
if (!channelID)
throw new Error('DicordDebug must be provided with a channel ID.');
if (!channelID) throw new Error('DicordDebug must be provided with a channel ID.');
const channel = await discordClient.channels.fetch(channelID);

View File

@ -43,10 +43,7 @@ function makeEmbed(server, options) {
embed: {
title: server.serverName,
color: options.colorGradient
? parseInt(
gradient.rgbAt(server.playerCount / server.publicSlots).toHex(),
16
)
? parseInt(gradient.rgbAt(server.playerCount / server.publicSlots).toHex(), 16)
: options.color,
fields: fields,
timestamp: new Date().toISOString(),
@ -58,13 +55,9 @@ function makeEmbed(server, options) {
}
export default async function(server, discordClient, options = {}) {
if (!server)
throw new Error(
'DiscordDebug must be provided with a reference to the server.'
);
if (!server) throw new Error('DiscordDebug must be provided with a reference to the server.');
if (!discordClient)
throw new Error('DiscordDebug must be provided with a Discord.js client.');
if (!discordClient) throw new Error('DiscordDebug must be provided with a Discord.js client.');
options = {
color: 16761867,
@ -87,8 +80,7 @@ export default async function(server, discordClient, options = {}) {
// confirm it's a status message
if (
reaction.message.embeds.length !== 1 ||
reaction.message.embeds[0].footer.text !==
`Server Status by ${COPYRIGHT_MESSAGE}`
reaction.message.embeds[0].footer.text !== `Server Status by ${COPYRIGHT_MESSAGE}`
)
return;

View File

@ -2,18 +2,11 @@ import { COPYRIGHT_MESSAGE } from 'core/config';
import { LOG_PARSER_TEAMKILL } from 'squad-server/events/log-parser';
export default async function(server, discordClient, channelID, options = {}) {
if (!server)
throw new Error(
'DiscordTeamKill must be provided with a reference to the server.'
);
if (!server) throw new Error('DiscordTeamKill must be provided with a reference to the server.');
if (!discordClient)
throw new Error(
'DiscordTeamkill must be provided with a Discord.js client.'
);
if (!discordClient) throw new Error('DiscordTeamkill must be provided with a Discord.js client.');
if (!channelID)
throw new Error('DiscordTeamkill must be provided with a channel ID.');
if (!channelID) throw new Error('DiscordTeamkill must be provided with a channel ID.');
options = {
teamkillColor: 16761867,
@ -64,9 +57,7 @@ export default async function(server, discordClient, channelID, options = {}) {
channel.send({
embed: {
title: `${info.suicide ? 'Suicide' : 'Teamkill'}: ${
info.attacker.name
}`,
title: `${info.suicide ? 'Suicide' : 'Teamkill'}: ${info.attacker.name}`,
color: info.suicide ? options.suicideColor : options.teamkillColor,
fields: fields,
timestamp: info.time.toISOString(),

View File

@ -9,13 +9,9 @@ import {
import { SERVER_PLAYERS_UPDATED } from 'squad-server/events/server';
export default function(server, influxDB, options = {}) {
if (!server)
throw new Error(
'InfluxDBLog must be provided with a reference to the server.'
);
if (!server) throw new Error('InfluxDBLog must be provided with a reference to the server.');
if (!influxDB)
throw new Error('InfluxDBLog must be provided with a InfluxDB connection.');
if (!influxDB) throw new Error('InfluxDBLog must be provided with a InfluxDB connection.');
const serverID = options.overrideServerID || server.id;

View File

@ -37,7 +37,20 @@ const activeLayerFilter = {
Invasion: 4 // invasion can only be played once every x layers
// if not specified they will default to off
},
playerCountComplianceEnabled: true // filter layers based on suggested player counts if true
gamemodeRepetitiveTolerance: {
Invasion: 4 // invasion can only be played up to x times in a row
// if not specified they will default to off
},
playerCountComplianceEnabled: true, // filter layers based on suggested player counts if true
factionComplianceEnabled: true, // a team cannot play the same faction twice in a row
factionHistoryTolerance: {
RUS: 4 // rus can only be played once every x layers
// if not specified they will default to off
},
factionRepetitiveTolerance: {
RUS: 4 // rus can only be played up to x times in a row
// if not specified they will default to off
},
};
```

View File

@ -22,10 +22,7 @@ export default function(server, options = {}) {
if (voteMatch) {
if (!mapvote) return;
try {
const layerName = await mapvote.makeVoteByNumber(
info.steamID,
parseInt(voteMatch[1])
);
const layerName = await mapvote.makeVoteByNumber(info.steamID, parseInt(voteMatch[1]));
await server.rcon.warn(info.steamID, `You voted for ${layerName}.`);
} catch (err) {
await server.rcon.warn(info.steamID, err.message);
@ -93,10 +90,7 @@ export default function(server, options = {}) {
if (results.length === 0)
await server.rcon.broadcast(`No layer gained enough votes to win.`);
else
await server.rcon.broadcast(
`${mapvote.getResults()[0].layer.layer} won the mapvote!`
);
else await server.rcon.broadcast(`${mapvote.getResults()[0].layer.layer} won the mapvote!`);
mapvote = null;
return;
@ -109,15 +103,9 @@ export default function(server, options = {}) {
}
if (commandMatch[1] === 'help') {
await server.rcon.warn(
info.steamID,
'To vote type the layer number into chat:'
);
await server.rcon.warn(info.steamID, 'To vote type the layer number into chat:');
for (const layer of mapvote.squadLayerFilter.getLayers()) {
await server.rcon.warn(
info.steamID,
`${layer.layerNumber} - ${layer.layer}`
);
await server.rcon.warn(info.steamID, `${layer.layerNumber} - ${layer.layer}`);
}
if (options.minVoteCount !== null)
@ -138,16 +126,13 @@ export default function(server, options = {}) {
if (results.length === 0) {
await server.rcon.warn(info.steamID, 'No one has voted yet.');
} else {
await server.rcon.warn(
info.steamID,
'The current vote counts are as follows:'
);
await server.rcon.warn(info.steamID, 'The current vote counts are as follows:');
for (const result of results) {
await server.rcon.warn(
info.steamID,
`${result.layer.layerNumber} - ${result.layer.layer} (${
result.votes
} vote${result.votes > 1 ? 's' : ''})`
`${result.layer.layerNumber} - ${result.layer.layer} (${result.votes} vote${
result.votes > 1 ? 's' : ''
})`
);
}
}

View File

@ -49,18 +49,9 @@ export default function(server, squadLayerFilter, options = {}) {
if (!match) return;
if (match[1] === 'help') {
await server.rcon.warn(
info.steamID,
'You may use any of the following commands in chat:'
);
await server.rcon.warn(
info.steamID,
'!mapvote results - View the current vote counts.'
);
await server.rcon.warn(
info.steamID,
'!mapvote <layer name> - Vote for the specified layer.'
);
await server.rcon.warn(info.steamID, 'You may use any of the following commands in chat:');
await server.rcon.warn(info.steamID, '!mapvote results - View the current vote counts.');
await server.rcon.warn(info.steamID, '!mapvote <layer name> - Vote for the specified layer.');
await server.rcon.warn(
info.steamID,
'When inputting a layer name, we autocorrect any miss spelling.'
@ -102,12 +93,8 @@ export default function(server, squadLayerFilter, options = {}) {
const results = mapvote.getResults(true);
if (results.length === 0)
await server.rcon.broadcast(`No layer gained enough votes to win.`);
else
await server.rcon.broadcast(
`${mapvote.getResults()[0].layer.layer} won the mapvote!`
);
if (results.length === 0) await server.rcon.broadcast(`No layer gained enough votes to win.`);
else await server.rcon.broadcast(`${mapvote.getResults()[0].layer.layer} won the mapvote!`);
mapvote = null;
return;
@ -125,16 +112,11 @@ export default function(server, squadLayerFilter, options = {}) {
if (results.length === 0) {
await server.rcon.warn(info.steamID, 'No one has voted yet.');
} else {
await server.rcon.warn(
info.steamID,
'The current vote counts are as follows:'
);
await server.rcon.warn(info.steamID, 'The current vote counts are as follows:');
for (const result of results) {
await server.rcon.warn(
info.steamID,
`${result.layer.layer} - ${result.votes} vote${
result.votes > 1 ? 's' : ''
}`
`${result.layer.layer} - ${result.votes} vote${result.votes > 1 ? 's' : ''}`
);
}
return;
@ -142,18 +124,12 @@ export default function(server, squadLayerFilter, options = {}) {
}
if (!manuallyCreated && server.players.length < options.minPlayerCount) {
await server.rcon.warn(
info.steamID,
'Not enough players online to vote.'
);
await server.rcon.warn(info.steamID, 'Not enough players online to vote.');
return;
}
try {
const layerName = await mapvote.makeVoteByDidYouMean(
info.steamID,
match[1]
);
const layerName = await mapvote.makeVoteByDidYouMean(info.steamID, match[1]);
await server.rcon.warn(info.steamID, `You voted for ${layerName}.`);
} catch (err) {
await server.rcon.warn(info.steamID, err.message);

View File

@ -9,6 +9,7 @@ export default class MapVote extends EventEmitter {
this.squadLayerFilter = squadLayerFilter;
this.layerVotes = {};
this.layerVoteTimes = {};
this.playerVotes = {};
this.currentWinner = null;
@ -20,6 +21,7 @@ export default class MapVote extends EventEmitter {
this.layerVotes[layerName] += 1;
} else {
this.layerVotes[layerName] = 1;
this.layerVoteTimes[layerName] = new Date();
}
this.playerVotes[identifier] = layerName;
}
@ -29,8 +31,11 @@ export default class MapVote extends EventEmitter {
if (this.layerVotes[this.playerVotes[identifier]])
this.layerVotes[this.playerVotes[identifier]] -= 1;
if (this.layerVotes[this.playerVotes[identifier]] === 0)
if (this.layerVotes[this.playerVotes[identifier]] === 0) {
delete this.layerVotes[this.playerVotes[identifier]];
delete this.layerVoteTimes[this.playerVotes[identifier]];
}
delete this.playerVotes[identifier];
}
@ -49,7 +54,7 @@ export default class MapVote extends EventEmitter {
.sort((a, b) => {
if (a.votes > b.votes) return -1;
if (a.votes < b.votes) return 1;
else return Math.random() < 0.5 ? 1 : -1;
return this.layerVoteTimes[a.layer.layer] < this.layerVoteTimes[b.layer.layer] ? -1 : 1;
});
} else return [];
}
@ -66,6 +71,18 @@ export default class MapVote extends EventEmitter {
throw new Error(`${layer.map} was played too recently.`);
if (!this.squadLayerFilter.isGamemodeHistoryCompliant(this.server, layer))
throw new Error(`${layer.gamemode} was played too recently.`);
if (!this.squadLayerFilter.isGamemodeRepetitiveCompliant(this.server, layer))
throw new Error(`${layer.gamemode} has been played too much recently.`);
if (!this.squadLayerFilter.isFactionCompliant(this.server, layer))
throw new Error('Cannot be played as one team will remain the same faction.');
if (!this.squadLayerFilter.isFactionHistoryCompliant(this.server, layer))
throw new Error(
`Cannot be played as either ${layer.teamOne.faction} or ${layer.teamTwo.faction} has been played too recently.`
);
if (!this.squadLayerFilter.isFactionRepetitiveCompliant(this.server, layer))
throw new Error(
`Cannot be played as either ${layer.teamOne.faction} or ${layer.teamTwo.faction} has been played too much recently.`
);
if (!this.squadLayerFilter.isPlayerCountCompliant(this.server, layer))
throw new Error(
`${layer.layer} is only suitable for a player count between ${layer.estimatedSuitablePlayerCount.min} and ${layer.estimatedSuitablePlayerCount.max}.`
@ -77,12 +94,10 @@ export default class MapVote extends EventEmitter {
const results = this.getResults(true);
if (results.length > 0) {
if (results[0] !== this.currentWinner) {
await this.server.rcon.execute(
`AdminSetNextMap ${results[0].layer.layer}`
);
if (results[0].layer.layer !== this.currentWinner) {
await this.server.rcon.execute(`AdminSetNextMap ${results[0].layer.layer}`);
this.emit('NEW_WINNER', results);
this.currentWinner = results[0];
this.currentWinner = results[0].layer.layer;
}
}

View File

@ -8,28 +8,25 @@ import {
import { SERVER_PLAYERS_UPDATED } from 'squad-server/events/server';
export default function(server, mysqlPool, options = {}) {
if (!server)
throw new Error(
'MySQLLog must be provided with a reference to the server.'
);
if (!server) throw new Error('MySQLLog must be provided with a reference to the server.');
if (!mysqlPool)
throw new Error('MySQLLog must be provided with a mysql Pool.');
if (!mysqlPool) throw new Error('MySQLLog must be provided with a mysql Pool.');
const serverID = options.overrideServerID || server.id;
server.on(LOG_PARSER_SERVER_TICK_RATE, info => {
mysqlPool.query(
'INSERT INTO ServerTickRate(time, server, tick_rate) VALUES (?,?,?)',
[info.time, serverID, info.tickRate]
);
mysqlPool.query('INSERT INTO ServerTickRate(time, server, tick_rate) VALUES (?,?,?)', [
info.time,
serverID,
info.tickRate
]);
});
server.on(SERVER_PLAYERS_UPDATED, players => {
mysqlPool.query(
'INSERT INTO PlayerCount(time, server, player_count) VALUES (NOW(),?,?)',
[serverID, players.length]
);
mysqlPool.query('INSERT INTO PlayerCount(time, server, player_count) VALUES (NOW(),?,?)', [
serverID,
players.length
]);
});
server.on(LOG_PARSER_NEW_GAME, info => {
@ -82,28 +79,25 @@ export default function(server, mysqlPool, options = {}) {
});
server.on(LOG_PARSER_PLAYER_REVIVED, info => {
mysqlPool.query(
'call InsertPlayerRevived(?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)',
[
serverID,
info.time,
info.woundTime,
info.victim ? info.victim.steamID : null,
info.victim ? info.victim.name : null,
info.victim ? info.victim.teamID : null,
info.victim ? info.victim.squadID : null,
info.attacker ? info.attacker.steamID : null,
info.attacker ? info.attacker.name : null,
info.attacker ? info.attacker.teamID : null,
info.attacker ? info.attacker.squadID : null,
info.damage,
info.weapon,
info.teamkill,
info.reviver ? info.reviver.steamID : null,
info.reviver ? info.reviver.name : null,
info.reviver ? info.reviver.teamID : null,
info.reviver ? info.reviver.squadID : null
]
);
mysqlPool.query('call InsertPlayerRevived(?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)', [
serverID,
info.time,
info.woundTime,
info.victim ? info.victim.steamID : null,
info.victim ? info.victim.name : null,
info.victim ? info.victim.teamID : null,
info.victim ? info.victim.squadID : null,
info.attacker ? info.attacker.steamID : null,
info.attacker ? info.attacker.name : null,
info.attacker ? info.attacker.teamID : null,
info.attacker ? info.attacker.squadID : null,
info.damage,
info.weapon,
info.teamkill,
info.reviver ? info.reviver.steamID : null,
info.reviver ? info.reviver.name : null,
info.reviver ? info.reviver.teamID : null,
info.reviver ? info.reviver.squadID : null
]);
});
}

View File

@ -1,10 +1,7 @@
import { LOG_PARSER_PLAYER_CONNECTED } from 'squad-server/events/log-parser';
export default function(server, options = {}) {
if (!server)
throw new Error(
'SeedingMessage must be provided with a reference to the server.'
);
if (!server) throw new Error('SeedingMessage must be provided with a reference to the server.');
const mode = options.mode || 'interval';
const interval = options.interval || 150 * 1000;

View File

@ -21,10 +21,7 @@ function shuffle(array) {
}
export default function(server, options = {}) {
if (!server)
throw new Error(
'TeamRandomizer must be provided with a reference to the server.'
);
if (!server) throw new Error('TeamRandomizer must be provided with a reference to the server.');
const command = options.command || '!randomize';
const commandRegex = new RegExp(`^${command}`, 'i');

View File

@ -40,9 +40,4 @@ const SERVER_LAYERS_UPDATED = 'SERVER_LAYERS_UPDATED';
*/
const SERVER_A2S_UPDATED = 'SERVER_A2S_UPDATED';
export {
SERVER_LAYER_CHANGE,
SERVER_PLAYERS_UPDATED,
SERVER_LAYERS_UPDATED,
SERVER_A2S_UPDATED
};
export { SERVER_LAYER_CHANGE, SERVER_PLAYERS_UPDATED, SERVER_LAYERS_UPDATED, SERVER_A2S_UPDATED };

View File

@ -27,8 +27,7 @@ export default class Server extends EventEmitter {
if (!('host' in options)) throw new Error('Server must have a host.');
this.host = options.host;
if (!('queryPort' in options))
throw new Error('Server must have a queryPort.');
if (!('queryPort' in options)) throw new Error('Server must have a queryPort.');
this.queryPort = options.queryPort;
this.updateInterval = options.updateInterval || 30 * 1000;
@ -51,10 +50,7 @@ export default class Server extends EventEmitter {
// setup period updaters
this.updatePlayers = this.updatePlayers.bind(this);
this.updatePlayerTimeout = setTimeout(
this.updatePlayers,
this.updateInterval
);
this.updatePlayerTimeout = setTimeout(this.updatePlayers, this.updateInterval);
setInterval(async () => {
const data = await this.rcon.getMapInfo();
@ -121,10 +117,7 @@ export default class Server extends EventEmitter {
}
// delay another update
this.updatePlayerTimeout = setTimeout(
this.updatePlayers,
this.updateInterval
);
this.updatePlayerTimeout = setTimeout(this.updatePlayers, this.updateInterval);
this.emit(SERVER_PLAYERS_UPDATED, this.players);
}

View File

@ -10,8 +10,7 @@ import rules from './rules/index.js';
export default class LogParser {
constructor(options = {}, server) {
if (!(server instanceof Server))
throw new Error('Server not an instance of a SquadJS server.');
if (!(server instanceof Server)) throw new Error('Server not an instance of a SquadJS server.');
this.server = server;
this.eventStore = {};

View File

@ -10,13 +10,10 @@ import sleep from 'core/utils/sleep';
export default class FTPLogReader {
constructor(queueLine, options = {}) {
if (typeof queueLine !== 'function')
throw new Error(
'queueLine argument must be specified and be a function.'
);
throw new Error('queueLine argument must be specified and be a function.');
if (!options.host) throw new Error('Host must be specified.');
if (!options.ftpUser) throw new Error('FTP user must be specified.');
if (!options.ftpPassword)
throw new Error('FTP password must be specified.');
if (!options.ftpPassword) throw new Error('FTP password must be specified.');
if (!options.remotePath) throw new Error('Remote path must be specified.');
this.queueLine = queueLine;
@ -79,8 +76,7 @@ export default class FTPLogReader {
if (this.lastByteReceived == null) {
const fileSize = await this.client.size(this.remotePath);
this.lastByteReceived =
fileSize -
(this.tailLastBytes < fileSize ? this.tailLastBytes : fileSize);
fileSize - (this.tailLastBytes < fileSize ? this.tailLastBytes : fileSize);
}
// Download the data to a temp file, overwrite any previous data

View File

@ -4,17 +4,12 @@ import TailModule from 'tail';
export default class TailLogReader {
constructor(queueLine, options = {}) {
if (typeof queueLine !== 'function')
throw new Error(
'queueLine argument must be specified and be a function.'
);
throw new Error('queueLine argument must be specified and be a function.');
if (!options.logDir) throw new Error('Log directory must be specified.');
this.reader = new TailModule.Tail(
path.join(options.logDir, 'SquadGame.log'),
{
useWatchFile: true
}
);
this.reader = new TailModule.Tail(path.join(options.logDir, 'SquadGame.log'), {
useWatchFile: true
});
this.reader.on('line', queueLine);
}

View File

@ -3,8 +3,7 @@ import { LOG_PARSER_PLAYER_CONNECTED } from '../../events/log-parser.js';
export default {
regex: /^\[([0-9.:-]+)]\[([ 0-9]*)]LogNet: Join succeeded: (.+)/,
onMatch: async (args, logParser) => {
logParser.server.suffixStore[logParser.eventStore['steamid-connected']] =
args[3];
logParser.server.suffixStore[logParser.eventStore['steamid-connected']] = args[3];
const data = {
raw: args[0],

View File

@ -11,10 +11,7 @@ export default {
switchPossess: false
};
if (
args[3] in logParser.eventStore &&
logParser.eventStore[args[3]] === args[2]
)
if (args[3] in logParser.eventStore && logParser.eventStore[args[3]] === args[2])
data.switchPossess = true;
delete logParser.eventStore[args[3]];

View File

@ -1,7 +1,4 @@
import {
LOG_PARSER_PLAYER_WOUNDED,
LOG_PARSER_TEAMKILL
} from '../../events/log-parser.js';
import { LOG_PARSER_PLAYER_WOUNDED, LOG_PARSER_TEAMKILL } from '../../events/log-parser.js';
export default {
regex: /^\[([0-9.:-]+)]\[([ 0-9]*)]LogSquadTrace: \[DedicatedServer](?:ASQSoldier::)?Wound\(\): Player:(.+) KillingDamage=(?:-)*([0-9.]+) from ([A-z_0-9]+) caused by ([A-z_0-9]+)_C/,

View File

@ -48,9 +48,7 @@ async function main() {
console.log('Done.');
console.log();
console.log(
`Matched ${matched} / ${total} (${(matched / total) * 100}%) log lines.`
);
console.log(`Matched ${matched} / ${total} (${(matched / total) * 100}%) log lines.`);
console.log();
}

View File

@ -15,8 +15,7 @@ export default class Rcon {
if (!options.rconPort) throw new Error('RCON port must be specified.');
this.port = options.rconPort;
if (!options.rconPassword)
throw new Error('RCON password must be specified.');
if (!options.rconPassword) throw new Error('RCON password must be specified.');
this.password = options.rconPassword;
this.verboseEnabled = options.rconVerbose || false;
@ -195,10 +194,7 @@ export default class Rcon {
''
);
if (
this.maximumPacketSize > 0 &&
encodedPacket.length > this.maximumPacketSize
)
if (this.maximumPacketSize > 0 && encodedPacket.length > this.maximumPacketSize)
reject(new Error('Packet too long.'));
// prepare to handle response.
@ -233,8 +229,7 @@ export default class Rcon {
resolve(response);
};
if (type === RCONProtocol.SERVERDATA_AUTH)
this.requestQueue.push(handleAuthMultiPacket);
if (type === RCONProtocol.SERVERDATA_AUTH) this.requestQueue.push(handleAuthMultiPacket);
else this.requestQueue.push(handleMultiPacket);
this.client.once('error', reject);
@ -311,7 +306,6 @@ export default class Rcon {
}
verbose(msg) {
if (this.verboseEnabled)
console.log(`[${Date.now()}] RCON (Verbose): ${msg}`);
if (this.verboseEnabled) console.log(`[${Date.now()}] RCON (Verbose): ${msg}`);
}
}