您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
从xfgryujk哪里抄来的,忽略了一个报错的地方
此脚本不应直接安装。它是供其他脚本使用的外部库,要使用该库请加入元指令 // @require https://update.gf.qytechs.cn/scripts/434638/984839/xfgryujk%27s%20bliveproxy.js
// ==UserScript== // @license MIT // @original-script https://github.com/xfgryujk/bliveproxy // @original-author xfgryujk // @original-license MIT // ==/UserScript== // MIT License // Copyright (c) 2020 xfgryujk // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal // in the Software without restriction, including without limitation the rights // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell // copies of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // The above copyright notice and this permission notice shall be included in all // copies or substantial portions of the Software. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE // SOFTWARE. (function () { const HEADER_SIZE = 16; const WS_BODY_PROTOCOL_VERSION_NORMAL = 0; const WS_BODY_PROTOCOL_VERSION_HEARTBEAT = 1; const WS_BODY_PROTOCOL_VERSION_DEFLATE = 2; const WS_BODY_PROTOCOL_VERSION_BROTLI = 3; const OP_HEARTBEAT_REPLY = 3; const OP_SEND_MSG_REPLY = 5; let textEncoder = new TextEncoder(); let textDecoder = new TextDecoder(); function main() { if (unsafeWindow.bliveproxy) { // 防止多次加载 return; } initApi(); hook(); } function initApi() { unsafeWindow.bliveproxy = api; } let api = { addCommandHandler(cmd, handler) { let handlers = this._commandHandlers[cmd]; if (!handlers) { handlers = this._commandHandlers[cmd] = []; } handlers.push(handler); }, removeCommandHandler(cmd, handler) { let handlers = this._commandHandlers[cmd]; if (!handlers) { return; } this._commandHandlers[cmd] = handlers.filter(item => item !== handler); }, // 私有API _commandHandlers: {}, _getCommandHandlers(cmd) { return this._commandHandlers[cmd] || null; } } function hook() { unsafeWindow.WebSocket = new Proxy(unsafeWindow.WebSocket, { construct(target, args) { let obj = new target(...args); return new Proxy(obj, proxyHandler); } }); } let proxyHandler = { get(target, property) { let value = target[property]; if ((typeof value) === 'function') { value = value.bind(target); } return value; }, set(target, property, value) { if (property === 'onmessage') { let realOnMessage = value; value = function (event) { myOnMessage(event, realOnMessage); } } target[property] = value; return value; } } function myOnMessage(event, realOnMessage) { if (!(event.data instanceof ArrayBuffer)) { realOnMessage(event); return; } let data = new Uint8Array(event.data); function callRealOnMessageByPacket(packet) { realOnMessage({ ...event, data: packet }); } handleMessage(data, callRealOnMessageByPacket); } function makePacketFromCommand(command) { let body = textEncoder.encode(JSON.stringify(command)); return makePacketFromUint8Array(body, OP_SEND_MSG_REPLY); } function makePacketFromUint8Array(body, operation) { let packLen = HEADER_SIZE + body.byteLength; let packet = new ArrayBuffer(packLen); // 不需要压缩 let ver = operation === OP_HEARTBEAT_REPLY ? WS_BODY_PROTOCOL_VERSION_HEARTBEAT : WS_BODY_PROTOCOL_VERSION_NORMAL; let packetView = new DataView(packet); packetView.setUint32(0, packLen); // pack_len packetView.setUint16(4, HEADER_SIZE); // raw_header_size packetView.setUint16(6, ver); // ver packetView.setUint32(8, operation); // operation packetView.setUint32(12, 1); // seq_id let packetBody = new Uint8Array(packet, HEADER_SIZE, body.byteLength); for (let i = 0; i < body.byteLength; i++) { packetBody[i] = body[i]; } return packet; } function handleMessage(data, callRealOnMessageByPacket) { let offset = 0; while (offset < data.byteLength) { let dataView = new DataView(data.buffer, offset); let packLen = dataView.getUint32(0); if (packLen > 1534026300) { return; } // let rawHeaderSize = dataView.getUint16(4); let ver = dataView.getUint16(6); let operation = dataView.getUint32(8); // let seqId = dataView.getUint32(12); let body = new Uint8Array(data.buffer, offset + HEADER_SIZE, packLen - HEADER_SIZE); if (operation === OP_SEND_MSG_REPLY) { switch (ver) { case WS_BODY_PROTOCOL_VERSION_NORMAL: body = textDecoder.decode(body); body = JSON.parse(body); handleCommand(body, callRealOnMessageByPacket); break; case WS_BODY_PROTOCOL_VERSION_DEFLATE: body = pako.inflate(body); handleMessage(body, callRealOnMessageByPacket); break; case WS_BODY_PROTOCOL_VERSION_BROTLI: body = BrotliDecode(body); handleMessage(body, callRealOnMessageByPacket); break; default: { let packet = makePacketFromUint8Array(body, operation); callRealOnMessageByPacket(packet); break; } } } else { let packet = makePacketFromUint8Array(body, operation); callRealOnMessageByPacket(packet); } offset += packLen; } } function handleCommand(command, callRealOnMessageByPacket) { if (command instanceof Array) { for (let oneCommand of command) { this.handleCommand(oneCommand); } return; } let cmd = command.cmd || ''; let pos = cmd.indexOf(':'); if (pos != -1) { cmd = cmd.substr(0, pos); } let handlers = api._getCommandHandlers(cmd); if (handlers) { for (let handler of handlers) { handler(command); } } let packet = makePacketFromCommand(command); callRealOnMessageByPacket(packet); } main(); })();
QingJ © 2025
镜像随时可能失效,请加Q群300939539或关注我们的公众号极客氢云获取最新地址