SquadJS/plugins/mapvote/index.js
2020-05-15 18:42:39 +01:00

146 lines
4.2 KiB
JavaScript

import didYouMean from 'didyoumean';
import { COPYRIGHT_MESSAGE } from 'core/config';
import SquadLayers from 'connectors/squad-layers';
import { RCON_CHAT_MESSAGE } from 'squad-server/events/rcon';
import { SERVER_LAYER_CHANGE } from 'squad-server/events/server';
export default function(server, layerFilter = {}, options = {}) {
if (!server)
throw new Error('Mapvote must be provided with a reference to the server.');
const command = options.command || '!mapvote';
const commandRegex = new RegExp(`^${command} ([A-z0-9'_ ]*)`, 'i');
const rotation = SquadLayers.getFilteredLayers(layerFilter);
let voteCounts = {};
let votes = {};
let currentWinner = null;
function getResults() {
let results;
results = Object.keys(voteCounts).map(layer => {
return {
layer: layer,
voteCount: voteCounts[layer]
};
});
results = results.sort((a, b) => {
if (a.voteCount > b.voteCount) return -1;
if (a.voteCount < b.voteCount) return 1;
else return Math.random() < 0.5 ? 1 : -1;
});
return results;
}
server.on(SERVER_LAYER_CHANGE, () => {
voteCounts = {};
votes = {};
currentWinner = null;
});
server.on(RCON_CHAT_MESSAGE, info => {
const match = info.message.match(commandRegex);
if (!match) return;
if (match[1] === 'help') {
// show help options
server.rcon.execute(
`AdminWarn "${info.steamID}" You may use any of the following commands in chat:`
);
server.rcon.execute(
`AdminWarn "${info.steamID}" !mapvote results - View the current vote counts.`
);
server.rcon.execute(
`AdminWarn "${info.steamID}" !mapvote <layer name> - Vote for the specified layer.`
);
server.rcon.execute(
`AdminWarn "${info.steamID}" When inputting a layer name, we autocorrect any miss spelling.`
);
} else if (match[1] === 'results') {
// display results to player
const results = getResults();
if (results.length === 0) {
server.rcon.execute(
`AdminWarn "${info.steamID}" No one has voted yet.`
);
} else {
server.rcon.execute(
`AdminWarn "${info.steamID}" The current vote counts are as follows:`
);
for (const result of results) {
if (result.voteCount === 0) continue;
server.rcon.execute(
`AdminWarn "${info.steamID}" ${result.layer} - ${
result.voteCount
} vote${result.voteCount > 1 ? 's' : ''}.`
);
}
}
} else {
const layer = didYouMean(match[1], SquadLayers.getLayerNames());
// check layer is valid
if (layer === null) {
server.rcon.execute(
`AdminWarn "${info.steamID}" ${match[1]} is not a valid layer name.`
);
return;
}
if (!rotation.includes(layer)) {
server.rcon.execute(
`AdminWarn "${info.steamID}" ${layer} is not in the rotation.`
);
return;
}
if (
!SquadLayers.isHistoryCompliant(server.layerHistory, layer, options)
) {
server.rcon.execute(
`AdminWarn "${info.steamID}" ${layer} has been played too recently.`
);
return;
}
// remove existing votes
if (info.steamID in votes) voteCounts[votes[info.steamID]]--;
// add new vote
if (layer in voteCounts) voteCounts[layer]++;
else voteCounts[layer] = 1;
// save what layer they votes for
votes[info.steamID] = layer;
// info them of their vote
server.rcon.execute(
`AdminWarn "${info.steamID}" You voted for ${layer}.`
);
server.rcon.execute(
`AdminWarn "${info.steamID}" Powered by: ${COPYRIGHT_MESSAGE}`
);
// check for new winner
const newWinner = getResults()[0].layer;
if (currentWinner !== newWinner) {
server.rcon.execute(`AdminSetNextMap ${newWinner}`);
server.rcon.execute(`AdminBroadcast New Map Vote Winner: ${newWinner}`);
server.rcon.execute(
`AdminBroadcast Participate in the map vote by typing "!mapvote help" in chat.`
);
currentWinner = newWinner;
}
}
});
}