您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
Reworks Oracle for Epicmafia as script. Originally created by lailai. Add rehost button, autorefresh ability and game search ability.
// ==UserScript== // @name Reworks Oracle for Epicmafia as script // @namespace https://greasyfork.org/en/users/159342-cleresd // @description Reworks Oracle for Epicmafia as script. Originally created by lailai. Add rehost button, autorefresh ability and game search ability. // @version 1.06 // @match https://epicmafia.com/* // @exclude https://epicmafia.com/game* // @grant GM_addStyle // @grant GM_setValue // @grant GM_getValue // @run-at document-end // ==/UserScript== GM_addStyle(` /* head additional */ ._orcDropdownContent { display: none; position: absolute; background-color: #eee; min-width: 160px; box-shadow: 0 8px 16px 0 rgba(0, 0, 0, 0.2); border-radius: 6px; z-index: 5; font-size: 85%; border: 1px solid #cd88d3; } ._orcDropdownContent a { color: black; padding: 12px 16px; text-decoration: none; float: left; } .sel:hover ._orcDropdownContent { display: none; } ._orcDropdownContent a:hover { background-color: #ccc; } li:hover ._orcDropdownContent { display: block; } /* auto refresh button */ ._oracle_icon { background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABMAAAATCAYAAAByUDbMAAABG2lUWHRYTUw6Y29tLmFkb2JlLnhtcAAAAAAAPD94cGFja2V0IGJlZ2luPSLvu78iIGlkPSJXNU0wTXBDZWhpSHpyZVN6TlRjemtjOWQiPz4KPHg6eG1wbWV0YSB4bWxuczp4PSJhZG9iZTpuczptZXRhLyIgeDp4bXB0az0iWE1QIENvcmUgNS41LjAiPgogPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4KICA8cmRmOkRlc2NyaXB0aW9uIHJkZjphYm91dD0iIi8+CiA8L3JkZjpSREY+CjwveDp4bXBtZXRhPgo8P3hwYWNrZXQgZW5kPSJyIj8+Gkqr6gAAAYFpQ0NQc1JHQiBJRUM2MTk2Ni0yLjEAACiRdZHfK4NRGMc/22iyieLChbQ0uxoxtbhRtoSS1kwZbrZ3v9Q2b+/7SsutcqsocePXBX8Bt8q1UkRKyp1r4ga9nndTk+w5Pef5nO85z9M5zwF7LK8U9Lo+KBQNLToW8szG5zzOJxx04qILX0LR1ZFIZJKa9n6LzYrXPVat2uf+NVcqrStgaxAeVlTNEB4XnlwxVIu3hNuUXCIlfCLs1+SCwjeWnqzws8XZCn9arMWiYbC3CHuyvzj5i5WcVhCWl+Mt5JeVn/tYL3GnizPTErvEO9CJMkYIDxOMEiZIP0MyB+khQK+sqJHfV86fYklyFZlVSmgskiWHgV/UZamelpgRPS0jT8nq/9++6pmBQKW6OwT1j6b52g3OTfjaMM2PA9P8OgTHA5wXq/lL+zD4JvpGVfPuQfManF5UteQ2nK1D+72a0BJlySFuz2Tg5Ria4tB6BY3zlZ797HN0B7FV+apL2NkFn5xvXvgGa+9n6Oaaag8AAAAJcEhZcwAADsQAAA7EAZUrDhsAAAFCSURBVDiNY2QgAnw6e/4/Mp/P2JARmzqsgvgMwmcgTsPa086gGJKdzkzQQCZiDGJgYGCYOvMvLnvhgIUYgwJleKCs76QZhmkAAjzbyskg5f0dzkYHKN6EuQqbQdjAjaYbKL7ACDN8BuFzFYZhlbNMsMauBucXBqmYrwwMgv8Y+Pb9ZZCK+cqw/skXDHUoYYbsbJjibO2jDJ8YGBgYGGwYGBgYGD6xHWVg2MzAwMBgjWEg3CUwg5AVZFfgTtNTOxDBBfMREy6DCIGjZzdjiGFNtNhsRwZRoZuwiqOEWaAMD4brPj+8D2enl1zGMAA50uAMbCkfBuIiHzDwGrshXObYy2Bt7IthIBMhgxgYGFAMYmBgYFi2vxiFD9OPN8wYGKAx+uY2VnH02GbC5yp8SQObGpwuQ1aEHqtRjr0YMdqeduY/AAVIe2d8BtH4AAAAAElFTkSuQmCC); height: 19px; width: 19px; display: inline-block; position: relative; top: 1px; } #_oAutoRefreshWrap { display: inline-block; border: 1px solid #cd88d3; padding: 0 2px 2px 2px; margin-left: 2px; } #_oAutoRefreshWrap::before { content: ''; position: absolute; right: 48px; top: 9px; width: 0; height: 0; border-top: 6px solid transparent; border-bottom: 6px solid transparent; border-right: 6px solid #c788d3; } #_oAutoRefreshWrap ._oracle_icon { top: 3px; left: -4px; } /* auto rehost */ ._oRehost { margin-left: 5px; border: 1px solid #c788d3; padding: 5px 5px 4px 5px; color: #c788d3; font-size: 12px; } ._oRehost:hover { background-color: #c788d3; color: white; } /* other */ select[name='siterule_id'] { margin: 10px 0; } @keyframes fadeIn { from { opacity: 0; } to { opacity: 1; } }`); // It needs to auto refresh games' list let lastActivity = Date.now(); $('body').mousemove(e => lastActivity = Date.now()); $("#header_inner").find("ul li:eq(0)").append ( ` <div class="_orcDropdownContent"> <a href="https://epicmafia.com/game/new">Create game</a> <a href="https://epicmafia.com/setup">Find setup</a> <a href="https://epicmafia.com/lobby/rules">Rules</a> ` ); $("#header_inner").find("ul li:eq(1)").append ( ` <div class="_orcDropdownContent"> <a href="https://epicmafia.com/message">Inbox</a> <a href="https://epicmafia.com/family">Family</a> <a href="https://epicmafia.com/addon">Buy</a> ` ); $("#header_inner").find("ul li:eq(2)").append ( ` <div class="_orcDropdownContent"> <a href="https://epicmafia.com/moderator">Moderators</a> <a href="https://epicmafia.com/report">Reports</a> ` ); if ($(".ll-refresh").length) { insertAutoRefresh(); insertRehost(); insertSearch(); } if ($("#nav").find("li.sel a").text() === "Round") { $("#subnav").append(`<li><a href="/lobby/rules" style="color: #c788d3">Rules</a></li>`); } function insertRehost() { let $body = $("body"); let rehostButtonHtml = `<div class="_oRehost" data-name="mafia_gamerow">Re</div>`; $body.on("mouseenter", ".gamerow.mafia_gamerow, .gamerow.dicewars_gamerow, .gamerow.snakes_gamerow", e => { $(e.currentTarget).find('.gamesetup').parent().before(rehostButtonHtml); //$(e.currentTarget).find(".gamesetup").parent().before(); }); $body.on("mouseleave", ".gamerow", e => { $(e.currentTarget).find("._oRehost").remove(); }); $body.on("click", "._oRehost", e => { $(e.currentTarget).text("Rehosting"); const $gameRow = $(e.currentTarget).parents(".gamerow"); const type = $gameRow[0].classList[2].split('_')[0]; const numPlayers = $gameRow.find('.players').children().length; const isGoldHeart = $gameRow.find("img[src='/images/goldlives.png'],img[src='/images/broken_goldlives.png']").length !== 0; const isRedHeart = $gameRow.find("img[src='/images/lives.png'],img[src='/images/broken_lives.png']").length !== 0; let isPassword = $gameRow.find("img[src='/images/lock.png']").length !== 0 ? 1 : 0; let password = ''; const rank = isGoldHeart ? 2 : (isRedHeart ? 1 : 0); const gid = $gameRow.attr("data-gid"); if (isPassword) { $('#pop').removeClass('hide'); $('#pop_').removeClass('hide'); $('#pop_warn').css('display', 'none'); $('#password').attr('placeholder', 'Leave empty to no password'); $('#password').next().click(() => { $('#pop_').addClass('hide'); $('#pop').addClass('hide'); $('#pop_warn').css('display', ''); password = $('#password').val(); if (!password) { isPassword = 0; } rehost(gid, type, rank, isPassword, password, numPlayers); return true; }); } else { rehost(gid, type, rank, isPassword, password, numPlayers); } }); } function rehost(gid, type, rank, isPassword, password, numPlayers) { if (type === 'mafia') { rehostMafiaGame(gid, rank, isPassword, password) } else if (type === 'dicewars' || type === 'snakes') { isPassword = !!isPassword; rehostCustomGame(type, numPlayers, isPassword, password) } } function rehostMafiaGame(gid, rank, isPassword, password) { $.get(`https://epicmafia.com/game/${gid}/info`, data => { const setup =data[1].data.match(/\/setup\/[0-9]+/)[0].split("/")[2]; $.get(`https://epicmafia.com/game/add/mafia?` + `setupid=${setup}&ranked=${rank}&add_password=${isPassword}&password=${password}`, d => { if (d[1].table) { let location = `game/${d[1].table}`; location += isPassword ? `?password=${d[1].password}` : ``; GM_setValue('_oGameSrcFirstConf', location); GM_setValue('_oGameSrcSecondConf', location); GM_setValue('_oGameSrcCh', location); document.location = location; } else { alert(d[1].msg || d[1]); } }) }); } function rehostCustomGame(type, numPlayers, isPassword, password) { $.get(`https://epicmafia.com/game/add/${type}?` + `numplayers=${numPlayers}&add_password=${isPassword}&password=${password}`, d => { if (d[1].game_id) { let location = `game/${d[1].game_id}`; location += isPassword ? `?password=${d[1].password}` : ``; GM_setValue('_oGameSrcFirstConf', location); GM_setValue('_oGameSrcSecondConf', location); GM_setValue('_oGameSrcCh', location); document.location = location; } else { alert(d[1].msg || d[1]); } }) } function insertAutoRefresh() { let autoRefresh = GM_getValue('_oAutoRefreshBox') === undefined ? true : GM_getValue('_oAutoRefreshBox'); $(".ll-refresh").after(`<div id="_oAutoRefreshWrap" class="tt" data-title="Auto-refresh"> <input type="checkbox" id="_oAutoRefreshBox" ${autoRefresh ? "checked" : ""}/> <label for="_oAutoRefreshBox"><i class="_oracle_icon"></i></label> </div>`); $("#_oAutoRefreshBox").change(e => { autoRefresh = e.target.checked; GM_setValue('_oAutoRefreshBox', autoRefresh); }); setTimeout(function run() { let isNeedRefresh = autoRefresh && $('.pagenav .grey.smallfont').text() === "Page 1"; let isJustRefresh = document.hasFocus() && (Date.now() - lastActivity < 5 * 60 * 1000) && $('.ll-gamelist.sel').length === 1; let isGameSearchEnable = autoRefresh && (Date.now() - lastActivity < 30 * 60 * 1000) && !($("#_oGameSearchNone")[0].checked); if (isNeedRefresh) { if (isGameSearchEnable || isJustRefresh) $('.icon-refresh').click(); if (isGameSearchEnable) { searchGame(); } } setTimeout(run, 2200); }, 10); $(document).focus(() => { if (autoRefresh) { $('.icon-refresh').click(); } }); } function getOpenGames($_oGameSearchOption) { let $openGames = []; let isRankedGamesChecked = $('#_oGameRankedRedHeart')[0].checked; let isCompetitionGamesChecked = $('#_oGameRankedGoldHeart')[0].checked; let doNotSearch = !$_oGameSearchOption[0].checked; if (doNotSearch) { // prepare if (isRankedGamesChecked) { $openGames = $('.gamerow.join > .gameoptions > .randimg > img[src="/images/lives.png"]').parent().parent().parent(); } else if (isCompetitionGamesChecked) { let $goldLives = $('.gamerow.join > .gameoptions > .randimg > img[src="/images/goldlives.png"]').parent().parent().parent(); $openGames = isRankedGamesChecked ? $openGames.add($goldLives) : $goldLives; } else { $openGames = $('.gamerow.join > .gameoptions > .randimg > img[src="/images/lock.png"], .gamerow.join > .gameoptions > .randimg > img[src="/images/cam.png"]') .parent().parent().parent(); $openGames = $openGames.add($('.gamerow.join > .gameoptions > .randimg:empty').parent().parent()); } } return $openGames; } function searchGame() { let $_oGameSearchOption = $("input[name=_oGameSearchOption]:radio"); let $openGames = getOpenGames($_oGameSearchOption); if ($openGames.length) { searchGameBy(); } function searchGameBy() { let searchByGameType = $_oGameSearchOption[1].checked; let searchByGameSetup = $_oGameSearchOption[2].checked; let searchByHostId = $_oGameSearchOption[3].checked; if (searchByGameType) { let _oGameType = $('#_oGameTypeSelect').val(); openGameByType($openGames, _oGameType); } else if (searchByGameSetup) { let _oGameSetups = $('#_oGameSetupId').val().replace(/\s/g, '').split(','); openGameBySetup($openGames, _oGameSetups); } else if (searchByHostId) { let _oGameCreators = $('#_oGameCreatorId').val().replace(/\s/g, '').split(','); openGameByCreator($openGames, _oGameCreators); } } } function insertSearch() { let insertHtml = ` <div> <!--Header--> <h2 class="separator vm">Search game when auto-refresh is on</h2> <!--Settings--> <input type="radio" id="_oGameSearchNone" name="_oGameSearchOption" checked>Don't search game<br> <input type="radio" name="_oGameSearchOption" value="_oGameSearchByType"> <label for="_oGameTypeSelect">Game type:</label><br> <select id="_oGameTypeSelect"> <option value="mafia">mafia</option> <option value="dicewars">dicewars</option> <option value="liarsdice">liarsdice</option> <option value="acrotopia">acrotopia</option> <option value="battlegrounds">battlegrounds</option> <option value="battleships">battleships</option> <option value="boggle">boggle</option> <option value="cheat">cheat</option> <option value="checkers">checkers</option> <option value="chess">chess</option> <option value="chinese">chinese</option> <option value="concentration">concentration</option> <option value="connect4">connect4</option> <option value="crackcode">crackcode</option> <option value="crazyeights">crazyeights</option> <option value="dotsboxes">dotsboxes</option> <option value="drawit">drawit</option> <option value="ghost">ghost</option> <option value="go">go</option> <option value="hearts">hearts</option> <option value="hex">hex</option> <option value="jotto">jotto</option> <option value="mancala">mancala</option> <option value="ratscrew">ratscrew</option> <option value="reversi">reversi</option> <option value="snakes">snakes</option> <option value="stackit">stackit</option> <option value="texas">texas</option> <option value="tira">tira</option> </select><br> <label for="_oGameRankedRedHeart"><img src="/images/lives.png">(Ranked)</label> <input type="checkbox" id="_oGameRankedRedHeart" name="redHeart" value="redHeart"><br> <label for="_oGameRankedGoldHeart"><img src="/images/goldlives.png">(Competition)</label> <input type="checkbox" id="_oGameRankedGoldHeart" name="goldHeart" value="goldHeart"><br> <input type="radio" name="_oGameSearchOption" value="_oGameSearchBySetup"> <label for="_oGameSetupId">Setup ids:</label><br> <input id="_oGameSetupId" type="text" value="1375880"><br> <input type="radio" name="_oGameSearchOption" value="_oGameSearchByCreator"> <label for="_oGameCreatorId">Creator ids:</label><br> <input id="_oGameCreatorId" type="text" value="656967"><br> </div>`; $('#lobbyinfo_box').before(insertHtml); $( "#_oGameSetupId" ).val(GM_getValue('_oGameSetupId') || ''); $( "#_oGameCreatorId" ).val(GM_getValue('_oGameCreatorId') || ''); $("#_oGameRankedRedHeart").prop("checked", GM_getValue('_oGameRankedRedHeart') || false); $("#_oGameRankedGoldHeart").prop("checked", GM_getValue('_oGameRankedGoldHeart') || false); $( "#_oGameSetupId" ).change((e) => { GM_setValue('_oGameSetupId', e.target.value); }); $( "#_oGameCreatorId" ).change((e) => { GM_setValue('_oGameCreatorId', e.target.value); }); $( "#_oGameRankedRedHeart" ).change((e) => { GM_setValue('_oGameRankedRedHeart', e.target.checked); }); $( "#_oGameRankedGoldHeart" ).change((e) => { GM_setValue('_oGameRankedGoldHeart', e.target.checked); }); } function openGameByType($openGames, _oGameType) { $openGames.each((_, row) => { if (row.classList.contains(_oGameType + '_gamerow')) { // let gameId = row.getAttribute('data-gid'); // document.location = `game/${gameId}`; $(row).find('.sitdown > a')[0].click(); $('#_oGameSearchNone')[0].click(); return false; } }); } async function openGameBySetup($gameRows, _oGameSetups) { let rowsLength = $gameRows.length; for (let i = 0; i < rowsLength; i++) { let data = await _openGameBySetup($gameRows[i]); let setup = data[1].data !== undefined ? data[1].data.match(/\/setup\/[0-9]+/)[0].split("/")[2] : ''; console.log(_oGameSetups, setup); if (_oGameSetups.indexOf(setup) !== -1) { console.log("found game = " + setup); let gameId = $gameRows.eq(i).attr('data-gid'); document.location = `game/${gameId}`; // $gameRows[i].querySelector('a').click(); // $gameRows[i].querySelector('.sitdown > a').click(); /*$gameRows.eq(i).find('.sitdown > a').each((_, e) => { if (e.textContent === "Join game") e.click(); }); $gameRows.eq(i).find('.sitdown > a').click();*/ $('#_oGameSearchNone')[0].click(); break; } } } function _openGameBySetup(gameRow) { const gid = gameRow.getAttribute("data-gid"); return Promise.resolve($.get(`https://epicmafia.com/game/${gid}/info`)); } function openGameByCreator($openGames, _oGameCreators) { $openGames.find('.pull_right > .creator > a').each((_, creator) => { let creatorId = creator.getAttribute('data-uid'); if (_oGameCreators.indexOf(creatorId) !== -1) { $(creator).parents('.gamerow').find('.sitdown > a')[0].click(); $('#_oGameSearchNone')[0].click(); } }); }