// ==UserScript== // @name generals.io Custom功能增强/聊天记忆 // @version 2024.7.30.2 // @description generals.io custom chat enhance and history // @author vasi 2 // @match https://generals.io/games/* // @icon https://www.google.com/s2/favicons?sz=64&domain=generals.io // @grant none // @license MIT // @namespace https://greasyfork.org/users/1340112 // @require https://code.jquery.com/jquery-3.7.1.min.js // @downloadURL https://update.greasyfork.icu/scripts/536281/generalsio%20Custom%E5%8A%9F%E8%83%BD%E5%A2%9E%E5%BC%BA%E8%81%8A%E5%A4%A9%E8%AE%B0%E5%BF%86.user.js // @updateURL https://update.greasyfork.icu/scripts/536281/generalsio%20Custom%E5%8A%9F%E8%83%BD%E5%A2%9E%E5%BC%BA%E8%81%8A%E5%A4%A9%E8%AE%B0%E5%BF%86.meta.js // ==/UserScript== (function () { "use strict"; function main() { window.onload = function () { if (localStorage.getItem("scriptSetting") == null) { localStorage.setItem( "scriptSetting", `{ "visibility": true,"displayTools":false,"lockChat":false }` ); } let gameName = window.location.href.split("s/")[1]; let prevStorage = []; $("body").append(``); $("body").append(` `); $("body").append(`

工具箱

加入时发送
启动
自动欢迎/OFF
自动告别/OFF
注:使用*user*指代加入/退出玩家,*room*指代该房间号
屏蔽玩家发言
添加
删除
block/OFF
`); $(".toolsButton").val(0); let dict = { 0: false, 1: true }; let dictT = { true: "block", false: "none" }; let blockedUser = []; function toggleButton( ele, funcOn, funcOff, textOn, textOff, colorOn, colorOff ) { ele.val(1 - ele.val()); if (dict[ele.val()]) { funcOn(); ele.css("background-color", colorOn); ele.html(textOn); } else { funcOff(); ele.css("background-color", colorOff); ele.html(textOff); } } let hello = (data) => { if ( data.split(" joined the custom game")[0] == $("#helloInput1").val() ) { socket.emit( "chat_message", "chat_custom_queue_" + gameName, $("#helloInput2").val(), "" ); } }; function replaceMsg(str, User, Room) { return str.split("*user*").join(User).split("*room*").join(Room); } let autohello = (data) => { if (data.indexOf(" joined the custom game") != -1) { socket.emit( "chat_message", "chat_custom_queue_" + gameName, replaceMsg( $("#autohelloInput").val(), data.split(" joined the custom game")[0], gameName ), "" ); } }; let autogoodbye = (data) => { if (data.indexOf(" left the custom game") != -1) { socket.emit( "chat_message", "chat_custom_queue_" + gameName, replaceMsg( $("#autogoodbyeInput").val(), data.split(" left the custom game")[0], gameName ), "" ); } }; let blockUser = (a, data) => { blockedUser.forEach((user) => { if (data.username == user) { $(".chat-message").eq(-1).addClass("blockedMsg"); } }); }; $("#helloButton").click(() => { toggleButton( $("#helloButton"), () => { socket.on("notify", hello); $("#helloInput1").attr("disabled", true); $("#helloInput2").attr("disabled", true); }, () => { socket.off("notify", hello); $("#helloInput1").attr("disabled", false); $("#helloInput2").attr("disabled", false); }, "终止", "启动", "#c62828", "green" ); }); $("#autohello").click(() => { toggleButton( $("#autohello"), () => { socket.on("notify", autohello); $("#autohelloInput").attr("disabled", true); $("#autohelloInput").attr("disabled", true); }, () => { socket.off("notify", autohello); $("#autohelloInput").attr("disabled", false); $("#autohelloInput").attr("disabled", false); }, "自动欢迎/ON", "自动欢迎/OFF", "green", "#c62828" ); }); $("#autogoodbye").click(() => { toggleButton( $("#autogoodbye"), () => { socket.on("notify", autogoodbye); $("#autogoodbyeInput").attr("disabled", true); $("#autogoodbyeInput").attr("disabled", true); }, () => { socket.off("notify", autogoodbye); $("#autogoodbyeInput").attr("disabled", false); $("#autogoodbyeInput").attr("disabled", false); }, "自动告别/ON", "自动告别/OFF", "green", "#c62828" ); }); $("#blockUser").click(() => { toggleButton( $("#blockUser"), () => { socket.on("chat_message", blockUser); }, () => { socket.off("chat_message", blockUser); }, "block/ON", "block/OFF", "green", "#c62828" ); }); $("#addBlockUser").click(() => { if (blockedUser.indexOf($("#blockUserInput").val()) == -1) { blockedUser.push($("#blockUserInput").val()); } else { alert("该用户名已存在"); } $("#blockedUserList").text(`已屏蔽玩家:${blockedUser.join(",")}.`); }); $("#delBlockUser").click(() => { if (blockedUser.indexOf($("#blockUserInput").val()) != -1) { blockedUser.splice( blockedUser.indexOf($("#blockUserInput").val()), 1 ); } else { alert("该用户名不存在"); } if (blockedUser.length == 0) { $("#blockedUserList").text(``); } else { $("#blockedUserList").text(`已屏蔽玩家:${blockedUser.join(",")}.`); } }); function downloadHistory() { prevStorage = JSON.parse(localStorage.getItem(gameName)); for (let item in prevStorage) { if (prevStorage[item][1] == 0) { $(".chat-messages-container") .eq(0) .append( `

