mirror of
https://github.com/AsgardEternal/SquadJS.git
synced 2024-09-28 23:24:26 -05:00
118 lines
4.2 KiB
JavaScript
118 lines
4.2 KiB
JavaScript
import EventEmitter from 'events';
|
|
|
|
import { SquadLayers } from 'core/squad-layers';
|
|
|
|
export default class MapVote extends EventEmitter {
|
|
constructor(server, squadLayerFilter, options = {}) {
|
|
super();
|
|
this.server = server;
|
|
this.squadLayerFilter = squadLayerFilter;
|
|
|
|
this.layerVotes = {};
|
|
this.layerVoteTimes = {};
|
|
this.playerVotes = {};
|
|
this.currentWinner = null;
|
|
|
|
this.minVoteCount = options.minVoteCount || null;
|
|
}
|
|
|
|
addVote(identifier, layerName) {
|
|
if (this.layerVotes[layerName]) {
|
|
this.layerVotes[layerName] += 1;
|
|
} else {
|
|
this.layerVotes[layerName] = 1;
|
|
this.layerVoteTimes[layerName] = new Date();
|
|
}
|
|
this.playerVotes[identifier] = layerName;
|
|
}
|
|
|
|
removeVote(identifier) {
|
|
if (!this.playerVotes[identifier]) return;
|
|
|
|
if (this.layerVotes[this.playerVotes[identifier]])
|
|
this.layerVotes[this.playerVotes[identifier]] -= 1;
|
|
|
|
if (this.layerVotes[this.playerVotes[identifier]] === 0) {
|
|
delete this.layerVotes[this.playerVotes[identifier]];
|
|
delete this.layerVoteTimes[this.playerVotes[identifier]];
|
|
}
|
|
|
|
delete this.playerVotes[identifier];
|
|
}
|
|
|
|
getResults(applyMinVoteCount = false) {
|
|
if (
|
|
!applyMinVoteCount ||
|
|
this.minVoteCount === null ||
|
|
Object.keys(this.playerVotes).length >= this.minVoteCount
|
|
) {
|
|
return Object.keys(this.layerVotes)
|
|
.map((layerName) => ({
|
|
layer: this.squadLayerFilter.getLayerByLayerName(layerName),
|
|
votes: this.layerVotes[layerName]
|
|
}))
|
|
.sort((a, b) => {
|
|
if (a.votes > b.votes) return -1;
|
|
if (a.votes < b.votes) return 1;
|
|
return this.layerVoteTimes[a.layer.layer] < this.layerVoteTimes[b.layer.layer] ? -1 : 1;
|
|
});
|
|
} else return [];
|
|
}
|
|
|
|
async makeVote(identifier, layer) {
|
|
layer = SquadLayers.getLayerByLayerName(layer);
|
|
|
|
if (!this.squadLayerFilter.inLayerPool(layer))
|
|
throw new Error(`${layer.layer} is not in layer pool.`);
|
|
|
|
if (!this.squadLayerFilter.isLayerHistoryCompliant(this.server, layer))
|
|
throw new Error(`${layer.layer} was played too recently.`);
|
|
if (!this.squadLayerFilter.isMapHistoryCompliant(this.server, layer))
|
|
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}.`
|
|
);
|
|
|
|
this.removeVote(identifier);
|
|
this.addVote(identifier, layer.layer);
|
|
|
|
const results = this.getResults(true);
|
|
|
|
if (results.length > 0) {
|
|
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].layer.layer;
|
|
}
|
|
}
|
|
|
|
return layer.layer;
|
|
}
|
|
|
|
async makeVoteByDidYouMean(identifier, layerName) {
|
|
const layer = SquadLayers.getLayerByDidYouMean(layerName);
|
|
if (layer === null) throw new Error(`${layerName} is not a Squad layer.`);
|
|
return this.makeVote(identifier, layer.layer);
|
|
}
|
|
|
|
async makeVoteByNumber(identifier, number) {
|
|
const layer = this.squadLayerFilter.getLayerByNumber(number);
|
|
return this.makeVote(identifier, layer.layer);
|
|
}
|
|
}
|