Sleazy Fork is available in English.

98助手

98助手,原98自动签到助手

  1. // ==UserScript==
  2. // @name 98助手
  3. // @namespace 98Helper@Never4Ever
  4. // @version 0.4
  5. // @description 98助手,原98自动签到助手
  6. // @author Never4Ever
  7.  
  8. // @include https://www.sehuatang.*
  9. // @include https://www.weterytrtrr.*
  10. // @include https://www.qweqwtret.*
  11. // @include https://www.retreytryuyt.*
  12. // @include https://www.qwerwrrt.*
  13. // @include https://sehuatang.*
  14. // @include https://weterytrtrr.*
  15. // @include https://qweqwtret.*
  16. // @include https://retreytryuyt.*
  17. // @include https://qwerwrrt.*
  18.  
  19. // @grant GM_setValue
  20. // @grant GM_getValue
  21. // @grant GM_setClipboard
  22. // @grant GM_xmlhttpRequest
  23. // @grant GM_getResourceText
  24. // @grant GM_addStyle
  25. // @grant GM_openInTab
  26. // @grant GM_registerMenuCommand
  27.  
  28. // @resource IMPORTED_CSS https://unpkg.com/view-design@4.7.0-beta.10/dist/styles/iview.css
  29.  
  30. // @require https://unpkg.com/arrive@2.4.1/src/arrive.js
  31. // @require https://unpkg.com/vue@2.6.14/dist/vue.min.js
  32. // @require https://unpkg.com/view-design@4.7.0-beta.10/dist/iview.min.js
  33. // @run-at document-end
  34. // ==/UserScript==
  35.  
  36. (function () {
  37. 'use strict';
  38.  
  39. const my_css = GM_getResourceText("IMPORTED_CSS");
  40. GM_addStyle(my_css);
  41.  
  42. const my_css_1 = `
  43. .readThread{
  44. background:#F7F2F2
  45. }
  46. a{
  47. color:#333;
  48. text-decoration:none;
  49. }
  50. .ttp a{
  51. height:28px
  52. }
  53. #scbar_txt{
  54. height:20px
  55. }
  56. .pi{
  57. height:40px
  58. }
  59. .avt img{
  60. padding:0px;
  61. border:0px
  62. }
  63.  
  64. .vertical-center-modal {
  65. display: flex;
  66. align-items: center;
  67. justify-content: center;
  68. }
  69. `;
  70.  
  71.  
  72. GM_addStyle(my_css_1);
  73.  
  74. GM_registerMenuCommand("设置", showSetting)
  75.  
  76. const ConfigKeys = {
  77. lastSignDate: "98+LastSignDate",
  78. quickJumpUrl: "98+QuickJumpUrl",
  79. ignoredIDs: "98+IgnoredIDs",
  80. readThreads: "98+ReadThreads",
  81. showImages: "98+ShowImages",
  82. setOrder: "98+SetOrder"
  83. };
  84.  
  85. const Config = {
  86. getLastSignDateByUserID: function (userID) {
  87. return GM_getValue(`${userID}+${ConfigKeys.lastSignDate}`) || "";
  88. },
  89. setLastSignDateByUserID: function (userID, dateString) {
  90. GM_setValue(`${userID}+${ConfigKeys.lastSignDate}`, dateString);
  91. },
  92.  
  93. getIgnoredIds: function () {
  94. return GM_getValue(ConfigKeys.ignoredIDs) || [];
  95. },
  96. setIgnoredIDs: function (ignoredidsList = []) {
  97. GM_setValue(ConfigKeys.ignoredIDs, ignoredidsList);
  98. },
  99.  
  100.  
  101. getReadThreads: function () {
  102. return GM_getValue(ConfigKeys.readThreads) || [];
  103. },
  104. setReadThreads: function (readThreadsList = []) {
  105. GM_setValue(ConfigKeys.readThreads, readThreadsList);
  106. },
  107.  
  108. getShowImages: function () {
  109. return GM_getValue(ConfigKeys.showImages) || true;
  110. },
  111. setShowImagess: function (showImages) {
  112. GM_setValue(ConfigKeys.showImages, showImages);
  113. },
  114.  
  115. getSetOrder: function () {
  116. return GM_getValue(ConfigKeys.setOrder) || false;
  117. },
  118. setSetOrder: function (setOrder) {
  119. GM_setValue(ConfigKeys.setOrder, setOrder);
  120. },
  121.  
  122. getQuickJumpUrl: function () {
  123. return GM_getValue(ConfigKeys.quickJumpUrl) || '';
  124. },
  125. setQuickJumpUrl: function (quickJumpUrl) {
  126. GM_setValue(ConfigKeys.quickJumpUrl, quickJumpUrl);
  127. },
  128.  
  129. }
  130.  
  131.  
  132.  
  133.  
  134. const siteMap = {
  135. "每日合集": 106,
  136. "国产原创": 2,
  137. "亚洲无码原创": 36,
  138. "亚洲有码原创": 37,
  139. "高清中文字幕": 103,
  140. "三级写真": 107,
  141. "素人有码系列": 104,
  142. "欧美无码": 38,
  143. "4K原版": 151,
  144. "韩国主播": 152,
  145. "动漫原创": 39,
  146. "国产自拍": 41,
  147. "中文字幕": 109,
  148. "日韩无码": 42,
  149. "日韩有码": 43,
  150. "欧美风情": 44,
  151. "卡通动漫": 45,
  152. "剧情三级": 46,
  153. "自提字幕区": 145,
  154. "自译字幕区": 146,
  155. "字幕分享区": 121,
  156. "分享新区": 159,
  157. "原创自拍区": 155,
  158. "转贴自拍": 125,
  159. "华人街拍区": 50,
  160. "亚洲性爱": 48,
  161. "欧美性爱": 49,
  162. "卡通动漫": 117,
  163. "原创人生": 154,
  164. "乱伦人妻": 135,
  165. "青春校园": 137,
  166. "武侠虚幻": 138,
  167. "激情都市": 136,
  168. "TXT小说下载": 139,
  169. "综合讨论区": 95,
  170. "色花视频自拍": 124,
  171. "网友原创区": 141,
  172. "转帖交流区": 142,
  173. "求片问答悬赏区": 143,
  174. "投诉建议区": 96,
  175. "禁言申诉区": 150,
  176. "资源出售区": 97,
  177. "投稿送邀请码": 157
  178. };
  179.  
  180.  
  181.  
  182.  
  183. const template = `
  184. <div id="mybutton" style="left: 93%;position:fixed;top:140px">
  185. <Row>
  186. <template>
  187. <Button style="width:80px;margin:1px" type="error" size="small" v-on:click="click"
  188. title="签到入口">{{signText}}</Button>
  189. <modal v-model="signModal"
  190. title="每日签到,验证,确认"
  191. :closable="false">
  192. <p>{{validateText}}</p>
  193. <input v-model="validateResult"/>
  194. </modal>
  195. </tamplate>
  196. </Row>
  197. <Row v-if="settingInfo.isShowPinnedItemButton">
  198. <Button title="快速跳转" @click="quickJump" style="width:80px;margin:1px" type="info" size="small">快速跳转</Button>
  199. </Row>
  200. <Row v-if="isShowTimeOrderButton">
  201. <Button @click="orderClick" title="强制按发帖时间排序,设置会被记忆" style="width:80px;margin:1px" type="warning" size="small">
  202. {{getOrderButtonText}}
  203. </Button>
  204. </Row>
  205. <Row v-if="isShowImageButton">
  206. <Button @click="imageClick" title="隐藏或者显示图片,设置会被记忆" style="width:80px;margin:1px" type="warning" size="small">
  207. {{getImageButtonText}}
  208. </Button>
  209. </Row>
  210. <Row v-if="isShowCopyCodeButton">
  211. <Button @click="copyCodes" style="width:80px;margin:1px" type="info" size="small">复制代码</Button>
  212. </Row>
  213. <Row v-if="isShowRateButton">
  214. <Button title="直接最高评分+通知作者,以资鼓励" @click="rate" style="width:80px;margin:1px" type="info" size="small">评分</Button>
  215. </Row>
  216. <Row v-if="isShowStarButton">
  217. <Button style="width:80px;margin:1px" type="info" size="small">收藏</Button>
  218. </Row>
  219.  
  220. <Row v-if="isShowTwoButton">
  221. <Button title="一键,收藏+直接最高评分+通知作者" @click="twoAction" id="twoButton" style="width:80px;margin:1px" type="info" size="small">一键二连</Button>
  222. </Row>
  223.  
  224. <template>
  225. <modal v-model="settingInfo.isShow" title="98助手设置"
  226. :closable="false" :mask-closable="false"
  227. fullscreen
  228. @on-ok="settingModalConfirm">
  229. <div >
  230. <div>
  231. <p>🔶设置“快速跳转”按钮的链接:(为空则不会出现这个按钮)</p>
  232. <input v-model="settingInfo.pinnedItemUrl" placeholder="添加本站链接,不需要域名.如:/forum.php?mod=viewthread&tid=717385" style="width:650px"/>
  233. </div>
  234. <Divider />
  235.  
  236. <p>🔶忽略设置,按默认顺序浏览的板块:</p>
  237. <template>
  238. <div >
  239. <CheckboxGroup style="display: flex;flex-wrap:wrap;" v-model="settingInfo.ignoredItems">
  240. <template>
  241. <Checkbox v-for="(item,index) in settingInfo.siteItems" :label="item" :key="item" style="margin-top:4px" border >{{item.name}}</Checkbox>
  242. </template>
  243. </CheckboxGroup>
  244. </div>
  245. </template>
  246.  
  247. </div>
  248. </modal>
  249. </template>
  250. </div>
  251.  
  252. `;
  253. let url = `https://${window.location.host}/plugin.php?id=dd_sign&mod=sign&infloat=yes&handlekey=pc_click_ddsign&inajax=1&ajaxtarget=fwin_content_pc_click_ddsign`;
  254. let jumpUrl = `https://${window.location.host}/plugin.php?id=dd_sign:index`;
  255. let signUrl = '/plugin.php?id=dd_sign&mod=sign&signsubmit=yes&handlekey=pc_click_ddsign&signhash=LsUpb&inajax=1'
  256.  
  257. let scrolltop = document.getElementById("scrolltop");
  258. let div = document.createElement('div');
  259. div.id = "mydivcommon";
  260. scrolltop.insertAdjacentElement("beforebegin", div);
  261.  
  262. var appVue = new Vue({
  263. el: '#mydivcommon',
  264. template: template,
  265. data: {
  266. userID: "",
  267. signText: "签到",
  268. validateText: "",
  269. validateResult: "98!",
  270. imageButtonText: "X 图片",
  271. isShowCopyCodeButton: false,
  272. isShowImageButton: false,
  273. isShowRateButton: false,
  274. isShowStarButton: false,
  275. isShowTwoButton: false,
  276. isImagesShows: true,
  277. isShowTimeOrderButton: false,
  278. isSetOrder: false,
  279. signModal: false,
  280. settingInfo: {
  281. isShow: false,
  282. ignoredItems: [],
  283. siteItems: [],
  284. pinnedItemUrl: "",
  285. isShowPinnedItemButton: false,
  286. },
  287. settingInfo_pinnedItemUrl: "",
  288. settingInfo_isShowPinnedItemButton: false,
  289. },
  290. computed: {
  291. getOrderButtonText: function () {
  292. return this.isSetOrder ? "关*发帖时间" : "开*发帖时间";
  293. },
  294. getImageButtonText: function () {
  295. return this.isImagesShows ? "隐藏图片" : "显示图片";
  296. }
  297. },
  298. methods: {
  299. quickJump: function () {
  300. GM_openInTab(`https://${window.location.host}${this.settingInfo.pinnedItemUrl}`, false);
  301. },
  302. checkSetting() {
  303. let quickJumpUrl = Config.getQuickJumpUrl();
  304. if (quickJumpUrl) {
  305. this.settingInfo.pinnedItemUrl = quickJumpUrl;
  306. this.settingInfo.isShowPinnedItemButton = true;
  307. }
  308.  
  309. // let ids = Config.getIgnoredIds();
  310. // for (let site in siteMap) {
  311. // let aSite = {
  312. // name: site,
  313. // id: siteMap[site]
  314. // };
  315. // this.settingInfo.siteItems.push(aSite);
  316. // if (ids.includes(aSite.id)) {
  317. // this.settingInfo.ignoredItems.push(aSite);
  318. // }
  319. // }
  320. },
  321. settingModalShow: function () {
  322. this.settingInfo.isShow = true;
  323. this.settingInfo.siteItems = [];
  324. this.settingInfo.ignoredItems = [];
  325.  
  326. let ids = Config.getIgnoredIds();
  327. for (let site in siteMap) {
  328. let aSite = {
  329. name: site,
  330. id: siteMap[site]
  331. };
  332. this.settingInfo.siteItems.push(aSite);
  333. if (ids.includes(aSite.id)) {
  334. this.settingInfo.ignoredItems.push(aSite);
  335. }
  336. }
  337.  
  338.  
  339. },
  340. settingModalConfirm: function () {
  341. if (this.settingInfo.pinnedItemUrl) {
  342. this.settingInfo.isShowPinnedItemButton = true;
  343. Config.setQuickJumpUrl(this.settingInfo.pinnedItemUrl);
  344. } else {
  345. this.settingInfo.isShowPinnedItemButton = false;
  346. Config.setQuickJumpUrl("");
  347. }
  348.  
  349. console.log(this.settingInfo.ignoredItems);
  350.  
  351. let ids = this.settingInfo.ignoredItems.map(q => q.id);
  352. Config.setIgnoredIDs(ids)
  353.  
  354.  
  355. },
  356. getUserID: function () {
  357. let urlWithUserID = document.querySelector("div.avt > a").href;
  358. let params = new URLSearchParams(urlWithUserID);
  359. this.userID = params.get("uid");
  360. },
  361. getValidateText: async function () {
  362. let signed = false;
  363. let xmlString = await fetch(url).then(r => r.text());
  364. let xml = new DOMParser().parseFromString(xmlString, 'text/xml');
  365. let content = xml.getElementsByTagName('root')[0].textContent;
  366.  
  367. let doc = new DOMParser().parseFromString(content, 'text/html')
  368. let formhash = doc.querySelector('input[name="formhash"]').value;
  369. let signtoken = doc.querySelector('input[name="signtoken"]').value;
  370. let signhash = doc.querySelector('form[name="login"]').getAttribute('id').replace('signform_', '');
  371.  
  372. console.log(`formhash:${formhash},signtoken:${signtoken},signhash:${signhash}`)
  373. let resultText = await fetch(`/misc.php?mod=secqaa&action=update&idhash=qSAxcb0`)
  374. .then(t => t.text());
  375.  
  376. let text = resultText.replace("sectplcode[2] + '", "前").replace("' + sectplcode[3]", "后");
  377. let re = /前([\w\W]+)后/;
  378. let groups = text.match(re);
  379. this.validateText = groups[1];
  380. this.validateResult = eval(this.validateText.replace("= ?", ""));
  381. let secqaahash = 'qSAxcb0';
  382.  
  383. let data = new URLSearchParams();
  384. data.append('formhash', formhash);
  385. data.append('signtoken', signtoken);
  386. data.append('secqaahash', secqaahash);
  387. data.append('secanswer', this.validateResult);
  388.  
  389. let thisSignUrl = `/plugin.php?id=dd_sign&mod=sign&signsubmit=yes&handlekey=pc_click_ddsign&signhash=${signhash}&inajax=1`
  390. let request = new Request(thisSignUrl, {
  391. method: 'post',
  392. headers: {
  393. 'Content-Type': 'application/x-www-form-urlencoded'
  394. },
  395. body: data
  396. })
  397.  
  398. await fetch(request).then(r => r.text()).then(r => {
  399. if (r.indexOf('已经签到过')) {
  400. this.showTip('已经签到过啦,请明天再来!')
  401. signed = true;
  402. } else if (r.indexOf('签到成功')) {
  403. this.showTip('签到成功,金钱+2,明天记得来哦。')
  404. signed = true;
  405. } else {
  406. this.showTip('抱歉,签到出现了未知错误!')
  407.  
  408. }
  409.  
  410. });
  411.  
  412. return signed;
  413.  
  414. },
  415. click: function () {
  416. GM_openInTab(jumpUrl, false);
  417. //this.signModal = !this.signModal;
  418. //this.getValidateText();
  419. },
  420. showImages: function (dom, isShow) {
  421. let display = isShow ? "inline" : "none";
  422. let nodes = dom.querySelectorAll('.t_fsz img');
  423. for (const img of nodes) {
  424. img.style.display = display;
  425. }
  426. },
  427. imageClick: function () {
  428. this.isImagesShows = !this.isImagesShows;
  429. this.showImages(document, this.isImagesShows);
  430. Config.setShowImagess(this.isImagesShows);
  431. let msg = `已经记住设置:${this.isImagesShows?"显示图片":"隐藏图片"}`;
  432. this.showTip(msg);
  433. },
  434. copyCodes: function () {
  435. let nodes = document.querySelectorAll('.blockcode li');
  436. if (nodes && nodes.length > 0) {
  437. let allLis = Array.prototype.slice.call(nodes);
  438. let text = allLis.map(li => li.innerText.replace("\n", "")).join("\r\n");
  439. console.log(text);
  440. GM_setClipboard(text);
  441. this.showTip(`已经复制${allLis.length}条到剪贴板!`);
  442. } else {
  443. this.showTip(`抱歉,未找到或者出现问题!`);
  444. }
  445.  
  446. },
  447. checkSign: async function () {
  448.  
  449. let date = new Date();
  450. let dateString = date.toLocaleDateString();
  451.  
  452. let recordDateString = Config.getLastSignDateByUserID(this.userID);
  453. let signed = false;
  454. if (recordDateString == dateString) {
  455. signed = true;
  456. }
  457.  
  458. if (!signed) {
  459. let isSigned = await this.getValidateText()
  460. if (isSigned) {
  461. Config.setLastSignDateByUserID(this.userID, dateString);
  462. signed = true;
  463. this.signText = "已签到";
  464. //GM_openInTab(jumpUrl, false);
  465. }
  466.  
  467. } else {
  468. this.signText = "已签到";
  469. }
  470. },
  471. checkImage: function () {
  472. this.isImagesShows = Config.getShowImages();
  473. this.showImages(document, this.isImagesShows);
  474. },
  475. checkOrder: function () {
  476. let searchParams = new URLSearchParams(window.location.search);
  477. let mod=searchParams.get("mod");
  478. if (window.location.href.indexOf("fid=") != -1&&mod=="forumdisplay") {
  479. this.isShowTimeOrderButton = true;
  480. } else {
  481. return;
  482. }
  483. let isWantedOrder = searchParams.get('filter') == "author" && searchParams.get('orderby') == "dateline";
  484. this.isSetOrder = Config.getSetOrder();
  485. if (this.isSetOrder && !isWantedOrder) {
  486. this.setOrder();
  487. }
  488. },
  489. setOrder: function () {
  490. let searchParams = new URLSearchParams(window.location.search);
  491. searchParams.set('filter', 'author');
  492. searchParams.set('orderby', 'dateline');
  493. let fid=parseInt(searchParams.get("fid"));
  494. let mod=searchParams.get("mod");
  495. if(mod=="forumdisplay"){
  496. let ignores= Config.getIgnoredIds();
  497. if(ignores.includes(fid)){
  498. this.showTip("此板块助手排序已被您忽略,有需要在“设置”中重新设置")
  499. }
  500. else{
  501. window.location.search = searchParams;
  502. }
  503. }
  504. },
  505. orderClick: function () {
  506. this.isSetOrder = !this.isSetOrder;
  507. Config.setSetOrder(this.isSetOrder);
  508. let msg = `已经记住设置:${this.isSetOrder?"强制按发帖时间排序":"不强制按发帖时间排序"}`;
  509. this.showTip(msg);
  510. let searchParams = new URLSearchParams(window.location.search);
  511. let isWantedOrder = searchParams.get('filter') == "author" && searchParams.get('orderby') == "dateline";
  512. if (!isWantedOrder && this.isSetOrder) {
  513. this.setOrder();
  514. }
  515. },
  516. showTip: function (msg) {
  517. if (msg.indexOf("抱歉") != -1) {
  518. this.$Message.error({
  519. background: true,
  520. content: msg
  521. });
  522. } else {
  523. this.$Message.success({
  524. background: true,
  525. content: msg
  526. });
  527. }
  528.  
  529. },
  530. checkAll: function () {
  531. this.getUserID();
  532. this.checkOrder();
  533. this.checkSign();
  534. this.checkImage();
  535. this.checkSetting();
  536. },
  537. getPid: async function () {
  538. let localUrl = window.location.href;
  539. let myUrl = new URL(localUrl);
  540. let params = new URLSearchParams(myUrl.search);
  541. params.set('page', 1);
  542. myUrl.search = params;
  543. console.log(myUrl.href);
  544. let pid = await fetch(myUrl.href).then(r => r.text()).then(r => {
  545. let doc = new DOMParser().parseFromString(r, 'text/html')
  546. return doc.querySelectorAll('table[id^="pid"]')[0].id
  547. });
  548. return pid.replace("pid", "");
  549. },
  550. getRateInfo: async function (pid, tid, timestamp) {
  551. let info = {
  552. state: false,
  553. max: 0,
  554. left: 0,
  555. formHash: '',
  556. referer: '',
  557. handleKey: '',
  558. error: ''
  559. };
  560. try {
  561. let url = `/forum.php?mod=misc&action=rate&tid=${tid}&pid=${pid}&infloat=yes&handlekey=rate&t=${timestamp}&inajax=1&ajaxtarget=fwin_content_rate`;
  562. let text = await fetch(url).then(r => r.text());
  563. let xml = new DOMParser().parseFromString(text, 'text/xml');
  564. let content = xml.getElementsByTagName('root')[0].textContent;
  565. if (content.indexOf('抱歉') != -1) {
  566. info.error = "抱歉,您不能对同一个帖子重复评分或者对自己发表的帖子评分";
  567. return info;
  568. }
  569. let doc = new DOMParser().parseFromString(content, 'text/html')
  570.  
  571. info.max = parseInt(doc.querySelector('#scoreoption8 li').innerText.replace("+", ""));
  572. info.left = parseInt(doc.querySelector('.dt.mbm td:last-child').innerText);
  573. info.formHash = doc.querySelector('input[name="formhash"]').value;
  574. info.referer = doc.querySelector('input[name="referer"]').value;
  575. info.handleKey = doc.querySelector('input[name="handlekey"]').value;
  576. if (info.max > info.left) {
  577. info.max = info.left;
  578. }
  579. info.state = true;
  580. console.log(info);
  581. } catch (error) {
  582. console.error("getRateInfo error");
  583. console.error(error);
  584. }
  585. return info;
  586. },
  587. rate: async function () {
  588. let pid = await this.getPid();
  589. let tid = new URLSearchParams(window.location.search).get("tid");
  590. let timestamp = new Date().getTime();
  591. let rateInfo = await this.getRateInfo(pid, tid, timestamp);
  592. console.log(rateInfo);
  593. if (!rateInfo.state) {
  594. this.showTip(rateInfo.error);
  595. return;
  596. }
  597.  
  598.  
  599. let rateUrl = '/forum.php?mod=misc&action=rate&ratesubmit=yes&infloat=yes&inajax=1';
  600. let data = new URLSearchParams();
  601. data.append('formhash', rateInfo.formHash);
  602. data.append('tid', tid);
  603. data.append('pid', pid);
  604. data.append('referer', rateInfo.referer);
  605. data.append('handlekey', rateInfo.handleKey);
  606. data.append('score8', `+${rateInfo.max}`);
  607. data.append('reason', '');
  608. data.append('sendreasonpm', 'on');
  609.  
  610. let request = new Request(rateUrl, {
  611. method: 'post',
  612. headers: {
  613. 'Content-Type': 'application/x-www-form-urlencoded'
  614. },
  615. body: data
  616. })
  617.  
  618. fetch(request).then(r => r.text()).then(r => {
  619. if (r.indexOf('感谢您的参与,现在将转入评分前页面') != -1) {
  620. this.showTip(`+${rateInfo.max} 评分成功,并通知了楼主!`);
  621. } else {
  622. console.log(r);
  623. this.showTip("抱歉,评分失败!")
  624. }
  625. });
  626.  
  627.  
  628. },
  629. star: async function () {
  630. let tid = new URLSearchParams(window.location.search).get("tid");
  631. let formHash = document.querySelector('input[name="formhash"]').value;
  632. let starUrl = `/home.php?mod=spacecp&ac=favorite&type=thread&id=${tid}&formhash=${formHash}&infloat=yes&handlekey=k_favorite&inajax=1&ajaxtarget=fwin_content_k_favorite`;
  633.  
  634. let text = await fetch(starUrl).then(r => r.text());
  635. if (text.indexOf("抱歉,您已收藏,请勿重复收藏") != -1) {
  636. this.showTip("抱歉,您已收藏,请勿重复收藏");
  637. } else if (text.indexOf("信息收藏成功") != -1) {
  638. this.showTip("信息收藏成功");
  639. } else {
  640. this.showTip("信息收藏出现问题!!!");
  641. console.error(text);
  642. }
  643. },
  644. twoAction: async function () {
  645. await this.star();
  646. await this.rate();
  647. }
  648.  
  649.  
  650.  
  651. },
  652. });
  653.  
  654. appVue.checkAll();
  655.  
  656. function showSetting() {
  657. appVue.settingModalShow();
  658. }
  659.  
  660. function addReadItem(){
  661. let searchParams = new URLSearchParams(window.location.search);
  662. let tid= searchParams.get("tid");
  663. if(tid){
  664. console.log("保存"+tid)
  665. let threads= Config.getReadThreads();
  666. threads.unshift(tid);
  667. threads.slice(0,98);
  668. Config.setReadThreads(threads);
  669. }
  670. }
  671.  
  672. addReadItem();
  673.  
  674. document.arrive('.t_fsz', {
  675. existing: true
  676. }, function () {
  677. appVue.isShowTwoButton = true;
  678. appVue.isShowRateButton = true;
  679.  
  680. let codes = this.querySelectorAll('.blockcode');
  681. if (codes && codes.length > 0) appVue.isShowCopyCodeButton = true;
  682.  
  683. for (let code of codes) {
  684. let btn = `<button class="ivu-btn ivu-btn-info ivu-btn-small">(增强)复制代码</button>`;
  685. code.insertAdjacentHTML("afterbegin", btn);
  686. let button = code.getElementsByTagName("button")[0];
  687. button.onclick = function () {
  688. let lis = Array.prototype.slice.call(code.getElementsByTagName("li"));
  689. let text = lis.map(li => li.innerText.replace("\n", "")).join("\r\n");
  690. GM_setClipboard(text);
  691. appVue.showTip(`已经复制${lis.length}条到剪贴板!`);
  692. }
  693. }
  694.  
  695. let imgs = this.querySelectorAll('img');
  696. if (imgs && imgs.length > 0) appVue.isShowImageButton = true;
  697. });
  698.  
  699. document.arrive(`tbody[id*="thread_"]`, {
  700. existing: true
  701. }, function () {
  702. let tid= this.id.split('_')[1];
  703. let tids= Config.getReadThreads();
  704. if(tids.includes(tid)){
  705. this.classList.add("readThread");
  706. }
  707. })
  708.  
  709.  
  710.  
  711.  
  712. // var buttonSign = '<button style="background: #b50000;color: white;" id="mySignButton">签到</button>';
  713.  
  714. // if (!document.getElementById('mySignButton')) {
  715. // var scoreP = document.getElementById('extcreditmenu');
  716. // scoreP.insertAdjacentHTML('beforebegin', buttonSign);
  717. // }
  718.  
  719. // var mySignButton = document.getElementById('mySignButton');
  720. // mySignButton.onclick = function () {
  721. // window.open(jump_url);
  722. // }
  723.  
  724. // if (signed) {
  725. // mySignButton.innerText = "今日已签到";
  726. // mySignButton.style.background='grey';
  727. // }
  728. // else {
  729. // //签到
  730. // GM_xmlhttpRequest(
  731. // {
  732. // method: "get",
  733. // url: url,
  734. // onload: function (r) {
  735. // GM_setValue("98tang+last+sign+date", my_date.toLocaleDateString());
  736. // signed = true;
  737. // mySignButton.innerText = "今日已签到"
  738. // mySignButton.style.background='grey';
  739. // window.open(jump_url);
  740. // }
  741. // }
  742. // );
  743. // }
  744.  
  745.  
  746.  
  747. // Your code here...
  748. })();