CWSS

Complete WebSocket Sniffer

目前为 2022-01-16 提交的版本,查看 最新版本

此脚本不应直接安装,它是供其他脚本使用的外部库。如果你需要使用该库,请在脚本元属性加入:// @require https://update.cn-greasyfork.org/scripts/438408/1009009/CWSS.js

  1. // ==UserScript==
  2. // @license MIT
  3. // @name CWSS
  4. // @version 1.1
  5. // @description Complete WebSocket Sniffer
  6. // @author 0vC4
  7. // @match http://*/*
  8. // @match https://*/*
  9. // @grant none
  10. // @run-at document-start
  11. // @namespace https://greasyfork.org/users/670183
  12. // ==/UserScript==
  13. const CWSS = (() => {
  14. const _hooks_ = 'hooks'; // all hooks WebSocket.prototype[_hooks_]
  15. const eventKey = key => key+'_listener'; // all event listeners WebSocket.prototype[eventKey('open'|'message'|'close')]
  16. const listeners = ['open', 'message', 'close']; // (+init&send hooks available by default)
  17. const proto = window.WebSocket.prototype;
  18. const def = Object.defineProperty;
  19. const hidden = (obj, key, value) => def(obj, key, {configurable: true, value});
  20. const rebase = (obj, key, list) => def(obj, key, {
  21. configurable: true,
  22. enumerable: true,
  23. set: func => list.push(func)
  24. });
  25. const native = (obj, value) => {
  26. obj.toString = function(){return Function.toString.call(value, ...arguments);};
  27. };
  28. const sockets = [];
  29. const hooks = (() => {
  30. if (_hooks_ in proto) return proto[_hooks_];
  31. hidden(proto, _hooks_, []);
  32. const hooks = proto[_hooks_];
  33. const {send, addEventListener} = proto;
  34. const pipe = (type, ...next) => function() {
  35. for (const hook of hooks.sort((a, b) => b.priority - a.priority)) {
  36. if (hook[type]) arguments = hook[type].call(this, ...arguments);
  37. if (!arguments) return;
  38. }
  39. next.flat().forEach(func => func.call(this, ...arguments));
  40. };
  41. proto.send = pipe('send', send);
  42. native(proto.send, send);
  43. proto.addEventListener = function() {
  44. const type = arguments[0];
  45. const func = arguments[1];
  46. const list = this[eventKey(type)];
  47. if (list) list.push(func);
  48. else addEventListener.call(this, ...arguments);
  49. }
  50. native(proto.addEventListener, addEventListener);
  51. const Ows = window.WebSocket;
  52. window.WebSocket = function() {
  53. const ws = new Ows(...arguments);
  54. sockets.push(ws);
  55. pipe('init').call(ws);
  56. for(const key of listeners) {
  57. const list_key = eventKey(key);
  58. const list = hidden(ws, list_key, [])[list_key];
  59. addEventListener.call(ws, key, pipe(key, list));
  60. rebase(ws, 'on'+key, list);
  61. }
  62. return ws;
  63. }
  64. for(const k in Ows) if (k != 'prototype') window.WebSocket[k] = Ows[k];
  65. for(const k in Ows.prototype) if (k != 'constructor') try {window.WebSocket.prototype[k] = Ows.prototype[k];} catch(e) {};
  66. WebSocket.prototype[_hooks_] = Ows.prototype[_hooks_];
  67. native(window.WebSocket, Ows);
  68. return hooks;
  69. })();
  70. const root = {
  71. sockets,
  72. setHook(hook) {
  73. hooks.push(hook);
  74. return root;
  75. },
  76. setHooks(..._hooks) {
  77. hooks.push(..._hooks.flat());
  78. return root;
  79. }
  80. };
  81. return root;
  82. })();
  83. // 0vC4#7152