2
0

3 Ревизии daaca9e618 ... c8b40fccf9

Автор SHA1 Съобщение Дата
  枫林 c8b40fccf9 fix: 修复事件数据概率和用户数据处理,更新依赖版本 преди 1 месец
  枫林 b8db3e0e15 feat: 添加群组数据和事件数据存储文件 преди 1 месец
  枫林 4a905f8c57 feat: 添加bilibili视频信息模板和接口定义 преди 1 месец

+ 3 - 0
.gitignore

@@ -91,3 +91,6 @@ src/plugins/*
 
 /src/plugins/mc.ts
 /src/config/mc.yml
+botQQ_screenshots/GroupEventData.json
+botQQ_screenshots/GroupWorldData.json
+botQQ_screenshots/bilibiliData.json

+ 1 - 0
botQQ_screenshots/GroupEventData.json

@@ -0,0 +1 @@
+{"638236452":{"f0dd89d1-b2ac-43a8-b929-75e7521f8ab3":{"eventContent":"小雪触犯了圣旨被贬下凡间!禁言5分钟","eventRewardType":"禁言","param":"","eventRewardNum":5,"probability":0.00006}},"773847213":{"0c835593-4d1b-4f42-8f7d-c15d894524ca":{"eventContent":"红磷偷偷努力写代码,偷偷奋斗!获得100金币","eventRewardType":"金币","param":"","eventRewardNum":10,"probability":0.006},"ed257a67-dba7-4452-848a-4a48006e7ed3":{"eventContent":"枫林删库导致老板变成鼻血喷射战士,奖励100元","eventRewardType":"金币","param":"8","eventRewardNum":100,"probability":0.003},"b232304c-43c2-4d8e-8005-912c0dc4b04f":{"eventContent":"枫林强夺小孩子棒棒糖,被孩子家长暴打,奖励300元","eventRewardType":"金币","param":"","eventRewardNum":300,"probability":0.008},"0766de73-c31b-40e0-8566-d1bacb6b5949":{"eventContent":"枫林扶老奶奶过马路将老奶奶带到火葬场,奖励10元","eventRewardType":"金币","param":"","eventRewardNum":10,"probability":0.008},"9b473ac5-8b9f-49af-a650-acab46582ef9":{"eventContent":"枫林干了太多缺德事被评为缺德之星,奖励100元","eventRewardType":"金币","param":"","eventRewardNum":100,"probability":0.008},"bf11f771-b944-4c62-8f53-000686afef6d":{"eventContent":"红磷挂彩票中奖了,奖励一张事件卡","eventRewardType":"道具","param":"eventCard","eventRewardNum":1,"probability":0.008},"08023a16-000c-4b72-909e-fe4c88c0be01":{"eventContent":"红磷打游戏困了,禁言1分钟","eventRewardType":"禁言","param":"","eventRewardNum":1,"probability":0.01}},"":{"":{"param":"","eventRewardNum":1,"probability":0.3}}}

+ 1 - 0
botQQ_screenshots/GroupWorldData.json

@@ -0,0 +1 @@
+{"638236452":{"worldData":["雪推个小妹","狗群主","gqz","√群主","群主","qz","🐶","🐶柚子","苟柚子"],"createtime":1752389067048,"updatetime":1752404552990,"userData":[]},"":{"worldData":"","createtime":1752388877325,"updatetime":1753081335343}}

+ 1 - 0
botQQ_screenshots/bilibiliData.json

@@ -0,0 +1 @@
+{"2180323481":{"bilibiliData":{"bili_jct":"bcd934db04ff7c0406b6e1855694a146","SESSDATA":"5043a2b4%2C1768459389%2C1ab35%2A72CjBlgusHSpvQm1app9OjgfkZiEW74fmn_D2xgWv5RA450iou0LNwaPLD59RiKvK-0uwSVm81T0s5M1FfNTdhNURHeUtLU2JabGdlYmhmUW92TDNKNllURVNtYVh6bVQta08ySmxaM2hndHN6WkY0VUhhcHZJV1cybjByREdveENMc1hRZUVwNlNRIIEC","DedeUserID":"156627564"},"createtime":1752908010065,"updatetime":1752908010065}}

+ 1 - 0
package.json

@@ -13,6 +13,7 @@
   "author": "",
   "license": "ISC",
   "dependencies": {
+    "@renmu/bili-api": "^2.7.0",
     "art-template": "^4.13.2",
     "axios": "^1.7.8",
     "jimp": "^1.6.0",

+ 155 - 12
pnpm-lock.yaml

@@ -8,6 +8,9 @@ importers:
 
   .:
     dependencies:
+      '@renmu/bili-api':
+        specifier: ^2.7.0
+        version: 2.7.0
       art-template:
         specifier: ^4.13.2
         version: 4.13.4
@@ -28,10 +31,10 @@ importers:
         version: 3.0.3
       node-napcat-ts:
         specifier: ^0.4.0
-        version: 0.4.11
+        version: 0.4.11(bufferutil@4.0.9)(utf-8-validate@5.0.10)
       puppeteer:
         specifier: ^23.9.0
-        version: 23.11.1(typescript@4.9.5)
+        version: 23.11.1(bufferutil@4.0.9)(typescript@4.9.5)(utf-8-validate@5.0.10)
       rcon-client:
         specifier: ^4.2.5
         version: 4.2.5
@@ -89,6 +92,9 @@ packages:
     resolution: {integrity: sha512-D2hP9eA+Sqx1kBZgzxZh0y1trbuU+JoDkiEwqhQ36nodYqJwyEIhPSdMNd7lOm/4io72luTPWH20Yda0xOuUow==}
     engines: {node: '>=6.9.0'}
 
+  '@bufbuild/protobuf@2.6.0':
+    resolution: {integrity: sha512-6cuonJVNOIL7lTj5zgo/Rc2bKAo4/GvN+rKCrUj7GdEHRzCk8zKOfFwUsL9nAVk5rSIsRmlgcpLzTRysopEeeg==}
+
   '@colors/colors@1.6.0':
     resolution: {integrity: sha512-Ir+AOibqzrIsL6ajt3Rz3LskB7OiMVHqltZmspbW/TJuTVuyOMirVqAkjfY6JISiLHgyNqicAC8AyHHGzNd/dA==}
     engines: {node: '>=0.1.90'}
@@ -227,6 +233,14 @@ packages:
     engines: {node: '>=18'}
     hasBin: true
 
+  '@renmu/bili-api@2.7.0':
+    resolution: {integrity: sha512-po/WsP4Rv/6L7AV//VR+rb520Km6xXt1e8D1qZ5jnBCVVvSAO90HE0da0PfVdSl9TR6lKJjUuYvhaWTiSU7UzA==}
+    engines: {node: '>=18'}
+
+  '@renmu/throttle@1.0.3':
+    resolution: {integrity: sha512-6ArdPb+EJ3IXnvemzNDj8YIAJMgyU8NMCi3Ad4nL0Vr9R8TfAk4KvHHsu9tWbmOmgrbp3bCYYO7AAQRN0MRQuw==}
+    engines: {node: '>= v0.8.0'}
+
   '@tokenizer/token@0.3.0':
     resolution: {integrity: sha512-OvjF+z51L3ov0OyAU0duzsYuvO01PH7x4t6DJx+guahgTnBHkhJdG7soQeTSFLWN3efnHyibZ4Z8l2EuWwJN3A==}
 
@@ -331,6 +345,11 @@ packages:
     resolution: {integrity: sha512-zJAaP9zxTcvTHRlejau3ZOY4V7SRpiByf3/dxx2uyKxxor19tpmpV2QRsTKikckwhaPmr2dVpxxMr7jOCYVp5g==}
     engines: {node: '>=6.0.0'}
 
+  axios-retry@4.5.0:
+    resolution: {integrity: sha512-aR99oXhpEDGo0UuAlYcn2iGRds30k366Zfa05XWScR9QaQD4JYiP3/1Qt1u7YlefUOK+cn0CcwoL1oefavQUlQ==}
+    peerDependencies:
+      axios: 0.x || 1.x
+
   axios@1.9.0:
     resolution: {integrity: sha512-re4CqKTJaURpzbLHtIi6XpDv20/CnpXOtjRY5/CU32L8gU8ek9UIivcfvSWvmKEngmVbrUtPpdDwWDWL7DNHvg==}
 
@@ -403,6 +422,10 @@ packages:
   buffer@6.0.3:
     resolution: {integrity: sha512-FTiCpNxtwiZZHEZbcbTIcZjERVICn9yq/pDFkTl95/AxzD1naBctN7YO68riM/gLSDY7sdrMby8hofADYuuqOA==}
 
+  bufferutil@4.0.9:
+    resolution: {integrity: sha512-WDtdLmJvAuNNPzByAYpRo2rF1Mmradw6gvWsQKf63476DDXmomT9zUiGypLcG4ibIM67vhAj8jJRdbmEws2Aqw==}
+    engines: {node: '>=6.14.2'}
+
   call-bind-apply-helpers@1.0.2:
     resolution: {integrity: sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ==}
     engines: {node: '>= 0.4'}
@@ -482,6 +505,14 @@ packages:
     resolution: {integrity: sha512-7hvf7/GW8e86rW0ptuwS3OcBGDjIi6SZva7hCyWC0yYry2cOPmLIjXAUHI6DK2HsnwJd9ifmt57i8eV2n4YNpw==}
     engines: {node: '>= 14'}
 
+  debug@2.6.9:
+    resolution: {integrity: sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==}
+    peerDependencies:
+      supports-color: '*'
+    peerDependenciesMeta:
+      supports-color:
+        optional: true
+
   debug@4.4.1:
     resolution: {integrity: sha512-KcKCqiftBJcZr++7ykoDIEwSa3XWowTfNPo92BYxjXiyYEVrUQh2aLyhxBCwww+heortUFxEJYcRzosstTEBYQ==}
     engines: {node: '>=6.0'}
@@ -580,6 +611,9 @@ packages:
     resolution: {integrity: sha512-i/2XbnSz/uxRCU6+NdVJgKWDTM427+MqYbkQzD321DuCQJUqOuJKIA0IM2+W2xtYHdKOmZ4dR6fExsd4SXL+WQ==}
     engines: {node: '>=6'}
 
+  eventemitter3@5.0.1:
+    resolution: {integrity: sha512-GWkBvjiSZK87ELrYOSESUYeVIc9mvLLf/nXalMOS5dYrgZq9o5OVkbZAVM06CVxYsCwH9BDZFPlQTlPA1j4ahA==}
+
   events@3.3.0:
     resolution: {integrity: sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q==}
     engines: {node: '>=0.8.x'}
@@ -598,6 +632,10 @@ packages:
   fast-levenshtein@2.0.6:
     resolution: {integrity: sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==}
 
+  fast-xml-parser@4.5.3:
+    resolution: {integrity: sha512-RKihhV+SHsIUGXObeVy9AXiBbFwkVk7Syp8XgwN5U3JV416+Gwp/GO9i0JYKmikykgz/UHRrrV4ROuZEo/T0ig==}
+    hasBin: true
+
   fd-slicer@1.1.0:
     resolution: {integrity: sha512-cE1qsB/VwyQozZ+q1dGxR8LBYNZeofhEdUNGSMbQD3Gw2lAzX9Zb3uIU6Ebc/Fmyjo9AWWfnn0AUCHqtevs/8g==}
 
@@ -756,6 +794,10 @@ packages:
     resolution: {integrity: sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==}
     engines: {node: '>=0.12.0'}
 
+  is-retry-allowed@2.2.0:
+    resolution: {integrity: sha512-XVm7LOeLpTW4jV19QSH38vkswxoLud8sQ57YwJVTPWdiaI9I8keEhGFpBlslyVsgdQy4Opg8QOLb8YRgsyZiQg==}
+    engines: {node: '>=10'}
+
   is-stream@2.0.1:
     resolution: {integrity: sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==}
     engines: {node: '>=8'}
@@ -852,6 +894,9 @@ packages:
   moment@2.30.1:
     resolution: {integrity: sha512-uEmtNhbDOrWPFS+hdjFCBfy9f2YoyzRpwcl+DqpC6taX21FzsTLQVbMV/W7PzNSX6x/bhC1zA3c2UQ5NzH6how==}
 
+  ms@2.0.0:
+    resolution: {integrity: sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==}
+
   ms@2.1.3:
     resolution: {integrity: sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==}
 
@@ -880,6 +925,10 @@ packages:
       encoding:
         optional: true
 
+  node-gyp-build@4.8.4:
+    resolution: {integrity: sha512-LA4ZjwlnUblHVgq0oBF3Jl/6h/Nvs5fzBLwdEF4nuxnFdsfajde4WfxtJr3CaiH+F6ewcIB/q4jQ4UzPyid+CQ==}
+    hasBin: true
+
   node-napcat-ts@0.4.11:
     resolution: {integrity: sha512-T2l8NeDhWr/UOqVKCDnBOWxVZvncNMRyEQExOgqRzJoQkGJFqiBWiW/xIRlye7d5en2bWdIFvWoyR+Vv/As6LA==}
 
@@ -913,6 +962,14 @@ packages:
     resolution: {integrity: sha512-+IW9pACdk3XWmmTXG8m3upGUJst5XRGzxMRjXzAuJ1XnIFNvfhjjIuYkDvysnPQ7qzqVzLt78BCruntqRhWQbA==}
     engines: {node: '>= 0.8.0'}
 
+  p-queue@8.1.0:
+    resolution: {integrity: sha512-mxLDbbGIBEXTJL0zEx8JIylaj3xQ7Z/7eEVjcF9fJX4DBiH9oqe+oahYnlKKxm0Ci9TlWTyhSHgygxMxjIB2jw==}
+    engines: {node: '>=18'}
+
+  p-timeout@6.1.4:
+    resolution: {integrity: sha512-MyIV3ZA/PmyBN/ud8vV9XzwTrNtR4jFrObymZYnZqMmW0zA8Z17vnT0rBgFE/TlohB+YCHqXMgZzb3Csp49vqg==}
+    engines: {node: '>=14.16'}
+
   pac-proxy-agent@7.2.0:
     resolution: {integrity: sha512-TEB8ESquiLMc0lV8vcd5Ql/JAKAoyzHFXaStwjkzpOpC5Yv+pIzLfHvjTSdf3vpa2bMiUQrg9i6276yn8666aA==}
     engines: {node: '>= 14'}
@@ -1093,6 +1150,9 @@ packages:
   stack-trace@0.0.10:
     resolution: {integrity: sha512-KGzahc7puUKkzyMt+IqAep+TVNbKP+k2Lmwhub39m1AsTSkaDutx56aDCo+HLDzf/D26BIHTJWNiTG1KAJiQCg==}
 
+  stream-parser@0.3.1:
+    resolution: {integrity: sha512-bJ/HgKq41nlKvlhccD5kaCr/P+Hu0wPNKPJOH7en+YrJu/9EgqUF+88w5Jb6KNcjOFMhfX4B2asfeAtIGuHObQ==}
+
   streamx@2.22.0:
     resolution: {integrity: sha512-sLh1evHOzBy/iWRiR6d1zRcLao4gGZr3C1kzNz4fopCOKJb6xD9ub8Mpi9Mr1R6id5o43S+d93fI48UC5uM9aw==}
 
@@ -1111,6 +1171,9 @@ packages:
     resolution: {integrity: sha512-vavAMRXOgBVNF6nyEEmL3DBK19iRpDcoIwW+swQ+CbGiu7lju6t+JklA1MHweoWtadgt4ISVUsXLyDq34ddcwA==}
     engines: {node: '>=4'}
 
+  strnum@1.1.2:
+    resolution: {integrity: sha512-vrN+B7DBIoTTZjnPNewwhx6cBA/H+IS7rfW68n7XxC1y7uoiGQBxaKzqucGUgavX15dJgiGztLJ8vxuEzwqBdA==}
+
   strtok3@6.3.0:
     resolution: {integrity: sha512-fZtbhtvI9I48xDSywd/somNqgUHl2L2cstmXCCif0itOf96jeW18MBSyrLuNicYQVkvpOxkZtkzujiTJ9LW5Jw==}
     engines: {node: '>=10'}
@@ -1140,6 +1203,9 @@ packages:
   through@2.3.8:
     resolution: {integrity: sha512-w89qg7PI8wAdvX60bMDP+bFoD5Dvhm9oLheFp5O4a2QF0cSBGsBX4qZmadPMvVqlLJBBci+WqGGOAPvcDeNSVg==}
 
+  tiny-typed-emitter@2.1.0:
+    resolution: {integrity: sha512-qVtvMxeXbVej0cQWKqVSSAHmKZEHAvxdF8HEUBFWts8h+xEo5m/lEiPakuyZ3BnCBjOD8i24kzNOiOLLgsSxhA==}
+
   tinycolor2@1.6.0:
     resolution: {integrity: sha512-XPaBkWQJdsf3pLKJV9p4qN/S+fm2Oj8AIPo1BTUhg5oxkvm9+SVEGFdhyOz7tTdUTfvxMiAs4sp6/eZO2Ew+pw==}
 
@@ -1212,6 +1278,10 @@ packages:
   upper-case@1.1.3:
     resolution: {integrity: sha512-WRbjgmYzgXkCV7zNVpy5YgrHgbBv126rMALQQMrmzOVC4GM2waQ9x7xtm8VU+1yF2kWyPzI9zbZ48n4vSxwfSA==}
 
+  utf-8-validate@5.0.10:
+    resolution: {integrity: sha512-Z6czzLq4u8fPOyx7TU6X3dvUZVvoJmxSQ+IcrlmagKhilxlhZgxPK6C5Jqbkw1IDUmFTM+cz9QDnnLTwDz/2gQ==}
+    engines: {node: '>=6.14.2'}
+
   utif2@4.1.0:
     resolution: {integrity: sha512-+oknB9FHrJ7oW7A2WZYajOcv4FcDR4CfoGB0dPNfxbi4GO05RRnFmt5oa23+9w32EanrYcSJWspUiJkLMs+37w==}
 
@@ -1322,6 +1392,8 @@ snapshots:
 
   '@babel/helper-validator-identifier@7.27.1': {}
 
+  '@bufbuild/protobuf@2.6.0': {}
+
   '@colors/colors@1.6.0': {}
 
   '@cspotcode/source-map-support@0.8.1':
@@ -1546,6 +1618,25 @@ snapshots:
       - bare-buffer
       - supports-color
 
+  '@renmu/bili-api@2.7.0':
+    dependencies:
+      '@bufbuild/protobuf': 2.6.0
+      '@renmu/throttle': 1.0.3
+      axios: 1.9.0
+      axios-retry: 4.5.0(axios@1.9.0)
+      fast-xml-parser: 4.5.3
+      p-queue: 8.1.0
+      tiny-typed-emitter: 2.1.0
+    transitivePeerDependencies:
+      - debug
+      - supports-color
+
+  '@renmu/throttle@1.0.3':
+    dependencies:
+      stream-parser: 0.3.1
+    transitivePeerDependencies:
+      - supports-color
+
   '@tokenizer/token@0.3.0': {}
 
   '@tootallnate/quickjs-emscripten@0.23.0': {}
@@ -1631,6 +1722,11 @@ snapshots:
 
   await-to-js@3.0.0: {}
 
+  axios-retry@4.5.0(axios@1.9.0):
+    dependencies:
+      axios: 1.9.0
+      is-retry-allowed: 2.2.0
+
   axios@1.9.0:
     dependencies:
       follow-redirects: 1.15.9
@@ -1699,6 +1795,11 @@ snapshots:
       base64-js: 1.5.1
       ieee754: 1.2.1
 
+  bufferutil@4.0.9:
+    dependencies:
+      node-gyp-build: 4.8.4
+    optional: true
+
   call-bind-apply-helpers@1.0.2:
     dependencies:
       es-errors: 1.3.0
@@ -1789,6 +1890,10 @@ snapshots:
 
   data-uri-to-buffer@6.0.2: {}
 
+  debug@2.6.9:
+    dependencies:
+      ms: 2.0.0
+
   debug@4.4.1(supports-color@5.5.0):
     dependencies:
       ms: 2.1.3
@@ -1873,6 +1978,8 @@ snapshots:
 
   event-target-shim@5.0.1: {}
 
+  eventemitter3@5.0.1: {}
+
   events@3.3.0: {}
 
   exif-parser@0.1.12: {}
@@ -1891,6 +1998,10 @@ snapshots:
 
   fast-levenshtein@2.0.6: {}
 
+  fast-xml-parser@4.5.3:
+    dependencies:
+      strnum: 1.1.2
+
   fd-slicer@1.1.0:
     dependencies:
       pend: 1.2.0
@@ -2050,13 +2161,15 @@ snapshots:
 
   is-number@7.0.0: {}
 
+  is-retry-allowed@2.2.0: {}
+
   is-stream@2.0.1: {}
 
   is-url@1.2.4: {}
 
-  isomorphic-ws@5.0.0(ws@8.18.2):
+  isomorphic-ws@5.0.0(ws@8.18.2(bufferutil@4.0.9)(utf-8-validate@5.0.10)):
     dependencies:
-      ws: 8.18.2
+      ws: 8.18.2(bufferutil@4.0.9)(utf-8-validate@5.0.10)
 
   jimp@1.6.0:
     dependencies:
@@ -2152,6 +2265,8 @@ snapshots:
 
   moment@2.30.1: {}
 
+  ms@2.0.0: {}
+
   ms@2.1.3: {}
 
   nanoid@5.1.5: {}
@@ -2170,11 +2285,14 @@ snapshots:
     dependencies:
       whatwg-url: 5.0.0
 
-  node-napcat-ts@0.4.11:
+  node-gyp-build@4.8.4:
+    optional: true
+
+  node-napcat-ts@0.4.11(bufferutil@4.0.9)(utf-8-validate@5.0.10):
     dependencies:
-      isomorphic-ws: 5.0.0(ws@8.18.2)
+      isomorphic-ws: 5.0.0(ws@8.18.2(bufferutil@4.0.9)(utf-8-validate@5.0.10))
       nanoid: 5.1.5
-      ws: 8.18.2
+      ws: 8.18.2(bufferutil@4.0.9)(utf-8-validate@5.0.10)
     transitivePeerDependencies:
       - bufferutil
       - utf-8-validate
@@ -2217,6 +2335,13 @@ snapshots:
       type-check: 0.3.2
       word-wrap: 1.2.5
 
+  p-queue@8.1.0:
+    dependencies:
+      eventemitter3: 5.0.1
+      p-timeout: 6.1.4
+
+  p-timeout@6.1.4: {}
+
   pac-proxy-agent@7.2.0:
     dependencies:
       '@tootallnate/quickjs-emscripten': 0.23.0
@@ -2305,27 +2430,27 @@ snapshots:
       end-of-stream: 1.4.4
       once: 1.4.0
 
-  puppeteer-core@23.11.1:
+  puppeteer-core@23.11.1(bufferutil@4.0.9)(utf-8-validate@5.0.10):
     dependencies:
       '@puppeteer/browsers': 2.6.1
       chromium-bidi: 0.11.0(devtools-protocol@0.0.1367902)
       debug: 4.4.1(supports-color@5.5.0)
       devtools-protocol: 0.0.1367902
       typed-query-selector: 2.12.0
-      ws: 8.18.2
+      ws: 8.18.2(bufferutil@4.0.9)(utf-8-validate@5.0.10)
     transitivePeerDependencies:
       - bare-buffer
       - bufferutil
       - supports-color
       - utf-8-validate
 
-  puppeteer@23.11.1(typescript@4.9.5):
+  puppeteer@23.11.1(bufferutil@4.0.9)(typescript@4.9.5)(utf-8-validate@5.0.10):
     dependencies:
       '@puppeteer/browsers': 2.6.1
       chromium-bidi: 0.11.0(devtools-protocol@0.0.1367902)
       cosmiconfig: 9.0.0(typescript@4.9.5)
       devtools-protocol: 0.0.1367902
-      puppeteer-core: 23.11.1
+      puppeteer-core: 23.11.1(bufferutil@4.0.9)(utf-8-validate@5.0.10)
       typed-query-selector: 2.12.0
     transitivePeerDependencies:
       - bare-buffer
@@ -2411,6 +2536,12 @@ snapshots:
 
   stack-trace@0.0.10: {}
 
+  stream-parser@0.3.1:
+    dependencies:
+      debug: 2.6.9
+    transitivePeerDependencies:
+      - supports-color
+
   streamx@2.22.0:
     dependencies:
       fast-fifo: 1.3.2
@@ -2434,6 +2565,8 @@ snapshots:
 
   strip-bom@3.0.0: {}
 
+  strnum@1.1.2: {}
+
   strtok3@6.3.0:
     dependencies:
       '@tokenizer/token': 0.3.0
@@ -2483,6 +2616,8 @@ snapshots:
 
   through@2.3.8: {}
 
+  tiny-typed-emitter@2.1.0: {}
+
   tinycolor2@1.6.0: {}
 
   to-regex-range@5.0.1:
@@ -2550,6 +2685,11 @@ snapshots:
 
   upper-case@1.1.3: {}
 
+  utf-8-validate@5.0.10:
+    dependencies:
+      node-gyp-build: 4.8.4
+    optional: true
+
   utif2@4.1.0:
     dependencies:
       pako: 1.0.11
@@ -2607,7 +2747,10 @@ snapshots:
 
   wrappy@1.0.2: {}
 
-  ws@8.18.2: {}
+  ws@8.18.2(bufferutil@4.0.9)(utf-8-validate@5.0.10):
+    optionalDependencies:
+      bufferutil: 4.0.9
+      utf-8-validate: 5.0.10
 
   xml-parse-from-string@1.0.1: {}
 

+ 1 - 0
src/interface/economy.ts

@@ -6,6 +6,7 @@ export interface UserData {
         coins: number;
         logs: Economylogs[];
     },
+    events:number//触发事件时保护次数
     props:UserProp[]
     Permission:string[]
 }

+ 33 - 0
src/interface/sakulin.ts

@@ -0,0 +1,33 @@
+export interface RootObject {
+  success: boolean;
+  detail: Detail;
+  pdf: string[];
+}
+
+export interface Detail {
+  save_path: string;
+  exists: boolean;
+  skip: boolean;
+  album_id: string;
+  scramble_id: string;
+  name: string;
+  page_count: number;
+  pub_date: string;
+  update_date: string;
+  likes: string;
+  views: string;
+  comment_count: number;
+  works: string[];
+  actors: any[];
+  tags: string[];
+  authors: string[];
+  episode_list: (number | string)[][];
+  related_list: Relatedlist[];
+}
+
+export interface Relatedlist {
+  id: string;
+  author: string;
+  name: string;
+  image: string;
+}

+ 1 - 1
src/lib/Puppeteer.ts

@@ -9,7 +9,7 @@ export class HtmlImg {
     async init() {
         if (!this.browser) {
             const options: PuppeteerLaunchOptions = {
-                headless: true, // 无头模式,可根据需要设置为false,
+                headless: false, // 无头模式,可根据需要设置为false,
                 args: [
                     '--no-sandbox',
                     '--disable-setuid-sandbox',

+ 1 - 0
src/lib/decorators.ts

@@ -271,6 +271,7 @@ export function schedule(cron: string): MethodDecorator {
         // 返回修改后的描述符
         return descriptor;
     };
+
 }
 
 // 添加金币相关的fn装饰器

+ 1 - 0
src/lib/economy.ts

@@ -48,6 +48,7 @@ export function getUserData(userId: string): UserData|null {
                 logs: [],
                 
             },
+            events:0,
             props: [],
             Permission: []
         };

+ 1 - 1
src/plugins/Permission.ts

@@ -14,7 +14,7 @@ import { addPermission, getuserPermissions, IsAdmin, removePermission } from "..
     }
 })
 export class Permission{
-    @runcod(["list", "查看权限"],"使用道具" )
+    @runcod(["list", "查看权限"],"查看权限" )
     async list(
         context: PrivateFriendMessage | PrivateGroupMessage | GroupMessage
     ){

+ 4 - 2
src/plugins/ecomony.ts

@@ -3,7 +3,7 @@ import { param, plugins, runcod } from "../lib/decorators.js";
 import { GroupMessage, PrivateFriendMessage, PrivateGroupMessage } from "node-napcat-ts/dist/Interfaces.js";
 import path from "path";
 import { fileURLToPath } from "url";
-import { IsAdmin } from "../lib/Permission.js";
+import { IsAdmin, Permission } from "../lib/Permission.js";
 import { Receive } from "node-napcat-ts";
 
 @plugins({
@@ -55,6 +55,7 @@ export class ecomony {
         }
     }
 
+    @Permission("Admin")
     @runcod(["add", "增加"], "增加金币")
     async addecomony(
         @param("QQ号", 'at',) userid: Receive["at"],
@@ -137,7 +138,8 @@ export class ecomony {
         }
         
     }
-
+    
+    @Permission("Admin")
     @runcod(["reduce", "减少"], "减少金币")
     async reduceecomony(
         @param("QQ号", 'at',) userid: Receive["at"],

+ 0 - 219
src/plugins/mc.ts

@@ -1,219 +0,0 @@
-import { param, plugins, runcod } from "../lib/decorators.js";
-import { Rcon } from "rcon-client"
-import { Permission } from '../lib/Permission.js';
-import { GroupMessage, PrivateFriendMessage, PrivateGroupMessage, Receive } from "node-napcat-ts";
-import { mccfg } from "../lib/config.js";
-import path from "path";
-import { fileURLToPath } from "url";
-import fs from 'fs'
-import { qqBot } from "../app.js";
-
-@plugins({
-    easycmd: true,
-    name: "我的世界工具箱",
-    version: "0.0.1",
-    describe: "这是一个我的世界工具箱,用来管理你的服务器",
-    author: "枫叶秋林",
-    help: {
-        enabled: true,
-        description: "查看帮助信息"
-    }
-})
-export class mc {
-    rcon: Rcon
-    constructor() {
-        this.rcon = new Rcon({
-            host: mccfg.host,
-            port: mccfg.port,
-            password: mccfg.password
-        })
-        qqBot.on('notice.group_decrease', async (context) => {
-            if (!context.user_id) {
-                return
-            }
-            const plId = await this.readpl(context.user_id)
-            if (plId?.plId) {
-                try {
-                    const rcon = await this.rcon.connect()
-                    if (context.sub_type === 'kick') {
-                        const res = await rcon.send(`ban ${plId?.plId}`)
-                        await this.deletepl(context.user_id)
-                        qqBot.send_group_msg({
-                            group_id: context.group_id,
-                            message: [{
-                                type: "text",
-                                data: {
-                                    text: `群友:${context.user_id}被踢出,玩家${plId.plId}已被封禁!:\n
-                                           指令执行结果:${res}`
-                                }
-                            }]
-                        })
-                        return
-                    }
-                    if (context.sub_type === 'leave') {
-                        const res = await rcon.send(`whitelist remove ${plId?.plId}`)
-                        if (res.includes(`Removed ${plId?.plId} from the whitelist`)) {
-                            await this.deletepl(context.user_id)
-                            qqBot.send_group_msg({
-                                group_id: context.group_id,
-                                message: [{
-                                    type: "text",
-                                    data: {
-                                        text: `群友:${context.user_id}离开群了,玩家${plId.plId}已移除白名单!`
-                                    }
-                                }]
-                            })
-                        }
-                    }
-                    rcon.end()
-                } catch (error) {
-                    console.log(error)
-                }
-            } else {
-                qqBot.send_group_msg({
-                    group_id: context.group_id,
-                    message: [{
-                        type: "text",
-                        data: {
-                            text: `群友:${context.user_id}离开群了,但是玩家${plId}不在白名单!`
-                        }
-                    }]
-                })
-            }
-        })
-    }
-
-    @runcod(["list", "在线玩家"], "查看在线玩家") //命令描述,用于显示在默认菜单中
-    async list() {
-        try {
-            const rcon = await this.rcon.connect()
-            const res = await rcon.send("list")
-            const players = res.split(":");
-            rcon.end()
-            return players[1]
-        } catch (error) {
-            return "连接失败"
-        }
-    }
-    @Permission('Admin')
-    @runcod(["指令", "cmd"], "运行指令") //命令描述,用于显示在默认菜单中
-    async cmd(@param("执行指令", 'text') runcod: Receive["text"]) {//参数装饰器,用于解析参数) {
-        try {
-            const rcon = await this.rcon.connect()
-            runcod.data.text = runcod.data.text?.replace(/,/g, ' ')
-            const res = await rcon.send(runcod?.data?.text ?? '')
-            rcon.end()
-            return res
-        } catch (error) {
-            return "连接失败"
-        }
-    }
-    @runcod(["绑定", ""], "绑定玩家") //命令描述,用于显示在默认菜单中
-    async bindPl(@param("Id", 'text') pId: Receive["text"],
-        context: PrivateFriendMessage | PrivateGroupMessage | GroupMessage) {
-        const seedId = context?.sender?.user_id ?? null
-        const plId = pId?.data?.text ?? null
-        if (!seedId || !plId) {
-            return "绑定失败"
-        }
-        try {
-            const rcon = await this.rcon.connect()
-            const res = await rcon.send(`whitelist add ${plId}`)
-            //Added feng_linH to the whitelist
-            if (res.includes(`Added ${plId} to the whitelist`)) {
-                await this.savepl(seedId, plId)
-                return "绑定成功!"
-            }
-            rcon.end()
-            return res
-        } catch (error: any) {
-            return `绑定失败:${error.message}`
-        }
-    }
-
-    @runcod(["解绑", ""], "解绑玩家") //命令描述,用于显示在默认菜单中
-    async unBindPl(
-        context: PrivateFriendMessage | PrivateGroupMessage | GroupMessage) {
-        const seedId = context?.sender?.user_id ?? null
-        if (!seedId) {
-            return "解绑失败"
-        }
-        try {
-            const plId = await this.readpl(seedId)
-            if (!plId) {
-                return "解绑失败"
-            }
-            const rcon = await this.rcon.connect()
-            const res = await rcon.send(`whitelist remove ${plId}`)
-            //Removed feng_linH from the whitelist
-            if (res.includes(`Removed ${plId} from the whitelist`)) {
-                await this.savepl(seedId, '')
-                return "解绑成功!"
-            }
-            rcon.end()
-            return res
-        } catch (error: any) {
-            return `解绑失败:${error.message}`
-        }
-    }
-
-
-
-    private async savepl(seedId: number, plId: string): Promise<void> {
-        const __dirname = path.dirname(fileURLToPath(import.meta.url));
-        //json
-        const filePath = path.join(__dirname, '..', '..', 'botQQ_screenshots', 'mcData.json');
-        let data: any = {};
-        if (fs.existsSync(filePath)) {
-            const fileContent = fs.readFileSync(filePath, 'utf-8');
-            data = JSON.parse(fileContent);
-        } else {
-            fs.writeFileSync(filePath, JSON.stringify(data));
-        }
-        if (data[seedId]) {
-            data[seedId].plId = plId;
-            data[seedId].updatetime = new Date().getTime()
-        } else {
-            data[seedId] = {
-                plId,
-                createtime: new Date().getTime(),
-                updatetime: new Date().getTime(),
-            }
-        }
-        fs.writeFileSync(filePath, JSON.stringify(data));
-        return;
-    }
-
-    private async readpl(seedId: number): Promise<{ plId: string, createtime: number, updatetime: number } | undefined> {
-        const __dirname = path.dirname(fileURLToPath(import.meta.url));
-        const filePath = path.join(__dirname, '..', '..', 'botQQ_screenshots', 'mcData.json');
-        let data: any = {};
-        if (fs.existsSync(filePath)) {
-            const fileContent = fs.readFileSync(filePath, 'utf-8');
-            data = JSON.parse(fileContent);
-            if (data[seedId]) {
-                return data[seedId];
-            }
-        }
-        if (data[seedId]) {
-            return data[seedId];
-        }
-    }
-    //deletepl
-    private async deletepl(seedId: number): Promise<void> {
-        const __dirname = path.dirname(fileURLToPath(import.meta.url));
-        const filePath = path.join(__dirname, '..', '..', 'botQQ_screenshots', 'mcData.json');
-        let data: any = {};
-        if (fs.existsSync(filePath)) {
-            const fileContent = fs.readFileSync(filePath, 'utf-8');
-            data = JSON.parse(fileContent);
-            if (data[seedId]) {
-                delete data[seedId];
-                fs.writeFileSync(filePath, JSON.stringify(data));
-            }
-        }
-    }
-
-
-
-}

+ 3 - 3
src/plugins/prop.ts

@@ -34,18 +34,18 @@ export class Propplu {
             return this.tl(`你没有${propId}道具`,'error',`你没有${propId}道具`)
         }
         
-        if (findprop.Num < Number(Num?.data?.text)) {
+        if (findprop.Num < Number(Num?.data?.text??1)) {
             return this.tl(`道具数量不足`,'error',`道具数量不足`)
         }
         Props.forEach((prop) => {
             if (prop.propId === propId?.data?.text) {
-                if(prop.maxuse<Number(Num?.data?.text)){
+                if(prop.maxuse<Number(Num?.data?.text??1)){
                     return this.tl(`该道具允许最大使用数量为${prop.maxuse}超过最大使用数量`,'error',`该道具允许最大使用数量为${prop.maxuse}超过最大使用数量`)
                 }
             }    
         });
         try {
-            for (let i = 0; i < Number(Num?.data?.text); i++) {
+            for (let i = 0; i < Number(Num?.data?.text??1); i++) {
                 let fn;
                 let classConstructor;
                 let propid=''

+ 2 - 2
src/plugins/test.ts

@@ -72,7 +72,7 @@ export class test {
                 enabled: true,//是否启用模板,启用将发送图片内容
                 sendText: false,//是否发送文本,启用将发送文本内容,如果都启用则发送两条消息
                 path: path.resolve(__dirname, '..', 'resources', 'test', 'param.html'),//模版路径,推荐按规范放置在resources目录下
-                html: `<div>简约自定义html渲染内容</div>`,//简易渲染,填写html内容
+                // html: `<div>简约自定义html渲染内容</div>`,//简易渲染,填写html内容
                 render: {//浏览器默认参数设置,用于打开浏览器的设置
                     width: 600, // 模板宽度
                     height: 1, // 模板高度
@@ -80,7 +80,7 @@ export class test {
                     quality: 100,// 模板质量
                     fullPage: false,// 是否全屏
                     background: true,// 是否背景
-                    url: 'http://www.baidu.com'// 直接使用网站截图渲染支持90%的网站,需要自行测试
+                    // url: 'http://www.baidu.com'// 直接使用网站截图渲染支持90%的网站,需要自行测试
                 }
             },
             toString() { //重写toString方法,用于返回文本内容,启用sendText时将发送文本内容,不启用时将发送图片内容,图片发送失败时发送文字内容

+ 94 - 0
src/resources/bilibili/video-info.html

@@ -0,0 +1,94 @@
+<!DOCTYPE html>
+<html lang="zh-CN">
+
+<head>
+    <meta charset="UTF-8">
+    <meta name="viewport" content="width=device-width, initial-scale=1.0">
+    <title>{{info.title}} - 视频信息</title>
+    <link href="https://cdn.bootcdn.net/ajax/libs/twitter-bootstrap/5.3.0/css/bootstrap.min.css" rel="stylesheet">
+    <style>
+        .video-header {
+            border-bottom: 1px solid #eee;
+            padding-bottom: 1rem;
+            margin-bottom: 1.5rem;
+        }
+
+        .media-container {
+            display: grid;
+            grid-template-columns: 1fr 2fr;
+            gap: 2rem;
+            margin-bottom: 2rem;
+        }
+
+        .thumbnail-wrapper {
+            position: relative;
+            border-radius: 8px;
+            overflow: hidden;
+        }
+
+        .stats-grid {
+            display: grid;
+            grid-template-columns: repeat(2, 1fr);
+            gap: 1rem;
+            background: #f8f9fa;
+            padding: 1.5rem;
+            border-radius: 8px;
+        }
+
+        .stat-item {
+            display: flex;
+            align-items: center;
+            gap: 8px;
+        }
+
+        .stat-icon {
+            width: 24px;
+            height: 24px;
+        }
+    </style>
+</head>
+
+<body class="bg-light">
+    <div class="container py-5">
+        <!-- 头部标题 -->
+        <div class="video-header">
+            <h1 class="h3 mb-0">{{info.title}}</h1>
+        </div>
+
+        <!-- 主体内容 -->
+        <div class="media-container">
+            <!-- 左侧封面 -->
+            <div class="thumbnail-wrapper">
+                <img src="{{info.pic}}" class="img-fluid" alt="视频封面">
+            </div>
+
+            <!-- 右侧介绍 -->
+            <div class="tags-section">
+                <p class="text-muted">{{info.desc}}</p>
+            </div>
+        </div>
+        <div class="stats-grid row">
+            <div class="stat-item">
+            
+                <svg class="stat-icon" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0 0 448 512"><path d="M424.4 214.7L72.4 6.6C43.8-10.3 0 6.1 0 47.9V464c0 37.5 40.7 60.1 72.4 41.3l352-208c31.4-18.5 31.5-64.1 0-82.6z" fill="currentColor"></path></svg>
+                <span>{{info.stat.view}}</span>
+            </div>
+            <div class="stat-item">
+                <svg class="stat-icon" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0 0 512 512"><path d="M256 32C114.6 32 0 125.1 0 240c0 47.6 19.9 91.2 52.9 126.3C38 405.7 7 439.1 6.5 439.5c-6.6 7-8.4 17.2-4.6 26S14.4 480 24 480c61.5 0 110-25.7 139.1-46.3C192 442.8 223.2 448 256 448c141.4 0 256-93.1 256-208S397.4 32 256 32zm0 368c-26.7 0-53.1-4.1-78.4-12.1l-22.7-7.2l-19.5 13.8c-14.3 10.1-33.9 21.4-57.5 29c7.3-12.1 14.4-25.7 19.9-40.2l10.6-28.1l-20.6-21.8C69.7 314.1 48 282.2 48 240c0-88.2 93.3-160 208-160s208 71.8 208 160s-93.3 160-208 160z" fill="currentColor"></path></svg>
+                <span>{{info.stat.reply}}</span>
+            </div>
+            <div class="stat-item">
+                <svg class="stat-icon" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0 0 512 512"><path d="M256 32C114.6 32 0 125.1 0 240c0 47.6 19.9 91.2 52.9 126.3C38 405.7 7 439.1 6.5 439.5c-6.6 7-8.4 17.2-4.6 26S14.4 480 24 480c61.5 0 110-25.7 139.1-46.3C192 442.8 223.2 448 256 448c141.4 0 256-93.1 256-208S397.4 32 256 32zm0 368c-26.7 0-53.1-4.1-78.4-12.1l-22.7-7.2l-19.5 13.8c-14.3 10.1-33.9 21.4-57.5 29c7.3-12.1 14.4-25.7 19.9-40.2l10.6-28.1l-20.6-21.8C69.7 314.1 48 282.2 48 240c0-88.2 93.3-160 208-160s208 71.8 208 160s-93.3 160-208 160z" fill="currentColor"></path></svg>
+                <span>{{info.stat.coin}}</span>
+            </div>
+            <div class="stat-item">
+                <svg class="stat-icon" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0 0 32 32"><path d="M22.45 6a5.47 5.47 0 0 1 3.91 1.64a5.7 5.7 0 0 1 0 8L16 26.13L5.64 15.64a5.7 5.7 0 0 1 0-8a5.48 5.48 0 0 1 7.82 0l2.54 2.6l2.53-2.58A5.44 5.44 0 0 1 22.45 6m0-2a7.47 7.47 0 0 0-5.34 2.24L16 7.36l-1.11-1.12a7.49 7.49 0 0 0-10.68 0a7.72 7.72 0 0 0 0 10.82L16 29l11.79-11.94a7.72 7.72 0 0 0 0-10.82A7.49 7.49 0 0 0 22.45 4z" fill="currentColor"></path></svg>
+                <span>{{info.stat.favorite}}</span>
+            </div>
+        </div>
+    </div>
+
+    <script src="https://cdn.bootcdn.net/ajax/libs/handlebars.js/4.7.7/handlebars.min.js"></script>
+</body>
+
+</html>

+ 1 - 1
src/resources/ecomony/info.html

@@ -101,7 +101,7 @@
 
         <!-- 交易记录列表 -->
         <ul class="transaction-list">
-            {{each logs}}
+            {{each logs.slice(0,10)}}
             <li class="transaction-item">
                 <div class="transaction-details">
                     <div class="transaction-time">{{$value.date}}</div>