[GC] - SDB Contents Collection

2/25/2024, 11:26:31 PM

  1. // ==UserScript==
  2. // @name [GC] - SDB Contents Collection
  3. // @namespace https://gf.qytechs.cn/en/users/1225524-kaitlin
  4. // @match https://www.grundos.cafe/safetydeposit/*
  5. // @grant GM.setValue
  6. // @grant GM.getValue
  7. // @grant GM.addStyle
  8.  
  9. // @license MIT
  10. // @version 1.2
  11. // @author Cupkait
  12. // @icon https://i.imgur.com/4Hm2e6z.png
  13. // @description 2/25/2024, 11:26:31 PM
  14. // ==/UserScript==
  15.  
  16.  
  17. let collect = false;
  18. let active = false;
  19.  
  20. const sdbStyle = createSdbStyle();
  21. document.head.appendChild(sdbStyle);
  22.  
  23. const collectContainer = createCollectContainer();
  24. document.querySelector('main .sdb-info').append(collectContainer);
  25.  
  26. initialize();
  27.  
  28. async function initialize() {
  29. collect = await GM.getValue('collect', false);
  30. active = await GM.getValue('active', false);
  31. collect ? showNextButtons() : active ? enableNextPageNavigation() : showEnableButton();
  32. }
  33.  
  34. function createSdbStyle() {
  35. const style = document.createElement('style');
  36. style.innerHTML = `
  37. .collect-sdb {
  38. text-align: center;
  39. margin: 10px;
  40. }
  41. .collect-sdb a {
  42. background-color: var(--grid_head);
  43. border: 1px solid grey;
  44. padding: 5px 15px;
  45. margin: 10px;
  46. }
  47. `;
  48. return style;
  49. }
  50.  
  51. function createCollectContainer() {
  52. const container = document.createElement('div');
  53. container.classList.add('collect-sdb');
  54. return container;
  55. }
  56.  
  57. function showEnableButton() {
  58. collectContainer.append(createButton('Begin SDB Data Collection', () => {
  59. GM.setValue('collect', true).then(showNextButtons);
  60. }));
  61. }
  62.  
  63. function showNextButtons() {
  64. removeAllButtons();
  65. collectContainer.append(
  66. createButton('Collect full SDB', () => setActiveAndNavigate('https://www.grundos.cafe/safetydeposit/?view=100')),
  67. createButton('Collect quest only', () => setActiveAndNavigate('https://www.grundos.cafe/safetydeposit/?page=1&&max_rarity=89&view=100'))
  68. );
  69. }
  70.  
  71. function createButton(text, onClick) {
  72. const button = document.createElement('a');
  73. button.textContent = text;
  74. button.addEventListener('click', onClick);
  75. return button;
  76. }
  77.  
  78. function removeAllButtons() {
  79. while (collectContainer.firstChild) collectContainer.firstChild.remove();
  80. }
  81.  
  82. async function setActiveAndNavigate(url) {
  83. await Promise.all([GM.setValue('collect', false), GM.setValue('active', true)]);
  84. window.location.href = url;
  85. }
  86.  
  87. function enableNextPageNavigation() {
  88. removeEnableButton();
  89. collectContainer.append(createButton('Cancel/Restart Collection', cancelCollection));
  90. initTableProcessing();
  91. }
  92.  
  93. function removeEnableButton() {
  94. const enableButton = collectContainer.querySelector('button');
  95. if (enableButton) enableButton.remove();
  96. }
  97.  
  98. function appendMessages(messageText) {
  99. const message = document.createElement('p');
  100. message.innerHTML = messageText;
  101. collectContainer.append(message);
  102. }
  103.  
  104. async function initTableProcessing() {
  105. await processTableData();
  106. displayPageInfo();
  107. setupKeyboardNavigation();
  108. }
  109.  
  110. async function loadSdbContents() {
  111. return GM.getValue('sdbContents', []);
  112. }
  113.  
  114. async function saveSdbContents(contents) {
  115. await GM.setValue('sdbContents', contents);
  116. }
  117.  
  118. async function processTableData() {
  119. const sdbContents = await loadSdbContents();
  120. const data = document.querySelectorAll('.data');
  121. const rows = [];
  122.  
  123. for (let i = 0; i < data.length; i += 7) {
  124. const row = createRow(data, i);
  125. const existingItemIndex = sdbContents.findIndex(item => item.n === row.n);
  126. if (existingItemIndex > -1) sdbContents[existingItemIndex] = row;
  127. else sdbContents.push(row);
  128. rows.push(row);
  129. }
  130.  
  131. await saveSdbContents(sdbContents);
  132. }
  133.  
  134. function createRow(data, index) {
  135. return {
  136. n: data[index + 1].querySelector('strong').textContent,
  137. r: parseInt(data[index + 1].querySelector('span').textContent.match(/\d+/)[0]),
  138. p: data[index + 2].querySelector('img').src.split('/').pop(),
  139. q: parseInt(data[index + 3].textContent),
  140. t: data[index + 4].querySelector('strong').textContent,
  141. };
  142. }
  143.  
  144. function setupKeyboardNavigation() {
  145. document.addEventListener('keydown', (event) => {
  146. if (event.key === 'ArrowRight' && !['INPUT', 'TEXTAREA'].includes(document.activeElement.tagName)) {
  147. const nextPageLink = [...document.querySelectorAll('.center a')].find(link => link.textContent.trim().startsWith('Next'));
  148. if (nextPageLink) nextPageLink.click();
  149. }
  150. });
  151. }
  152.  
  153. async function displayPageInfo() {
  154. const pageCount = document.querySelectorAll('#page option').length;
  155. const currentPage = parseInt(new URLSearchParams(window.location.search).get('page')) || 1;
  156. const sdbContents = await loadSdbContents();
  157. const totalItems = sdbContents.length;
  158. const endTotal = parseFloat(document.querySelector('main .center').childNodes[4].textContent.replace(/[^0-9.]/g, '').replace(/,/g, ''));
  159.  
  160. appendMessages(`Total items collected: <strong>${totalItems.toLocaleString()}</strong> <br>You are viewing page <strong>${currentPage.toLocaleString()}</strong> / <strong>${pageCount.toLocaleString()}</strong>.`);
  161. appendMessages(`Click "Next" or press the right arrow key to go to the next page.`);
  162.  
  163. if (totalItems === endTotal) appendExportButtons();
  164. }
  165.  
  166. function appendExportButtons() {
  167. collectContainer.append(createButton('Export to CSV', exportToCSV), createButton('Copy to Clipboard', copyToClipboard));
  168. appendMessages(`Export to CSV to make a spreadsheet of the results. Copy to Clipboard to paste into a Virtupets.net Checklist.`)
  169. }
  170.  
  171. function exportToCSV() {
  172. loadSdbContents().then(sdbContents => {
  173. const csvContent = "data:text/csv;charset=utf-8," + sdbContents.map(e => Object.values(e).join(",")).join("\n");
  174. const link = document.createElement("a");
  175. link.setAttribute("href", encodeURI(csvContent));
  176. link.setAttribute("download", "sdbContents.csv");
  177. document.body.appendChild(link);
  178. link.click();
  179. link.remove();
  180. displayCompletionMessage();
  181. });
  182. }
  183.  
  184. function copyToClipboard() {
  185. loadSdbContents().then(sdbContents => {
  186. navigator.clipboard.writeText(JSON.stringify(sdbContents)).then(displayCompletionMessage).catch(err => {
  187. console.error('Could not copy text: ', err);
  188. });
  189. });
  190. }
  191.  
  192. function displayCompletionMessage() {
  193. let message = collectContainer.querySelector('.completion-message');
  194. let button = collectContainer.querySelector('button');
  195. button.textContent = 'Done Collecting'
  196.  
  197. if (!message) {
  198. message = document.createElement('p');
  199. message.classList.add('completion-message');
  200. collectContainer.append(message);
  201. }
  202. message.innerHTML = 'Action complete! Press "Done Collecting" to return to your usual SDB view.';
  203.  
  204.  
  205. }
  206.  
  207. async function cancelCollection() {
  208. await Promise.all([GM.setValue('active', false), GM.setValue('sdbContents', [])]);
  209. window.location.href = 'https://www.grundos.cafe/safetydeposit/?view=100';
  210. }

QingJ © 2025

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