MediaWiki举报工具

MediaWiki页面举报

  1. // ==UserScript==
  2. // @name MediaWiki举报工具
  3. // @namespace mwreport
  4. // @version 1.0.0
  5. // @description MediaWiki页面举报
  6. // @include *://*/wiki/*
  7. // @include *://*/wiki/index.php?title=*
  8. // @include *://*/wiki/index.php?*&title=*
  9. // @include *://*/wiki/index.php/*
  10. // @include *://*/w/*
  11. // @include *://*/w/index.php?title=*
  12. // @include *://*/w/index.php?*&title=*
  13. // @include *://*/w/index.php/*
  14. // @include *://*/index.php?title=*
  15. // @include *://*/index.php?*&title=*
  16. // @include *://*/index.php/*
  17. // @license Parity-6.0.0
  18. // @author 全身肥肉的小猪佩奇
  19. // @run-at document-end
  20. // ==/UserScript==
  21. if (!unsafeWindow.localStorage["mwRoot"]) {
  22. unsafeWindow.localStorage["mwRoot"] = prompt("MediaWiki 的根目录是什么", "/")
  23. }
  24. mwRootPath = unsafeWindow.localStorage["mwRoot"] == "/" ? "": unsafeWindow.localStorage["mwRoot"]
  25.  
  26. const mwXHR = function(host, url, config, body) {
  27. var xhr = new XMLHttpRequest()
  28. xhr.open(config.method, location.protocol + "//" + host + "/" + url, config.async)
  29. xhr.onerror = function() {
  30. if (xhr.status == 406) {
  31. config.header.push(["Accept", "*"])
  32. return mwXHR(host, url, config, body)
  33. }
  34. if (xhr.responseText != null) {
  35. if (config.async) {
  36. config.onProcessEnd(true, xhr.responseText)
  37. } else {
  38. return xhr.responseText
  39. }
  40. }
  41. if (config.async) {
  42. config.onProcessEnd(false, xhr)
  43. } else {
  44. return [false,
  45. xhr
  46. ]
  47. }
  48. }
  49. xhr.onload = function() {
  50. if (config.async) {
  51. config.onProcessEnd(true, xhr.responseText)
  52. } else {
  53. return xhr.responseText
  54. }
  55. }
  56. config.header.forEach((i) => {
  57. xhr.setRequestHeader.apply(xhr, i)
  58. })
  59. xhr.send(body)
  60. if (!config.async) {
  61. if (xhr.status == 200) {
  62. return xhr.responseText
  63. } else {
  64. return [false,
  65. xhr]
  66. }
  67. }
  68. }
  69.  
  70. const mwUseAPI = function(action, parms, cb, body) {
  71. var parmsStr = parms.map((parm) => `&${parm[0]}=${parm[1]}`).join("")
  72. return mwXHR(location.host, action != undefined ? mwRootPath + "api.php?action=" + action + parmsStr: mwRootPath + "api.php", {
  73. method: body == undefined ? "GET": "POST",
  74. async: cb == undefined ? false: true,
  75. header: [
  76. ["MediaWiki", "MediaWiki-User"],
  77. ["Content-Type", "application/x-www-form-urlencoded"]
  78. ],
  79. onProcessEnd: function(success, data) {
  80. if (success) {
  81. cb(JSON.parse(data))
  82. } else {
  83. cb( {
  84. batchcomplete: false,
  85. err: data
  86. })
  87. }
  88. }
  89. },
  90. body)
  91. }
  92.  
  93. const inUserPage = function() {
  94. return location.href.indexOf("User:") != -1 || unescape(location.href).indexOf("用户:") != -1
  95. }
  96.  
  97. const isSysop = function (username) {
  98. const queryResult = JSON.parse(mwUseAPI("query", [
  99. ["list", "users"],
  100. ["ususers", username],
  101. ["usprop", "rights|groups"],
  102. ["format", "json"]
  103. ])).query.users[0]
  104. return queryResult.rights.includes("delete") || queryResult.rights.includes("block") || queryResult.groups.includes("sysop")
  105.  
  106. }
  107.  
  108. const report = function(pageTitle) {
  109. var mwCSRFToken = escape(JSON.parse(mwUseAPI("query",
  110. [
  111. ["meta",
  112. "tokens"
  113. ],
  114. ["type",
  115. "csrf"
  116. ],
  117. ["format",
  118. "json"
  119. ]
  120. ])).query.tokens.csrftoken)
  121. if (!unsafeWindow.localStorage["sysopName"]) return alert("未记录管理员,无法举报,请打开任意管理员的用户页面以记录")
  122. const sysopUsername = unsafeWindow.localStorage["sysopName"]
  123. const rvInfo = JSON.parse(mwUseAPI("query", [
  124. ["prop", "revisions"],
  125. ["titles", pageTitle],
  126. ["rvprop", "ids|timestamp"],
  127. ["format", "json"]])).query.pages
  128. const rvInfo2 = JSON.parse(mwUseAPI("query", [
  129. ["prop", "revisions"],
  130. ["titles", "User:" + sysopUsername],
  131. ["rvprop", "ids|timestamp"],
  132. ["format", "json"]])).query.pages
  133. const pgID = Object.keys(rvInfo)[0]
  134. const rvID = rvInfo[pgID].revisions[0].revid
  135. const rvTime = rvInfo[pgID].revisions[0].timestamp
  136. const pgID2 = Object.keys(rvInfo2)[0]
  137. const rvID2 = rvInfo2[pgID2].revisions[0].revid
  138. const rvTime2 = rvInfo2[pgID2].revisions[0].timestamp
  139. mwCSRFToken = mwCSRFToken.replace("+", "%2B")
  140. mwUseAPI(undefined,
  141. [],
  142. () => {},
  143. "action=edit&title=" + pageTitle + "&section=new&sectiontitle=举报页面&text=@[[User:" + sysopUsername + " ]] 您好,此页面违反了维基的规则,我在此向您举报。&basetimestamp=" + rvTime + "&baserevid=" + rvID + "&starttimestamp=now&watchlist=watch&format=json&token=" + mwCSRFToken)
  144. mwUseAPI(undefined,
  145. [],
  146. () => {},
  147. "action=edit&title=User:" + sysopUsername + "&section=new&sectiontitle=举报页面&text=您好,页面[[" + pageTitle + "]]违反了维基的规则,我在此向您举报。&basetimestamp=" + rvTime2 + "&baserevid=" + rvID2 + "&starttimestamp=now&watchlist=watch&format=json&token=" + mwCSRFToken)
  148. }
  149. const pgTitle = document.querySelector(".mw-page-title-main").innerText
  150. if (inUserPage()) {
  151. const usName = pgTitle.replace("用户:", "").replace("User:", "")
  152. if (isSysop(usName)) unsafeWindow.localStorage["sysopName"] = usName
  153. }
  154. var reportButton = document.createElement("li")
  155. reportButton.onclick = () => {
  156. report(pgTitle)
  157. }
  158. reportButton.classList.add("mw-list-item")
  159. reportButton.setAttribute("id", "ca-report")
  160. var reportLink = document.createElement("a")
  161. reportLink.setAttribute("title", "举报该页面")
  162. reportLink.setAttribute("href", "javascript:[]")
  163. var reportText = document.createElement("span")
  164. reportText.innerText = "举报"
  165. reportLink.appendChild(reportText)
  166. reportButton.appendChild(reportLink)
  167. document.querySelector("#p-cactions .vector-menu-content .vector-menu-content-list").appendChild(reportButton)
  168. debugger

QingJ © 2025

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