- // ==UserScript==
- // @name 98助手
- // @namespace 98Helper@Never4Ever
- // @version 0.4
- // @description 98助手,原98自动签到助手
- // @author Never4Ever
-
- // @include https://www.sehuatang.*
- // @include https://www.weterytrtrr.*
- // @include https://www.qweqwtret.*
- // @include https://www.retreytryuyt.*
- // @include https://www.qwerwrrt.*
- // @include https://sehuatang.*
- // @include https://weterytrtrr.*
- // @include https://qweqwtret.*
- // @include https://retreytryuyt.*
- // @include https://qwerwrrt.*
-
- // @grant GM_setValue
- // @grant GM_getValue
- // @grant GM_setClipboard
- // @grant GM_xmlhttpRequest
- // @grant GM_getResourceText
- // @grant GM_addStyle
- // @grant GM_openInTab
- // @grant GM_registerMenuCommand
-
- // @resource IMPORTED_CSS https://unpkg.com/view-design@4.7.0-beta.10/dist/styles/iview.css
-
- // @require https://unpkg.com/arrive@2.4.1/src/arrive.js
- // @require https://unpkg.com/vue@2.6.14/dist/vue.min.js
- // @require https://unpkg.com/view-design@4.7.0-beta.10/dist/iview.min.js
- // @run-at document-end
- // ==/UserScript==
-
- (function () {
- 'use strict';
-
- const my_css = GM_getResourceText("IMPORTED_CSS");
- GM_addStyle(my_css);
-
- const my_css_1 = `
- .readThread{
- background:#F7F2F2
- }
- a{
- color:#333;
- text-decoration:none;
- }
- .ttp a{
- height:28px
- }
- #scbar_txt{
- height:20px
- }
- .pi{
- height:40px
- }
- .avt img{
- padding:0px;
- border:0px
- }
-
- .vertical-center-modal {
- display: flex;
- align-items: center;
- justify-content: center;
- }
-
- `;
-
-
- GM_addStyle(my_css_1);
-
- GM_registerMenuCommand("设置", showSetting)
-
- const ConfigKeys = {
- lastSignDate: "98+LastSignDate",
- quickJumpUrl: "98+QuickJumpUrl",
- ignoredIDs: "98+IgnoredIDs",
- readThreads: "98+ReadThreads",
- showImages: "98+ShowImages",
- setOrder: "98+SetOrder"
- };
-
- const Config = {
- getLastSignDateByUserID: function (userID) {
- return GM_getValue(`${userID}+${ConfigKeys.lastSignDate}`) || "";
- },
- setLastSignDateByUserID: function (userID, dateString) {
- GM_setValue(`${userID}+${ConfigKeys.lastSignDate}`, dateString);
- },
-
- getIgnoredIds: function () {
- return GM_getValue(ConfigKeys.ignoredIDs) || [];
- },
- setIgnoredIDs: function (ignoredidsList = []) {
- GM_setValue(ConfigKeys.ignoredIDs, ignoredidsList);
- },
-
-
- getReadThreads: function () {
- return GM_getValue(ConfigKeys.readThreads) || [];
- },
- setReadThreads: function (readThreadsList = []) {
- GM_setValue(ConfigKeys.readThreads, readThreadsList);
- },
-
- getShowImages: function () {
- return GM_getValue(ConfigKeys.showImages) || true;
- },
- setShowImagess: function (showImages) {
- GM_setValue(ConfigKeys.showImages, showImages);
- },
-
- getSetOrder: function () {
- return GM_getValue(ConfigKeys.setOrder) || false;
- },
- setSetOrder: function (setOrder) {
- GM_setValue(ConfigKeys.setOrder, setOrder);
- },
-
- getQuickJumpUrl: function () {
- return GM_getValue(ConfigKeys.quickJumpUrl) || '';
- },
- setQuickJumpUrl: function (quickJumpUrl) {
- GM_setValue(ConfigKeys.quickJumpUrl, quickJumpUrl);
- },
-
- }
-
-
-
-
- const siteMap = {
- "每日合集": 106,
- "国产原创": 2,
- "亚洲无码原创": 36,
- "亚洲有码原创": 37,
- "高清中文字幕": 103,
- "三级写真": 107,
- "素人有码系列": 104,
- "欧美无码": 38,
- "4K原版": 151,
- "韩国主播": 152,
- "动漫原创": 39,
- "国产自拍": 41,
- "中文字幕": 109,
- "日韩无码": 42,
- "日韩有码": 43,
- "欧美风情": 44,
- "卡通动漫": 45,
- "剧情三级": 46,
- "自提字幕区": 145,
- "自译字幕区": 146,
- "字幕分享区": 121,
- "分享新区": 159,
- "原创自拍区": 155,
- "转贴自拍": 125,
- "华人街拍区": 50,
- "亚洲性爱": 48,
- "欧美性爱": 49,
- "卡通动漫": 117,
- "原创人生": 154,
- "乱伦人妻": 135,
- "青春校园": 137,
- "武侠虚幻": 138,
- "激情都市": 136,
- "TXT小说下载": 139,
- "综合讨论区": 95,
- "色花视频自拍": 124,
- "网友原创区": 141,
- "转帖交流区": 142,
- "求片问答悬赏区": 143,
- "投诉建议区": 96,
- "禁言申诉区": 150,
- "资源出售区": 97,
- "投稿送邀请码": 157
- };
-
-
-
-
- const template = `
-
- <div id="mybutton" style="left: 93%;position:fixed;top:140px">
- <Row>
- <template>
- <Button style="width:80px;margin:1px" type="error" size="small" v-on:click="click"
- title="签到入口">{{signText}}</Button>
- <modal v-model="signModal"
- title="每日签到,验证,确认"
- :closable="false">
- <p>{{validateText}}</p>
- <input v-model="validateResult"/>
- </modal>
- </tamplate>
- </Row>
- <Row v-if="settingInfo.isShowPinnedItemButton">
- <Button title="快速跳转" @click="quickJump" style="width:80px;margin:1px" type="info" size="small">快速跳转</Button>
- </Row>
- <Row v-if="isShowTimeOrderButton">
- <Button @click="orderClick" title="强制按发帖时间排序,设置会被记忆" style="width:80px;margin:1px" type="warning" size="small">
- {{getOrderButtonText}}
- </Button>
- </Row>
- <Row v-if="isShowImageButton">
- <Button @click="imageClick" title="隐藏或者显示图片,设置会被记忆" style="width:80px;margin:1px" type="warning" size="small">
- {{getImageButtonText}}
- </Button>
- </Row>
- <Row v-if="isShowCopyCodeButton">
- <Button @click="copyCodes" style="width:80px;margin:1px" type="info" size="small">复制代码</Button>
- </Row>
- <Row v-if="isShowRateButton">
- <Button title="直接最高评分+通知作者,以资鼓励" @click="rate" style="width:80px;margin:1px" type="info" size="small">评分</Button>
- </Row>
- <Row v-if="isShowStarButton">
- <Button style="width:80px;margin:1px" type="info" size="small">收藏</Button>
- </Row>
-
- <Row v-if="isShowTwoButton">
- <Button title="一键,收藏+直接最高评分+通知作者" @click="twoAction" id="twoButton" style="width:80px;margin:1px" type="info" size="small">一键二连</Button>
- </Row>
-
-
- <template>
- <modal v-model="settingInfo.isShow" title="98助手设置"
- :closable="false" :mask-closable="false"
- fullscreen
- @on-ok="settingModalConfirm">
- <div >
- <div>
- <p>🔶设置“快速跳转”按钮的链接:(为空则不会出现这个按钮)</p>
- <input v-model="settingInfo.pinnedItemUrl" placeholder="添加本站链接,不需要域名.如:/forum.php?mod=viewthread&tid=717385" style="width:650px"/>
- </div>
- <Divider />
-
- <p>🔶忽略设置,按默认顺序浏览的板块:</p>
- <template>
- <div >
- <CheckboxGroup style="display: flex;flex-wrap:wrap;" v-model="settingInfo.ignoredItems">
- <template>
- <Checkbox v-for="(item,index) in settingInfo.siteItems" :label="item" :key="item" style="margin-top:4px" border >{{item.name}}</Checkbox>
-
- </template>
- </CheckboxGroup>
- </div>
-
- </template>
-
-
- </div>
- </modal>
- </template>
- </div>
-
- `;
- 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`;
- let jumpUrl = `https://${window.location.host}/plugin.php?id=dd_sign:index`;
- let signUrl = '/plugin.php?id=dd_sign&mod=sign&signsubmit=yes&handlekey=pc_click_ddsign&signhash=LsUpb&inajax=1'
-
- let scrolltop = document.getElementById("scrolltop");
- let div = document.createElement('div');
- div.id = "mydivcommon";
- scrolltop.insertAdjacentElement("beforebegin", div);
-
- var appVue = new Vue({
- el: '#mydivcommon',
- template: template,
- data: {
- userID: "",
- signText: "签到",
- validateText: "",
- validateResult: "98!",
- imageButtonText: "X 图片",
- isShowCopyCodeButton: false,
- isShowImageButton: false,
- isShowRateButton: false,
- isShowStarButton: false,
- isShowTwoButton: false,
- isImagesShows: true,
- isShowTimeOrderButton: false,
- isSetOrder: false,
- signModal: false,
- settingInfo: {
- isShow: false,
- ignoredItems: [],
- siteItems: [],
- pinnedItemUrl: "",
- isShowPinnedItemButton: false,
- },
- settingInfo_pinnedItemUrl: "",
- settingInfo_isShowPinnedItemButton: false,
- },
- computed: {
- getOrderButtonText: function () {
- return this.isSetOrder ? "关*发帖时间" : "开*发帖时间";
- },
- getImageButtonText: function () {
- return this.isImagesShows ? "隐藏图片" : "显示图片";
- }
- },
- methods: {
- quickJump: function () {
- GM_openInTab(`https://${window.location.host}${this.settingInfo.pinnedItemUrl}`, false);
- },
- checkSetting() {
- let quickJumpUrl = Config.getQuickJumpUrl();
- if (quickJumpUrl) {
- this.settingInfo.pinnedItemUrl = quickJumpUrl;
- this.settingInfo.isShowPinnedItemButton = true;
- }
-
- // let ids = Config.getIgnoredIds();
- // for (let site in siteMap) {
- // let aSite = {
- // name: site,
- // id: siteMap[site]
- // };
- // this.settingInfo.siteItems.push(aSite);
- // if (ids.includes(aSite.id)) {
- // this.settingInfo.ignoredItems.push(aSite);
- // }
- // }
- },
- settingModalShow: function () {
- this.settingInfo.isShow = true;
- this.settingInfo.siteItems = [];
- this.settingInfo.ignoredItems = [];
-
- let ids = Config.getIgnoredIds();
- for (let site in siteMap) {
- let aSite = {
- name: site,
- id: siteMap[site]
- };
- this.settingInfo.siteItems.push(aSite);
- if (ids.includes(aSite.id)) {
- this.settingInfo.ignoredItems.push(aSite);
- }
- }
-
-
- },
- settingModalConfirm: function () {
- if (this.settingInfo.pinnedItemUrl) {
- this.settingInfo.isShowPinnedItemButton = true;
- Config.setQuickJumpUrl(this.settingInfo.pinnedItemUrl);
- } else {
- this.settingInfo.isShowPinnedItemButton = false;
- Config.setQuickJumpUrl("");
- }
-
- console.log(this.settingInfo.ignoredItems);
-
- let ids = this.settingInfo.ignoredItems.map(q => q.id);
- Config.setIgnoredIDs(ids)
-
-
- },
- getUserID: function () {
- let urlWithUserID = document.querySelector("div.avt > a").href;
- let params = new URLSearchParams(urlWithUserID);
- this.userID = params.get("uid");
- },
- getValidateText: async function () {
- let signed = false;
- let xmlString = await fetch(url).then(r => r.text());
- let xml = new DOMParser().parseFromString(xmlString, 'text/xml');
- let content = xml.getElementsByTagName('root')[0].textContent;
-
- let doc = new DOMParser().parseFromString(content, 'text/html')
- let formhash = doc.querySelector('input[name="formhash"]').value;
- let signtoken = doc.querySelector('input[name="signtoken"]').value;
- let signhash = doc.querySelector('form[name="login"]').getAttribute('id').replace('signform_', '');
-
- console.log(`formhash:${formhash},signtoken:${signtoken},signhash:${signhash}`)
- let resultText = await fetch(`/misc.php?mod=secqaa&action=update&idhash=qSAxcb0`)
- .then(t => t.text());
-
- let text = resultText.replace("sectplcode[2] + '", "前").replace("' + sectplcode[3]", "后");
- let re = /前([\w\W]+)后/;
- let groups = text.match(re);
- this.validateText = groups[1];
- this.validateResult = eval(this.validateText.replace("= ?", ""));
- let secqaahash = 'qSAxcb0';
-
- let data = new URLSearchParams();
- data.append('formhash', formhash);
- data.append('signtoken', signtoken);
- data.append('secqaahash', secqaahash);
- data.append('secanswer', this.validateResult);
-
- let thisSignUrl = `/plugin.php?id=dd_sign&mod=sign&signsubmit=yes&handlekey=pc_click_ddsign&signhash=${signhash}&inajax=1`
- let request = new Request(thisSignUrl, {
- method: 'post',
- headers: {
- 'Content-Type': 'application/x-www-form-urlencoded'
- },
- body: data
- })
-
- await fetch(request).then(r => r.text()).then(r => {
- if (r.indexOf('已经签到过')) {
- this.showTip('已经签到过啦,请明天再来!')
- signed = true;
- } else if (r.indexOf('签到成功')) {
- this.showTip('签到成功,金钱+2,明天记得来哦。')
- signed = true;
- } else {
- this.showTip('抱歉,签到出现了未知错误!')
-
- }
-
- });
-
- return signed;
-
- },
- click: function () {
- GM_openInTab(jumpUrl, false);
- //this.signModal = !this.signModal;
- //this.getValidateText();
- },
- showImages: function (dom, isShow) {
- let display = isShow ? "inline" : "none";
- let nodes = dom.querySelectorAll('.t_fsz img');
- for (const img of nodes) {
- img.style.display = display;
- }
- },
- imageClick: function () {
- this.isImagesShows = !this.isImagesShows;
- this.showImages(document, this.isImagesShows);
- Config.setShowImagess(this.isImagesShows);
- let msg = `已经记住设置:${this.isImagesShows?"显示图片":"隐藏图片"}`;
- this.showTip(msg);
- },
- copyCodes: function () {
- let nodes = document.querySelectorAll('.blockcode li');
- if (nodes && nodes.length > 0) {
- let allLis = Array.prototype.slice.call(nodes);
- let text = allLis.map(li => li.innerText.replace("\n", "")).join("\r\n");
- console.log(text);
- GM_setClipboard(text);
- this.showTip(`已经复制${allLis.length}条到剪贴板!`);
- } else {
- this.showTip(`抱歉,未找到或者出现问题!`);
- }
-
- },
- checkSign: async function () {
-
- let date = new Date();
- let dateString = date.toLocaleDateString();
-
- let recordDateString = Config.getLastSignDateByUserID(this.userID);
- let signed = false;
- if (recordDateString == dateString) {
- signed = true;
- }
-
- if (!signed) {
- let isSigned = await this.getValidateText()
- if (isSigned) {
- Config.setLastSignDateByUserID(this.userID, dateString);
- signed = true;
- this.signText = "已签到";
- //GM_openInTab(jumpUrl, false);
- }
-
- } else {
- this.signText = "已签到";
- }
- },
- checkImage: function () {
- this.isImagesShows = Config.getShowImages();
- this.showImages(document, this.isImagesShows);
- },
- checkOrder: function () {
- let searchParams = new URLSearchParams(window.location.search);
- let mod=searchParams.get("mod");
- if (window.location.href.indexOf("fid=") != -1&&mod=="forumdisplay") {
- this.isShowTimeOrderButton = true;
- } else {
- return;
- }
-
- let isWantedOrder = searchParams.get('filter') == "author" && searchParams.get('orderby') == "dateline";
-
- this.isSetOrder = Config.getSetOrder();
- if (this.isSetOrder && !isWantedOrder) {
- this.setOrder();
- }
- },
- setOrder: function () {
- let searchParams = new URLSearchParams(window.location.search);
- searchParams.set('filter', 'author');
- searchParams.set('orderby', 'dateline');
- let fid=parseInt(searchParams.get("fid"));
- let mod=searchParams.get("mod");
- if(mod=="forumdisplay"){
- let ignores= Config.getIgnoredIds();
- if(ignores.includes(fid)){
- this.showTip("此板块助手排序已被您忽略,有需要在“设置”中重新设置")
- }
- else{
- window.location.search = searchParams;
- }
- }
- },
- orderClick: function () {
- this.isSetOrder = !this.isSetOrder;
- Config.setSetOrder(this.isSetOrder);
- let msg = `已经记住设置:${this.isSetOrder?"强制按发帖时间排序":"不强制按发帖时间排序"}`;
- this.showTip(msg);
- let searchParams = new URLSearchParams(window.location.search);
- let isWantedOrder = searchParams.get('filter') == "author" && searchParams.get('orderby') == "dateline";
- if (!isWantedOrder && this.isSetOrder) {
- this.setOrder();
- }
- },
- showTip: function (msg) {
- if (msg.indexOf("抱歉") != -1) {
- this.$Message.error({
- background: true,
- content: msg
- });
- } else {
- this.$Message.success({
- background: true,
- content: msg
- });
- }
-
- },
- checkAll: function () {
- this.getUserID();
- this.checkOrder();
- this.checkSign();
- this.checkImage();
- this.checkSetting();
- },
- getPid: async function () {
- let localUrl = window.location.href;
- let myUrl = new URL(localUrl);
- let params = new URLSearchParams(myUrl.search);
- params.set('page', 1);
- myUrl.search = params;
- console.log(myUrl.href);
- let pid = await fetch(myUrl.href).then(r => r.text()).then(r => {
- let doc = new DOMParser().parseFromString(r, 'text/html')
- return doc.querySelectorAll('table[id^="pid"]')[0].id
- });
- return pid.replace("pid", "");
- },
- getRateInfo: async function (pid, tid, timestamp) {
- let info = {
- state: false,
- max: 0,
- left: 0,
- formHash: '',
- referer: '',
- handleKey: '',
- error: ''
- };
- try {
- let url = `/forum.php?mod=misc&action=rate&tid=${tid}&pid=${pid}&infloat=yes&handlekey=rate&t=${timestamp}&inajax=1&ajaxtarget=fwin_content_rate`;
- let text = await fetch(url).then(r => r.text());
- let xml = new DOMParser().parseFromString(text, 'text/xml');
- let content = xml.getElementsByTagName('root')[0].textContent;
- if (content.indexOf('抱歉') != -1) {
- info.error = "抱歉,您不能对同一个帖子重复评分或者对自己发表的帖子评分";
- return info;
- }
- let doc = new DOMParser().parseFromString(content, 'text/html')
-
- info.max = parseInt(doc.querySelector('#scoreoption8 li').innerText.replace("+", ""));
- info.left = parseInt(doc.querySelector('.dt.mbm td:last-child').innerText);
- info.formHash = doc.querySelector('input[name="formhash"]').value;
- info.referer = doc.querySelector('input[name="referer"]').value;
- info.handleKey = doc.querySelector('input[name="handlekey"]').value;
- if (info.max > info.left) {
- info.max = info.left;
- }
- info.state = true;
- console.log(info);
- } catch (error) {
- console.error("getRateInfo error");
- console.error(error);
- }
- return info;
- },
- rate: async function () {
- let pid = await this.getPid();
- let tid = new URLSearchParams(window.location.search).get("tid");
- let timestamp = new Date().getTime();
- let rateInfo = await this.getRateInfo(pid, tid, timestamp);
- console.log(rateInfo);
- if (!rateInfo.state) {
- this.showTip(rateInfo.error);
- return;
- }
-
-
- let rateUrl = '/forum.php?mod=misc&action=rate&ratesubmit=yes&infloat=yes&inajax=1';
- let data = new URLSearchParams();
- data.append('formhash', rateInfo.formHash);
- data.append('tid', tid);
- data.append('pid', pid);
- data.append('referer', rateInfo.referer);
- data.append('handlekey', rateInfo.handleKey);
- data.append('score8', `+${rateInfo.max}`);
- data.append('reason', '');
- data.append('sendreasonpm', 'on');
-
- let request = new Request(rateUrl, {
- method: 'post',
- headers: {
- 'Content-Type': 'application/x-www-form-urlencoded'
- },
- body: data
- })
-
- fetch(request).then(r => r.text()).then(r => {
- if (r.indexOf('感谢您的参与,现在将转入评分前页面') != -1) {
- this.showTip(`+${rateInfo.max} 评分成功,并通知了楼主!`);
- } else {
- console.log(r);
- this.showTip("抱歉,评分失败!")
- }
- });
-
-
- },
- star: async function () {
- let tid = new URLSearchParams(window.location.search).get("tid");
- let formHash = document.querySelector('input[name="formhash"]').value;
- 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`;
-
- let text = await fetch(starUrl).then(r => r.text());
- if (text.indexOf("抱歉,您已收藏,请勿重复收藏") != -1) {
- this.showTip("抱歉,您已收藏,请勿重复收藏");
- } else if (text.indexOf("信息收藏成功") != -1) {
- this.showTip("信息收藏成功");
- } else {
- this.showTip("信息收藏出现问题!!!");
- console.error(text);
- }
- },
- twoAction: async function () {
- await this.star();
- await this.rate();
- }
-
-
-
- },
- });
-
- appVue.checkAll();
-
- function showSetting() {
- appVue.settingModalShow();
- }
-
- function addReadItem(){
- let searchParams = new URLSearchParams(window.location.search);
- let tid= searchParams.get("tid");
- if(tid){
- console.log("保存"+tid)
- let threads= Config.getReadThreads();
- threads.unshift(tid);
- threads.slice(0,98);
- Config.setReadThreads(threads);
- }
- }
-
- addReadItem();
-
- document.arrive('.t_fsz', {
- existing: true
- }, function () {
- appVue.isShowTwoButton = true;
- appVue.isShowRateButton = true;
-
- let codes = this.querySelectorAll('.blockcode');
- if (codes && codes.length > 0) appVue.isShowCopyCodeButton = true;
-
- for (let code of codes) {
- let btn = `<button class="ivu-btn ivu-btn-info ivu-btn-small">(增强)复制代码</button>`;
- code.insertAdjacentHTML("afterbegin", btn);
- let button = code.getElementsByTagName("button")[0];
- button.onclick = function () {
- let lis = Array.prototype.slice.call(code.getElementsByTagName("li"));
- let text = lis.map(li => li.innerText.replace("\n", "")).join("\r\n");
- GM_setClipboard(text);
- appVue.showTip(`已经复制${lis.length}条到剪贴板!`);
- }
- }
-
- let imgs = this.querySelectorAll('img');
- if (imgs && imgs.length > 0) appVue.isShowImageButton = true;
- });
-
- document.arrive(`tbody[id*="thread_"]`, {
- existing: true
- }, function () {
- let tid= this.id.split('_')[1];
- let tids= Config.getReadThreads();
- if(tids.includes(tid)){
- this.classList.add("readThread");
- }
-
- })
-
-
-
-
- // var buttonSign = '<button style="background: #b50000;color: white;" id="mySignButton">签到</button>';
-
- // if (!document.getElementById('mySignButton')) {
- // var scoreP = document.getElementById('extcreditmenu');
- // scoreP.insertAdjacentHTML('beforebegin', buttonSign);
- // }
-
- // var mySignButton = document.getElementById('mySignButton');
- // mySignButton.onclick = function () {
- // window.open(jump_url);
- // }
-
- // if (signed) {
- // mySignButton.innerText = "今日已签到";
- // mySignButton.style.background='grey';
- // }
- // else {
- // //签到
- // GM_xmlhttpRequest(
- // {
- // method: "get",
- // url: url,
- // onload: function (r) {
- // GM_setValue("98tang+last+sign+date", my_date.toLocaleDateString());
- // signed = true;
- // mySignButton.innerText = "今日已签到"
- // mySignButton.style.background='grey';
- // window.open(jump_url);
- // }
- // }
- // );
- // }
-
-
-
- // Your code here...
- })();