${prevStorage[item][0]}

` ); } else { $(".chat-messages-container") .eq(0) .append( `

${prevStorage[item][0]}

` ); } } $(".chat-message").eq(prevStorage.length).css({ display: "block", "border-bottom": "white solid 2px", "padding-bottom": "4px", }); } function getUsername(name) { const contentText = encodeURIComponent( name.contents().not(name.children()).text() ); return contentText !== "" ? contentText : name.children().eq(0).text(); } function renewLink() { let alist = $(".custom-queue-page-container").children(); for (let i = 2; i < alist.length; i++) { for (let j = 1; j < alist.eq(i).children().length; j++) { let name = alist.eq(i).children().eq(j).children().eq(-1); name.addClass("names"); let procName = getUsername(name); name.attr( "onclick", `window.open("https://generals.io/profiles/${procName}",'_blank')` ); name.attr("id", procName.replace(/ /g, "-")); } } } socket.on("queue_update", () => { renewLink(); setTimeout(() => { loadProfile(); }, 3000); }); function lockChat() { if ($(window).width() >= 1000) { $("#lockChatCSS").html(` .minimized{opacity:1 !important} .chat-messages-container.minimized{ max-height: 240px !important; width: 400px !important; } `); } else { $("#lockChatCSS").html(` .minimized{opacity:1 !important} .chat-messages-container.minimized{ max-height: 240px !important; width: 320px !important; }`); } } function lockChatOn() { lockChat(); $(window).on("resize", lockChat); } function lockChatOff() { $(window).off("resize", lockChat); $("#lockChatCSS").html(``); } function generateButton() { $(".custom-queue-page-container").css("overflow-x", "hidden"); $(".chat-messages-container") .parent() .append( `
设置
清空历史
锁定聊天框
下载聊天记录
显示/隐藏系统消息
工具箱
` ); $("#dump").click(() => { $(".chat-messages-container").html("") localStorage.setItem(gameName, "[]"); }) $("#lockChat").click(() => { toggleButton( $("#lockChat"), () => { lockChatOn(); let setting = JSON.parse(localStorage.getItem("scriptSetting")); setting.lockChat = !setting.lockChat; localStorage.setItem("scriptSetting", JSON.stringify(setting)); }, () => { lockChatOff(); let setting = JSON.parse(localStorage.getItem("scriptSetting")); setting.lockChat = !setting.lockChat; localStorage.setItem("scriptSetting", JSON.stringify(setting)); }, `锁定聊天框`, `锁定聊天框`, "", "" ); }); $("#save").click(() => { $(".chat-messages-container").html(""); prevStorage = JSON.parse(localStorage.getItem(gameName)); let text = prevStorage .map((item) => { return item[0]; }) .join("\n"); let blob = new Blob([text], { type: "text/plain" }); let url = URL.createObjectURL(blob); let a = document.createElement("a"); a.href = url; a.download = "chatHistory.txt"; document.body.appendChild(a); a.click(); document.body.removeChild(a); URL.revokeObjectURL(url); downloadHistory(); }); $("#visibility").click(() => { $(".chat-messages-container").html(""); downloadHistory(); let setting = JSON.parse(localStorage.getItem("scriptSetting")); setting.visibility = !setting.visibility; changeHistoryVisibility(setting.visibility); localStorage.setItem("scriptSetting", JSON.stringify(setting)); }); $("#tools").click(() => { let setting = JSON.parse(localStorage.getItem("scriptSetting")); setting.displayTools = !setting.displayTools; $("#functionPanel").css("display", dictT[setting.displayTools]); localStorage.setItem("scriptSetting", JSON.stringify(setting)); }); changeHistoryVisibility( JSON.parse(localStorage.getItem("scriptSetting")).visibility ); } socket.on("game_over", () => { generateButton(); downloadHistory(); $("#functionPanel").css("display", "block"); }); $("#functionPanel").css( "display", dictT[JSON.parse(localStorage.getItem("scriptSetting")).displayTools] ); if (localStorage.getItem(gameName) == null) { localStorage.setItem(gameName, "[]"); } socket.on("game_start", () => { $("#functionPanel").css("display", "none"); }); socket.on("chat_message", (a, data) => { console.log(data) prevStorage = JSON.parse(localStorage.getItem(gameName)); if (data.username != undefined) { prevStorage.push([`${data.username}: ${data.text}`, 1]); } else if(data.text.indexOf("join")==-1){ prevStorage.push([`${data.text}`, 0]); } if ( data.text == `${localStorage.getItem( "GIO_CACHED_USERNAME" )} joined the custom lobby.` ) { generateButton(); downloadHistory(); if (JSON.parse(localStorage.getItem("scriptSetting")).lockChat) { lockChatOn(); $("#lockChatSvg").html( `` ); } else { lockChatOff(); $("#lockChatSvg").html( `` ); } //setTimeout(loadProfile, 1000) } localStorage.setItem(gameName, JSON.stringify(prevStorage)); }); function changeHistoryVisibility(visibility) { if (visibility) { $(".history-message").css("display", "block"); $("#visibility").css("background-color", "green"); $("#slash").css("--slash-width", "0px"); $("#visibility").css("--vis-hover-color", "#08a408"); } else { $(".history-message").css("display", "none"); $("#visibility").css("background-color", "red"); $("#slash").css("--slash-width", "35px"); $("#visibility").css("--vis-hover-color", "#fa6363"); } } function loadProfile() { $(".stickyNode").remove(); $(".names").each((i) => { let ele = $(".names").eq(i); const profileID = `${btoa(ele.attr("id") || "") .replace(/\+/g, "-") .replace(/\//g, "_") .replace(/=+$/, "")}-profile`; fetch( `https://generals.io/api/starsAndRanks?u=${getUsername( ele )}&client=true` ) .then((data) => data.json()) .then((json) => { $(`#${profileID}`).html(``); ele.append( `
` ); let k = 0; if (json.stars.ffa != undefined && json.stars.ffa != null) { $(`#${profileID}`).append(`
FFA
⭐${Math.round(json.stars.ffa * 10) / 10 }
#${json.ranks.ffa}
`); k = 1; } if (json.stars.duel != undefined && json.stars.duel != null) { $(`#${profileID}`).append(`
1v1
⭐${Math.round(json.stars.duel * 10) / 10 }
#${json.ranks.duel}
`); k = 1; } if (json.stars["2v2"] != undefined && json.stars["2v2"] != null) { $(`#${profileID}`).append(`
2v2
⭐${Math.round(json.stars["2v2"] * 10) / 10 }
#${json.ranks["2v2"]}
`); k = 1; } if (k == 0) { $(`#${profileID}`).append(`

无天梯信息

`); } $(`#${profileID}`).css( "margin-left", `${$(`#${profileID}`).parent().parent().width() + 20}px` ); ele.on("mouseover", () => $(`#${profileID}`).css("display", "block") ); ele.on("mouseout", () => $(`#${profileID}`).css("display", "none") ); }); }); } }; } main(); })();