mirror of
https://github.com/AsgardEternal/SquadJS.git
synced 2024-09-29 15:44:26 -05:00
146 lines
4.2 KiB
JavaScript
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;
|
||
|
}
|
||
|
}
|
||
|
});
|
||
|
}
|