V2EX Pro Max

为V2EX添加自动签到、新标签页打开、替换站内搜索、提醒所有人、楼中楼、自动解析图片链接等功能

  1. // ==UserScript==
  2. // @name V2EX Pro Max
  3. // @description 为V2EX添加自动签到、新标签页打开、替换站内搜索、提醒所有人、楼中楼、自动解析图片链接等功能
  4. // @icon https://i.loli.net/2020/03/13/DMA2TbVNUwyoFcQ.jpg
  5. // @author doggeddog
  6. // @include https://*.v2ex.com/*
  7. // @include https://v2ex.com/*
  8. // @version 1.0.0
  9. // @grant none
  10. // @namespace https://www.v2ex.com
  11. // @homepageURL https://greasyfork.org/zh-CN/users/306515
  12. // @license MIT
  13. // ==/UserScript==
  14.  
  15. //移动端网页转换为PC版
  16. (function (){
  17. var url = location.href;
  18. if (url.indexOf("/amp/") > 0) {
  19. var url1 = url.replace("/amp/", "/");
  20. var url2 = url1.slice(url1.indexOf("/t/") + 1).split('/')
  21. // console.log(location.protocol+"//www.v2ex.com/t/"+url2[1])
  22. location.replace(location.protocol+"//www.v2ex.com/t/"+url2[1]);
  23. }
  24. var nowurl = location.pathname;
  25. if (nowurl == "/" || nowurl.substr(0, 6) == "/?tab=" || nowurl.substr(0, 4) == "/go/" || nowurl == "/recent") {
  26. $("span.item_title a").attr("target", "_blank");
  27. }
  28. })();
  29.  
  30. //替换为SOV2EX搜索 TODO 没时间,哪天整
  31. (function() {
  32. function exec() {
  33. window.dispatch = function () {
  34. var value = document.getElementById('search').value
  35. if ( value) {
  36. var url = "https://www.sov2ex.com/?q=" + encodeURIComponent(value);
  37. if (window.open) {
  38. window.open(url + '&sort=created', '_blank')
  39. } else{
  40. location.href = url
  41. }
  42. return false
  43. }
  44. return false
  45. }
  46. }
  47. window.addEventListener('load', exec, false)
  48. })();
  49. //自动签到 代码来自caoyue@v2ex
  50. (function(){
  51. var load, execute, loadAndExecute;
  52. load = function(a, b, c) {
  53. var d;
  54. d = document.createElement("script"), d.setAttribute("src", a), b != null && d.addEventListener("load", b), c != null && d.addEventListener("error", c), document.body.appendChild(d);
  55. return d;
  56. }, execute = function(a) {
  57. var b, c;
  58. typeof a == "function" ? b = "(" + a + ")();" : b = a, c = document.createElement("script"), c.textContent = b, document.body.appendChild(c);
  59. return c;
  60. }, loadAndExecute = function(a, b) {
  61. return load(a, function() {
  62. return execute(b);
  63. });
  64. };
  65.  
  66. loadAndExecute("//lib.sinaapp.com/js/jquery/2.0/jquery.min.js", function() {
  67. if ( !$("a[href='/signup']").length && !$("a[href='/signin']").length && document.body.innerHTML.indexOf(";<\/span> 创建新回复<\/div>") == -1 ) {
  68. var uid=$.find('a[href^="/member/"]')[0].innerHTML;//用户名
  69. var dateinfo=new Date().getUTCDate();//获得GMT时间今天几号
  70. var SigninInfo=uid + ":" + dateinfo + "";
  71. var daily = $('input[id="search"]');
  72. if (daily.length && localStorage.SigninInfo != SigninInfo ) {
  73. $.ajax({url:"/"});
  74. daily.val("正在检测每日签到状态...");
  75. $.ajax({
  76. url: "/mission/daily",
  77. success: function(data) {
  78. var awards = $(data).find('input[value^="领取"]');
  79. if (awards.length) {
  80. // daily.val("正在" + awards.attr("value") + "...");
  81. daily.val("正在领取今日的登录奖励......");
  82. $.ajax({
  83. url: awards.attr('onclick').match(/(?=\/).+?(?=\')/),
  84. success: function(data) {
  85. daily.val("正在提交...");
  86. var days=data.split("已连续登")[1].split(" ")[1];
  87. if ( $('a[href="/mission/daily"]').length==1 ) {$('a[href="/mission/daily"]').parent().parent().fadeOut(3000);}
  88. $.ajax({
  89. url: "/balance",
  90. success: function(data) {
  91. function p(s) {return s < 10 ? '0' + s: s;} //自动补0
  92. var date2="" + new Date().getUTCFullYear() + p(new Date().getUTCMonth()+1) +p(new Date().getUTCDate());
  93. if (data.indexOf(date2+" 的每日登录奖励")!="-1") {
  94. daily.val( "已连续领取" + days + "天,本次领到" + data.split("每日登录")[2].split(" ")[1] + "铜币" );
  95. localStorage.SigninInfo = SigninInfo;
  96. } else {
  97. daily.val( "自动领取遇到意外,你可以试试手动领。" );
  98. }
  99. }
  100. });
  101. },
  102. error: function() {
  103. daily.val("网络异常 :(");
  104. }
  105. });
  106. }else{
  107. if (data.indexOf("已领取") != -1) {
  108. daily.val("今日奖励领取过了");
  109. localStorage.SigninInfo = SigninInfo;
  110. } else {
  111. daily.val("无法辩识领奖按钮 :(");
  112. }
  113.  
  114. }
  115. },
  116. error: function() {
  117. daily.val("请手动领取今日的登录奖励!");
  118. }
  119. });
  120. } else {
  121. //console.log("");
  122. }
  123. }
  124. });
  125. })();
  126.  
  127. //标记楼主 代码来自ejin
  128. (function (){
  129. var uid=document.getElementById("Rightbar").getElementsByTagName("a")[0].href.split("/member/")[1];//自己用户名
  130. if (location.href.indexOf(".com/t/") != -1) {
  131. var lzname=document.getElementById("Main").getElementsByClassName("avatar")[0].parentNode.href.split("/member/")[1];
  132. var allname='@'+lzname+' ';
  133. var all_elem = document.getElementsByClassName("dark");
  134. for(var i=0; i<all_elem.length; i++) {
  135. //为回复所有人做准备
  136. if ( uid != all_elem[i].innerHTML && all_elem[i].href.indexOf("/member/") != -1 && all_elem[i].innerText == all_elem[i].innerHTML && allname.indexOf('@'+all_elem[i].innerHTML+' ') == -1 ) {
  137. allname+='@'+ all_elem[i].innerHTML+' ';
  138. }
  139. }
  140. }
  141.  
  142. if ( document.getElementById("reply_content") ) {
  143. document.getElementById("reply_content").parentNode.innerHTML+="&nbsp;&nbsp;&nbsp;&nbsp;<a href='javascript:;' onclick='if ( document.getElementById(\"reply_content\").value.indexOf(\""+allname+"\") == -1 ) {document.getElementById(\"reply_content\").value+=\"\\r\\n"+allname+"\"}'>@所有人</a>";
  144. if ( document.body.style.WebkitBoxShadow !== undefined ) {
  145. //允许调整回复框高度
  146. document.getElementById("reply_content").style.resize="vertical";
  147. }
  148. document.getElementById("reply_content").style.overflow="auto";
  149. var magagers="@Livid @Kai @Olivia @GordianZ @sparanoid";
  150. document.getElementById("reply_content").parentNode.innerHTML+="&nbsp;&nbsp;&nbsp;&nbsp;<a href='javascript:;' onclick='if ( document.getElementById(\"reply_content\").value.indexOf(\""+magagers+"\") == -1 ) {document.getElementById(\"reply_content\").value+=\"\\r\\n"+magagers+"\"}'>@管理员</a>";
  151. }
  152. })();
  153.  
  154. // 图片链接自动转换成图片 代码来自caoyue@v2ex
  155. (function (){
  156. var links = document.links;
  157. for (var i=0;i<links.length;i++){
  158. var link = links[i];
  159. if (/^http.*\.(?:jpg|jpeg|jpe|bmp|png|gif)/i.test(link.href)
  160. && !/<img\s/i.test(link.innerHTML) && link.href.indexOf("v2ex.com/tag")==-1){
  161. link.innerHTML = "<img title='" + link.href + "' src='" + link.href + "' />";
  162. }
  163. }
  164. })();
  165. //
  166.  
  167. //新浪图床的图片反防盗链
  168. (function (){
  169. var images = document.images;
  170. for (var i=0;i<images.length;i++){
  171. var image = images[i];
  172. if ( image.src && image.src.indexOf(".sinaimg.cn")!=-1 &&image.src.indexOf(".sinaimg.cn")<13 ) {
  173. image.setAttribute("referrerPolicy","no-referrer");
  174. image.src=image.src + "?";
  175. }
  176. }
  177. })();
  178.  
  179.  
  180.  
  181. //V2EX帖子盖楼显示
  182. (function() {
  183.  
  184.  
  185. //楼层
  186. var a = $('div.cell > table > tbody > tr > td:nth-child(3) > div.fr > span').get().map(i=>i.innerHTML);
  187. //回复内容
  188. var replyText = $('div.cell > table > tbody > tr > td:nth-child(3) > div.reply_content').get().map(i=>i.innerHTML);
  189. var ids = $('div.cell > table > tbody > tr > td:nth-child(3) > strong > a').get().map(i=>i.innerHTML);
  190.  
  191. var replyContent = $('div.cell > table > tbody > tr > td:nth-child(3) > div.reply_content');
  192. var cells = $('#Main > div:nth-child(4) > div[id].cell');
  193.  
  194. var user = $('div.cell > table > tbody > tr > td:nth-child(3) > strong > a');
  195. var author = $('#Main > div:nth-child(2) > div.header > small > a')[0].innerHTML;
  196. var loginUser = $('#Rightbar > div:nth-child(2) > div:nth-child(1) > table:nth-child(1) > tbody > tr > td:nth-child(3) > span > a')
  197. loginUser = loginUser.length ? loginUser[0].innerHTML :null ;
  198. var replyLink = new Object();
  199. var replyDeep = new Object();
  200.  
  201. function getRootFloor(currentFloor, user1, user2) {
  202. var pre = replyLink[currentFloor];
  203. if (pre == undefined) {
  204. return currentFloor;
  205. }
  206. var deep = replyDeep[currentFloor] || 1;
  207. if (deep >= 6) {
  208. return getRootFloor(pre, user1, user2);
  209. }
  210.  
  211. if (ids[pre] != user1 && ids[pre] != user2) {
  212. return currentFloor;
  213. }
  214. return getRootFloor(pre, user1, user2);
  215. }
  216.  
  217.  
  218. let i = 1;
  219. while(i< cells.length){
  220. if( ids[i] == loginUser )
  221. {
  222. user[i].setAttribute('style','color:purple');
  223. }
  224.  
  225. if(replyText[i].match("楼上")){
  226. replyContent[i-1].append(cells[i]);
  227. }
  228.  
  229. for(var j=i-1;j>=0;j--){
  230. if(replyText[i].match(ids[j])){
  231. var root = getRootFloor(j, ids[j], ids[i]);
  232.  
  233. var deep = replyDeep[root] || 1;
  234. replyDeep[i] = deep + 1;
  235.  
  236. replyLink[i] = j;
  237. replyContent[root].append(cells[i]);
  238. break;
  239. }
  240. }
  241. i++;
  242. }
  243. console.log(replyDeep);
  244. })();