init commit
This commit is contained in:
362
libs/phantombot/scripts/systems/pollSystem.js
Normal file
362
libs/phantombot/scripts/systems/pollSystem.js
Normal file
@@ -0,0 +1,362 @@
|
||||
/*
|
||||
* Copyright (C) 2016-2020 phantombot.github.io/PhantomBot
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
/**
|
||||
* pollSystem.js
|
||||
*
|
||||
* This module enables the channel owner to start/manage polls
|
||||
* Start/stop polls is exported to $.poll for use in other scripts
|
||||
*/
|
||||
(function() {
|
||||
var poll = {
|
||||
pollId: 0,
|
||||
options: [],
|
||||
votes: [],
|
||||
voters: [],
|
||||
callback: function() {},
|
||||
pollRunning: false,
|
||||
pollMaster: '',
|
||||
time: 0,
|
||||
question: '',
|
||||
minVotes: 0,
|
||||
result: '',
|
||||
hasTie: 0,
|
||||
counts: [],
|
||||
},
|
||||
timeout;
|
||||
var objOBS = [];
|
||||
|
||||
/**
|
||||
* @function hasKey
|
||||
* @param {Array} list
|
||||
* @param {*} value
|
||||
* @param {Number} [subIndex]
|
||||
* @returns {boolean}
|
||||
*/
|
||||
function hasKey(list, value, subIndex) {
|
||||
var i;
|
||||
|
||||
if (subIndex > -1) {
|
||||
for (i in list) {
|
||||
if (list[i][subIndex].equalsIgnoreCase(value)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
for (i in list) {
|
||||
if (list[i].equalsIgnoreCase(value)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
};
|
||||
|
||||
// Compile regular expressions.
|
||||
var rePollOpenFourOptions = new RegExp(/"([\w\W]+)"\s+"([\w\W]+)"\s+(\d+)\s+(\d+)/),
|
||||
rePollOpenThreeOptions = new RegExp(/"([\w\W]+)"\s+"([\w\W]+)"\s+(\d+)/),
|
||||
rePollOpenTwoOptions = new RegExp(/"([\w\W]+)"\s+"([\w\W]+)"/);
|
||||
|
||||
/**
|
||||
* @function runPoll
|
||||
* @export $.poll
|
||||
* @param {string} question
|
||||
* @param {Array} options
|
||||
* @param {Number} time
|
||||
* @param {string} pollMaster
|
||||
* @param {Number} [minVotes]
|
||||
* @param {Function} callback
|
||||
* @param {string} [initialVote]
|
||||
* @returns {boolean}
|
||||
*/
|
||||
function runPoll(question, options, time, pollMaster, minVotes, callback) {
|
||||
var optionsStr = "";
|
||||
|
||||
if (poll.pollRunning) {
|
||||
return false
|
||||
}
|
||||
|
||||
objOBS = [];
|
||||
|
||||
poll.pollRunning = true;
|
||||
poll.pollMaster = pollMaster;
|
||||
poll.time = (parseInt(time) * 1000);
|
||||
poll.callback = callback;
|
||||
poll.question = question;
|
||||
poll.options = options;
|
||||
poll.minVotes = (minVotes ? minVotes : 1);
|
||||
poll.votes = [];
|
||||
poll.voters = [];
|
||||
poll.counts = [];
|
||||
poll.hasTie = 0;
|
||||
|
||||
// Remove the old files.
|
||||
$.inidb.RemoveFile('pollPanel');
|
||||
$.inidb.RemoveFile('pollVotes');
|
||||
|
||||
|
||||
for (var i = 0; i < poll.options.length; i++) {
|
||||
optionsStr += (i + 1) + ") " + poll.options[i] + " ";
|
||||
$.inidb.set('pollVotes', poll.options[i], 0);
|
||||
objOBS.push({
|
||||
'label': poll.options[i],
|
||||
'votes': 0
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
if (poll.time > 0) {
|
||||
$.say($.lang.get('pollsystem.poll.started', $.resolveRank(pollMaster), time, poll.minVotes, poll.question, optionsStr));
|
||||
|
||||
timeout = setTimeout(function() {
|
||||
endPoll();
|
||||
}, poll.time);
|
||||
} else {
|
||||
$.say($.lang.get('pollsystem.poll.started.nottime', $.resolveRank(pollMaster), poll.minVotes, poll.question, optionsStr));
|
||||
}
|
||||
|
||||
var msg = JSON.stringify({
|
||||
'start_poll': 'true',
|
||||
'data': JSON.stringify(objOBS)
|
||||
});
|
||||
$.alertspollssocket.sendJSONToAll(msg);
|
||||
|
||||
$.inidb.set('pollPanel', 'title', question);
|
||||
$.inidb.set('pollPanel', 'options', options.join(','));
|
||||
$.inidb.set('pollPanel', 'isActive', 'true');
|
||||
return true;
|
||||
};
|
||||
|
||||
/**
|
||||
* @function vote
|
||||
* @param {string} sender
|
||||
* @param {string} voteText
|
||||
*/
|
||||
function vote(sender, voteText) {
|
||||
var optionIndex;
|
||||
|
||||
if (!poll.pollRunning) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (hasKey(poll.voters, sender.toLowerCase())) {
|
||||
$.say($.whisperPrefix(sender) + $.lang.get('pollsystem.vote.already'));
|
||||
return;
|
||||
}
|
||||
|
||||
optionIndex = parseInt(voteText);
|
||||
if (isNaN(optionIndex) || optionIndex < 1 || optionIndex > poll.options.length) {
|
||||
$.say($.whisperPrefix(sender) + $.lang.get('pollsystem.vote.invalid', voteText));
|
||||
return;
|
||||
}
|
||||
|
||||
optionIndex--;
|
||||
poll.voters.push(sender);
|
||||
poll.votes.push(optionIndex);
|
||||
for (var i = 0; i < objOBS.length; i++) {
|
||||
if (objOBS[i].label == poll.options[optionIndex])
|
||||
objOBS[i].votes++;
|
||||
}
|
||||
var msg = JSON.stringify({
|
||||
'new_vote': 'true',
|
||||
'data': JSON.stringify(objOBS)
|
||||
});
|
||||
$.alertspollssocket.sendJSONToAll(msg);
|
||||
$.inidb.incr('pollVotes', poll.options[optionIndex], 1);
|
||||
};
|
||||
|
||||
/**
|
||||
* @function endPoll
|
||||
* @export $.poll
|
||||
*/
|
||||
function endPoll() {
|
||||
var mostVotes = -1,
|
||||
i;
|
||||
|
||||
if (!poll.pollRunning) {
|
||||
return;
|
||||
}
|
||||
|
||||
clearTimeout(timeout);
|
||||
|
||||
$.inidb.set('pollPanel', 'isActive', 'false');
|
||||
var msg = JSON.stringify({
|
||||
'end_poll': 'true'
|
||||
});
|
||||
$.alertspollssocket.sendJSONToAll(msg);
|
||||
if (poll.minVotes > 0 && poll.votes.length < poll.minVotes) {
|
||||
poll.result = '';
|
||||
poll.pollMaster = '';
|
||||
poll.pollRunning = false;
|
||||
poll.callback(false);
|
||||
return;
|
||||
}
|
||||
|
||||
for (i = 0; i < poll.options.length; poll.counts.push(0), i++);
|
||||
for (i = 0; i < poll.votes.length; poll.counts[poll.votes[i++]] += 1);
|
||||
for (i = 0; i < poll.counts.length; winner = ((poll.counts[i] > mostVotes) ? i : winner), mostVotes = ((poll.counts[i] > mostVotes) ? poll.counts[i] : mostVotes), i++);
|
||||
for (i = 0; i < poll.counts.length;
|
||||
(i != winner && poll.counts[i] == poll.counts[winner] ? poll.hasTie = 1 : 0), (poll.hasTie == 1 ? i = poll.counts.length : 0), i++);
|
||||
|
||||
poll.result = poll.options[winner];
|
||||
poll.pollMaster = '';
|
||||
poll.pollRunning = false;
|
||||
|
||||
// Store the results for the Panel to read.
|
||||
$.inidb.set('pollresults', 'question', poll.question);
|
||||
$.inidb.set('pollresults', 'result', poll.result);
|
||||
$.inidb.set('pollresults', 'votes', poll.votes.length);
|
||||
$.inidb.set('pollresults', 'options', poll.options.join(','));
|
||||
$.inidb.set('pollresults', 'counts', poll.counts.join(','));
|
||||
$.inidb.set('pollresults', 'istie', poll.hasTie);
|
||||
poll.callback(poll.result);
|
||||
};
|
||||
|
||||
/**
|
||||
* @event command
|
||||
*/
|
||||
$.bind('command', function(event) {
|
||||
var sender = event.getSender().toLowerCase(),
|
||||
command = event.getCommand(),
|
||||
argsString = event.getArguments().trim(),
|
||||
args = event.getArgs(),
|
||||
action = args[0];
|
||||
|
||||
if (command.equalsIgnoreCase('vote') && action !== undefined) {
|
||||
if (poll.pollRunning) {
|
||||
vote(sender, action);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @commandpath poll - Announce information about a poll, if one is running.
|
||||
*/
|
||||
if (command.equalsIgnoreCase('poll')) {
|
||||
if (!action) {
|
||||
if (poll.pollRunning) {
|
||||
var optionsStr = "";
|
||||
for (var i = 0; i < poll.options.length; i++) {
|
||||
optionsStr += (i + 1) + ") " + poll.options[i] + (i == poll.options.length - 1 ? "" : " ");
|
||||
}
|
||||
$.say($.whisperPrefix(sender) + $.lang.get('pollsystem.poll.running', poll.question, optionsStr));
|
||||
} else {
|
||||
$.say($.whisperPrefix(sender) + $.lang.get('pollsystem.poll.usage'));
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
/**
|
||||
* @commandpath poll results - Announce result information about the last run poll (Poll information is retained until shutdown)
|
||||
*/
|
||||
if (action.equalsIgnoreCase('results')) {
|
||||
if (poll.pollRunning) {
|
||||
$.say($.lang.get('pollsystem.results.running'));
|
||||
} else if (poll.result != '') {
|
||||
if (poll.hasTie) {
|
||||
$.say($.lang.get('pollsystem.results.lastpoll', poll.question, poll.votes.length, "Tie!", poll.options.join(', '), poll.counts.join(', ')));
|
||||
} else {
|
||||
$.say($.lang.get('pollsystem.results.lastpoll', poll.question, poll.votes.length, poll.result, poll.options.join(', '), poll.counts.join(', ')));
|
||||
}
|
||||
} else {
|
||||
$.say($.whisperPrefix(sender) + $.lang.get('pollsystem.results.404'));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @commandpath poll open ["poll question"] ["option1, option2, ..."] [seconds] [min votes] - Starts a poll with question and options. Optionally provide seconds and min votes.
|
||||
*/
|
||||
if (action.equalsIgnoreCase('open')) {
|
||||
var time = 0,
|
||||
question = '',
|
||||
options = [],
|
||||
minVotes = 1;
|
||||
|
||||
argsString = argsString + ""; // Cast as a JavaScript string.
|
||||
|
||||
if (argsString.match(rePollOpenFourOptions)) {
|
||||
question = argsString.match(rePollOpenFourOptions)[1];
|
||||
options = argsString.match(rePollOpenFourOptions)[2].split(/,\s*/);
|
||||
time = parseInt(argsString.match(rePollOpenFourOptions)[3]);
|
||||
minVotes = parseInt(argsString.match(rePollOpenFourOptions)[4]);
|
||||
} else if (argsString.match(rePollOpenThreeOptions)) {
|
||||
question = argsString.match(rePollOpenThreeOptions)[1];
|
||||
options = argsString.match(rePollOpenThreeOptions)[2].split(/,\s*/);
|
||||
time = parseInt(argsString.match(rePollOpenThreeOptions)[3]);
|
||||
} else if (argsString.match(rePollOpenTwoOptions)) {
|
||||
question = argsString.match(rePollOpenTwoOptions)[1];
|
||||
options = argsString.match(rePollOpenTwoOptions)[2].split(/,\s*/);
|
||||
} else {
|
||||
$.say($.whisperPrefix(sender) + $.lang.get('pollsystem.open.usage'));
|
||||
return;
|
||||
}
|
||||
|
||||
if (!question || !options || options.length === 0 || isNaN(minVotes) || minVotes < 1) {
|
||||
$.say($.whisperPrefix(sender) + $.lang.get('pollsystem.open.usage'));
|
||||
return;
|
||||
}
|
||||
if (options.length === 1) {
|
||||
$.say($.whisperPrefix(sender) + $.lang.get('pollsystem.open.moreoptions'));
|
||||
return;
|
||||
}
|
||||
|
||||
if (runPoll(question, options, parseInt(time), sender, minVotes, function(winner) {
|
||||
if (winner === false) {
|
||||
$.say($.lang.get('pollsystem.runpoll.novotes', question));
|
||||
return;
|
||||
}
|
||||
if (poll.hasTie) {
|
||||
$.say($.lang.get('pollsystem.runpoll.tie', question));
|
||||
} else {
|
||||
$.say($.lang.get('pollsystem.runpoll.winner', question, winner));
|
||||
}
|
||||
})) {
|
||||
$.say($.whisperPrefix(sender) + $.lang.get('pollsystem.runpoll.started'));
|
||||
} else {
|
||||
$.say($.whisperPrefix(sender) + $.lang.get('pollsystem.results.running'));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @commandpath poll close - Close the current poll and tally the votes
|
||||
*/
|
||||
if (action.equalsIgnoreCase('close')) {
|
||||
if (!poll.pollRunning) {
|
||||
$.say($.whisperPrefix(sender) + $.lang.get('pollsystem.close.nopoll'));
|
||||
return;
|
||||
}
|
||||
endPoll();
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
/**
|
||||
* @event initReady
|
||||
*/
|
||||
$.bind('initReady', function() {
|
||||
$.registerChatCommand('./systems/pollSystem.js', 'poll', 2);
|
||||
$.registerChatCommand('./systems/pollSystem.js', 'vote', 7);
|
||||
$.registerChatSubcommand('poll', 'results', 2);
|
||||
$.registerChatSubcommand('poll', 'open', 2);
|
||||
$.registerChatSubcommand('poll', 'close', 2);
|
||||
});
|
||||
|
||||
/** Export functions to API */
|
||||
$.poll = {
|
||||
runPoll: runPoll,
|
||||
endPoll: endPoll
|
||||
};
|
||||
})();
|
||||
Reference in New Issue
Block a user