🏠 Home 

NGA Post Status Query

Check NGA post status.

  1. // ==UserScript==
  2. // @name NGA Post Status Query
  3. // @namespace https://greasyfork.org/users/826221
  4. // @version 1.0.4
  5. // @description Check NGA post status.
  6. // @author DSakura207
  7. // @include /^https?://(bbs\.ngacn\.cc|nga\.178\.com|bbs\.nga\.cn|ngabbs\.com)/.+/
  8. // @require https://greasyfork.org/scripts/39014-nga-user-script-loader/code/NGA%20User%20Script%20Loader.js?version=809809
  9. // @grant none
  10. // @license GPL-3.0-or-later
  11. // @supportURL https://github.com/DSakura207/NgaPostStatus/issues
  12. // ==/UserScript==
  13. // This user script is inspired by https://greasyfork.org/en/scripts/376589.
  14. (function () {
  15. function init($) {
  16. let b = (commonui.PostQuery = {
  17. // Bit mask for post status
  18. statusFlag: {
  19. _POST_IF_COMMENT: { flag: 1, description: "此贴是评论" },
  20. _POST_IF_HIDDEN: { flag: 2, description: "此贴已隐藏" },
  21. _POST_IF_HAVE_COMMENT: { flag: 4, description: "此贴有评论" },
  22. _POST_UNKNOWN_BIT_4: { flag: 8, description: "未知状态4" },
  23. _POST_IF_EXTRA_USER_INFO: {
  24. flag: 16,
  25. description: "此贴在列表显示更多用户信息",
  26. },
  27. _POST_IF_REPORTED: { flag: 32, description: "此贴已被标记" },
  28. _POST_IF_NO_HINT: { flag: 64, description: "此贴不产生回复提示" },
  29. _POST_IF_FREE_EDIT: { flag: 128, description: "此贴无编辑期限" },
  30. _POST_MULTI_USE_1: {
  31. flag: 256,
  32. description: "此贴仅限自己回复/回复不受注册时间限制",
  33. },
  34. _POST_WAIT_FOR_AUDIT_1: { flag: 512, description: "此贴等待审核" },
  35. _POST_IF_LOCK: { flag: ####, description: "此贴被锁定" },
  36. _POST_USER_PUNISHED_IN_POST: {
  37. flag: 2048,
  38. description: "此贴内有用户被处罚",
  39. },
  40. _POST_IF_HAS_AUTO_TRANSLATE: {
  41. flag: 4096,
  42. description: "此贴有版主翻译",
  43. },
  44. _POST_IF_HAS_ATTACHMENT: { flag: 8192, description: "此贴包含附件" },
  45. _POST_WAIT_FOR_AUDIT_2: { flag: 16384, description: "此贴等待审核" },
  46. _POST_IS_ST: { flag: 32768, description: "此贴是合集主题" },
  47. _POST_UNKNOWN_BIT_17: { flag: 65536, description: "未知状态17" },
  48. _POST_MULTI_USE_2: {
  49. flag: 131072,
  50. description: "不在联合版面中显示/锁定合集的全部主题",
  51. },
  52. _POST_MULTI_USE_3: {
  53. flag: 262144,
  54. description: "此贴是匿名发布/此主题新回复在前",
  55. },
  56. _POST_MULTI_USE_4: {
  57. flag: 524288,
  58. description: "此贴在主题列表中显示附件/合集子主题不上浮",
  59. },
  60. _POST_UNKNOWN_BIT_21: { flag: 1048576, description: "未知状态21" },
  61. _POST_MULTI_USE_5: {
  62. flag: 2097152,
  63. description: "版面镜像/此主题回复全部匿名",
  64. },
  65. _POST_UNKNOWN_BIT_23: { flag: 4194304, description: "未知状态23" },
  66. _POST_UNKNOWN_BIT_24: { flag: 8388608, description: "未知状态24" },
  67. _POST_MULTI_USE_6: {
  68. flag: 16777216,
  69. description: "此功能主题不上浮/此功能主题不显示子主题",
  70. },
  71. _POST_UNKNOWN_BIT_26: { flag: 33554432, description: "未知状态26" },
  72. _POST_MULTI_USE_7: {
  73. flag: 67108864,
  74. description: "此贴未通过审核/在主题列表中显示图片",
  75. },
  76. _POST_SHOW_RECENT_REPLY: {
  77. flag: 134217728,
  78. description: "在主题列表中显示最近回复",
  79. },
  80. _POST_UNKNOWN_BIT_29: { flag: 268435456, description: "未知状态29" },
  81. _POST_UNKNOWN_BIT_30: { flag: 536870912, description: "未知状态30" },
  82. _POST_ONLY_ONE_REPLY: {
  83. flag: 1073741824,
  84. description: "此贴只能回复一次",
  85. },
  86. _POST_UNKNOWN_BIT_32: { flag: 2147483648, description: "未知状态32" },
  87. },
  88. f: function (e) {
  89. const pidElement = $(e.currentTarget).parent().children("a[id]");
  90. console.debug(e.currentTarget);
  91. if (pidElement.length != 1) {
  92. console.error(
  93. "Expected 1 element, got " + pidElement.length + " elements"
  94. );
  95. return;
  96. }
  97. let pid = $(pidElement[0]).attr("id").match(/(\d+)/)[0];
  98. console.debug("PID from anchor: " + pid);
  99. if (pid == 0) {
  100. console.debug("Not a reply post, use TID!");
  101. let params = new URLSearchParams(
  102. document.location.search.substring(1)
  103. );
  104. let tid = params.get("tid");
  105. console.debug("TID is " + tid);
  106. $.get(`/read.php?tid=${tid}&__output=11`).done(function (data) {
  107. b.showData(data, tid, "thread");
  108. });
  109. } else {
  110. console.debug("PID is " + pid);
  111. $.get(`/read.php?pid=${pid}&__output=11`).done(function (data) {
  112. b.showData(data, pid, "post");
  113. });
  114. }
  115. },
  116. showData: function (data, pid, postType) {
  117. const typeName = postType.toUpperCase();
  118. const postData = data;
  119. // Post status
  120. const typeFlags = postData["data"]["__R"][0]["type"];
  121. // Thread status
  122. let typeFlags2 = postData["data"]["__T"]["type"];
  123. // POST status object
  124. let postStatusObj = {};
  125. // Thread status object
  126. let postStatusObj2 = {};
  127. // commonui.alert content string
  128. let postStatusString = "";
  129. // Produce thread main or reply post status object.
  130. for (const [info, mask] of Object.entries(b.statusFlag)) {
  131. // Hack for JavaScript bitwise operation.
  132. // Thanks for https://stackoverflow.com/questions/6798111/bitwise-operations-on-32-bit-unsigned-ints
  133. let rc = (mask.flag & typeFlags) >>> 0;
  134. let rc2 = (mask.flag & typeFlags2) >>> 0;
  135. if (rc == mask.flag && postType === "post") {
  136. postStatusObj[info] = mask.description;
  137. postStatusString += (mask.description + ";");
  138. }
  139. if (rc2 == mask.flag && postType === "thread") {
  140. postStatusObj2[info] = mask.description;
  141. postStatusString += (mask.description + ";");
  142. }
  143. }
  144. // Output status object for reference
  145. console.debug(postStatusObj);
  146. console.debug(postStatusObj2);
  147. // Return when status is normal (0).
  148. if (postStatusString.length == 0) {
  149. return;
  150. }
  151. commonui.alert(postStatusString, `${typeName} ${pid}`);
  152. },
  153. r: function () {
  154. // Ensure only one handler is attached
  155. $("div.postInfo")
  156. .off("dblclick.PostQuery")
  157. .on("dblclick.PostQuery", b.f);
  158. },
  159. mo: new MutationObserver(function () {
  160. b.r();
  161. }),
  162. });
  163. b.r();
  164. b.mo.observe($("body")[0], {
  165. childList: true,
  166. subtree: true,
  167. });
  168. }
  169. (function check() {
  170. try {
  171. init(commonui.userScriptLoader.$);
  172. } catch (e) {
  173. setTimeout(check, 50);
  174. }
  175. })();
  176. })();