TagPro Groups on Homepage

Show available groups *of all servers* on the homepage, joiner page and inside a group

目前為 2018-06-27 提交的版本,檢視 最新版本

您需要先安裝使用者腳本管理器擴展,如 TampermonkeyGreasemonkeyViolentmonkey 之後才能安裝該腳本。

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

您需要先安裝使用者腳本管理器擴充功能,如 TampermonkeyViolentmonkey 後才能安裝該腳本。

您需要先安裝使用者腳本管理器擴充功能,如 TampermonkeyUserscripts 後才能安裝該腳本。

你需要先安裝一款使用者腳本管理器擴展,比如 Tampermonkey,才能安裝此腳本

您需要先安裝使用者腳本管理器擴充功能後才能安裝該腳本。

(我已經安裝了使用者腳本管理器,讓我安裝!)

你需要先安裝一款使用者樣式管理器擴展,比如 Stylus,才能安裝此樣式

你需要先安裝一款使用者樣式管理器擴展,比如 Stylus,才能安裝此樣式

你需要先安裝一款使用者樣式管理器擴展,比如 Stylus,才能安裝此樣式

你需要先安裝一款使用者樣式管理器擴展後才能安裝此樣式

你需要先安裝一款使用者樣式管理器擴展後才能安裝此樣式

你需要先安裝一款使用者樣式管理器擴展後才能安裝此樣式

(我已經安裝了使用者樣式管理器,讓我安裝!)

// ==UserScript==
// @name         TagPro Groups on Homepage
// @version      1.1
// @description  Show available groups *of all servers* on the homepage, joiner page and inside a group
// @author       Ko
// @supportURL   https://www.reddit.com/message/compose/?to=Wilcooo
// @website      https://redd.it/no-post-yet
// @download     https://raw.githubusercontent.com/wilcooo/TagPro-GroupsOnHomepage/master/tpgoh.user.js
// @match        http://*.koalabeast.com:*/*
// @grant        GM_xmlhttpRequest
// @grant        GM_getValue
// @grant        GM_setValue
// @license      MIT
// @require      https://cdnjs.cloudflare.com/ajax/libs/socket.io/2.1.0/socket.io.slim.js
// @connect      script.google.com
// @connect      script.googleusercontent.com
// @namespace https://greasyfork.org/users/152992
// ==/UserScript==

////////////////////////////////////////////////////////////////////////////////////////////
//     ### --- OPTIONS --- ###                                                            //
////////////////////////////////////////////////////////////////////////////////////////  //
                                                                                      //  //
// Shows available groups *of all servers* on the homepage, and lets you create a new //  //
// group with a single click from there too. This also works when you've already      //  //
// joined a group!                                                                    //  //
const groups_on_home = true;                                                          //  //
                                                                                      //  //
// Shows available groups *of all servers* while finding/joining a game, and lets you //  //
// create a new group with a single click from there too. Works when already in one!  //  //
const groups_on_find = true;                                                          //  //
                                                                                      //  //
// Shows available groups *of all servers* on the 'groups' page not just those of the //  //
// server that you happen to be on.                                                   //  //
const groups_on_groups = true;                                                        //  //
                                                                                      //  //
// Shows available groups *of all servers* within a group you've already joined       //  //
const groups_in_group = true;                                                         //  //
                                                                                      //  //
// Position on homepage ( can be 'top', 'home', or 'bottom' )                         //  //
// 'home' means beneath the video on the homepage                                     //  //
// TODO: link to a picture that explains these positions                              //  //
const position = 'top';                                                               //  //
                                                                                      //  //
////////////////////////////////////////////////////////////////////////////////////////  //
//                                                     ### --- END OF OPTIONS --- ###     //
////////////////////////////////////////////////////////////////////////////////////////////





//////////////////////////////////////
// SCROLL FURTHER AT YOUR OWN RISK! //
//////////////////////////////////////



var short_name = 'groups_on_homepage';             // An alphabetic (no spaces/numbers, preferably lowercase) distinctive name for the script.
var version = GM_info.script.version;  // The version number is automatically fetched from the metadata.
tagpro.ready(function(){ tagpro.scripts = Object.assign( tagpro.scripts || {}, {short_name:{version:version}} ); });
console.log('START: ' + GM_info.script.name + ' (v' + version + ' by ' + GM_info.script.author + ')');




// Userscripts load in the order that they appear in Tamermonkey.
// Set this option to true if you want this script to be inserted to
// the page above than previously load scripts, instead of below.
const insertBefore = false;


const servers = ['centra','pi','chord','diameter','origin','sphere','radius','orbit'];

const groups_api = 'https://script.google.com/macros/s/AKfycbxF5kcVoFbqmLlbHB2_nJ_dCRoh2iOXDpFyzAq0Kw2UDjM7qEHf/exec';





if (window.location.pathname === '/groups') {  // If we are on the groups selection page

    if (groups_on_groups) show_groups( document.getElementById('groups-list'), false);
}

else if (window.location.pathname.match(/^\/groups\/[a-z]{8}$/)) {  // If we are in a group

    if (groups_in_group) show_groups();
}

else if (window.location.pathname === '/games/find') {  // In the process of joining a game

    if (groups_on_find) show_groups();
}

else if (window.location.port.match(/^8[0-9]{3}$/)) {  // If we are in a game
}

else if (window.location.pathname === '/') {  // If we are on the homepage

    if (groups_on_home) show_groups();
}

