您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
Unaffiliated extension for the Xat HTML5 Chatbox. RIP Xat Edition.
// ==UserScript== // @name Xat Plus // @namespace http://sulptax.io/ // @version 0.4.7 // @description Unaffiliated extension for the Xat HTML5 Chatbox. RIP Xat Edition. // @author sulptax // @match https://xat.com/content/web/*/box/www/classic.html // @require http://code.jquery.com/jquery-3.5.1.js // @require https://cdnjs.cloudflare.com/ajax/libs/crypto-js/4.0.0/crypto-js.min.js // @grant unsafeWindow // ==/UserScript== const secret = 'sulptax'; function xp_encrypt(str) { return CryptoJS.enc.Base64.stringify(CryptoJS.enc.Utf8.parse(str)); } function xp_decrypt(str) { return CryptoJS.enc.Base64.parse(str).toString(CryptoJS.enc.Utf8); } function xp_aes_encrypt(str) { return CryptoJS.AES.encrypt(str, secret).toString(); } function xp_aes_decrypt(str) { var bytes = CryptoJS.AES.decrypt(str, secret); return bytes.toString(CryptoJS.enc.Utf8); } // Allow functions below to be used in the console, not like these are used for storing important data anyways. // You must be at the chat directly for these to work: // https://xat.com/content/web/R00022/box/www/classic.html unsafeWindow.xp_encrypt = xp_encrypt; unsafeWindow.xp_decrypt = xp_decrypt; var users = { "585435788": { "type": "color", // color, pawn, pawn2 "reghide": true, // like reghide power "v": "000001", // the color value }, "400444434": { "type": "color", "v": "y", "effective": true, // overwrites the message pawn as well if true, This is the case by default. "persistent": true // keep the pawn color regardless of the pawn used in the list }, "287773358": { // Shadez bot is here for demonstration purposes, because it's everywhere. "type": "pawn2", // pawn2 changes the pawn type "v": "p1bot" // examples: p1bot, p1emerald, p1pwn }, "981989": { "type": "pawn2", "v": "p1emerald#y" // can also use color codes in pawn2 value }, "30000013": { "type":"pawn2", "v": "p1emerald#r#r" } } var effectiveChanges = {} const observer = new MutationObserver((mutationList, observer) => { mutationList.forEach((mutation) => { if (mutation.type === "childList") { if (mutation.target.id == "idvisitors" || mutation.target.id == "idfriends" || mutation.target.id == "messages") { mutation.addedNodes.forEach((node) => { Object.keys(users).forEach(function(user) { var color = ""; var holder = $(node).find(".holder:first"); var res = holder.attr("data-sm"); if ($(node).attr("data-user") == user) { var str = res if (res.split("#")[1] != "ff0000" && res.split("#")[1] != "ff0000)_20") { if (users[$(node).attr("data-user")]['type'] == "color") { color = users[$(node).attr("data-user")]['v'] res = str.split("#"); res[1] = color; res = res.join("#"); res = res + ")_20" } if (users[$(node).attr("data-user")]['type'] == "pawn") { res = users[$(node).attr("data-user")]['v'] } var res3 = ""; if (users[$(node).attr("data-user")]['type'] == "pawn2") { var res2 = str.split("#"); res2[0] = res2[0].split("(")[0] + "(" + users[$(node).attr("data-user")]['v']; res = res2.join("#") res3 = res.split("#", 2).join("#") + ")_20"; } else { res3 = res; } if (Object.keys(users[$(node).attr("data-user")]).includes("reghide")) { $(node).find(".relIcon2").hide(); } var filters = ""; if (Object.keys(users[$(node).attr("data-user")]).includes("glow")) { if(isColor(users[$(node).attr("data-user")]['glow'])) { filters = filters + "drop-shadow(0px 0px 0.2rem " + users[$(node).attr("data-user")]['glow'] + ") " } } if(filters) { holder.css("filter", filters); } if (!(Object.keys(users[$(node).attr("data-user")]).includes("effective") && !(users[$(node).attr("data-user")]['effective'] == true))) { effectiveChanges[$(node).find(".message").text()] = res3 } else if (color && (Object.keys(users[$(node).attr("data-user")]).includes("persistent") && users[$(node).attr("data-user")]['persistent'])) { effectiveChanges[$(node).find(".message").text()] = "s_(p1pwn#" + color + ")_20" } holder.attr("data-sm", res) } } }); }); } } }); }); messages.addMessageP = messages.addMessage messages.addMessage = function(t) { messages.addMessageP(t); } visitors.addVisitorP = visitors.addVisitor visitors.addVisitor = function(e, l) { visitors.addVisitorP(e, l); var e_parsed = JSON.parse(e); if (Object.keys(e_parsed).includes("image")) { e_parsed['image'].split("#").forEach((im) => { if (true) { // im.toString(CryptoJS.enc.Utf8) try { var checkForPawn = xp_decrypt(im) if (checkForPawn && (checkForPawn.startsWith('{') && checkForPawn.endsWith('}'))) { // example JSON // {"type":"pawn2", "v":"p1emerald#y#hat3#w1i0ic#y", "reghide": true} // {"type":"pawn2", "v":"p1emerald#y#hat3#w1i0ic#y", "reghide": true, "glow":"red"} console.log("JSON PAWN DETECTED IN avatar/image:", checkForPawn); try { users[e_parsed['id']] = JSON.parse(checkForPawn); } catch (e) { console.log("Error parsing pawn code"); } } else if (checkForPawn && checkForPawn.substring(0, 2) == "p1") { console.log("NORMAL PAWN DETECTED IN avatar/image:", checkForPawn); users[e_parsed['id']] = { "type": "pawn2", "v": checkForPawn } } } catch(e) { // decrypt error? } } }) } } const observer2 = new MutationObserver((mutationList, observer) => { mutationList.forEach((mutation) => { if (mutation.type === "childList") { mutation.addedNodes.forEach((node) => { if (Object.keys(effectiveChanges).includes($(node).find(".messagesName").find(".message").text())) { $(node).find(".messagesName").find(".holder:first").attr("data-sm", effectiveChanges[$(node).find(".messagesName").find(".message").text()]) } }); } }); }); observer.observe(document.querySelector("#visitorsContainer"), { childList: true, subtree: true }); observer2.observe(document.querySelector("#messagesContainer"), { childList: true, subtree: true }); function isColor(color) { var div = $("<div>"); div.css("border", "1px solid " + color); return (div.css("border-color") != "") }