CGChat

The CodinGame web-chat without CodinGame.

目前為 2020-12-28 提交的版本,檢視 最新版本

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

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

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

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

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

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

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

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

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

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

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

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

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

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

// ==UserScript==
// @name        CGChat
// @namespace   BlaiseEbuth
// @match       https://www.codingame.com/*
// @grant       none
// @version     1.2.0
// @author      BlaiseEbuth
// @description The CodinGame web-chat without CodinGame.
// @icon https://i.imgur.com/E39sADi.png
// ==/UserScript==

/*
CGChat is an externalization as a standalone window of the CodinGame's web chat.
Copyright (C) 2020  BlaiseEbuth
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program.  If not, see <https://www.gnu.org/licenses/>.
*/

'use strict'; // Be strict !

// A map to store the clicked links.
var openedLinks = {};

// A function that set "CGChat" as window's title.
function setTitle()
{
    // The window's title is defined by the page's <title> tag.
    var title = document.getElementsByTagName("title");

    if(title.length == 1) // If the page is loaded.
    {
        // We change the title.
        title[0].innerHTML = "CGChat";
    }
}

// A function that clean the connexion page.
function signin()
{
    // Select all elements that are not related to the connexion process:
    var nav = document.getElementById("navigation"); // The navigation bar.
    var cookies = document.getElementsByClassName("cg-cookies-banner"); // The cookies notification.
    var footer = document.getElementsByClassName("cg-login-form_footer"); // The login form footer that allow to create a new account.
    
    // Hide all of this uselles stuff.
    if(nav != null)nav.style.display = "none";
    if(cookies.length == 1)cookies[0].style.display = "none";
    if(footer.length == 1)footer[0].style.display = "none";
}

// The function that manage all the chat-related actions.
function chat()
{
    // If we are in the application and jquerry is not loaded yet.
    if(window.isNwjs && document.getElementById("jquery") == null)
    {
        // We get the page's <head> element.
        var head = document.getElementsByTagName("head");

        if(head.length == 1) // If head is defined.
        {
            // We create a <script> element.
            var jquery = document.createElement("script");
            // With the "jquerry" id.
            jquery.id = "jquery";
            jquery.type = "text/javascript";
            jquery.src = "https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js";
            // And we add it to the page's <head>.
            head[0].appendChild(jquery);
        }
    }

    // We select the navigation bar and the site's content.
    var leftCol = document.getElementsByClassName("left-column");
    var nav = document.getElementById("navigation");

    // If they exist we delete them.
    if(leftCol.length == 1)leftCol[0].style.display = "none"; 
    if(nav != null)nav.style.display = "none";
    
    // We select the chat's containers.
    var wrapper = document.getElementsByClassName("chat-wrapper");
    var chat = document.getElementById("chat");

    // If they exist, we make them occupy the full window.
    if(wrapper.length == 1)wrapper[0].style.cssText = "width:100% !important"; 
    if(chat != null)chat.style.cssText = "display:flex !important";
    
    // We check if the chat is minimized.
    var small = document.getElementsByClassName("small-chat");

    // If yes, we maximize it.
    if(small.length == 1)small[0].click();

    // We select the chat itself.
    var chatClass = document.getElementsByClassName("chat");
    // And some of it's elements which need to be removed:
    var discord = document.getElementsByTagName("cg-discord-disclaimer"); // The discord disclaimer.
    var hideWrapper = document.getElementsByClassName("hide-wrapper"); // The "Hide/Show" button.
    var help = document.getElementsByClassName("help-center"); // The help center.

    // We make the chat occupy 100% of its container.
    if(chatClass.length == 1)chatClass[0].style.width = "100%";
    // And we delete the useless stuff.
    if(discord.length == 1)discord[0].style.display = "none";
    if(hideWrapper.length == 1)hideWrapper[0].style.display = "none";
    if(help.length == 1)help[0].style.display = "none";

    // We get the settings popup.
    var settings = document.getElementsByClassName("settings-popup");

    if(settings.length == 1) // If it exist.
    {
        for(var i = 0; i < 3; i++)
        {
             // We delete the 3 first elements to only keep the theme settings.
            settings[0].children[i].style.display = "none";
        }
    }
    
    // If the refresh button does not exist yet.
    if(document.getElementById("refreshButton") == null)
    {   
        // We create it.
        var refreshButton = document.createElement("span");
        refreshButton.id = "refreshButton";
        refreshButton.style.cssText = 
          "display : inline-block;\
          width : 15px;\
          height : 15px;\
          margin-left : 8px;\
          background-image : url('https://i.imgur.com/rDqWLLQ.png');\
          background-size : contain;";
      
        // As well as a wrapper, for display purposes.
        var buttonWrapper = document.createElement("span");
        buttonWrapper.classList.add("button-wrapper");
        buttonWrapper.setAttribute("onClick", "window.location.reload(true)");
        buttonWrapper.title = "Reload";
      
        // We get the chat's settings bar.
        var settingsBar = document.getElementsByClassName("settings-bar");
      
        // And we add the button and its wrapper to it.
        buttonWrapper.appendChild(refreshButton);
        settingsBar[0].appendChild(buttonWrapper);
    }

    // We get the messages container.
    var messages = document.getElementById("messages");
    
    //TODO: Use this variable.
    
    if(document.getElementById("messages") != null) // If it is defined.
    {
        // We make the messages occupy 100% of their container.
        messages.style.width = "100%";
        
        if(window.isNwjs) // If in the application.
        {
          // We select all the links in the messages.
          var links = messages.getElementsByTagName("a");

          if(links.length > 0) // If there's at least one link.
          {
              // We set a click event on each of those links.
              $('a[target=_blank]').on('click', function()
              {
                  // If the link is not in the openedLinks map.
                  if(!(this.href in openedLinks))
                  {
                      // We open it in a browser.
                      require('nw.gui').Shell.openExternal(this.href);
                      // And we add the URL in the map with a value of 100.
                      openedLinks[this.href] = 100;
                  }
                  return false;
              });
          }
        }
    }
}

// The main() function.
var main = function()
{
    // If we don't know if we are in the application or the browser extension.
    if(window.isNwjs == null)
    {
        try
        {
            // We call a NWJS specific knack and if it is defined we set the 'isNwjs' variable to true.
            window.isNwjs = (typeof require('nw.gui') !== "undefined");
        }
        catch(e)
        {
            // If not, we set the 'isNwjs' variable to false;
            window.isNwjs = false;
        }
    }
  
    setTitle(); // Change the window's title.

    for(var l in openedLinks) // For each URL in the map.
    {
        openedLinks[l]--; // We decrease its countdown.

        if(openedLinks[l] == 0) // If the countdown reach 0.
        {
            // We delete the URL from the map.
            delete openedLinks[l];
        }
    }

    // Get the current URI.
    var path = window.location.pathname;

    if(path  == "/start") // If not logged in.
    {
        // Go to the connexion page.
        window.location.replace("/signin");
    }
    else if(path == "/signin") // If on the connexion page.
    {
        // Call the signin() function.
        signin();
    }
    else // In other cases.
    {
        // Lets chat !
        chat();
    }
}

// Repeat the main() function every 100ms.
setInterval(main, 100);