Script for appeals

forward-only!

  1. // ==UserScript==
  2. // @name Script for appeals
  3. // @namespace https://forum.blackrussia.online
  4. // @version 4.1
  5. // @description forward-only!
  6. // @author Jaden Young
  7. // @match https://forum.blackrussia.online/index.php?threads/*
  8. // @include https://forum.blackrussia.online/index.php?threads/
  9. // @icon https://forum.blackrussia.online/data/avatars/l/304/304304.jpg?1646559749
  10. // @grant none
  11. // @license MIT
  12. // ==/UserScript==
  13.  
  14. (async function () {
  15. `use strict`;
  16. const UNACCEPT_PREFIX = 4; // Prefix that will be set when thread closes
  17. const ACCEPT_PREFIX = 8; // Prefix that will be set when thread accepted
  18. const PIN_PREFIX = 2; // Prefix that will be set when thread pins
  19. const COMMAND_PREFIX = 10; // Prefix that will be set when thread send to project team
  20. const WATCHED_PREFIX = 9;
  21. const CLOSE_PREFIX = 7;
  22. const TECH_PREFIX = 13;
  23. const RESHENO_PREFIX = 6;
  24. const data = await getThreadData(),
  25. greeting = data.greeting,
  26. user = data.user;
  27. const buttons = [
  28. {
  29. title: `-------------------------------------------------- РАССМОТРЕНИЕ --------------------------------------------------`,
  30. content: ``,
  31. },
  32. {
  33. title: `На рассмотрении`,
  34. content:
  35. `[SIZE=4][CENTER]Приветствую, уважаемый игрок!.[/CENTER]<br><br>` +
  36. `[SIZE=4][CENTER]На рассмотрении.[/SIZE][/CENTER]`,
  37. prefix: PIN_PREFIX,
  38. status: true,
  39. },
  40. {
  41. title: `Свяжитесь со мной во ВКонтакте`,
  42. content:
  43. `[SIZE=4][CENTER]Приветствую, уважаемый игрок!.[/CENTER]<br><br>` +
  44. `[CENTER][SIZE=4]Свяжитесь со мной ВКонтакте по следующей форме:[/CENTER]<br><br>` +
  45. `[CENTER][SIZE=4]1. Ваш NickName:[/CENTER]<br>` +
  46. `[CENTER][SIZE=4]2. Ссылка на обжалование:[/CENTER]<br><br>` +
  47. `[CENTER][SIZE=4]VK: https://vk.com/iyghjiyfcbjkk <br><br>` +
  48. `[CENTER][SIZE=4]На рассмотрении.<br>`,
  49. prefix: PIN_PREFIX,
  50. status: true,
  51. },
  52. {
  53. title: `Разблокировка для передачи украденного имущества`,
  54. content:
  55. `[SIZE=4][CENTER]Приветствую, уважаемый игрок!.[/CENTER]<br><br>` +
  56. `[CENTER][SIZE=4]Ваш аккаунт разблокирован на 24 часа.
  57. За это время Вы должны успеть вернуть украденное имущество пострадавшему игроку.
  58. Если условие не будет выполнено, то аккаунт вновь будет заблокирован.[/CENTER][/SIZE]`,
  59.  
  60. prefix: PIN_PREFIX,
  61. status: true,
  62. },
  63. {
  64. title: `-------------------------------------------------- ОТКАЗ --------------------------------------------------`,
  65. content: ``,
  66. },
  67. {
  68. title: `Не готов пойти навстречу`,
  69. content:
  70. `[CENTER][SIZE=4]Приветствую, уважаемый игрок!.[/CENTER]<br><br>` +
  71. `[CENTER][SIZE=4]Пока я не готов пойти к Вам навстречу.[/CENTER]<br><br>` +
  72. `[CENTER][SIZE=4]Закрыто.[/SIZE][/CENTER]`,
  73. prefix: UNACCEPT_PREFIX,
  74. status: false,
  75. },
  76. {
  77. title: `Не готов пойти навстречу (напишите через 2 дня)`,
  78. content:
  79. `[SIZE=4][CENTER]Приветствую, уважаемый игрок!.[/CENTER]<br><br>` +
  80. `[CENTER][SIZE=4]Пока я не готов пойти к Вам навстречу, напишите обжалование спустя два дня.[/CENTER]<br><br>` +
  81. `[CENTER][SIZE=4]Закрыто.[/SIZE][/CENTER]`,
  82. prefix: UNACCEPT_PREFIX,
  83. status: false,
  84. },
  85. {
  86. title: `Не готов пойти навстречу (напишите через 3 дня)`,
  87. content:
  88. `[SIZE=4][CENTER]Приветствую, уважаемый игрок!.[/CENTER]<br><br>` +
  89. `[CENTER][SIZE=4]Пока я не готов пойти к Вам навстречу, напишите обжалование спустя три дня.[/CENTER]<br><br>` +
  90. `[CENTER][SIZE=4]Закрыто.[/SIZE][/CENTER]`,
  91. prefix: UNACCEPT_PREFIX,
  92. status: false,
  93. },
  94. {
  95. title: `Не готов пойти навстречу (напишите через 4 дня)`,
  96. content:
  97. `[SIZE=4][CENTER]Приветствую, уважаемый игрок!.[/CENTER]<br><br>` +
  98. `[CENTER][SIZE=4]Пока я не готов пойти к Вам навстречу, напишите обжалование спустя четыре дня.[/CENTER]<br><br>` +
  99. `[CENTER][SIZE=4]Закрыто.[/SIZE][/CENTER]`,
  100. prefix: UNACCEPT_PREFIX,
  101. status: false,
  102. },
  103. {
  104. title: `Не готов пойти навстречу (напишите через 4 дня)`,
  105. content:
  106. `[SIZE=4][CENTER]Приветствую, уважаемый игрок!.[/CENTER]<br><br>` +
  107. `[CENTER][SIZE=4]Пока я не готов пойти к Вам навстречу, напишите обжалование спустя пять дней.<br><br>` +
  108. `[CENTER][SIZE=4]Закрыто.[/SIZE][/CENTER]`,
  109. prefix: UNACCEPT_PREFIX,
  110. status: false,
  111. },
  112. {
  113. title: обжаловании отказано`,
  114. content:
  115. `[SIZE=4][CENTER]Приветствую, уважаемый игрок!.[/CENTER]<br><br>` +
  116. `[CENTER][SIZE=4 обжаловании отказано.[/CENTER]<br><br>` +
  117. `[CENTER][SIZE=4]Закрыто.[/SIZE][/CENTER]`,
  118. prefix: UNACCEPT_PREFIX,
  119. status: false,
  120. },
  121. {
  122. title: `Не подлежит обжалованию`,
  123. content:
  124. `[SIZE=4][CENTER]Приветствую, уважаемый игрок!.[/CENTER]<br><br>` +
  125. `[CENTER][SIZE=4]Данное наказание не подлежит обжалованию.[/CENTER]<br><br>` +
  126. `[CENTER][SIZE=4]Закрыто. [/SIZE][/CENTER]`,
  127. prefix: UNACCEPT_PREFIX,
  128. status: false,
  129. },
  130. {
  131. title: `Блокировка была выдана от Тех. спец-а`,
  132. content:
  133. `[SIZE=4][CENTER]Приветствую, уважаемый игрок!.[/CENTER]<br><br>` +
  134. `[CENTER][SIZE=4]Блокировка была выдана от технического специалиста, собственно все дальнейшие разбирательства будут происходить в техническом разделе > жалобы на технических специалистов.[/CENTER]<br><br>` +
  135. `[CENTER][SIZE=4]Закрыто.[/SIZE][/CENTER]`,
  136. prefix: UNACCEPT_PREFIX,
  137. status: false,
  138. },
  139. {
  140. title: `Блокировка была выдана по наводке от Тех. спец-а`,
  141. content:
  142. `[SIZE=4][CENTER]Приветствую, уважаемый игрок!.[/CENTER]<br><br>` +
  143. `[CENTER][SIZE=4]Блокировка была выдана по наводке от технического специалиста, соответственно Вам требуется обратиться в технический раздел => жалобы на технических специалистов.[/CENTER]<br><br>` +
  144. `[CENTER][SIZE=4]Закрыто.[/SIZE][/CENTER]`,
  145. prefix: UNACCEPT_PREFIX,
  146. status: false,
  147. },
  148. {
  149. title: `Обжалование составлено не по форме`,
  150. content:
  151. `[SIZE=4][CENTER]Приветствую, уважаемый игрок!.[/CENTER]<br><br>` +
  152. `[CENTER][SIZE=4]Обжалование составлено не по форме.[/CENTER]<br><br>` +
  153. `[CENTER][SIZE=4]Закрыто.[/SIZE][/CENTER]`,
  154. prefix: UNACCEPT_PREFIX,
  155. status: false,
  156. },
  157. {
  158. title: `Обращайтесь в раздел жалоб на администрацию`,
  159. content:
  160. `[SIZE=4][CENTER]Приветствую, уважаемый игрок!.[/CENTER]<br><br>` +
  161. `[CENTER][SIZE=4]Если вы не согласны с выданным наказанием, то Вам следует обратиться в раздел > жалобы на администрацию.[/CENTER]<br><br>` +
  162. `[CENTER][SIZE=4]Закрыто.[/SIZE][/CENTER]`,
  163. prefix: UNACCEPT_PREFIX,
  164. status: false,
  165. },
  166. {
  167. title: `Отсутствуют док-ва`,
  168. content:
  169. `[SIZE=4][CENTER]Приветствую, уважаемый игрок!.[/CENTER]<br><br>` +
  170. `[CENTER][SIZE=4 Вашем обжаловании отсутствуют доказательства выдачи наказания.[/CENTER][/SIZE]<br><br>` +
  171. `[CENTER][SIZE=4]Закрыто.[/SIZE][/CENTER]`,
  172. prefix: UNACCEPT_PREFIX,
  173. status: false,
  174. },
  175. {
  176. title: `Отсутствуют док-ва с пострадавшим на его согласие в получении украденного имущества`,
  177. content:
  178. `[SIZE=4][CENTER]Приветствую, уважаемый игрок!.[/CENTER]<br><br>` +
  179. `[CENTER][SIZE=4 обжаловании отсутствуют доказательства переписки с пострадавшим игроком на его согласие в получении украденного имущества.[/CENTER][/SIZE]<br><br>` +
  180. `[CENTER][SIZE=4]Закрыто.[/SIZE][/CENTER]`,
  181. prefix: UNACCEPT_PREFIX,
  182. status: false,
  183. },
  184. {
  185. title: `Вы ошиблись разделом сервера`,
  186. content:
  187. `[SIZE=4][CENTER]Приветствую, уважаемый игрок!.[/CENTER]<br><br>` +
  188. `[CENTER][SIZE=4]Вы ошиблись разделом сервера.[/CENTER][/SIZE]<br><br>` +
  189. `[CENTER][SIZE=4]Закрыто.[/SIZE][/CENTER]`,
  190.  
  191. prefix: UNACCEPT_PREFIX,
  192. status: false,
  193. },
  194. {
  195. title: `Прошло 2 дня с момента выдачи наказания`,
  196. content:
  197. `[SIZE=4][CENTER]Приветствую, уважаемый игрок!.[/CENTER]<br><br>` +
  198. `[CENTER][SIZE=4]Ваша жалоба не может быть рассмотрена по причине несоблюдения обязательного условия:<br>` +
  199. `[QUOTE]3.1. Срок написания жалобы составляет два дня (48 часов) с момента совершенного нарушения со стороны администратора сервера.<br><br>` +
  200. `Примечание: в случае истечения срока жалоба рассмотрению не подлежит.[/QUOTE][/CENTER]<br><br><br>` +
  201. `[CENTER][SIZE=4]Закрыто.[/SIZE][/CENTER]`,
  202. prefix: UNACCEPT_PREFIX,
  203. status: false,
  204. },
  205. {
  206. title: `-------------------------------------------------- Для жалоб на администрацию --------------------------------------------------`,
  207. },
  208. {
  209. title: `Жалоба составлена не по форме`,
  210. content:
  211. `[SIZE=4][FONT=times new roman][CENTER]${greeting},[SIZE=4][FONT=times new roman] уважаемый (ая) ${user.mention}.[/CENTER]<br><br>` +
  212. `[CENTER][SIZE=4][FONT=times new roman]Жалоба составлена не по форме. Внимательно прочитайте правила составления жалобы, которые закреплены в этом разделе. <br><br>` +
  213. `[COLOR=rgb(255, 0, 13)]Закрыто[/COLOR].[/SIZE][/FONT][/CENTER]`,
  214. prefix: UNACCEPT_PREFIX,
  215. status: false,
  216. },
  217. ];
  218.  
  219. $(document).ready(() => {
  220. // Загрузка скрипта для обработки шаблонов
  221. $(`body`).append(
  222. `<script src="https://cdn.jsdelivr.net/npm/handlebars@latest/dist/handlebars.js"></script>`
  223. );
  224. // Добавление кнопок при загрузке страницы
  225. addButton(`На рассмотрении`, `pinned`);
  226. addButton(`Одобрено`, `accepted`);
  227. addButton(`Отказано`, `unaccepted`);
  228. addButton(`Закрыто`, `closed`);
  229. addButton(`Тех специалисту`, `tech`);
  230. addButton(`Рассмотрено`, `watched`);
  231. addButton(`Решено`, `resheno`);
  232. addButton(`Ответы`, `selectAnswer`);
  233.  
  234. // Поиск информации о теме
  235. const threadData = getThreadData();
  236.  
  237. $(`button#pinned`).click(() => editThreadData(PIN_PREFIX, true));
  238. $(`button#accepted`).click(() => editThreadData(ACCEPT_PREFIX, false));
  239. $(`button#unaccepted`).click(() => editThreadData(UNACCEPT_PREFIX, false));
  240. $(`button#closed`).click(() => editThreadData(CLOSE_PREFIX, false));
  241. $(`button#tech`).click(() => editThreadData(TECH_PREFIX, true));
  242. $(`button#watched`).click(() => editThreadData(WATCHED_PREFIX, false));
  243. $(`button#resheno`).click(() => editThreadData(RESHENO_PREFIX, false));
  244. $(`button#selectAnswer`).click(() => {
  245. XF.alert(buttonsMarkup(buttons), null, `Выберите ответ:`);
  246. buttons.forEach((btn, id) => {
  247. if (id > 0) {
  248. $(`button#answers-${id}`).click(() =>
  249. pasteContent(id, threadData, true)
  250. );
  251. } else {
  252. $(`button#answers-${id}`).click(() =>
  253. pasteContent(id, threadData, false)
  254. );
  255. }
  256. });
  257. });
  258. });
  259.  
  260. function addButton(name, id) {
  261. $(`.button--icon--reply`).before(
  262. `<button type="button" class="button rippleButton" id="${id}" style="margin: 3px;">${name}</button>`
  263. );
  264. }
  265.  
  266. function buttonsMarkup(buttons) {
  267. return `<div class="select_answer">${buttons
  268. .map(
  269. (btn, i) =>
  270. `<button id="answers-${i}" class="button--primary button ` +
  271. `rippleButton" style="margin:5px"><span class="button-text">${btn.title}</span></button>`
  272. )
  273. .join(``)}</div>`;
  274. }
  275.  
  276. function pasteContent(id, data = {}, send = false) {
  277. const template = Handlebars.compile(buttons[id].content);
  278. if ($(`.fr-element.fr-view p`).text() === ``)
  279. $(`.fr-element.fr-view p`).empty();
  280.  
  281. $(`span.fr-placeholder`).empty();
  282. $(`div.fr-element.fr-view p`).append(template(data));
  283. $(`a.overlay-titleCloser`).trigger(`click`);
  284.  
  285. if (send == true) {
  286. editThreadData(buttons[id].prefix, buttons[id].status);
  287. $(`.button--icon.button--icon--reply.rippleButton`).trigger(`click`);
  288. }
  289. }
  290.  
  291. async function getThreadData() {
  292. const authorID = $(`a.username`)[0].attributes[`data-user-id`].nodeValue;
  293. const authorName = $(`a.username`).html();
  294. const hours = new Date().getHours();
  295. const greeting =
  296. 4 < hours && hours <= 11
  297. ? `Доброе утро`
  298. : 11 < hours && hours <= 15
  299. ? `Добрый день`
  300. : 15 < hours && hours <= 21
  301. ? `Добрый вечер`
  302. : `Доброй ночи`;
  303.  
  304. return {
  305. user: {
  306. id: authorID,
  307. name: authorName,
  308. mention: `[USER=${authorID}]${authorName}[/USER]`,
  309. },
  310. greeting: greeting,
  311. };
  312. }
  313.  
  314. function editThreadData(prefix, pin = false) {
  315. // Получаем заголовок темы, так как он необходим при запросе
  316. const threadTitle = $(`.p-title-value`)[0].lastChild.textContent;
  317.  
  318. if (pin == false) {
  319. fetch(`${document.URL}edit`, {
  320. method: `POST`,
  321. body: getFormData({
  322. prefix_id: prefix,
  323. title: threadTitle,
  324. _xfToken: XF.config.csrf,
  325. _xfRequestUri: document.URL.split(XF.config.url.fullBase)[1],
  326. _xfWithData: 1,
  327. _xfResponseType: `json`,
  328. }),
  329. }).then(() => location.reload());
  330. }
  331. if (pin == true) {
  332. fetch(`${document.URL}edit`, {
  333. method: `POST`,
  334. body: getFormData({
  335. prefix_id: prefix,
  336. title: threadTitle,
  337. sticky: 1,
  338. _xfToken: XF.config.csrf,
  339. _xfRequestUri: document.URL.split(XF.config.url.fullBase)[1],
  340. _xfWithData: 1,
  341. _xfResponseType: `json`,
  342. }),
  343. }).then(() => location.reload());
  344. }
  345. }
  346.  
  347. function getFormData(data) {
  348. const formData = new FormData();
  349. Object.entries(data).forEach((i) => formData.append(i[0], i[1]));
  350. return formData;
  351. }
  352. })();