Weibo Huati Check-in

超级话题集中签到,基于 congxz6688 的 tiebaAllsign ( https://greasyfork.org/scripts/152 )

当前为 2017-09-11 提交的版本,查看 最新版本

  1. // ==UserScript==
  2. // @name Weibo Huati Check-in
  3. // @description 超级话题集中签到,基于 congxz6688 的 tiebaAllsign ( https://greasyfork.org/scripts/152 )
  4. // @version 0.1.2017091118
  5. // @author xyau
  6. // @namespace https://greasyfork.org/users/10290
  7. // @match http*://www.weibo.com/*
  8. // @match http*://weibo.com/*
  9. // @icon https://n.sinaimg.cn/photo/5b5e52aa/20160628/supertopic_top_area_big_icon_default.png
  10. // @grant GM_getValue
  11. // @grant GM_setValue
  12. // @grant GM_deleteValue
  13. // @grant GM_xmlhttpRequest
  14. // ==/UserScript==
  15.  
  16. // * 设置区
  17.  
  18. // 签到黑名单,括以半角引号,隔以半角逗号,见下
  19. var undoList = ["话题一", "话题二", "话题三"];
  20.  
  21. // 允许显示的最大行数;
  22. var maxLines = 20;
  23.  
  24. // 最大签到数
  25. var maxSign = 9999;
  26.  
  27. // 自动签到
  28. var autoCheckIn = true;
  29.  
  30. // * 功能区
  31.  
  32. //脚本应用式样
  33. function addStyle(css) {
  34. document.head.appendChild(document.createElement("style")).textContent = css;
  35. }
  36. var signCSS = "";
  37. signCSS += "#headTd{border-bottom:1px solid grey; color:blue; padding:0px 0px 5px 0px !important;}";
  38. signCSS += "#footTd{border-top:1px solid grey; color:blue; padding:6px 0px 0px 0px !important;}";
  39. signCSS += ".signbaInfor{white-space:nowrap; padding:0px 6px 0px 6px;}";
  40. signCSS += "#scrollDiv *{font-size:12px !important; line-height:18px !important;} #scrollDiv{max-height:" + (maxLines * 18) + "px; max-width:1200px;}";
  41. signCSS += "#newbutn,#newbutn2,#newbutn3,#zhidaoDiv{float:right;}#useIdDiv,#thDiv{float:left;}";
  42. signCSS += "#timerDiv{z-index:997; position:fixed;left:5px;top:5px;}";
  43. signCSS += "#getDown,#newbutn,#newbutn2,#newbutn3{font-size:12px; background:rgba(228,228,228,0.4); cursor:pointer; margin:0px 1px 0px 0px; padding:0px 3px;color:black; border:2px ridge black;}";
  44. signCSS += "#getDown:active,#newbutn:active,#newbutn3:active{border:2px groove black;}";
  45. signCSS += "#readyDiv,#messageWindow{z-index:9999; padding:6px 10px 8px 10px;background-color:lightGrey;position:fixed;left:5px;bottom:5px;border:1px solid grey}";
  46. addStyle(signCSS);
  47.  
  48.  
  49. //北京时间
  50. function parseDate(){
  51. e = new Date(28800000 + new Date().getTime());
  52. return [e.getUTCFullYear(), e.getUTCMonth() + 1, e.getUTCDate()].join('/');
  53. }
  54.  
  55. //获取签到话题名单
  56. function jjuds() {
  57. document.querySelector('.ficon_checkin').classList.remove('S_ficon'); //签到过程中,高亮签到按钮
  58.  
  59. var readyDiv = document.createElement("div");
  60. readyDiv.id = "readyDiv";
  61. readyDiv.innerHTML = "开始签到准备,正在获取话题列表第1页";
  62. document.body.appendChild(readyDiv);
  63. var htIdName = []; //话题收集数组
  64. pageSize = 30; //单页话题数量
  65.  
  66. getHuati(1);
  67.  
  68. function getHuati(nn, lp= Math.ceil(maxSign/30)) { //获取话题列表
  69. readyDiv.innerHTML = "开始签到准备,正在获取话题列表第" + nn + "页";
  70. var xhr = new XMLHttpRequest();
  71. xhr.open(
  72. 'get',
  73. '/p/100505'+$CONFIG.uid+'/myfollow?relate=interested&Pl_Official_RelationInterested__95_page=' + nn,
  74. 'false'
  75. );
  76. xhr.onload = function(e){
  77. var text = xhr.responseText.slice(xhr.responseText.indexOf('Pl_Official_RelationQuietuser__97'), xhr.responseText.lastIndexOf('"Pl_Official_RelationGroupList__96'));
  78. var ww = text.match(/100808([\d\w]+)&belongs=interest&screen_name=[^&]+&/g);debugger;
  79. for (s = 0; s < ww.length; s++) {
  80. if (htIdName.length < maxSign) {
  81. htIdName.push([
  82. /100808([\d\w]+)/g.exec(ww[s])[1], // 话题ID
  83. /e=([^&]+)&/g.exec(ww[s])[1] //话题名称
  84. ]);
  85. } else {
  86. break;
  87. }
  88. }
  89. if (nn == 1) //检查是否分页
  90. lp = /95_page/.test(text) ? Math.min(lp, text.match(/95_page/g).length) : 1;
  91. if (nn == lp) //最后一页读取完毕,开始执行签到
  92. gowork(htIdName);
  93. else //自调用,顺序循环
  94. setTimeout(getHuati(nn + 1, lp), 200);
  95. };
  96. xhr.send();
  97. }
  98. }
  99.  
  100. //功能函数
  101. function gowork(htIdName) { //以获取的话题数组为参数
  102. document.body.removeChild(document.getElementById("readyDiv"));
  103.  
  104. anotherTime = parseDate(); //当前时间
  105.  
  106. //创建窗口
  107. if (document.getElementById("messageWindow")) {
  108. document.body.removeChild(document.getElementById("messageWindow"));
  109. }
  110. var newDiv = document.createElement("div");
  111. newDiv.id = "messageWindow";
  112. newDiv.align = "left";
  113. document.body.appendChild(newDiv);
  114.  
  115. var tablee = document.createElement("table");
  116. newDiv.appendChild(tablee);
  117.  
  118. var thh = document.createElement("th");
  119. thh.id = "headTd";
  120. var thDiv = document.createElement("span");
  121. thDiv.id = "thDiv";
  122. thh.appendChild(thDiv);
  123. tablee.appendChild(thh);
  124.  
  125. var tr1 = document.createElement("tr");
  126. var tr2 = document.createElement("tr");
  127.  
  128. tablee.appendChild(tr1);
  129. tablee.appendChild(tr2);
  130.  
  131. var td1 = document.createElement("td");
  132. var td2 = document.createElement("td");
  133. td2.id = "footTd";
  134.  
  135. tr1.appendChild(td1);
  136. tr2.appendChild(td2);
  137.  
  138. var huatiNums = htIdName.length; //话题总数量
  139. var Tds = []; //各话题签到信息栏的空白数组
  140.  
  141. var scrollDiv = document.createElement("div");
  142. scrollDiv.id = "scrollDiv";
  143. newTable = creaseTable(huatiNums); //根据话题数量创建列表
  144. scrollDiv.appendChild(newTable);
  145. td1.appendChild(scrollDiv);
  146. td2.innerHTML += anotherTime + " 共" + huatiNums + "个话题需要签到&nbsp;&nbsp;";
  147.  
  148. onebyone(0, "conti"); //这里开始启动逐一签到动作
  149.  
  150.  
  151. var newbutn = document.createElement("span"); //创建关窗按钮
  152. newbutn.id = "newbutn";
  153. newbutn.innerHTML = "关闭窗口";
  154. newbutn.addEventListener("click", function () {
  155. document.querySelector('.ficon_checkin').classList.add('S_ficon');
  156. document.body.removeChild(document.getElementById("messageWindow"));
  157. }, false);
  158. td2.appendChild(newbutn);
  159.  
  160. var useIdDiv = document.createElement("span");
  161. useIdDiv.id = "useIdDiv";
  162. useIdDiv.innerHTML = "昵称&nbsp;:&nbsp;" + $CONFIG.nick;
  163. thDiv.appendChild(useIdDiv);
  164.  
  165. //列表创建函数
  166. function creaseTable(UrlLength) {
  167. var cons = (UrlLength <= maxLines * 2) ? 2 : 3;
  168. if (huatiNums > maxLines * cons) {
  169. addStyle("#scrollDiv{overflow-x:auto; overflow-y:scroll; padding-right:15px}");
  170. }
  171. var tablepp = document.createElement("table");
  172. var trs = [];
  173. for (ly = 0; ly < Math.ceil(UrlLength / cons); ly++) {
  174. var tr = document.createElement("tr");
  175. mmd = trs.push(tr);
  176. tablepp.appendChild(tr);
  177. }
  178. for (ls = 0; ls < UrlLength; ls++) {
  179. var td = document.createElement("td");
  180. td.setAttribute("class", "signbaInfor");
  181. wq = Tds.push(td);
  182. trs[Math.floor(ls / cons)].appendChild(td);
  183. }
  184. return tablepp;
  185. }
  186.  
  187. //显示信息序号的函数
  188. function consNum(n){
  189. n += 1;
  190. return '0'.repeat(huatiNums.toString().length - n.toString().length) + n;
  191. }
  192.  
  193. function onebyone(gg, goorstop) { //这里的gg是从0开始的话题序号,goorstop用于判别是否递进执行。
  194. //话题名缩略显示
  195. String.prototype.reComLength = function () {
  196. var yn = 0;
  197. var kuu = "";
  198. for (var w in this) {
  199. if (w < this.length) {
  200. if (/[a-zA-Z0-9]/.exec(this[w])) {
  201. yn += 1;
  202. } else {
  203. yn += 2;
  204. }
  205. if (yn < 11) {
  206. kuu += this[w];
  207. }
  208. }
  209. }
  210. var uui = yn > 13 ? kuu + "..." : this;
  211. return uui;
  212. };
  213.  
  214. gg = Number(gg);
  215. var timeout = 0; //默认延时
  216. var huatiName = "<a href='/p/100808" + htIdName[gg][0] + "' title='" + htIdName[gg][1] + "' target='_blank'><font color='blue'>" + htIdName[gg][1].reComLength() + "</font></a>";
  217. if (!todaySign[$CONFIG.nick])
  218. todaySign[$CONFIG.nick] = [];
  219. Tds[gg].innerHTML = consNum(gg) + ".&nbsp;" + huatiName;
  220. var msg = document.createElement('em');
  221. msg.classList.add('checkInMsg');
  222. Tds[gg].appendChild(msg);
  223. if (undoList.indexOf(htIdName[gg][1]) != -1) {
  224. msg.innerHTML = " 用户指定不签到";
  225. if (gg + 1 < huatiNums && !Tds[gg + 1].innerHTML) {
  226. onebyone(gg + 1, "conti");
  227. }
  228. } else if (todaySign.date == fulltime && todaySign[$CONFIG.nick].indexOf(htIdName[gg][1]) != -1 && goorstop!="stop") {
  229. msg.innerHTML = " 已有签到记录";
  230. if (gg + 1 < huatiNums && !Tds[gg + 1].innerHTML) {
  231. onebyone(gg + 1, "conti");
  232. }
  233. } else {
  234. msg.innerHTML = " 访问中......";
  235. if (goorstop == "conti") {
  236. document.getElementById("scrollDiv").scrollTop = document.getElementById("scrollDiv").scrollHeight; //滚动时总显示最下一行
  237. }
  238. var ttss;
  239. var myRequest = GM_xmlhttpRequest({
  240. method : 'GET',
  241. synchronous : false,
  242. headers : {
  243. "cookie" : encodeURIComponent(document.cookie),
  244. },
  245. url : '/p/aj/general/button?ajwvr=6&api=http://i.huati.weibo.com/aj/super/checkin&texta=签到&textb=已签到&status=0&id=100808' + htIdName[gg][0],
  246. onload : function (responseDetails) {
  247. var wwdata =JSON.parse( responseDetails.responseText);
  248. if (wwdata.code=='100000'||'382004') {
  249. if (todaySign[$CONFIG.nick].indexOf(htIdName[gg][1]) == -1) {
  250. rqq = todaySign[$CONFIG.nick].push(htIdName[gg][1]);
  251. }
  252. GM_setValue('todaySigned', JSON.stringify(todaySign)); //成功一个保存一个,以防签到意外中断
  253. if(wwdata.code=='100000'){ // 签到成功
  254. info ='签到第' + /\d+/g.exec(wwdata.data.alert_title)[0] + '名,经验+' + /\d+/g.exec(wwdata.data.alert_subtitle)[0];}
  255. else {info = wwdata.msg;}
  256. } else {
  257. var km = gg; //把gg此时的值记录下来是必须的,因为gg值将发生变化,后面不便调用
  258. var reSignAn = document.createElement("a");
  259. reSignAn.href = 'javascript:void(0);';
  260. reSignAn.innerHTML = "重签";
  261. reSignAn.setAttribute("sentValue", km);
  262. reSignAn.addEventListener('click', function (ee) {
  263. k = ee.target.getAttribute("sentValue");
  264. onebyone(k, "stop"); //带"stop"参数,避免递进执行。
  265. }, true);
  266. Tds[km].appendChild(reSignAn);
  267. info = wwdata.msg;
  268. }
  269. Tds[gg].innerHTML = consNum(gg) + ".&nbsp;" + huatiName + info;
  270. if ( goorstop == "conti" && Tds[gg + 1] && !Tds[gg + 1].innerHTML) { //只有当参数为"conti"、下一表格存在且内容为空时,才继续下一个签到动作
  271. setTimeout(function () {
  272. onebyone(gg + 1, "conti"); //函数自调用,其实是另一种循环
  273. }, timeout);
  274. }
  275. },
  276. onreadystatechange : function (responseDe) { //访问超时应对
  277. if (responseDe.readyState == 1 && typeof ttss == 'undefined') {
  278. ttss = setTimeout(function () { //添加延时
  279. myRequest.abort(); //中止请求
  280. var delayRetry = GM_getValue("delayRetry", 0);
  281. if (delayRetry < 5) {
  282. console.log(htIdName[gg][1] + "话题 访问超时!第" + (delayRetry + 1) + "次重试中...");
  283. GM_setValue("delayRetry", delayRetry + 1);
  284. onebyone(gg, "conti"); //再请求
  285. } else {
  286. Tds[gg].innerHTML = consNum(gg) + ".&nbsp;" + huatiName + " 暂时无法访问 ";
  287. Tds[gg].appendChild(pauseAc);
  288. GM_deleteValue("delayRetry");
  289. }
  290. }, 5000);
  291. } else if (responseDe.readyState == 2) { //如顺利,消除延时
  292. clearTimeout(ttss);
  293. GM_deleteValue("delayRetry");
  294. }
  295. }
  296. });
  297. //跳过功能
  298. var hii = gg;
  299. var pauseAc = document.createElement("a");
  300. pauseAc.href = 'javascript:void(0);';
  301. pauseAc.innerHTML = " 跳过";
  302. pauseAc.addEventListener('click', function () {
  303. myRequest.abort(); //中止请求
  304. clearTimeout(ttss); //取消延时块
  305. GM_deleteValue("delayRetry");
  306. var dnn = hii + 1;
  307. if (dnn < huatiNums && !Tds[dnn].innerHTML) {
  308. onebyone(dnn, "conti"); //进行下一个话题的签到
  309. }
  310. Tds[hii].innerHTML = consNum(hii) + ".&nbsp;" + huatiName + " 已跳过 ";
  311. var reSignAn = document.createElement("a"); //添加重试按钮
  312. reSignAn.href = 'javascript:void(0);';
  313. reSignAn.innerHTML = "重试";
  314. reSignAn.addEventListener('click', function () {
  315. onebyone(hii, "stop"); //带"stop"参数,避免递进执行。
  316. }, true);
  317. Tds[hii].appendChild(reSignAn);
  318. }, true);
  319. Tds[gg].appendChild(pauseAc);
  320. }
  321. }
  322. }
  323.  
  324. // 清理旧版数据
  325. ['autoSignbox'].forEach(function(e) {
  326. GM_deleteValue(e);
  327. });
  328.  
  329. // 隐藏游戏按钮,替换为超话签到
  330. document.querySelector('a[nm="game"]').parentNode.style = 'display: none';
  331. var checkInBtn = document.createElement("li");
  332. checkInBtn.innerHTML = '<a href="javascript:void;"><em class="W_ficon ficon_checkin S_ficon">s</em><em class="S_txt1 signBtn">超话签到</em></a>';
  333. checkInBtn.addEventListener(
  334. 'click',
  335. function () {
  336. jjuds();
  337. },
  338. true
  339. );
  340. document.querySelector('a[nm="name"]').parentNode.before(checkInBtn);
  341.  
  342. // 隔日清空已签记录
  343. var todaySign = JSON.parse(GM_getValue('todaySigned', "{}"));
  344. fulltime = parseDate();
  345. if (!todaySign.date || todaySign.date != fulltime) {
  346. todaySign = {};
  347. GM_setValue('todaySigned', JSON.stringify(todaySign));
  348. todaySign.date = fulltime;
  349. }
  350.  
  351. // 自动签到
  352. if ($CONFIG.islogin) {
  353. if (GM_getValue('autoCheckIn', true) && (!todaySign.date || todaySign.date != fulltime || todaySign[$CONFIG.nick] === undefined)) {
  354. jjuds();
  355. }
  356. }