您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
A TinyChat Launcher improving moderation, enabling bots, and sharing themes in a compact userscript.
// ==UserScript== // @name SUPER Thin Core // @version 0.26.13 // @description A TinyChat Launcher improving moderation, enabling bots, and sharing themes in a compact userscript. // @author thebanon // @license Copyright (C) thebanon // @icon https://i.imgur.com/_______.png // @match https://tinychat.com/room/* // @match https://tinychat.com/* // @exclude https://tinychat.com/settings/*a // @exclude https://tinychat.com/subscription/* // @exclude https://tinychat.com/promote/* // @exclude https://tinychat.com/coins/* // @exclude https://tinychat.com/gifts* // @grant none // @run-at document-start // @namespace https://greasyfork.org/users/1236617 // ==/UserScript== //WSS window.WSS = {}; window.WSS.con = {}; window.WSS.con.open = ()=>{ if (window.Proxy === undefined) return; var handler = { set: function(Target, prop, value) { if (prop == "onmessage") { var oldMessage = value; value = function(event) { WSS.msg.recv(JSON.parse(event.data), Target); oldMessage(event); } ; } return (Target[prop] = value); }, get: function(Target, prop) { var value = Target[prop]; if (prop == "send") { value = function(event) { WSS.msg[prop](JSON.parse(event), Target); Target.send(event); } ; } else if (typeof value == 'function') { value = value.bind(Target); } return value; } }; var WebSocketProxy = new window.Proxy(window.WebSocket,{ construct: function(Target, args) { APP.SocketTarget = new Target(args[0]); console.log("SOCKET::CONNECTING", args[0]); return new window.Proxy(APP.SocketTarget,handler); } }); window.WebSocket = WebSocketProxy; } window.WSS.msg = {}; window.WSS.msg.recv = function({tc}) { if (typeof API.server.recv[arguments[0].tc] == "function") { console.log(("SERVER::" + arguments[0].tc.toUpperCase()), arguments[0]); API.server.recv[arguments[0].tc](arguments[0]); addCSS(); } } window.WSS.msg.send = function({tc}) { if (typeof API.server.send[arguments[0].tc] == "function") { console.log(("CLIENT::" + arguments[0].tc.toUpperCase()), arguments[0]); API.server.send[arguments[0].tc](arguments[0]); addCSS(); } } window.WSS.msg.req = ({tc})=>{ if (arguments[1] === undefined) arguments[1] = "Open Request"; console.log(("CLIENT::SEND::" + arguments[0].toUpperCase()), arguments[1]); } //APP window.APP = {} window.APP.config = {} window.APP.config.json = null; window.APP.config.Message = [[]] window.APP.config.version = { Major: 0, Minor: 0, Patch: 1 } window.APP.config.theme = "modern"; window.APP.route = {}; window.APP.route.r = ()=>{ return window.location.pathname.split('/').filter(o=>o.length > 0); } window.APP.view = {} window.APP.view.room = async(params)=>{ //ELEMENTS var obj = {} obj.body = document.body; obj.main = document.querySelector("tinychat-webrtc-app").shadowRoot; obj.title = obj.main.querySelector("tc-title").shadowRoot; obj.chatlog = obj.main.querySelector("tc-chatlog").shadowRoot; obj.textarea = obj.chatlog.querySelector("#textarea"); obj.videolist = obj.main.querySelector("tc-videolist").shadowRoot; obj.videoitems = obj.videolist.querySelectorAll("tc-video-item"); obj.sidemenu = obj.main.querySelector("tc-sidemenu").shadowRoot; obj.userlist = obj.sidemenu.querySelector("tc-userlist").shadowRoot; obj.moderationlist = obj.sidemenu.querySelector("tc-video-moderation").shadowRoot; obj.chatlist = obj.sidemenu.querySelector("tc-chatlist").shadowRoot; obj.usercontext = obj.userlist.querySelector("tc-user-contextmenu").shadowRoot; console.log("TinyScript::APP.VIEW.ROOM", { params, obj }); window.DOM = obj; //STYLES window.APP.css = {}; Object.keys(obj).forEach(function(name) { window.APP.css[name] = { element: obj[name], stylesheet: null } }); console.log(125, "TinyScript::APP.VIEW.ROOM", { app: window.app }); //INSERT document.body.querySelector("style").insertAdjacentHTML("beforeend", APP.css.main); var local = await window.is.local(); Object.keys(obj).forEach(async function(name) { var fullname = "thebanon/tinyscript"; var user = fullname.split("/")[0]; var repo = fullname.split("/")[1]; var paths = fullname.split("/").splice(2, fullname.split("/").length - 1); var dir = paths.length > 0 ? paths.join("/") : ""; var host = "https://" + user + ".github.io"; var theme = window.APP.config.theme; var path = "/" + repo + "/files/css" + (theme ? "/" + theme : ""); var file = "/" + name + ".css"; var href = local ? "https://tinychat.local/files/css/" + theme + file : host + path + file; try { var css = await request(href, { cache: "reload", mode: "cors" }); console.log(151, 'insert.css', { css }); var res = await request(href, { cache: "reload", mode: "cors" }); console.log(151, 'insert.css', { css, name, res, len: res.length }); if (res.length > 0) { console.log(152, { name, res, len: res.length }); if (name === "body") { var style = document.createElement("link"); //var backgroundColor = "#ffff69"; var backgroundColor = "#c0c0c0"; style.id = "style-body"; //style.innerHTML = res; style.setAttribute("href", href); style.setAttribute("rel", "stylesheet"); document.body.removeAttribute("data-mode"); //document.body.style.backgroundColor = backgroundColor; var el = document.body.querySelector("#style-body"); el ? el.replaceWith(style) : document.body.insertAdjacentHTML('afterbegin', style.outerHTML); var el = document.getElementById(style.id); el.stylesheet = res; } else if (name === "videoitems") { console.log(154, { name, res, len: res.length, obj, vid: obj.videolist }); } else { var style = document.createElement("link"); style.setAttribute("href", href); style.setAttribute("rel", "stylesheet"); //style.innerHTML = res; var el = window.APP.css[name].element.querySelector("style"); el.insertAdjacentHTML("afterend", style.outerHTML); el.stylesheet = res; } } } catch (e) { console.log(151, { e }); } }); var obj = { main: document.querySelector("tinychat-webrtc-app").shadowRoot } var MainElement = obj.main; console.log(185, MainElement.querySelector("tc-chatlog").shadowRoot); new MutationObserver(function(elem) { MainElement.querySelector("#modal").shadowRoot.querySelector("#modal-window").classList.remove("modal-show"); if (MainElement.querySelector("#fatal")) Remove(MainElement.querySelector("#fatal")); if (MainElement.querySelector("#modal").hasChildNodes()) MainElement.querySelector("#modal").shadowRoot.querySelector("#modal-window").classList.add("modal-show"); } ).observe(MainElement.querySelector("#modal"), { childList: true }); document.body.onclick = ()=>{ var set = MainElement.querySelector("#modal #settings"); if (set) { var settings = set.shadowRoot.querySelector("#modal-content-settings"); console.log(197, settings, settings.getAttribute("data-mode")); if (settings.getAttribute("data-mode") === "dark") { document.body.removeAttribute("data-mode", "dark"); } else { document.body.setAttribute("data-mode", "dark"); } } } } //BOT window.BOT = {}; window.BOT.cmd = {} window.BOT.cmd.ver = ()=>{ console.log("BOT.cmd.ver", window.Version); } window.BOT.sys = {} window.BOT.sys.prompt = function() { var UserCommand = arguments[0].match(/^!([a-z0-9]*)(?: ?)(.*)/i); if (UserCommand) { if (typeof BOT.cmd[UserCommand[1].toLowerCase()] == "function") { console.log("COMMAND::" + ((arguments[1]) ? "PM" : "MAIN"), UserCommand[1] + ":" + UserCommand[2]); BOT.cmd[UserCommand[1].toLowerCase()](UserCommand[2], arguments[1]); } } } //API window.API = {}; window.API.queue = {}; window.API.queue.add = function() { APP.SendQueue.push(arguments[0]); API.queue.run(); } window.API.queue.run = function() { if (APP.SendQueue !== undefined && APP.SendQueue.length > 0) { setTimeout(function() { var temp = new Date(); var OffsetTime = temp - APP.LastMessage; if (OffsetTime >= 1500) { APP.LastMessage = new Date(); APP.SocketTarget.send(APP.SendQueue[0]); APP.SendQueue.shift(); } API.queue.run(); }, 1600); } } window.API.server = {}; window.API.server.recv = { joined: function() { APP.SocketConnected = true; }, Users: function() { console.log(arguments[0]); }, join: function() { console.log(arguments[0]); 3 }, sysmsg: function() { console.log(arguments[0]); }, nick: function() { console.log(arguments[0]); }, stream_connected: async function() { console.log(232, 'stream_connected', arguments, arguments[0]); var id = arguments[0].handle; var fullname = "thebanon/tinyscript"; var name = "videoitems"; var user = fullname.split("/")[0]; var repo = fullname.split("/")[1]; var paths = fullname.split("/").splice(2, fullname.split("/").length - 1); var host = "https://" + user + ".github.io"; var theme = window.APP.config.theme; var path = "/" + repo + "/files/css" + (theme ? "/" + theme : ""); var file = "/" + name + ".css"; var href = await is.local() ? "https://tinychat.local/files/css/" + theme + file : host + path + file; window.vcs ? null : window.vcs = await request(href, { cache: "reload" }); var cams = window.DOM.videolist.querySelectorAll("tc-video-item"); console.log(155, { DOM, cams, arr: Array.from(cams) }); Array.from(cams).forEach(function(elem) { var cam = elem.shadowRoot; var vid = cam.querySelector("video[data-video-id='" + id + "']"); console.log(157, { id, cam, vid, vcs }); if (vid) { var style = document.createElement("link"); //style.innerHTML = window.vcs; style.setAttribute("href", href); style.setAttribute("rel", "stylesheet"); cam.querySelector('style:has( + :not(style))').insertAdjacentHTML("afterend", style.outerHTML); //cam.querySelector('style:has( + :not(style))').previousElementSibling.remove(); window.APP.css[name].stylesheet = window.vcs; } }); }, stream_closed: function() { console.log(arguments[0]); }, publish: function() { console.log(arguments[0]); }, unpublish: function() { console.log(arguments[0]); }, ping: function() { window.TinychatApp.getInstance().defaultChatroom._chatlog.items = []; window.TinychatApp.getInstance().defaultChatroom.packetWorker.queue = {}; }, quit: function() { console.log(arguments[0]); }, msg: async function() { console.log(arguments[0]) }, pvtmsg: function() { console.log(arguments[0]); }, gift: function() { console.log(arguments[0]); }, }; window.API.server.send = { pvtmsg: function() { console.log(arguments[0]); }, msg: async function() { if (APP.ScriptInit) { console.log(arguments[0]) } }, ban: function() { console.log(arguments[0]); }, kick: function() { console.log(arguments[0]); }, stream_moder_close: function() { console.log(arguments[0]); } }; window.is = {}; window.is.local = async(json)=>{ try { console.log(397, window.APP.config.file); if(window.APP.config.file) { json = window.APP.config.file; console.log(400, window.APP.config); } else { var repository = await github.user.user();//"tinychat.local"; var obj = { owner: localStorage.user, repo: repository.login, resource: "config.json" }; console.log(408, obj); var contents = await github.raw.file(obj); json = JSON.parse(contents); window.APP.config.file = json; 0 < 1 ? console.log(499, 'github.repos.contents', window.APP.config, { contents, json }) : null; } var bool = Boolean(json.devMode); return bool; } catch(e) { console.log(420, e); } } (async function() { "use strict"; var fullname = "thebanon/tinyscript"; var theme = window.APP.config.theme; var user = fullname.split("/")[0]; var repo = fullname.split("/")[1]; var host = "https://" + user + ".github.io"; var path = "/" + repo + "/files/js"; var scripts = ["/firebase.app.js", "/firebase.auth.js", "/ochopussy.js", "/" + window.APP.config.theme + ".js"]; window.scriptsLoaded = []; var local = await window.is.local(); console.log(436, local); scripts.forEach(async(file)=>{ var href = local ? "https://tinychat.local/files/js" + file : host + path + file; console.log(413, 'sCSS', { local, href }); var script = document.createElement("script"); script.setAttribute("src", href); document.head.appendChild(script); document.head.lastElementChild.addEventListener('load', function(e) { console.log('Loaded: ' + file, { e }); window.scriptsLoaded.push(file) }); } ); if (window.firebase && firebase.apps.length > 0) { firebase.app().delete(); } console.log(280, "window.init"); var err_out = 0; APP.ScriptLoading = setInterval(function() { err_out++; var twa = document.querySelector("tinychat-webrtc-app"); if (twa) { if (twa.shadowRoot) { clearInterval(APP.ScriptLoading); APP.ScriptInit = true; APP.view.room() } } else { err_out++; } if (err_out == 50) { clearInterval(APP.ScriptLoading); clearInterval(APP.FullLoad); } }, 200); if (!document.URL.match(/^https:\/\/tinychat\.com\/(?:$|#)/i)) { console.log("WSS.hook", document.URL); new MutationObserver(function() { this.disconnect(); WSS.con.open(); } ).observe(document, { subtree: true, childList: true }); } APP.FullLoad = setInterval(async function() { if (APP.ScriptInit && APP.SocketConnected && window.scriptsLoaded.length === scripts.length && window.firebase && window.firebase.app && window.firebase.auth) { clearInterval(APP.FullLoad); localStorage.user ? document.body.setAttribute("uid", localStorage.user) : null; var config = { apiKey: "AIzaSyDMmPEKuKd6hKjue-W9DL3W_GXrPXIS_Y4", authDomain: "tiny-script.firebaseapp.com", projectId: "tiny-script", storageBucket: "tiny-script.appspot.com", messagingSenderId: "722058993902", appId: "1:722058993902:web:3a0be4c17845beedc953ff" }; console.log(424, config); firebase.initializeApp(config); console.log(424, config); 0 < 1 ? firebase.auth().onAuthStateChanged(async(user)=>{ console.log(469, 'firebase.auth', { user }); if (user) { window.user = user; var paths = window.location.pathname.split('/').filter(o=>o.length > 0); var path = paths.length === 1 ? paths[0] : null; var path = paths.length === 2 && paths[0] === "room" ? paths[1] : null; var repo = path; try { var local = await window.is.local(); console.log(516, { local, config: window.APP.config.file }); } catch (e) { try { console.log(487, { e, repo }); var contents = await github.user.repos(null, { body: JSON.stringify({ name: repository, private: true }), method: "POST" }); 0 < 1 ? console.log(494, 'github.user.repos', { contents }) : null; } catch (e) { var fullname = "thebanon/tinyscript"; var theme = window.APP.config.theme; var user = fullname.split("/")[0]; var repo = fullname.split("/")[1]; var host = "https://" + user + ".github.io"; var path = "/" + repository + "/files/js"; var file = "resolve.js"; console.log(517, 'Welcome to ' + path, e); var href = await is.local() ? "https://tinychat.local/files/js/" + file : host + path + file; console.log(413, 'sCSS', href); var resolving = 0 > 1; if(resolving) { var script = document.createElement("script"); script.setAttribute("src", href); document.head.appendChild(script); //script = document.lastElementChild; alert(542); script.addEventListener('load', function(e) { console.log('Loaded: ' + file, { e }); console.log(558, "Welcome to " + path); }) alert(551); } else { console.log(561, "Welcome to " + (paths[1] ? paths[1] : paths[0])); var script = document.createElement("script"); script.setAttribute("src", href); //document.head.appendChild(script); script = document.lastElementChild; try { var obj = { owner: localStorage.user, repo: "tinyscript.local", resource: repo + "/config.json" }; var data = { "content": { "devMode": "false" }, "message": "Create Configuration File" } //alert(data.message); var contents = await github.repos.contents(obj, { body: atob(JSON.stringify(data, null, 4)), method: "POST" }); alert("Configuration File Created"); } catch(e) { console.log(565, e); } } } } } else { window.user = null; localStorage.removeItem('user'); } } ) : null; //window.model ? window.model = MVC.m : null; //window.view ? window.view = MVC.v : null; //window.controller ? window.controller = MVC.c : null; } }, 500); } )(); async function addCSS() { console.log(403, 'addCSS'); var obj = { main: document.querySelector("tinychat-webrtc-app").shadowRoot } var MainElement = obj.main; var fullname = "thebanon/tinyscript"; var theme = window.APP.config.theme; var elem = MainElement.querySelector("tc-chatlog").shadowRoot; var name = "messages"; var user = fullname.split("/")[0]; var repo = fullname.split("/")[1]; var paths = fullname.split("/").splice(2, fullname.split("/").length - 1); var host = "https://" + user + ".github.io"; var path = "/" + repo + "/files/css" + (theme ? "/" + theme : ""); var file = "/" + name + ".css"; var href = await is.local() ? "https://tinychat.local/files/css/" + theme + file : host + path + file; console.log(413, 'sCSS', href); window.scvs ? null : window.scvs = await request(href, { cache: "reload" }); var style = document.createElement("style"); //style.innerHTML = window.scvs; style.setAttribute("loaded", true); style.setAttribute("href", href); style.setAttribute("rel", "stylesheet"); console.log(290, "recv.msg.0", { elem, href, scvs, l, arguments }, window.DOM); var l = elem.lastElementChild; console.log(290, "recv.msg.1", { elem, href, scvs, l, arguments }, window.DOM); var m = l.querySelector("tc-message-html"); console.log(290, "recv.msg.2", { scvs, l, m, html: l.querySelectorAll("tc-message-html"), arguments: arguments[0] }); //var els = m[m.length - 1];//.shadowRoot.querySelector("style"); Array.from(l.querySelectorAll("tc-message-html")).forEach(function(d) { var e = d.shadowRoot; console.log(290, "recv.msg 3", { scvs, e, m, arguments: arguments[0] }); if (e) { e.lastElementChild.insertAdjacentHTML("afterend", style.outerHTML); e.host.stylesheet = scvs; e.host.setAttribute('loaded', true); } }); } async function request(resource, options) { return new Promise(async function(resolve, reject) { await fetch(resource, options).then(async(response)=>{ //console.log(response); if (!response.ok) { return response.text().then(text=>{ var text = JSON.stringify({ code: response.status, message: JSON.parse(text) }); throw new Error(text); } ) } return response.text(); } ).then(response=>{ try { //console.log(39, response); response = JSON.parse(response); console.log(41, 'fetch.request', { response, url }); resolve(response); } catch (err) { resolve(response); } } ).catch(error=>{ console.log("function_get 404 ERROR", error); reject(error); } ) } ); }