else {  // If we are on any other page of the server
}





function show_groups(groups_list=document.createElement('div'), newGroupWidget=true) {

    // Create a container for the groups
    if (!groups_list.parentElement) {
        var container = document.createElement('div');
        container.id = 'GroPro-groups';
        container.className = 'container';

        container.appendChild(groups_list);

        // Add the container to the userscript-div and make unhide that
        var pos =
            document.getElementById('userscript-'+position) ||
            document.getElementById('userscript-home') ||
            document.getElementById('userscript-top');
        if (!pos) return tagpro.helpers.displayError('Sorry, something went wrong while trying to show you the groups of all servers. Error code: Giraffe (inform /u/Wilcooo if you want me to fix it)');
        if (insertBefore) pos.insertBefore(container, pos.firstChild);
        else              pos.append(container);
        pos.classList.remove('hidden');
    }

    groups_list.className = 'row groups-list';

    var groups_list_cache = GM_getValue('groups-list-cache',{});

    groups_list.innerHTML = '<div class=spinner align=center> <div class=spinner-item></div> <div class=spinner-item></div> <div class=spinner-item></div> <div class=spinner-item></div>';

    if (Date.now() - groups_list_cache.time < 65e3) groups_list.innerHTML += groups_list_cache.html;

    // Get ping and server stats for each server
    window.addEventListener('load',function(){

        servers.forEach( function(server) {
            var host = 'http://tagpro-'+server+'.koalabeast.com:80';

            var connection = io.connect(host, {transports: ["websocket"]});
            console.log(io)

            connection.on('connect',function(){
                var ping = -Date.now();
                connection.emit('stats',{},function(stats) {
                    ping += Date.now();

                    styleSheet.insertRule('.'+server+'-stats:after { content:"(ping: '+ping+', '+stats.players+' players in '+stats.games+' games)"; color:#868686; font-style:italic; font-size:small; }');
                    styleSheet.insertRule('.'+server+'-stats .spinner { display:none !important; }');
                });
            });
        });
    });


    var request = new XMLHttpRequest();

    request.onload = function() {
        var data = JSON.parse(request.response);

        groups_list.innerHTML = '';

        for (var group of data.groups) {
            var group_html =
                    `<div class="col-sm-6 col-md-4">
                        <div class="group-item">
                            <div class="row">
                                <div class="col-md-12">
                                    <div class="pull-right group-type"> `+group.type+` </div>
                                    <div class="group-name ellipsis"> `+group.name+` </div>
                                </div>
                                <div class="col-xs-6">
                                    <div class="ellipsis"> Leader: `+group.leader+` </div>
                                    <div class="ellipsis"> Players: `+group.players+` </div>
                                </div>
                                <div class="col-xs-6">
                                    <a class="btn btn-primary pull-right" href="`+group.link+`"> Join Group </a>
                                </div>
                                <div class="col-xs-12 ellipsis `+group.server+`-stats">
                                    Server: `+group.server[0].toUpperCase() + group.server.slice(1)+`
                                    <div class=spinner style="display:inline">
                                        <div class=spinner-item></div>
                                        <div class=spinner-item></div>
                                        <div class=spinner-item></div>
                                    </div>
                                </div>
                            </div>
                        </div>
                    </div>`;
            groups_list.innerHTML += group_html;
        }

        if (data.groups.length == 0) {
            groups_list.innerHTML = `
                    <div class="col-sm-6 col-md-4">
                        <div class="group-item">
                            <div class="row">
                                <div class="col-md-12">
                                    <div class="group-name">No public groups available. Create one!</div>
                                </div>
                            </div>
                        </div>
                    </div>`;
        }

        if (newGroupWidget) {
            groups_list.innerHTML +=
                `<div class="col-sm-6 col-md-4">
                     <div class="group-item">
                         <div class="row">
                             <form method="post" action="/groups/create">
                                 <div class="col-md-12">
                                     <input name="name" class="group-name" style="background:0;border:0;width:100%" value="Your group">
                                 </div>
                                 <div class="col-md-12 pull-right">
                                     <label tabindex="0" class="btn btn-default input-label" style="margin:6px">
                                         <input tabindex="-1" type="checkbox" name="public"> Public Group
                                     </label>
                                     <button class="btn btn-primary" style="margin:6px">Create Group</button>
                                 </div>
                             </form>
                         </div>
                     </div>
                 </div>`;
        }

        for (var label of document.getElementsByClassName('input-label')) {
            label.onkeydown = function(keydown) {
                if (keydown.code == 'Space') {
                    keydown.preventDefault();
                    keydown.target.firstElementChild.checked ^= true;
                }
                if (keydown.code == 'Enter') {
                    keydown.preventDefault();
                    keydown.target.closest('form').submit();
                }
            };
        }

        GM_setValue('groups-list-cache', {'html': groups_list.innerHTML, 'time': Date.now()});
    };

    request.open( "GET", groups_api );
    request.send();

    labelKeyDown = function(event) {
        if (event.code == 'Space') {
            event.preventDefault();
            event.target.firstElementChild.checked ^= true;
        }
        if (event.code == 'Enter') {
            event.preventDefault();
            event.target.closest('form').submit();
        }
    };

}


document.head.appendChild( document.createElement('style' ));
var styleSheet = document.styleSheets[ document.styleSheets.length -1 ];

styleSheet.insertRule( '.ellipsis { white-space:nowrap; overflow:hidden; text-overflow:ellipsis; }' );