Young People in Yaohuo

青少年模式

  1. // ==UserScript==
  2. // @name Young People in Yaohuo
  3. // @description 青少年模式
  4. // @version 0.8
  5. // @author Polygon
  6. // @match https://yaohuo.me/*
  7. // @icon https://yaohuo.me/css/favicon.png
  8. // @grant GM_addStyle
  9. // @grant GM_info
  10. // @run-at document-end
  11. // @namespace https://gf.qytechs.cn/users/788115
  12. // ==/UserScript==
  13.  
  14. (function() {
  15. 'use strict';
  16. // 添加一个style,PC端字体有点看不清
  17. GM_addStyle(`
  18. body, html {
  19. font-family: Arial, SimHei !important;
  20. }
  21. `)
  22. let forbiddenLocal
  23. if (localStorage.getItem("forbidden") == null) {
  24. forbiddenLocal = {keywords: [], usernames: []}
  25. localStorage.setItem("forbidden", JSON.stringify(forbiddenLocal))
  26. }
  27. forbiddenLocal = JSON.parse(localStorage.getItem("forbidden"))
  28. var keywords = forbiddenLocal.keywords
  29. var usernames = forbiddenLocal.usernames
  30. // 在record中读取k,读取过程中可能会初始化record[k]
  31. let getRecord = (itemid) => {
  32. if (localStorage.getItem("record-version") != GM_info.script.version) {
  33. localStorage.removeItem("record")
  34. alert("清空老版本record成功")
  35. localStorage.setItem("record-version", GM_info.script.version)
  36. }
  37. // 读取最新localStorage的record
  38. let record = localStorage.getItem("record")
  39. record = JSON.parse(record)
  40. if (record == null) {
  41. // 第一次初始化
  42. record = {}
  43. }
  44. if (!Object.keys(record).includes(itemid)) {
  45. record[itemid] = {
  46. "latest_time": null, // 最近一次访问时间戳
  47. "latest_comment": 0, // 上一次访问时的评论数量
  48. "latest_read": 0, // 上一次访问时的阅读数量
  49. "count": 0, // 访问次数
  50. }
  51. }
  52. return record
  53. }
  54. // 指定k,添加一个时间戳
  55. let recordAdd = (itemid, comment=null, read=null) => {
  56. let record
  57. record = getRecord(itemid)
  58. // 防止重复添加
  59. if (comment != null && read != null) {
  60. // 这俩应该在帖子打开后解析更新
  61. record[itemid]["latest_comment"] = comment
  62. record[itemid]["latest_read"] = read
  63. } else {
  64. // 没有这两个参数就只更新次数
  65. if (record[itemid]["latest_time"] && (new Date()).valueOf() - record[itemid]["latest_time"] < 1e3) return
  66. record[itemid]["latest_time"] = (new Date()).valueOf()
  67. record[itemid]["count"] ++
  68. }
  69. // 记录更新后record
  70. localStorage.setItem("record", JSON.stringify(record))
  71. }
  72. function timestampToTime(timestamp) {
  73. // https://www.byteblogs.com/article/259
  74. var date = new Date(timestamp)
  75. var Y = date.getFullYear() + '-'
  76. var M = (date.getMonth()+1 < 10 ? '0'+(date.getMonth()+1) : date.getMonth()+1) + '-'
  77. var D = date.getDate() + ' '
  78. var h = date.getHours() + ':'
  79. var m = date.getMinutes() + ':'
  80. var s = date.getSeconds()
  81. return Y+M+D+h+m+s
  82. }
  83. let getTimeInfo = (t) => {
  84. let delta = ((new Date()).valueOf() - t) / 1000
  85. if (delta < 60) {
  86. // 小于60秒
  87. delta = `${parseInt(delta)}秒前`
  88. } else if (delta / (60 ** 2) < 1) {
  89. // 小于一小时
  90. delta = `${parseInt(delta / 60)}分前`
  91. } else if (delta / (60 ** 3) < 24) {
  92. // 小于一天
  93. delta = `${parseInt(delta / (60 ** 2))}时前`
  94. } else {
  95. // 直接显示日期
  96. delta = timestampToTime(t)
  97. }
  98. return delta
  99. }
  100. let parseElement = (ele) => {
  101. let itemid = ele.querySelector("a").href.match(/bbs-(\d+)/)[1]
  102. let [text, info, _] = ele.innerText.split("\n")
  103. let [username, comment, read] = info.split("/")
  104. comment = parseInt(comment.replace("回", ""))
  105. read = parseInt(read.replace("阅", ""))
  106. return [itemid, text, username, comment, read]
  107. }
  108. let validate = (text) => {
  109. return keywords.filter((keyword) => {
  110. return text.match(new RegExp(keyword, "gi"))
  111. }).length
  112. }
  113. let setting = () => {
  114. // 当前搜索屏蔽词settingText
  115. let div = document.createElement("div")
  116. div.setAttribute("id", "setting")
  117. let maxWidth = parseInt(getComputedStyle(document.querySelector(".btBox")).width.replace("px", ""))
  118. div.innerHTML = `
  119. <button id="switch" class="close">
  120. <svg viewBox="0 0 100 100" width="20" height="20" id="open" style="display: none;">
  121. <path d="M5,70 L50,30 95,70" style="
  122. fill: none;
  123. stroke: #1abc9c;
  124. stroke-linecap: round;
  125. stroke-linejoin: round;
  126. stroke-width: 10;
  127. "/>
  128. </svg>
  129. <svg viewBox="0 0 100 100" width="20" height="20" id="close">
  130. <path d="M5,30 L50,70 95,30" style="
  131. fill: none;
  132. stroke: #1abc9c;
  133. stroke-linecap: round;
  134. stroke-linejoin: round;
  135. stroke-width: 10;
  136. "/>
  137. </svg>
  138. </button>
  139. <div class="forbidden-selection" style="
  140. display: flex;
  141. flex-flow: column;
  142. align-items: center;
  143. display: none;
  144. ">
  145. <div class="input-box">
  146. <div class="forbidden-tag" value="[发晒看]工资">
  147. [发晒看]工资
  148. <div class="cancel">×</div>
  149. </div><div class="input">
  150. <input placeholder="按回车键Enter创建屏蔽词" type="text">
  151. </div>
  152. </div>
  153. <div class="forecommend-forbidden-tags">
  154. <div class="forbidden-tag forbidden-tag-selected">[发晒看]工资</div>
  155. <div class="forbidden-tag">(拼多多|并夕夕|pdd)</div>
  156. <div class="forbidden-tag">话费</div>
  157. <div class="forbidden-tag">"张三"</div>
  158. <div class="forbidden-tag" style="cursor: not-allowed;">敬请期待</div>
  159. </div>
  160. <div id="forbidden-list" style="width: 100%;"></div>
  161. </div>
  162. <style>
  163. *, *::after, *::before {
  164. box-sizing: border-box;
  165. --bakground-color: #2c3e50;
  166. --selected-color: #3498db;
  167. --pic-opacity: 23%;
  168. --title-height: 50px;
  169. --number-color: #00cec9;
  170. --forbidden-input-box-width: ${maxWidth * 0.9}px;
  171. --forbidden-input-box-border-width: 1.5px;
  172. }
  173. #switch {
  174. width: 100%;
  175. height: 20px;
  176. background: none;
  177. border: 0;
  178. cursor: pointer;
  179. }
  180. #setting {
  181. display: flex;
  182. justify-content: center;
  183. flex-flow: column;
  184. padding: 10px;
  185. border: 1px solid rgb(26, 188, 156);
  186. border-radius: 8px;
  187. width: 97%;
  188. margin: 0 auto;
  189. margin-bottom: 8px;
  190. }
  191. .forbidden-selection {
  192. margin-top: 10px;
  193. }
  194. .forbidden-selection > .input-box {
  195. width: var(--forbidden-input-box-width);
  196. display: flex;
  197. align-items: center;
  198. flex-wrap: wrap;
  199. padding: 0px;
  200. margin-bottom: 5px;
  201. outline: solid var(--forbidden-input-box-border-width) rgba(0, 0, 0, .2);
  202. font-size: 14px;
  203. }
  204. .forbidden-selection > .input-box[active] {
  205. outline: solid calc(1.2*var(--forbidden-input-box-border-width)) var(--number-color);
  206. }
  207. .forbidden-selection > .input-box .input {
  208. display: block;
  209. min-width: calc(var(--forbidden-input-box-width) / 2);
  210. flex: 1;
  211. margin: 0 10px;
  212. height: 40px;
  213. }
  214. .forbidden-selection > .input-box .input input {
  215. width: 100%;
  216. height: 100%;
  217. outline: none;
  218. border: none;
  219. }
  220. .forbidden-selection > .input-box:not([active]):hover {
  221. outline: solid var(--forbidden-input-box-border-width) rgba(0, 0, 0, 1);
  222. }
  223. .forecommend-forbidden-tags {
  224. display: flex;
  225. align-items: center;
  226. flex-wrap: wrap;
  227. flex-direction: row;
  228. width: var(--forbidden-input-box-width);
  229. }
  230. .forecommend-forbidden-tags .forbidden-tag, .input-box .forbidden-tag {
  231. border: solid 1px white;
  232. border-radius: 5px;
  233. padding: 4px 10px;
  234. margin: 5px 0 5px 5px;
  235. background-color: #f6f6f6;
  236. cursor: pointer;
  237. font-size: 14px;
  238. line-height: 1.5em;
  239. user-select: none;
  240. }
  241. .input-box .forbidden-tag:active {
  242. background-color: #FF7D7D;
  243. }
  244. .forecommend-forbidden-tags {
  245. display: flex;
  246. align-items: center;
  247. flex-wrap: wrap;
  248. flex-direction: row;
  249. width: var(--forbidden-input-box-width);
  250. }
  251. .forecommend-forbidden-tags .forbidden-tag, .input-box .forbidden-tag {
  252. border: solid 1px white;
  253. border-radius: 5px;
  254. padding: 4px 10px;
  255. margin: 5px 0 5px 5px;
  256. background-color: #f6f6f6;
  257. cursor: pointer;
  258. font-size: 14px;
  259. }
  260. .forecommend-forbidden-tags .forbidden-tag-selected {
  261. background-color: var(--number-color);
  262. color: #fff;
  263. cursor: not-allowed;
  264. }
  265. .input-box .forbidden-tag {
  266. display: flex;
  267. flex-direction: row;
  268. justify-content: space-around;
  269. background-color: var(--number-color);
  270. color: #fff;
  271. padding-right: 5px;
  272. }
  273. .forbidden-selection > .input-box .forbidden-tag .cancel {
  274. margin-left: 5px;
  275. }
  276. </style>
  277. `
  278. document.body.insertBefore(div, document.querySelector(".btbox"))
  279. setTimeout(() => {
  280. // 按钮展开
  281. document.querySelector("#switch").addEventListener("click", function (e) {
  282. if (this.classList.contains("open")) {
  283. // 关闭
  284. this.classList.remove("open")
  285. this.classList.add("close")
  286. this.querySelector("svg#close").style.display = ""
  287. this.querySelector("svg#open").style.display = "none"
  288. document.querySelector(".forbidden-selection").style.display = "none"
  289. } else if (this.classList.contains("close")){
  290. // 打开
  291. this.classList.remove("close")
  292. this.classList.add("open")
  293. this.querySelector("svg#close").style.display = "none"
  294. this.querySelector("svg#open").style.display = ""
  295. document.querySelector(".forbidden-selection").style.display = "flex"
  296. }
  297. })
  298. // 数据选择
  299. document.querySelector(".forbidden-selection input").addEventListener('click', (event) => {
  300. // 输入状态input-box边框变色
  301. document.querySelector(".forbidden-selection .input-box").setAttribute('active', '')
  302. })
  303. document.querySelector(".forbidden-selection input").addEventListener('blur', (event) => {
  304. // 失去焦点恢复
  305. document.querySelector(".forbidden-selection .input-box").removeAttribute('active')
  306. })
  307. let getSelectedForbiddenTags = () => {
  308. let forbiddenTags = []
  309. let selectedNodes = document.querySelectorAll('.input-box .forbidden-tag')
  310. if (selectedNodes.length) {
  311. selectedNodes.forEach((ele) => {
  312. forbiddenTags.push(ele.getAttribute('value'))
  313. })
  314. }
  315. return forbiddenTags
  316. }
  317. let isUseranme = (text) => {
  318. return text.search(/["'“].+["'”]/) != -1
  319. }
  320. let removeForbiddenTag = (forbiddenTag) => {
  321. // 取消要从数据库删除
  322. let forbiddenLocal = JSON.parse(localStorage.getItem("forbidden"))
  323. if (isUseranme(forbiddenTag)) {
  324. // 是用户
  325. forbiddenLocal.usernames = forbiddenLocal.usernames.filter(tag=>{
  326. return tag != forbiddenTag.slice(1, -1)
  327. })
  328. } else {
  329. forbiddenLocal.keywords = forbiddenLocal.keywords.filter(tag=>{
  330. return tag != forbiddenTag
  331. })
  332. }
  333. keywords = forbiddenLocal.keywords
  334. usernames = forbiddenLocal.usernames
  335. localStorage.setItem("forbidden", JSON.stringify(forbiddenLocal))
  336. }
  337. let saveForbiddenTag = (forbiddenTag) => {
  338. // 更新到本地
  339. let forbiddenLocal = JSON.parse(localStorage.getItem("forbidden"))
  340. // 判断新增类型是否为用户
  341. if (isUseranme(forbiddenTag)) {
  342. // 是用户
  343. if (!forbiddenLocal.usernames.includes(forbiddenTag)) {
  344. forbiddenLocal.usernames.push(forbiddenTag.slice(1,-1))
  345. }
  346. } else {
  347. if (!forbiddenLocal.keywords.includes(forbiddenTag)) {
  348. forbiddenLocal.keywords.push(forbiddenTag)
  349. }
  350. }
  351. // 储存
  352. keywords = forbiddenLocal.keywords
  353. usernames = forbiddenLocal.usernames
  354. localStorage.setItem("forbidden", JSON.stringify(forbiddenLocal))
  355. }
  356. let createForbiddenTag = (forbiddenTag) => {
  357. // 判断是否存在
  358. if (getSelectedForbiddenTags().includes(forbiddenTag)) return
  359. let div = document.createElement('div')
  360. div.className = 'forbidden-tag'
  361. div.setAttribute('value', forbiddenTag) // 方便取变量
  362. div.innerHTML = `
  363. ${forbiddenTag}
  364. <div class="cancel">×</div>
  365. `
  366. document.querySelector('.input-box').insertBefore(div, document.querySelector('.input-box .input'))
  367. // 绑定取消选择事件
  368. div.querySelector('.cancel').addEventListener('click', (e) => {
  369. div.remove()
  370. // 取消选择对应的推荐标签
  371. document.querySelectorAll('.forecommend-forbidden-tags .forbidden-tag').forEach((item) => {
  372. if (item.innerText == forbiddenTag) {
  373. item.classList.remove('forbidden-tag-selected')
  374. }
  375. })
  376. removeForbiddenTag(forbiddenTag)
  377. e.stopPropagation()
  378. })
  379. // 点击标签编辑
  380. div.addEventListener("click", (e) => {
  381. let tag = div.getAttribute("value")
  382. div.querySelector(".cancel").click()
  383. document.querySelector(".forbidden-selection input").value = tag
  384. })
  385. // 保存
  386. saveForbiddenTag(forbiddenTag)
  387. // 检查推荐里面是否有同名
  388. document.querySelectorAll(".forecommend-forbidden-tags>.forbidden-tag").forEach(ele=>{
  389. if (ele.innerText == forbiddenTag) {
  390. ele.click()
  391. }
  392. })
  393. }
  394. // 从已有变量选择
  395. document.querySelectorAll(".forecommend-forbidden-tags .forbidden-tag").forEach((item) => {
  396. item.addEventListener('click', (event) => {
  397. if (item.innerText == "敬请期待") return
  398. // 选中颜色高亮
  399. item.classList.add('forbidden-tag-selected')
  400. // 向数据框添加元素
  401. createForbiddenTag(item.innerText)
  402. })
  403. })
  404. // 输入框输入变量
  405. document.querySelector(".forbidden-selection input").addEventListener('keyup', function(event) {
  406. if (event.keyCode == 13) {
  407. let inputValue = this.value
  408. createForbiddenTag(inputValue)
  409. this.value = ""
  410. }
  411. })
  412. // 首次进入需要从本地内存读取关键词
  413. let forbiddenLocal
  414. forbiddenLocal = JSON.parse(localStorage.getItem("forbidden"))
  415. if (localStorage.getItem("forbidden") == null) {
  416. forbiddenLocal = {keywords: [], usernames: []}
  417. localStorage.setItem("forbidden", JSON.stringify(forbiddenLocal))
  418. }
  419. forbiddenLocal.keywords.forEach(forbiddenTag=>{
  420. createForbiddenTag(forbiddenTag)
  421. })
  422. forbiddenLocal.usernames.forEach(forbiddenTag=>{
  423. createForbiddenTag(`"${forbiddenTag}"`)
  424. })
  425. }, 1e3);
  426. }
  427. let currentURL = window.location.href
  428. // 判断当前网址是否为主页
  429. if (currentURL == 'https://yaohuo.me/' || currentURL.search(/bbs-\d+/) != -1) {
  430. console.log("主页/新帖")
  431. // 主页移除关键词
  432. let items = []
  433. document.querySelectorAll('.list a').forEach((e) => {
  434. // 每个节点有两个关键信息:1.href;2.innerText
  435. let href = e.href
  436. let text = e.innerText
  437. if (validate(text)) {
  438. console.log(`remove ${text}`)
  439. } else {
  440. items.push(`${items.length+1}.<a href="${href}">${text}</a>`)
  441. }
  442. })
  443. document.querySelector('.list').innerHTML = items.join("<br>")
  444. // 添加监控点击
  445. document.querySelectorAll('.list>a').forEach((a) => {
  446. a.addEventListener("click", (e) => {
  447. let itemid = a.href.match(/bbs-(\d+)/)[1]
  448. recordAdd(itemid)
  449. })
  450. })
  451. } else if (currentURL.startsWith('https://yaohuo.me/bbs/book_list.aspx?')) {
  452. setting()
  453. // 可能是新帖,也可能是搜索页
  454. if (currentURL.includes('key=')) {
  455. console.log("搜索页")
  456. let searchText = decodeURI(currentURL.match(/key=(.+?)&/)[1])
  457. console.log(searchText)
  458. if (validate(searchText)) {
  459. setTimeout(() => {
  460. alert("你可以遗忘屏蔽词,本脚本将永远不会!\nYou can forget about blocking words, this script will never!")
  461. }, 233);
  462. }
  463. } else {
  464. console.log("新帖页")
  465. }
  466. if (!document.querySelector("#KL_show_next_list")) {
  467. let div = document.createElement("div")
  468. div.setAttribute('id', 'KL_show_next_list')
  469. document.body.insertBefore(div, document.querySelector(".btBox"))
  470. }
  471. // 把body下的条目统一放到KL_show_next_list下,便于统一操作
  472. document.querySelector("#KL_show_next_list").style.display = ""
  473. document.querySelectorAll(".listdata").forEach((ele) => {
  474. document.querySelector("#KL_show_next_list").appendChild(ele.cloneNode(true))
  475. ele.remove()
  476. })
  477. let filterList = (mutations, observer) => {
  478. document.querySelectorAll("#KL_show_next_list>div").forEach((ele) => {
  479. // 每个节点有很多元素
  480. let [itemid, text, username, comment, read] = parseElement(ele)
  481. if (validate(text) || usernames.includes(username.replace(" /", ""))) {
  482. // 这是被过滤掉的e,需要移除
  483. console.log(`remove ${text} - ${username}`)
  484. document.querySelector("#forbidden-list").appendChild(ele.cloneNode(true))
  485. ele.remove()
  486. } else {
  487. // 这是保留下来的ele,先绑定一个点击事件
  488. ele.querySelector("a").addEventListener("click", function(e) {
  489. // 更新次数
  490. recordAdd(itemid)
  491. })
  492. let record = getRecord(itemid)[itemid]
  493. if (record["count"] > 0) {
  494. // 有浏览记录才处理
  495. ele.style.position = "relative"
  496. let add_comment = comment - record["latest_comment"]
  497. let add_read = read - record["latest_read"]
  498. if (ele.querySelector("#record")) {
  499. ele.querySelector("#count>span").innerText = record["count"]
  500. ele.querySelector("#time_info").innerText = getTimeInfo(record["latest_time"])
  501. if (add_comment > 0) {
  502. ele.querySelector("#add_comment").style.display = 'inline-block'
  503. } else {
  504. ele.querySelector("#add_comment").style.display = 'none'
  505. }
  506. if (add_read > 0) {
  507. ele.querySelector("#add_read").style.display = 'inline-block'
  508. } else {
  509. ele.querySelector("#add_read").style.display = 'none'
  510. }
  511. ele.querySelector("#add_comment>span").innerText = (add_comment > 99) ? "+" : add_comment
  512. ele.querySelector("#add_read>span").innerText = (add_read > 99) ? "+" : add_read
  513. } else {
  514. let div = document.createElement('div')
  515. div.setAttribute("id", "record")
  516. div.style = `
  517. position: absolute;
  518. right: 8px;
  519. top: 8px;
  520. color: #999;
  521. font-size: 10px;
  522. opacity: .7;
  523. `
  524. div.innerHTML = `
  525. <div id="count" style="
  526. display: inline-block;
  527. text-align: center;
  528. line-height: 15px;
  529. width: 15px;
  530. height: 15px;
  531. background-color: #FF7D7D;
  532. border-radius: 50%;
  533. ">
  534. <span style="font-size: 12px; color: white;">${record["count"]}</span>
  535. </div>
  536. <div id="add_comment" style="
  537. display: inline-block;
  538. text-align: center;
  539. line-height: 15px;
  540. width: 15px;
  541. height: 15px;
  542. background-color: #54BAB9;
  543. border-radius: 50%;
  544. display: ${(add_comment<=0) ? 'none' : ''};
  545. ">
  546. <span style="font-size: 12px; color: white;">${(add_comment > 99) ? "+" : add_comment}</span>
  547. </div>
  548. <div id="add_read" style="
  549. display: inline-block;
  550. text-align: center;
  551. line-height: 15px;
  552. width: 15px;
  553. height: 15px;
  554. background-color: #636e72;
  555. border-radius: 50%;
  556. display: ${(add_read <= 0) ? 'none' : ''};
  557. ">
  558. <span style="font-size: 12px; color: white;">${(add_read > 99) ? "+" : add_read}</span>
  559. </div>
  560. <div style="
  561. width: 50px;
  562. display: inline-block;
  563. text-align: right;
  564. ">
  565. <span id="time_info">${getTimeInfo(record["latest_time"])}</span>
  566. </div>
  567. `
  568. ele.appendChild(div)
  569. }
  570. }
  571. }
  572. })
  573. }
  574. filterList(null, null)
  575. var observer = new MutationObserver(filterList)
  576. var node = document.querySelector('#KL_show_tip')
  577. if (node) {
  578. observer.observe(node, {childList: true})
  579. }
  580. setInterval(() => {
  581. // 5s一次更新时间
  582. filterList(null, null)
  583. }, 1e3)
  584. }
  585. // 监控浏览页面数据变化及时更新
  586. if (currentURL.search(/bbs-\d+/) != -1) {
  587. let update = (mutations, observer) => {
  588. let itemid = currentURL.match(/bbs-(\d+)/)[1]
  589. let comment
  590. // 根据最新回复显示楼层判断回复数量
  591. let text = document.querySelector(".reline").innerText
  592. let res = text.match(/\[(\d+)楼\]/)
  593. if (res) {
  594. comment = parseInt(res[1])
  595. } else {
  596. comment = document.querySelectorAll(".reline").length
  597. }
  598. let read = parseInt(document.querySelector(".content").innerText.match(/阅(\d+)/)[1])
  599. recordAdd(itemid, comment, read)
  600. console.log(itemid, comment, read)
  601. }
  602. setTimeout(() => {
  603. update(null, null)
  604. let observer = new MutationObserver(update)
  605. const config = {childList: true, subtree: true, characterDataOldValue: true}
  606. document.querySelectorAll(".content").forEach(ele=>{
  607. observer.observe(ele, config)
  608. })
  609. }, 1000)
  610. }
  611. // 添加搜索按钮监听
  612. if (currentURL == 'https://yaohuo.me/') {
  613. document.querySelector("input[type=submit]").addEventListener("click", (e) => {
  614. let text = document.querySelector("input[type=text]").value
  615. console.log(text)
  616. if (validate(text)) {
  617. e.preventDefault()
  618. document.querySelector("input[type=text]").value = "请重新组织你的语言!"
  619. setTimeout(() => {
  620. document.querySelector("input[type=text]").value = ""
  621. }, 1000);
  622. }
  623. })
  624. }
  625. })();

QingJ © 2025

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