emjack++

The new emjack

Tendrás que instalar una extensión para tu navegador como Tampermonkey, Greasemonkey o Violentmonkey si quieres utilizar este script.

You will need to install an extension such as Tampermonkey to install this script.

Necesitarás instalar una extensión como Tampermonkey o Violentmonkey para instalar este script.

Necesitarás instalar una extensión como Tampermonkey o Userscripts para instalar este script.

Necesitará instalar una extensión como Tampermonkey para instalar este script.

Necesitarás instalar una extensión para administrar scripts de usuario si quieres instalar este script.

(Ya tengo un administrador de scripts de usuario, déjame instalarlo)

Necesitará instalar una extensión como Stylus para instalar este estilo.

Necesitará instalar una extensión como Stylus para instalar este estilo.

Necesitará instalar una extensión como Stylus para instalar este estilo.

Necesitará instalar una extensión del gestor de estilos de usuario para instalar este estilo.

Necesitará instalar una extensión del gestor de estilos de usuario para instalar este estilo.

Necesitará instalar una extensión del gestor de estilos de usuario para instalar este estilo.

(Ya tengo un administrador de estilos de usuario, déjame instalarlo)

// ==UserScript==
// @name			emjack++
// @version			3.4.3
// @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.id = "emjack";
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;
	window.voteList = {};
    var lastActive = false;
	//abort if not mafia
	var gamemode = document.title.match(/([\w\s]+)\s-/)[1];
	if (gamemode !== "Epicmafia" || scope.compete || scope.ranked || scope.record) {
		return;
	}

    $("body").mousemove(function() {lastActive = new Date().getTime()});
    $("body").keypress(function() {lastActive = new Date().getTime()});
    
	//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") {
						var vote;
						voteList = {};

						$(".meet_entity[id*='target']").each(function () {
							vote = $(this).text().replace(/votes/g, "");
							vote = vote.replace(/vote/g, "");
							vote = vote.replace(/ /g, "");
							if (vote) {
								if (voteList[vote]) {
									voteList[vote]++;
								}
								else {
									voteList[vote] = 1;
								}
							}
						});
					}
				}
			}
		}
	}(scope.execute_cmds);

	//chat input
	$(window).on("keydown", function (event) {
		if (event.target.value === undefined && !event.ctrlKey && !event.metaKey) {
			$("#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!");
						}

					}
                    else if (cmd == "afk") {
                        if (autoAfkSetting) {
                            autoAfkSetting = false;
                            errordisplay(".errordisplay", "AFK Mode Off!");
                        } else {
                            autoAfkSetting = true;
                            errordisplay(".errordisplay", "AFK Mode On!");
                        }
                    }
                    else if (cmd == "nl") {
                        $(".booth_noimg").click();
                    }
                    else if (cmd == "vote") {
                        $(".one_booth_choice:contains('" + data + "')").click();
                    }
                    else if (cmd == "bug") {
                        $.post("/message", {msg: data, subject: "emjack Bug Report", "recipients[]": 392447});
                        log("Bug report sent!");
                    }
                    else if (cmd == "suggest") {
                        $.post("/message", {msg: data, subject: "emjack Suggestion", "recipients[]": 392447});
                        log("Suggestion sent!");
                    }
					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;
		});
	}

	//Init Vote Tracker
	var setVoteInt = setInterval(function () {
		if (scope.user_list.length > 0 && $(".jackVote").length == 0 && scope.gamestate > 0) {
			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>");
				}
			}
			$(".jackVote").hide();
			clearInterval(setVoteInt);
		}
	}, 100);

	//Role Info, voteTracker, and setWill
	setInterval(function () {

		//voteTracker
		if (scope.is_day() && showvotes) {
			$(".jackVote").show();
			for (var i = 0; i < scope.user_list.length; i++) {
				query = "[data-uname*='" + scope.user_list[i] + "']";
				if (voteList[scope.user_list[i]]) {
					$(query).find(".jackVote").text(voteList[scope.user_list[i]]);
				}
				else {
					$(query).find(".jackVote").text("0");
				}
			}
		}
		else {
			$(".jackVote").hide();
		}

		//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;
		}
        
        //Typebox always visible
        $("#speak_container").removeClass("ng-hide");
	}, 100);
    
    //AFK Mode
    var gamestates = {};
    var chosenYet;
    var choices;

    function doVote() {
        $(".booth_choices").each(function() {
            chosenYet = false;
            choices = $(this).find(".booth_inner");

            choices.each(function(index) {
                if ($(this).text() == "no one") {
                    $(this).click();
                    chosenYet = true;
                }
                else if (!chosenYet && (choices.length - 1) == index) {
                    $(this).first().click();
                    chosenYet = true;
                }
            });
        });

        $(".inputchoice").click();

        gamestates[scope.gamestate] = true;
    }
    
    setInterval(function(){
        var currentTime = new Date().getTime();
        if (!gamestates[scope.gamestate] && autoAfkSetting) {
            if (Math.round( (currentTime - lastActive) / 1000 ) >= 5 && !$("#id_" + scope.user).text().replace("You", "").replace(" ", "") && scope.kick_countdown == "Time is up!") {
                doVote();
            }
        }
        
        
    }, 5000);

	//save settings
	var emjackSettings = {
		acronym: false,
		emoticons: false,
		fullscreen: false,
		mutemusic: false,
		muting: false,
		timestamp: false,
		voting: false
	};

	setTrue = function (setting) {
		var selector = "#" + setting;
		$(selector).click();
	};

	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");
	autoAfkSetting = GM_getValue("emjack_autoafk");

	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);
		GM_setValue("emjack_autoafk", autoAfkSetting);
	});

	saveSettings = function (set, settings) {
		GM_setValue("emjack_" + set, settings[set]);
	}


	console.log("emjack++ activated!");
} + "()");
window.addEventListener("load", function (event) {
	document.body.appendChild(inject);
});