TagPro GroPro

Enhance your group experience!

目前為 2018-01-15 提交的版本,檢視 最新版本

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

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

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

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

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

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

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

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

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

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

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

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

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

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

// ==UserScript==
// @name         TagPro GroPro
// @version      0.2
// @description  Enhance your group experience!
// @author       Ko
// @icon         https://raw.githubusercontent.com/wilcooo/TagPro-GroPro/master/G(roPro).png
// @download     https://raw.githubusercontent.com/wilcooo/TagPro-GroPro/master/tpgp.user.js
// @include      http://tagpro-*.koalabeast.com*
// @grant        GM_notification
// @namespace https://greasyfork.org/users/152992
// ==/UserScript==


const show_time = true;
const show_seconds = false;

var chat_sound = new Audio('https://raw.githubusercontent.com/wilcooo/TagPro-GroPro/master/audio/chat.wav');
var left_sound = new Audio('https://raw.githubusercontent.com/wilcooo/TagPro-GroPro/master/audio/left.mp3');
var join_sound = new Audio('https://raw.githubusercontent.com/wilcooo/TagPro-GroPro/master/audio/joined.mp3');



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

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

    tagpro.ready( function(){

        // Show notifications on receiving chats // Play sound
        tagpro.group.socket.on('chat', function(chat){
            if (! document.hasFocus()) {
                // GM_notification( text, title, icon (defaults to script icon), onclick)
                GM_notification( chat.message, chat.from || 'GroPro', null, window.focus );
            }

            // Play a sound
            if (chat.from) chat_sound.play();
            else if (chat.message.endsWith(' has left the group.'))
                left_sound.play();
            else if (chat.message.endsWith(' has joined the group.'))
                join_sound.play();
            else chat_sound.play();
        });


        // This function will fade the timestamp when you've seen the message
        function fadeTimestamp(t) {
            if (document.hasFocus()) {
                setTimeout( function(){
                    if (document.hasFocus())
                        t.fadeTo("slow",0.4);
                    else fadeTimestamp(t);
                }, 3000);
            } else {
                window.addEventListener("focus", function() {
                    fadeTimestamp(t);
                });
            }
        }

        var last_chat = '';

        // Replace TagPro's function that puts chats in the chat-log
        tagpro.group.socket.listeners('chat')[0] = function(chat) {
            var chat_log = $(".js-chat-log");

            if ( chat.message.startsWith('⋯') && group.chat[group.chat.length-1].from == chat.from) {
                last_chat = last_chat + chat.message.slice(1);
                $(".js-chat-log .chat-message").last().text( last_chat );
            } else {
                last_chat = chat.message;

                var time = new Date().toTimeString().substr(0,  show_seconds ? 8 : 5  );
                var timestamp = show_time ? $("<span></span>").addClass("timestamp").text( time ) : null;

                fadeTimestamp(timestamp);

                var player_name = null;
                if (chat.from) {
                    var player = group.players[Object.keys(group.players).filter( id => group.players[id].name == chat.from )[0]];
                    var team = player && player.team+1 ? " team-"+player.team : "";

                    player_name = $("<span></span>").addClass("player-name" + team).text(chat.from + ": ");
                }

                var chat_message = $("<span></span>").text(chat.message).addClass("chat-message");
                $("<div></div>").addClass("chat-line").append(timestamp).append(player_name).append(chat_message).appendTo(chat_log);
            }

            chat_log.scrollTop(chat_log.get(0).scrollHeight);
        };

        // Find the correct styleSheet
        for (var styleSheet of document.styleSheets) if (styleSheet.href.includes('/style.css')) break;

        // Add a rule to the sheet for the timestamp
        styleSheet.insertRule(".group .chat-log .timestamp { margin-right: 5px; color: Yellow; }");
        styleSheet.insertRule(".group .chat-log .player-name { color: #4c4c4c }");          // Gray
        styleSheet.insertRule(".group .chat-log .player-name.team-0 { color: #8BC34A; }");  // Green
        styleSheet.insertRule(".group .chat-log .player-name.team-1 { color: #D32F2F; }");  // Red
        styleSheet.insertRule(".group .chat-log .player-name.team-2 { color: #1976D2; }");  // Blue
        styleSheet.insertRule(".group .chat-log .player-name.team-3 { color: #e0e0e0; }");  // White


        // Split long messages, so that you can send those too
        // Also save all sent messages

        var sent = [], hist = -1, curr = "";

        $('.js-chat-input').off('keydown');  // Remove old handler

        document.getElementsByClassName('js-chat-input')[0].onkeydown = function(key){
            if (key.which == 13) {  // ENTER
                sent.unshift(this.value);
                hist = -1;

                if (this.value.length <= 120) group.socket.emit("chat", this.value);
                else {
                    var cut, chats = [ this.value.slice( 0, 120 ) ];
                    while ((cut = this.value.slice( chats.length*119+1 ))) {
                        chats.push( '⋯' + cut.slice(0,119) );
                    }

                    for (var c of chats) group.socket.emit("chat", c);
                }
                this.value = "";
            }

            if (key.which == 38) { // ARROW-UP
                if (hist == -1) curr = this.value;
                if (hist < sent.length-1) {
                    this.value = sent[ ++hist ];
                    key.preventDefault();   // Prevent the caret/cursor to jump to the start
                }
            }
            if (key.which == 40) { // ARROW-DOWN
                if (hist > -1) {
                    this.value = sent[ --hist ] || curr;
                    key.preventDefault();   // Prevent the caret to jump to the end
                }
            }
        };

        // Group description
        document.getElementsByClassName('js-chat-input')[0].placeholder = 'Send a message';
        $('<div class="chat chat-input" style="margin-top:20px"><textarea id="group-description" maxlength=100 placeholder="Group description (also sent to those without the script)" type="text" style="border-top:none;background:#212121;width:100%;border:none;padding:5px 10px;resize:vertical">').appendTo(document.getElementById('group-chat').parentNode);

        // Keep track of all interesting variables.
        // TagPro does this too, but it's hidden :(
        // Thats why we do this ourselfs too :)

        var group = tagpro.group = Object.assign(tagpro.group, {
            self:            null,
            players:         {},
            privateGame:     $(".group.container").hasClass("js-private-game"),
            privateGroup:    false,
            currentGamePort: null,
            chat:            [],
            selfAssignment:  false,
            settings:        {},
            maxPlayers:      0,
            maxSpectators:   0,
        });

        var socket = group.socket;

        socket.on('chat', function(chat) {
            group.chat.push(chat);
        });

        socket.on('port', function(port) {
            group.currentGamePort = port;
        });

        socket.on('member', function(member) {
            var description;
            if (!group.players[member.id]  &&  (description = document.getElementById("group-description").value)) {
                group.socket.emit('chat', "[GroPro:description]"+description);
            }
            group.players[member.id] = member;
            if (group.self) group.self = group.players[group.self.id];
        });

        socket.on('removed', function(removed) {
            delete group.players[removed.id];
        });

        socket.on('full', function() {
            alert('GroPro: This group is full :(');
        });

        socket.on('banned', function() {
            alert('GroPro: You got banned :(');
        });

        socket.on('you', function(you) {
            group.self = group.players[you];
        });

        socket.on('private', function(private){
            group.privateGame = private.isPrivate;
            group.maxSpectators = private.maxSpectators;
            group.maxPlayers = private.maxPlayers;
            group.selfAssignment = private.selfAssignment;
            group.noScript = private.noScript;
            group.respawnWarnings = private.respawnWarnings;
        });

        socket.on('setting', function(setting) {
            group.settings[setting.name] = setting.value;
        });

        socket.on('publicGroup', function(publicGroup) {
            group.public = publicGroup;
        });
    });

}

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

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

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


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