// ==UserScript==
// @name emjack++
// @version 2.9.6
// @description The new emjack
// @match https://epicmafia.com/game/*
// @author Foxie, Croned
// @namespace https://greasyfork.org/en/users/9694-croned
// @grant GM_setValue
// @grant GM_getValue
// ==/UserScript==
unsafeWindow.GM_setValue = GM_setValue;
unsafeWindow.GM_getValue = GM_getValue;
unsafeWindow.notes = {};
inject=document.createElement("script");
inject.textContent="void "+String(function() {
//initiate
var scope=$(document.body).scope(),
dev=false,
settings=scope.settings;
function log(msg) {
scope.log(msg, "ejack");
}
var roleDisplay = false;
var voteTracker = {"length": 0, "users": {}, "voted": {}};
var query;
var showvotes = true;
var setWill = false;
//abort if not mafia
var gamemode=document.title.match(/([\w\s]+)\s-/)[1];
if(gamemode!=="Epicmafia") {
return;
}
//load config
if(localStorage.notes && !scope.ranked) {
notes=JSON.parse(localStorage.notes);
}
//intercept packets
scope.execute_cmds=function(initial) {
//console.log("Init:" + initial);
return function(pkg) {
initial.call(scope, pkg);
//console.log(pkg);
for(var i=0, cmd, data; i<pkg.length; ++i) {
cmd=pkg[i][0];
//console.log("COMMAND:" + cmd);
data=pkg[i][1];
//console.log("DATA:" + data);
if(dev) {
console.log(cmd, data);
}
if(cmd==="a") {
if(!ranked) {
if(!options.fastgame) {
scope.set_option("fastgame");
}
if(!options.nospectate) {
scope.set_option("nospectate");
}
}
}
else if(cmd==="join") {
log(data.user+" has joined");
}
else if(cmd==="leave") {
log(data.user+" has left");
}
else if(cmd==="kill") {
scope.users[data.target].dead=true;
}
else if(cmd==="kk") {
scope.users[data.user].dead=true;
}
else if(cmd==="speech") {
if(data.type==="contact") {
log("The roles are... "+data.data.join(", "));
}
}
else if(cmd==="ms") {
if(data==="Zombie wins!") {
log("brraaaaaaiiinnnsss...");
}
}
else if(cmd==="m") {
if(data.meet==="mafia" && data.choosedata) {
for(var key in scope.users) {
if(!data.choosedata[key] && !scope.users[key].dead) {
if(!scope.users[key].revealed) {
scope.select_role(key, "mafia");
}
if(data.members.indexOf(key)===-1) {
log(key+" is your partner!");
}
}
}
}
}
else if (cmd == "p") {
if (data.meet == "village") {
if (!data.unpoint) {
if (voteTracker.voted[data.user]) {
voteTracker.users[voteTracker.voted[data.user]] -= 1;
if (data.target !== "*") {
voteTracker.users[data.target] += 1;
voteTracker.voted[data.user] = data.target;
}
else {
voteTracker.voted[data.user] = false;
}
}
else {
voteTracker.users[data.target] += 1;
voteTracker.voted[data.user] = data.target;
}
}
else {
voteTracker.users[data.target] -= 1;
voteTracker.voted[data.user] = false;
}
}
}
}
}
}(scope.execute_cmds);
//chat input
$(window).on("keydown",function(event) {
if(event.target.value===undefined && !event.ctrlKey) {
$("#typebox").focus();
}
});
scope.keypress=function(initial) {
return function(event) {
if(event.which===13) {
var input=event.target.value;
if(input[0]==="/") {
var cmd=input.match(/\/(\w+)/)[1],
data=input.match(/\/\w+\s?(.+)?/)[1];
if(cmd==="dev") {
dev=!dev;
log(dev?"Logging on":"Logging off");
}
else if(cmd==="help") {
log("/me - action message");
log("/ping - ping living players");
log("/join - join first open game");
log("/host - host game with current setup");
log("/games - list open games");
}
else if(cmd==="clear") {
$(".ejack").remove();
}
else if(cmd==="ping") {
var ping=[];
for(var key in scope.users) {
if(!scope.users[key].dead) {
ping.push(key);
}
}
event.target.value=ping.join(" ");
initial.call(scope, event);
return;
}
else if(cmd==="kick") {
if(data) {
data=data.toLowerCase();
for(var key in scope.users) {
if(key.toLowerCase()===data) {
scope.ban(scope.users[key].id);
break;
}
}
}
}
else if(cmd==="emotes") {
log("global - "+Object.keys(_emotes).join(" "));
log("lobby - "+Object.keys(lobby_emotes).join(" "));
}
else if(cmd==="whois") {
if(data) {
data=data.toLowerCase();
for(var key in scope.users) {
if(data==="all" || key.toLowerCase()===data) {
log(key+" ("+scope.users[key].id+")");
var emotes=scope.users[key].emotes;
log(" -- emotes: "+(
emotes?Object.keys(emotes).join(" "):"none"
));
if(data!=="all") {
break;
}
}
}
}
}
else if(cmd==="games") {
var a,
div,
chat=document.getElementById("window");
lobbyGames({
status_id: 0,
password: false
}, function(table) {
a=document.createElement("a");
a.textContent="Table "+table.id;
a.addEventListener("click", function(event) {
leaveand(function() {
location.href="/game/"+table.id;
});
});
div=document.createElement("div");
div.className="log ejack";
div.appendChild(a);
div.appendChild(document.createTextNode(" - "+table.numplayers+" / "+table.target+" players"));
chat.appendChild(div);
chat.scrollTop=chat.scrollHeight;
});
}
else if(cmd==="join") {
lobbyGames({
status_id: 0,
target: 12,
password: false
}, function(table) {
leaveand(function() {
location.href="/game/"+table.id;
});
return true;
}
);
}
else if(cmd==="host") {
leaveand(function() {
$.getJSON("/game/add/mafia", {
setupid: scope.setup_id,
ranked: false,
add_title: data===undefined?0:1,
game_title: data
}, function(json) {
if(json[1].table) {
location.href="/game/"+json[1].table;
}
}
);
});
}
else if(cmd==="leave") {
scope.definite_leave();
}
else if(cmd==="me") {
if(data) {
initial.call(scope, event);
return;
}
else {
log("Add text!");
log("i.e.: /me slaps Foxie with a fish");
}
}
else if (cmd == "toggle") {
if (showvotes) {
showvotes = false;
$(".jackVote").hide();
showVotesSetting = false;
}
else {
showvotes = true;
$(".jackVote").show();
showVotesSetting = true;
}
}
else if (cmd == "role") {
if (data) {
data=data.toLowerCase();
}
else {
data = scope.users[scope.user].role;
}
var roleurl = "/role/" + data + "/info/roleid";
var roleInfo = $.ajax({method: "GET", url: roleurl, async: false});
roleInfo = roleInfo.responseText;
var roleHTML = $(roleInfo);
var roleName = roleHTML.find("h4").text();
if (roleName.length > 0) {
var roleAttrs = roleHTML.find("li");
log(roleName + ":");
for (var i = 0; i < roleAttrs.length; i++) {
log("* " + roleAttrs[i].textContent);
}
}
else {
log("Role does not exist!");
}
}
event.target.value="";
return;
}
}
initial.call(scope, event);
};
}(scope.keypress);
//anti-votespam
var votetimes=[];
$(document).on("click", ".one_booth_choice", function(event) {
var now=Date.now();
for(var i=votetimes.length; i--;) {
if(now-votetimes[i]>5000) {
votetimes.splice(i, 1);
}
}
votetimes.push(now);
if(votetimes.length>10) {
log("You're voting too fast!");
event.stopPropogation();
}
});
void function(eventlist) {
eventlist.unshift(eventlist[eventlist.length-1]);
eventlist.pop();
}($._data(document).events.click);
//utility
function leaveand(callback) {
scope.redirect_back=callback;
scope.definite_leave();
};
function lobbyGames(criteria,callback) {
$.ajax({url: "/game/find?page=1", method: "get"}).success(function(json) {
var criterion,
openGames=[],
games=JSON.parse(json[1]);
games.data.forEach(function(table) {
for(criterion in criteria) {
if(criteria[criterion]!==table[criterion]) {
return;
}
}
openGames.push(table);
})
if(openGames.length===0) {
log("No open games available!");
}
else {
openGames.some(function(table) {
return callback(table);
});
}
});
};
//clickable links
vocabs.push("https?://.+");
$(document).delegate(".acronym", "click", function() {
if(/\bhttps?:\/\/.+\b/ig.test(this.textContent)) {
window.open(this.textContent, "_blank");
}
});
//manage notes
if(!scope.ranked) {
$(document).on("mouseenter", ".user_li", function(event) {
this.setAttribute("title", notes[this.dataset.uname]||"no notes for "+this.dataset.uname);
});
$(document).on("click", ".user_note", function(event) {
var user=scope.selected_user;
if(user.details.notes===undefined) {
user.details.notes=notes[user.username]||"";
$(".notes").val(user.details.notes);
}
});
$(".notes").on("keyup",function(event) {
notes[scope.selected_user.username]=this.value;
});
}
//Role Info, voteTracker, and setWill
setInterval(function() {
window.voteTracker = voteTracker;
//voteTracker
if (scope.current_day) {
if (voteTracker.length == 0) {
for (var i = 0; i < scope.user_list.length; i++) {
if (!scope.users[scope.user_list[i]].dead) {
voteTracker.voted[scope.user_list[i]] = false;
voteTracker.users[scope.user_list[i]] = 0;
voteTracker.length += 1;
}
}
}
else {
for (var i = 0; i < scope.user_list.length; i++) {
query = "[data-uname*='" + scope.user_list[i] + "']";
$(query).find(".jackVote").text(voteTracker.users[scope.user_list[i]]);
}
}
if ($(".jackVote").length == 0 && scope.gamestate > 0 && scope.is_day()) {
for (var i = 0; i < scope.user_list.length; i++) {
if (!scope.users[scope.user_list[i]].dead) {
query = "[data-uname*='" + scope.user_list[i] + "']";
$(query).prepend("<span class='jackVote'>0</span>");
if (!showvotes) {
$(".jackVote").hide();
}
}
}
}
if (scope.is_night()) {
$(".jackVote").remove();
}
}
else {
voteTracker.users = {};
voteTracker.voted = {};
voteTracker.length = 0;
$(".jackVote").remove();
}
//Role Display
if (!roleDisplay && scope.gamestate > 0 && scope.users[scope.user].role) {
var role = scope.users[scope.user].role;
var alignment = scope.role_data[scope.users[scope.user].role];
$(".gamesetup").append("<li class='jackLi'>Role: <span id='jackRole' class='jackSpan'></span> Alignment: <span id='jackAlign' class='jackSpan'></span></li>");
$(".jackLi").css({
"color": "#b44",
"font-weight": "bold",
"margin-left": "10px"
});
$(".jackSpan").css({
"color": "black",
"margin-right": "5px"
});
$("#jackRole").text(role);
$("#jackAlign").text(alignment);
roleDisplay = true;
}
//setWill
if (scope.is_night() && scope.gamestate == 1 && !setWill && scope.role_data[scope.users[scope.user].role] != "mafia") {
scope.lastwill = scope.user + ", " + scope.users[scope.user].role;
scope.update_will();
setWill = true;
}
}, 100);
//save settings
var emjackSettings = {
acronym: false,
emoticons: false,
fullscreen: false,
mutemusic: false,
muting: false,
timestamp: false,
voting: false
};
var showVotesSetting = false;
emjackSettings.acronym = GM_getValue("emjack_acronym");
emjackSettings.emoticons = GM_getValue("emjack_emoticons");
emjackSettings.fullscreen = GM_getValue("emjack_fullscreen");
emjackSettings.mutemusic = GM_getValue("emjack_mutemusic");
emjackSettings.muting = GM_getValue("emjack_muting");
emjackSettings.timestamp = GM_getValue("emjack_timestamp");
emjackSettings.voting = GM_getValue("emjack_voting");
showVotesSetting = GM_getValue("emjack_showvotes");
for (var set in emjackSettings) {
if (emjackSettings.hasOwnProperty(set)) {
if (emjackSettings[set] && !scope.settings[set]) {
setTrue(set);
}
}
}
if (!showVotesSetting) {
showvotes = false;
$(".jackVote").hide();
}
$(window).on("beforeunload",function(event) {
localStorage.notes=JSON.stringify(notes);
for (set in scope.settings) {
if (scope.settings.hasOwnProperty(set)) {
saveSettings(set, scope.settings);
}
}
GM_setValue("emjack_showvotes", showVotesSetting);
});
setTrue = function(setting) {
var selector = "#" + setting;
$(selector).click();
};
saveSettings = function(set, settings) {
GM_setValue("emjack_" + set, settings[set]);
}
}+"()");
window.addEventListener("load", function(event) {
document.body.appendChild(inject);
});