2020-08-20 15:21:03 -05:00
|
|
|
import { COPYRIGHT_MESSAGE } from 'core/constants';
|
2020-09-09 03:31:48 -05:00
|
|
|
import { NEW_GAME, CHAT_MESSAGE } from 'squad-server/events';
|
2020-06-13 09:33:44 -05:00
|
|
|
|
|
|
|
import MapVote from './mapvote.js';
|
|
|
|
|
2020-08-20 15:21:03 -05:00
|
|
|
export default {
|
|
|
|
name: 'mapvote-did-you-mean',
|
|
|
|
description:
|
2020-09-10 08:17:27 -05:00
|
|
|
'The <code>mapvote-did-you-mean</code> plugin provides map voting functionality. This variant of map voting uses a "Did you ' +
|
2020-08-22 08:32:39 -05:00
|
|
|
'mean?" algorithm to allow players to easily select one of a large pool of layers by typing it\'s name into ' +
|
|
|
|
'the in-game chat.' +
|
|
|
|
'\n\n' +
|
|
|
|
'Player Commands:\n' +
|
2020-09-10 08:17:27 -05:00
|
|
|
' * <code>!mapvote help</code> - Show other commands players can use.\n' +
|
|
|
|
' * <code>!mapvote results</code> - Show the results of the current map vote.\n' +
|
|
|
|
' * <code>!mapvote <layer name></code> - Vote for the specified layer. Misspelling will be corrected where possible.\n' +
|
2020-08-22 08:32:39 -05:00
|
|
|
'\n\n' +
|
|
|
|
'Admin Commands (Admin Chat Only):\n' +
|
2020-09-10 08:17:27 -05:00
|
|
|
' * <code>!mapvote start</code> - Start a new map vote\n' +
|
|
|
|
' * <code>!mapvote restart</code> - Restarts the map vote.\n' +
|
|
|
|
' * <code>!mapvote end</code> - End the map vote and announce the winner.\n' +
|
|
|
|
' * <code>!mapvote destroy</code> - End the map vote without announcing the winner.\n',
|
2020-08-20 15:21:03 -05:00
|
|
|
|
2020-08-22 10:54:05 -05:00
|
|
|
defaultEnabled: false,
|
2020-08-20 15:21:03 -05:00
|
|
|
optionsSpec: {
|
|
|
|
layerFilter: {
|
|
|
|
required: false,
|
2020-09-10 08:17:27 -05:00
|
|
|
description: 'The layers players can choose from.',
|
|
|
|
default: 'layerFilter'
|
2020-08-20 15:21:03 -05:00
|
|
|
},
|
|
|
|
alwaysOn: {
|
|
|
|
required: false,
|
2020-09-10 08:17:27 -05:00
|
|
|
description: 'If true then the map voting system will always be live.',
|
|
|
|
default: true
|
2020-08-20 15:21:03 -05:00
|
|
|
},
|
|
|
|
minPlayerCount: {
|
|
|
|
required: false,
|
2020-09-10 08:17:27 -05:00
|
|
|
description: 'The minimum number of players required for the vote to succeed.',
|
2020-08-20 15:21:03 -05:00
|
|
|
default: null,
|
2020-09-10 08:17:27 -05:00
|
|
|
example: 10
|
2020-08-20 15:21:03 -05:00
|
|
|
},
|
|
|
|
minVoteCount: {
|
|
|
|
required: false,
|
2020-09-10 08:17:27 -05:00
|
|
|
description: 'The minimum number of votes required for the vote to succeed.',
|
2020-08-20 15:21:03 -05:00
|
|
|
default: null,
|
2020-09-10 08:17:27 -05:00
|
|
|
example: 5
|
2020-08-20 15:21:03 -05:00
|
|
|
}
|
|
|
|
},
|
2020-06-13 09:33:44 -05:00
|
|
|
|
2020-08-20 15:21:03 -05:00
|
|
|
init: async (server, options) => {
|
|
|
|
let mapvote;
|
|
|
|
let manuallyCreated;
|
2020-06-13 09:33:44 -05:00
|
|
|
|
2020-08-20 15:21:03 -05:00
|
|
|
async function newMapvote(manuallyCreatedOption = true) {
|
2020-08-22 11:16:49 -05:00
|
|
|
mapvote = new MapVote(server, options.layerFilter, {
|
2020-08-20 15:21:03 -05:00
|
|
|
minVoteCount: options.minVoteCount
|
|
|
|
});
|
2020-06-13 09:33:44 -05:00
|
|
|
|
2020-08-20 15:21:03 -05:00
|
|
|
manuallyCreated = manuallyCreatedOption;
|
2020-06-13 09:33:44 -05:00
|
|
|
|
2020-08-20 15:21:03 -05:00
|
|
|
mapvote.on('NEW_WINNER', async (results) => {
|
|
|
|
await server.rcon.broadcast(
|
|
|
|
`New Map Vote Winner: ${results[0].layer.layer}. Participate in the map vote by typing "!mapvote help" in chat.`
|
|
|
|
);
|
|
|
|
});
|
2020-06-13 09:33:44 -05:00
|
|
|
|
2020-08-20 15:21:03 -05:00
|
|
|
if (manuallyCreated)
|
|
|
|
await server.rcon.broadcast(
|
|
|
|
`A new map vote has started. Participate in the map vote by typing "!mapvote help" in chat.`
|
|
|
|
);
|
|
|
|
}
|
2020-06-13 09:33:44 -05:00
|
|
|
|
2020-08-20 15:21:03 -05:00
|
|
|
if (options.alwaysOn) newMapvote(false);
|
2020-06-13 09:33:44 -05:00
|
|
|
|
2020-09-09 03:31:48 -05:00
|
|
|
server.on(NEW_GAME, () => {
|
2020-08-20 15:21:03 -05:00
|
|
|
if (options.alwaysOn) {
|
|
|
|
newMapvote(false);
|
|
|
|
} else {
|
|
|
|
mapvote = null;
|
|
|
|
}
|
|
|
|
});
|
|
|
|
|
2020-09-09 03:31:48 -05:00
|
|
|
server.on(CHAT_MESSAGE, async (info) => {
|
2020-08-20 15:21:03 -05:00
|
|
|
const match = info.message.match(/^!mapvote ?(.*)/);
|
|
|
|
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.');
|
2020-06-13 09:33:44 -05:00
|
|
|
await server.rcon.warn(
|
|
|
|
info.steamID,
|
2020-08-20 15:21:03 -05:00
|
|
|
'!mapvote <layer name> - Vote for the specified layer.'
|
|
|
|
);
|
|
|
|
await server.rcon.warn(
|
|
|
|
info.steamID,
|
|
|
|
'When inputting a layer name, we autocorrect any miss spelling.'
|
2020-06-13 09:33:44 -05:00
|
|
|
);
|
|
|
|
|
2020-08-20 15:21:03 -05:00
|
|
|
if (options.minVoteCount !== null)
|
|
|
|
await server.rcon.warn(
|
|
|
|
info.steamID,
|
|
|
|
`${options.minVoteCount} votes need to be made for a winner to be selected.`
|
|
|
|
);
|
2020-06-13 09:33:44 -05:00
|
|
|
|
2020-08-20 15:21:03 -05:00
|
|
|
return;
|
2020-06-13 09:33:44 -05:00
|
|
|
}
|
|
|
|
|
2020-08-20 15:21:03 -05:00
|
|
|
if (match[1] === 'start') {
|
|
|
|
if (info.chat !== 'ChatAdmin') return;
|
2020-06-13 09:33:44 -05:00
|
|
|
|
2020-08-20 15:21:03 -05:00
|
|
|
if (mapvote) {
|
|
|
|
await server.rcon.warn(info.steamID, 'A mapvote has already begun.');
|
|
|
|
} else {
|
|
|
|
await newMapvote();
|
|
|
|
}
|
|
|
|
return;
|
|
|
|
}
|
2020-06-13 09:33:44 -05:00
|
|
|
|
2020-08-20 15:21:03 -05:00
|
|
|
if (!mapvote) {
|
|
|
|
await server.rcon.warn(info.steamID, 'A map vote has not begun.');
|
|
|
|
return;
|
|
|
|
}
|
2020-06-13 09:33:44 -05:00
|
|
|
|
2020-08-20 15:21:03 -05:00
|
|
|
if (match[1] === 'restart') {
|
|
|
|
if (info.chat !== 'ChatAdmin') return;
|
|
|
|
await newMapvote();
|
|
|
|
return;
|
|
|
|
}
|
2020-06-13 09:33:44 -05:00
|
|
|
|
2020-08-20 15:21:03 -05:00
|
|
|
if (match[1] === 'end') {
|
|
|
|
if (info.chat !== 'ChatAdmin') return;
|
2020-06-13 09:33:44 -05:00
|
|
|
|
2020-08-20 15:21:03 -05:00
|
|
|
const results = mapvote.getResults(true);
|
2020-06-13 09:33:44 -05:00
|
|
|
|
2020-08-20 15:21:03 -05:00
|
|
|
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!`);
|
2020-06-13 09:33:44 -05:00
|
|
|
|
2020-08-20 15:21:03 -05:00
|
|
|
mapvote = null;
|
|
|
|
return;
|
|
|
|
}
|
2020-06-13 09:33:44 -05:00
|
|
|
|
2020-08-20 15:21:03 -05:00
|
|
|
if (match[1] === 'destroy') {
|
|
|
|
if (info.chat !== 'ChatAdmin') return;
|
|
|
|
mapvote = null;
|
2020-06-13 09:33:44 -05:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2020-08-20 15:21:03 -05:00
|
|
|
if (match[1] === 'results') {
|
|
|
|
const results = mapvote.getResults();
|
|
|
|
|
|
|
|
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:');
|
|
|
|
for (const result of results) {
|
|
|
|
await server.rcon.warn(
|
|
|
|
info.steamID,
|
|
|
|
`${result.layer.layer} - ${result.votes} vote${result.votes > 1 ? 's' : ''}`
|
|
|
|
);
|
|
|
|
}
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
}
|
2020-06-13 09:33:44 -05:00
|
|
|
|
2020-08-20 15:21:03 -05:00
|
|
|
if (!manuallyCreated && server.players.length < options.minPlayerCount) {
|
|
|
|
await server.rcon.warn(info.steamID, 'Not enough players online to vote.');
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
try {
|
|
|
|
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);
|
|
|
|
}
|
2020-09-10 17:09:58 -05:00
|
|
|
await server.rcon.warn(info.steamID, COPYRIGHT_MESSAGE);
|
2020-08-20 15:21:03 -05:00
|
|
|
});
|
|
|
|
}
|
|
|
|
};
|