左手医生匿名化

去除或随机更换左手医生页面水印

  1. /* eslint-disable no-multi-spaces */
  2. /* eslint-disable no-return-assign */
  3.  
  4. // ==UserScript==
  5. // @name 左手医生匿名化
  6. // @namespace PY-DNG userscripts
  7. // @version 0.1.9
  8. // @description 去除或随机更换左手医生页面水印
  9. // @author PY-DNG
  10. // @license Do What The F*ck You Want To Public License
  11. // @match *://ai-app.zuoshouyisheng.com/chat/*
  12. // @require https://update.gf.qytechs.cn/scripts/456034/1282804/Basic%20Functions%20%28For%20userscripts%29.js
  13. // @icon data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAAXNSR0IArs4c6QAAArZJREFUOE99k1toVFcUhr91ZubMGTXGRE2a1jJBk4qJYsWA2qdYiopUrBewSKIhRS1BRXwI4tOhIPggoqJUbBqs2JaqKBTxAkWD16CNGtRUBGMxGpJ2qk7UMZl95iyZkYmDqa6XvdiXb//7X2sLOVF3X53SUpKuiJ87/3aum49cQWS9bFnSKunFuh7d4Bs2iKdRNbwQI5fUcMDxOLqvShJZQHxuUxnIZ3nTRu6SIE1gnZK6Xm1Qjz0YUAPZMZN7xMVwyPdo/nm2tMbnNDUAa+2S8Cfhkki3BOiQFd16I3GXqf+0gHkJThHkl8GI4gxgEIrHX+rRbP/H7p2//vhQxfp61On6P2Rllz74+wc+TlwD9XiWLOSMSVFtOeQXlkNxBdiR18oyQGHR93ub7ZQVPjX6ZE2fLLuiqx8d0k2mTQ56yq62FolNX6DDKGVjfhS3aCIBK21C+rAP/Y9ZcmyVHM36kjExN5Zf1E+tFI3qsVQNoawnL3rgaReYfhZc3i7HhwBqrmq1+rpJDHPVSOZGfwCedsKTTkgl6Q0G2REvZHuHK8lBwMqbOsf3+E4NM7KmpRJK7LYQu6Pgyb1AiG15hv0t+6X/bcVS264xNYxOSzVx6P4T/r2l4NMeCMvWsRM40uKK967Gkto27euPkdd1nlTvDQL5H5EqmsyFMZOo/+UL6cRVa+YFvhq3jsbhFfQlkiw+XCnPB58wy9XH3a0URAqg/HPIGwcSAkKkLJtzsbMUvbynlSXfCKGxIAEW/jRefh8EROfpfPX1Wysg8wqihIorYVQ5BCIgdgaUAWagQRh4xKzfZkvrkCqUztcPnGHUBMOssIczpaDsNSjyIYgDqjDQxfXKNqpc981nG9IHafK0NVrl2H5d0LG+DDlE7RE8s8Q/DtbGE43Sk2vo/wJyN1S7GnxfFV4B3Vgcanqr72kAAAAASUVORK5CYII=
  14. // @grant GM_registerMenuCommand
  15. // @grant GM_unregisterMenuCommand
  16. // @grant GM_getValue
  17. // @grant GM_setValue
  18. // @run-at document-start
  19. // ==/UserScript==
  20.  
  21. /* global LogLevel DoLog Err $ $All $CrE $AEL $$CrE addStyle detectDom destroyEvent copyProp copyProps parseArgs escJsStr replaceText getUrlArgv dl_browser dl_GM AsyncManager */
  22.  
  23. (function() {
  24. 'use strict';
  25.  
  26. const CONST = {
  27. Text: {
  28. Setting: {
  29. Random: ['[ ]随机水印ID', '[✔]随机水印ID'],
  30. HideID: ['[ ]隐藏水印ID', '[✔]隐藏水印ID'],
  31. Hide: ['[ ]隐藏水印', '[✔]隐藏水印'],
  32. }
  33. }
  34. };
  35.  
  36. let watermark, content;
  37. detectDom({
  38. selector: 'body>div>div[style="position: relative;"]>div[style]:first-child',
  39. attributes: true,
  40. callback: _watermark => {
  41. watermark = _watermark;
  42. const observer = new MutationObserver((mutationList, observer) => {
  43. const content = getContent();
  44. if (!(!!getUrlArgv('showId') ^ !!content.id) && content.text) {
  45. work(watermark, content);
  46. observer.disconnect();
  47. }
  48. });
  49. observer.observe(watermark, {
  50. attributes: true,
  51. attributeFilter: ['style']
  52. });
  53. }
  54. });
  55.  
  56. function work(_watermark, _content) {
  57. [watermark, content] = [_watermark, _content];
  58.  
  59. // Load settings
  60. setContent(GM_getValue('id', null), GM_getValue('text', null));
  61. makeBooleanSettings([{
  62. key: 'random',
  63. text: CONST.Text.Setting.Random,
  64. callback: (key, val) => val ? setContent(randstr(content.id.length, false, false), null) : setContent(content.id, null),
  65. initCallback: true
  66. }, {
  67. key: 'hideid',
  68. text: CONST.Text.Setting.HideID,
  69. callback: (key, val) => val ? hideID() : showID(),
  70. initCallback: true
  71. }, {
  72. key: 'hide',
  73. text: CONST.Text.Setting.Hide,
  74. callback: (key, val) => watermark.style.display = val ? 'none' : '',
  75. initCallback: true
  76. }]);
  77. }
  78.  
  79. function hideID() {
  80. const xml = parseXML();
  81. $(xml, 'tspan:first-child').style.visibility = 'hidden';
  82.  
  83. setSVG(xml);
  84. }
  85.  
  86. function showID() {
  87. const xml = parseXML();
  88. $(xml, 'tspan:first-child').style.removeProperty('visibility');
  89.  
  90. setSVG(xml);
  91. }
  92.  
  93. function setContent(id=null, text=null) {
  94. const xml = parseXML();
  95. id !== null && ($(xml, 'tspan:first-child').innerHTML = id);
  96. text !== null && ($(xml, 'tspan:last-child').innerHTML = text);
  97.  
  98. setSVG(xml);
  99. }
  100.  
  101. function getContent() {
  102. const xml = parseXML();
  103.  
  104. return {
  105. id: $(xml, 'tspan:first-child').innerHTML,
  106. text: $(xml, 'tspan:last-child').innerHTML
  107. }
  108. }
  109.  
  110. function parseXML() {
  111. const url = watermark.style.backgroundImage.split(',', 2)[1].split('"', 2)[0];
  112. const svg = decodeURIComponent(url);
  113. const DP = new DOMParser();
  114. const xml = DP.parseFromString(svg, 'image/svg+xml');
  115.  
  116. return xml;
  117. }
  118.  
  119. function setSVG(xml) {
  120. const svg = xml.lastChild.outerHTML;
  121. const url = encodeURIComponent(svg);
  122. const val = `url("data:image/svg+xml,${url}")`;
  123. watermark.style.backgroundImage = val;
  124. }
  125.  
  126. function makeBooleanSettings(settings) {
  127. for (const setting of settings) {
  128. makeBooleanMenu(setting.text, setting.key, setting.defaultValue, setting.callback, setting.initCallback);
  129. }
  130.  
  131. function makeBooleanMenu(texts, key, defaultValue=false, callback=null, initCallback=false) {
  132. const initialVal = GM_getValue(key, defaultValue);
  133. const initialText = texts[initialVal + 0];
  134. let id = GM_registerMenuCommand(initialText, onClick/*, {
  135. autoClose: false
  136. }*/);
  137. initCallback && callback(key, initialVal);
  138.  
  139. function onClick() {
  140. const newValue = !GM_getValue(key, defaultValue);
  141. const newText = texts[newValue + 0];
  142. GM_setValue(key, newValue);
  143. GM_unregisterMenuCommand(id);
  144. id = GM_registerMenuCommand(newText, onClick/*, {
  145. autoClose: false
  146. }*/);
  147.  
  148. typeof callback === 'function' && callback(key, newValue);
  149. }
  150. }
  151. }
  152.  
  153. // Returns a random string
  154. function randstr(length=16, nums=true, cases=true) {
  155. const all = 'abcdefghijklmnopqrstuvwxyz' + (nums ? '0123456789' : '') + (cases ? 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' : '');
  156. return Array(length).fill(0).reduce(pre => (pre += all.charAt(randint(0, all.length-1))), '');
  157. }
  158.  
  159. function randint(min, max) {
  160. return Math.floor(Math.random() * (max - min + 1)) + min;
  161. }
  162. }) ();

QingJ © 2025

镜像随时可能失效,请加Q群300939539或关注我们的公众号极客氢云获取最新地址