emjack++

The new emjack

נכון ליום 03-08-2015. ראה הגרסה האחרונה.

// ==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);
	});