查看S1不可见内容(审核中/禁言)手动版

查看S1正在审核中的帖子和被禁言用户的回帖

  1. // ==UserScript==
  2. // @name 查看S1不可见内容(审核中/禁言)手动版
  3. // @namespace http://tampermonkey.net/
  4. // @version 0.1.8
  5. // @description 查看S1正在审核中的帖子和被禁言用户的回帖
  6. // @author ShienPro
  7. // @match https://stage1st.com/2b/thread-*
  8. // @grant none
  9. // @run-at context-menu
  10. // @require https://lf6-cdn-tos.bytecdntp.com/cdn/expire-1-M/jquery/3.5.1/jquery.min.js
  11. // @require https://lf6-cdn-tos.bytecdntp.com/cdn/expire-1-M/jsrender/1.0.8/jsrender.min.js
  12. // @license WTFPL
  13. // ==/UserScript==
  14. (function () {
  15. 'use strict';
  16.  
  17. const $ = jQuery.noConflict();
  18. const api = 'https://app.stage1st.com/2b/api/app';
  19.  
  20. const dialogTmpl = $.templates(`
  21. <div id="login-dialog" style="width: 400px; height: 260px; position: fixed; top: 50%; left: 50%; margin-left: -200px; margin-top: -130px; z-index: 999; background: #F6F7EB; border: 3px solid #CCCC99; padding-left: 20px; padding-right: 20px;">
  22. <div style="width: 100%; padding-top: 20px">通过s1官方app接口查看不可见内容,需要单独登录(不可用)<span style="float: right" class="flbc" id="login-close"></span></div>
  23. <div style="width: 100%; padding-top: 20px"><input type="text" id="username" value="{{:username}}" placeholder="用户名"></div>
  24. <div style="width: 100%; padding-top: 20px"><input type="password" id="password" value="{{:password}}" placeholder="密码"></div>
  25. <div style="width: 100%; padding-top: 20px">
  26. <select id="questionId">
  27. <option value="0">安全提问(未设置请忽略)</option>
  28. <option value="1">母亲的名字</option>
  29. <option value="2">爷爷的名字</option>
  30. <option value="3">父亲出生的城市</option>
  31. <option value="4">您其中一位老师的名字</option>
  32. <option value="5">您个人计算机的型号</option>
  33. <option value="6">您最喜欢的餐馆名称</option>
  34. <option value="7">驾驶执照最后四位数字</option>
  35. </select>
  36. </div>
  37. <div id="answer-row" hidden>
  38. <div style="width: 100%; padding-top: 20px"><input type="text" id="answer" placeholder="答案"></div>
  39. </div>
  40. <div style="width: 100%; padding-top: 20px"><button id="login-confirm">确定</button></div>
  41. <div style="width: 100%; padding-top: 20px; color: red">{{:msg}}</div>
  42. </div>`);
  43. const postTmpl = $.templates(`
  44. <div class="t_fsz">
  45. <table cellspacing="0" cellpadding="0">
  46. <tbody>
  47. <tr>
  48. <td class="t_f" id="postmessage_{{:pid}}">
  49. {{:message}}
  50. </td>
  51. </tr>
  52. </tbody>
  53. </table>
  54. </div>
  55. `);
  56. const threadTmpl = $.templates(`
  57. <script type="text/javascript">var fid = parseInt('{{:fid}}'), tid = parseInt('{{:tid}}');</script>
  58.  
  59. <script src="data/cache/forum_viewthread.js?Qin" type="text/javascript"></script>
  60. <script type="text/javascript">zoomstatus = parseInt(1);
  61. var imagemaxwidth = '800';
  62. var aimgcount = new Array();</script>
  63.  
  64.  
  65. <div class="wp">
  66. <!--[diy=diy1]-->
  67. <div id="diy1" class="area"></div><!--[/diy]-->
  68. </div>
  69.  
  70. <div id="ct" class="wp cl">
  71. <div id="pgt" class="pgs mbm cl ">
  72. <div class="pgt">
  73. <div class="pg">
  74. <label>
  75. <input type="text" name="custompage" class="px" size="{{:totalPage}}" title="输入页码,按回车快速跳转"
  76. value="{{:pageNo}}"
  77. onkeydown="if(event.keyCode==13) {window.location='forum.php?mod=viewthread&amp;tid={{:tid}}&amp;extra=page%3D1&amp;page='+this.value;; doane(event);}">
  78. <span title="共 {{:totalPage}} 页"> / {{:totalPage}} 页</span>
  79. </label>
  80. {{if nextPage != null}}
  81. <a href="thread-{{:tid}}-{{:nextPage}}-1.html" class="nxt">下一页</a>
  82. {{/if}}
  83. </div>
  84. </div>
  85. <span class="y pgb" id="visitedforums"
  86. onmouseover="$('visitedforums').id = 'visitedforumstmp';this.id = 'visitedforums';showMenu({'ctrlid':this.id,'pos':'34'})"
  87. initialized="true"><a href="forum-{{:fid}}-1.html">返回列表</a></span>
  88. </div>
  89.  
  90. <div id="postlist" class="pl bm">
  91. <table cellspacing="0" cellpadding="0">
  92. <tbody>
  93. <tr>
  94. <td class="pls ptn pbn">
  95. <div class="hm ptn">
  96. <span class="xg1">查看:</span> <span class="xi1">{{:views}}</span><span class="pipe">|</span><span
  97. class="xg1">回复:</span> <span class="xi1">{{:replies}}</span>
  98. </div>
  99. </td>
  100. <td class="plc ptm pbn vwthd">
  101. <div class="y">
  102. <a href="forum.php?mod=viewthread&amp;action=printable&amp;tid=296694" title="打印"
  103. target="_blank"><img src="https://static.stage1st.com/image/s1/print.png" alt="打印"
  104. class="vm"></a>
  105. <a href="forum.php?mod=redirect&amp;goto=nextoldset&amp;tid=296694" title="上一主题"><img
  106. src="https://static.stage1st.com/image/s1/thread-prev.png" alt="上一主题" class="vm"></a>
  107. <a href="forum.php?mod=redirect&amp;goto=nextnewset&amp;tid=296694" title="下一主题"><img
  108. src="https://static.stage1st.com/image/s1/thread-next.png" alt="下一主题" class="vm"></a>
  109. </div>
  110. <h1 class="ts">
  111. <span id="thread_subject">{{:subject}}</span>
  112. </h1>
  113. <span class="xg1">
  114. </span>
  115. </td>
  116. </tr>
  117. </tbody>
  118. </table>
  119. <table cellspacing="0" cellpadding="0" class="ad">
  120. <tbody>
  121. <tr>
  122. <td class="pls">
  123. </td>
  124. <td class="plc">
  125. </td>
  126. </tr>
  127. </tbody>
  128. </table>
  129. </div>
  130. {{if nextPage != null}}
  131. <div class="pgbtn"><a href="thread-{{:tid}}-{{:nextPage}}-1.html" hidefocus="true" class="bm_h">下一页 »</a></div>
  132. {{/if}}
  133. <div class="pgs mtm mbm cl">
  134. <div class="pg">
  135. <label><input type="text" name="custompage" class="px" size="{{:totalPage}}" title="输入页码,按回车快速跳转"
  136. value="{{:pageNo}}"
  137. onkeydown="if(event.keyCode==13) {window.location='forum.php?mod=viewthread&amp;tid={{:tid}}&amp;extra=page%3D1&amp;page='+this.value;; doane(event);}">
  138. <span title="共 {{:totalPage}} 页"> / {{:totalPage}} 页</span>
  139. </label>
  140. {{if nextPage != null}}
  141. <a href="thread-{{:tid}}-2-1.html" class="nxt">下一页</a>
  142. {{/if}}
  143. </div>
  144. </div>
  145.  
  146. <script type="text/javascript">document.onkeyup = function (e) {
  147. keyPageScroll(e, 0, 1, 'forum.php?mod=viewthread&tid={{:tid}}', 1);
  148. }</script>
  149. </div>
  150.  
  151. <div class="wp mtn">
  152. <!--[diy=diy3]-->
  153. <div id="diy3" class="area"></div><!--[/diy]-->
  154. </div>`)
  155. const postInThreadTmpl = $.templates(`
  156. <div id="post_{{:pid}}">
  157. <table id="pid{{:pid}}" class="plhin" summary="pid{{:pid}}" cellspacing="0" cellpadding="0">
  158. <tbody>
  159. <tr>
  160. <td class="pls" rowspan="2">
  161. <div id="favatar{{:pid}}" class="pls favatar">
  162. <div class="pi">
  163. <div class="authi"><a href="space-uid-{{:authorid}}.html" target="_blank" class="xw1">{{:author}}</a>
  164. </div>
  165. </div>
  166. <div class="p_pop blk bui card_gender_0" id="userinfo{{:pid}}"
  167. style="display: none; margin-top: -11px;">
  168. <div class="m z">
  169. <div id="userinfo{{:pid}}_ma">
  170. <a href="space-uid-{{:pid}}.html" class="avtm" target="_blank">
  171. <img src="https://avatar.stage1st.com/images/noavatar_middle.gif"
  172. onerror="this.onerror=null;this.src='https://avatar.stage1st.com/images/noavatar_middle.gif'">
  173. </a>
  174. </div>
  175. </div>
  176. </div>
  177. <div>
  178. <div class="avatar" onmouseover="showauthor(this, 'userinfo{{:pid}}')"><a
  179. href="space-uid-{{:authorid}}.html" class="avtm" target="_blank"><img
  180. src="https://avatar.stage1st.com/images/noavatar_middle.gif"
  181. onerror="this.onerror=null;this.src='https://avatar.stage1st.com/images/noavatar_middle.gif'"></a>
  182. </div>
  183. </div>
  184.  
  185. <p><em><a href="home.php?mod=spacecp&amp;ac=usergroup&amp;gid={{:gorupidid}}" target="_blank">{{:grouptitle}}</a></em>
  186. </p>
  187.  
  188.  
  189. <p><span id="g_up{{:pid}}" onmouseover="showMenu({'ctrlid':this.id, 'pos':'12!'});"></span></p>
  190. <div id="g_up{{:pid}}_menu" class="tip tip_{{:position}}" style="display: none;">
  191. <div class="tip_horn"></div>
  192. <div class="tip_c">{{:grouptitle}}, 积分 0, 距离下一级还需 500 积分</div>
  193. </div>
  194.  
  195.  
  196. <p><span class="pbg2" id="upgradeprogress_{{:pid}}"
  197. onmouseover="showMenu({'ctrlid':this.id, 'pos':'12!', 'menuid':'g_up{{:pid}}_menu'});"><span
  198. class="pbr2" style="width:2%;"></span></span></p>
  199. <div id="g_up{{:pid}}_menu" class="tip tip_{{:position}}" style="display: none;">
  200. <div class="tip_horn"></div>
  201. <div class="tip_c">{{:grouptitle}}, 积分 0, 距离下一级还需 500 积分</div>
  202. </div>
  203. </div>
  204. </td>
  205. <td class="plc">
  206. <div class="pi">
  207. <strong>
  208. <a href="forum.php?mod=redirect&amp;goto=findpost&amp;ptid=29669{{:position}}&amp;pid={{:pid}}"
  209. id="postnum{{:pid}}" onclick="setCopy(this.href, '帖子地址复制成功');return false;">
  210. <em>{{:position}}</em><sup>#</sup></a>
  211. </strong>
  212. <div class="pti">
  213. <div class="pdbt">
  214. </div>
  215. <div class="authi">
  216. <img class="authicn vm" id="authicon{{:pid}}"
  217. src="https://static.stage1st.com/image/common/online_member.gif">
  218. <em id="authorposton{{:pid}}">发表于 {{:time}}</em>
  219. <span class="pipe">|</span>
  220. <a href="forum.php?mod=viewthread&amp;tid={{:tid}}&amp;page=1&amp;authorid={{:authorid}}"
  221. rel="nofollow">只看该作者</a>
  222. </div>
  223. </div>
  224. </div>
  225. <div class="pct">
  226. <div class="pcb">
  227. <div class="t_fsz">
  228. <table cellspacing="0" cellpadding="0">
  229. <tbody>
  230. <tr>
  231. <td class="t_f" id="postmessage_{{:pid}}">
  232. {{:message}}
  233. </td>
  234. </tr>
  235. </tbody>
  236. </table>
  237. </div>
  238. <div id="comment_{{:pid}}" class="cm">
  239. </div>
  240.  
  241. <div id="post_rate_div_{{:pid}}"></div>
  242. </div>
  243. </div>
  244.  
  245. </td>
  246. </tr>
  247. <tr>
  248. <td class="plc plm">
  249. </td>
  250. </tr>
  251. <tr id="_postposition{{:pid}}"></tr>
  252. <tr>
  253. <td class="pls"></td>
  254. <td class="plc" style="overflow:visible;">
  255. <div class="po hin">
  256. <div class="pob cl">
  257. <em>
  258. <a class="fastre"
  259. href="forum.php?mod=post&amp;action=reply&amp;fid=27&amp;tid={{:tid}}&amp;repquote={{:pid}}&amp;extra=page%3D1&amp;page=1"
  260. onclick="showWindow('reply', this.href)">回复</a>
  261. </em>
  262.  
  263. <p>
  264. <a href="javascript:;" id="mgc_post_{{:pid}}" onmouseover="showMenu(this.id)"
  265. class="showmenu" style="display: none;"></a>
  266. <a href="javascript:;"
  267. onclick="showWindow('rate', 'forum.php?mod=misc&amp;action=rate&amp;tid={{:tid}}&amp;pid={{:pid}}', 'get', -1);return false;">评分</a>
  268. <a href="javascript:;"
  269. onclick="showWindow('miscreport{{:pid}}', 'misc.php?mod=report&amp;rtype=post&amp;rid={{:pid}}&amp;tid={{:tid}}&amp;fid=27', 'get', -1);return false;">举报</a>
  270. </p>
  271.  
  272. <ul id="mgc_post_{{:pid}}_menu" class="p_pop mgcmn" style="display: none;">
  273. </ul>
  274. <script type="text/javascript" reload="1">checkmgcmn('post_{{:pid}}')</script>
  275. </div>
  276. </div>
  277. </td>
  278. </tr>
  279. <tr class="ad">
  280. <td class="pls">
  281. </td>
  282. <td class="plc">
  283. </td>
  284. </tr>
  285. </tbody>
  286. </table>
  287. </div>`)
  288.  
  289. function login(username, password, questionId, answer) {
  290. const data = {
  291. username: username,
  292. password: password
  293. }
  294. if (questionId !== '0') {
  295. data.questionid = questionId;
  296. data.answer = answer;
  297. }
  298. $.ajax({
  299. type: 'POST',
  300. url: api + '/user/login',
  301. data: data,
  302. success: function (resp) {
  303. const code = resp.code.toString();
  304. if (code.startsWith('50')) {
  305. loginAndReplaceThreadContent({username, password, msg: resp.message});
  306. return;
  307. }
  308. localStorage.setItem('app_sid', resp.data.sid);
  309. $('#login-dialog').remove();
  310. main();
  311. },
  312. error: function (err) {
  313. loginAndReplaceThreadContent({username, password, msg: '请求错误'});
  314. }
  315. });
  316. }
  317.  
  318. function loginAndReplaceThreadContent(data) {
  319. $('#login-dialog').remove();
  320. $('body').append(dialogTmpl.render(data));
  321.  
  322. const rawHeight = $('#login-dialog').height();
  323. $('#questionId').change(function () {
  324. let questionId = $(this).val();
  325. if (questionId === '0') {
  326. $('#login-dialog').height(rawHeight);
  327. $('#answer-row').hide();
  328. } else {
  329. $('#login-dialog').height(rawHeight + 44);
  330. $('#answer-row').show();
  331. }
  332. });
  333.  
  334. $('#login-confirm').click(function () {
  335. const username = $('#username').val();
  336. const password = $('#password').val();
  337. const questionId = $('#questionId').val();
  338. const answer = $('#answer').val();
  339. login(username, password, questionId, answer);
  340. });
  341.  
  342. $('#login-close').click(function () {
  343. $('#login-dialog').remove();
  344. })
  345. }
  346.  
  347. function replaceThreadContent() {
  348. // 整个帖子
  349. if ($('#messagetext:contains(内容审核中,即将开放)').html()) {
  350. getThreadInfo()
  351. .then(info => {
  352. info.pageNo = parseInt(pageNo);
  353. info.totalPage = (parseInt(info.replies / pageSize)) + 1;
  354. info.nextPage = info.pageNo < info.totalPage ? info.pageNo + 1 : null;
  355. $('#wp').html(threadTmpl.render(info));
  356. document.title = document.title.replace('提示信息', info.subject + ' - ' + info.fname);
  357. return getThreadContent();
  358. })
  359. .then(data => {
  360. const postList = $('#postlist');
  361. data.list.forEach(post => {
  362. const date = new Date(post.dateline * 1000);
  363. post.time = date.getFullYear() + '-' + (date.getMonth() + 1) + '-' + date.getDate() + ' ' + date.getHours() + ':' + date.getMinutes();
  364. const content = postInThreadTmpl.render(post);
  365. postList.append(content);
  366. });
  367. })
  368. .catch(() => main({msg: "登录(不可用)失效"}));
  369. }
  370. // 部分回复
  371. else {
  372. const blockedPost = $('.plhin:contains(作者被禁止或删除 内容自动屏蔽)');
  373. if (blockedPost.length === 0) return;
  374.  
  375. getThreadContent()
  376. .then(data => {
  377. const postList = data.list;
  378. let pi = 0;
  379. blockedPost.each((i, post) => {
  380. const postId = post.id.substr(3);
  381. let postData;
  382. for (; pi < postList.length && (postData = postList[pi]).pid.toString() !== postId; pi++) ;
  383.  
  384. $(post).find('.pcb').html(postTmpl.render(postData));
  385. });
  386. })
  387. .catch(() => main({msg: "登录(不可用)失效"}));
  388. }
  389. }
  390.  
  391. function getThreadInfo() {
  392. return new Promise(function (resolve, reject) {
  393. $.ajax({
  394. type: 'POST',
  395. url: api + '/thread',
  396. data: {
  397. sid: sid,
  398. tid: tid
  399. },
  400. success: resp => handleRequest(resp, resolve, reject),
  401. error: function () {
  402. localStorage.removeItem('app_sid');
  403. reject();
  404. }
  405. });
  406. });
  407. }
  408.  
  409. function getThreadContent() {
  410. return new Promise(function (resolve, reject) {
  411. $.ajax({
  412. type: 'POST',
  413. url: api + '/thread/page',
  414. data: {
  415. sid: sid,
  416. tid: tid,
  417. pageNo: pageNo,
  418. pageSize: pageSize
  419. },
  420. success: resp => handleRequest(resp, resolve, reject),
  421. error: function () {
  422. localStorage.removeItem('app_sid');
  423. reject();
  424. }
  425. });
  426. });
  427. }
  428.  
  429. function handleRequest(resp, resolve, reject) {
  430. // content-type返回text/html可还行
  431. resp = typeof resp === 'string' ? JSON.parse(resp) : resp;
  432. const code = resp.code.toString();
  433. if (code.startsWith('50')) {
  434. localStorage.removeItem('app_sid');
  435. reject();
  436. return;
  437. }
  438.  
  439. resolve(resp.data);
  440. }
  441.  
  442. let sid, tid, pageNo, pageSize;
  443.  
  444.  
  445. function getThreadId() {
  446. const pathname = window.location.pathname;
  447. if (pathname.startsWith('/2b/thread-')) {
  448. // [前缀, tid, pageNo, ...]
  449. const threadParams = location.pathname.split('-');
  450. tid = threadParams[1];
  451. pageNo = threadParams[2];
  452. } else if (pathname.startsWith('/2b/forum.php')) {
  453. const urlParams = new URLSearchParams(window.location.search);
  454. tid = urlParams.get('tid');
  455. pageNo = urlParams.get('page') || 1;
  456. }
  457. pageSize = 40;
  458. }
  459.  
  460. function main(data) {
  461. data = data || {};
  462.  
  463. getThreadId();
  464. if (!tid) return;
  465.  
  466. sid = localStorage.getItem('app_sid');
  467. if (sid) {
  468. replaceThreadContent();
  469. } else {
  470. loginAndReplaceThreadContent(data);
  471. }
  472. }
  473.  
  474. main();
  475. })();

QingJ © 2025

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