All user data for FoundryVTT. Includes worlds, systems, modules, and any asset in the "foundryuserdata" directory. Does NOT include the FoundryVTT installation itself.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

175 lines
7.3 KiB

  1. Hooks.on("init", () => {
  2. game.settings.register("theripper-premium-hub", "autoCheck", {
  3. name: "Check for Updates on Startup",
  4. hint: "Automatically check on world load if any of my premium modules have updates.",
  5. scope: "world",
  6. config: true,
  7. type: Boolean,
  8. default: true,
  9. });
  10. game.settings.register("theripper-premium-hub", "checkDisabled", {
  11. name: "Check Modules not Enabled",
  12. hint: "Check for updates on modules that are installed but not enabled.",
  13. scope: "world",
  14. config: true,
  15. type: Boolean,
  16. default: true,
  17. });
  18. game.settings.register("theripper-premium-hub", "viewedAnnouncements", {
  19. scope: "world",
  20. config: false,
  21. type: String,
  22. default: "",
  23. });
  24. game.settings.register("theripper-premium-hub", "viewedUpdates", {
  25. scope: "world",
  26. config: false,
  27. type: Object,
  28. default: {},
  29. });
  30. game.settings.register("theripper-premium-hub", "prevEnabledModules", {
  31. scope: "world",
  32. config: false,
  33. type: Array,
  34. default: [],
  35. });
  36. const prevEnabledModules = game.settings.get("theripper-premium-hub", "prevEnabledModules");
  37. async function reEnableModules() {
  38. if (game.user.isGM && prevEnabledModules.length > 0) {
  39. const confirm = await Dialog.confirm({
  40. title: "TheRipper93 Premium HUB",
  41. content: "Would you like to re-enable your previously enabled modules?<br>Choose 'No' to disable this prompt, you will have to manually re-enable modules in the module management menu.<br>Close this prompt to be asked again on next refresh.",
  42. yes: () => {
  43. return true;
  44. },
  45. no: () => {
  46. return false;
  47. },
  48. defaultYes: true,
  49. });
  50. if(confirm === false) await game.settings.set("theripper-premium-hub", "prevEnabledModules", []);
  51. if (!confirm) return;
  52. const modulesSetting = game.settings.get("core", ModuleManagement.CONFIG_SETTING);
  53. for (const [k, v] of Object.entries(modulesSetting)) {
  54. if (prevEnabledModules.includes(k)) {
  55. modulesSetting[k] = true;
  56. }
  57. }
  58. await game.settings.set("theripper-premium-hub", "prevEnabledModules", []);
  59. await game.settings.set("core", ModuleManagement.CONFIG_SETTING, modulesSetting);
  60. debouncedReload();
  61. }
  62. }
  63. Hooks.once("ready", () => {
  64. reEnableModules();
  65. });
  66. });
  67. Hooks.on("renderSettingsConfig", (app, html, data) => {
  68. if (!game.user.isGM) return;
  69. function generateSupportReport(moduleId) {
  70. const supportInfo = SupportDetails.generateSupportReport();
  71. const supportOutput = {
  72. "Core Version": supportInfo.coreVersion,
  73. System: supportInfo.systemVersion,
  74. Client: supportInfo.client,
  75. GPU: supportInfo.gpu,
  76. "Module Count": supportInfo.activeModuleCount,
  77. };
  78. const module = game.modules.get(moduleId);
  79. supportOutput[module.title] = module.version;
  80. const dependencies = game.theripperpremiumhub.getDependencies(moduleId);
  81. dependencies.forEach((m) => {
  82. supportOutput[m.title] = m.version;
  83. });
  84. const tableHtml = Object.keys(supportOutput)
  85. .map((key) => {
  86. return `<tr><td>${key}</td><td>${supportOutput[key]}</td></tr>`;
  87. })
  88. .join("");
  89. const html = `<table>${tableHtml}</table>`;
  90. Dialog.prompt({
  91. title: "Support Report",
  92. content: html,
  93. label: "Copy to Clipboard",
  94. callback: (html) => {
  95. const text = Object.entries(supportOutput)
  96. .map(([k, v]) => `${k}: ${v}`)
  97. .join("\n");
  98. game.clipboard.copyPlainText("```" + text + "```");
  99. ui.notifications.info("Copied to Clipboard, please paste it along with your support request on discord.");
  100. },
  101. });
  102. }
  103. //Add wiki buttons
  104. html[0].querySelectorAll(".tab.category").forEach((el) => {
  105. const moduleId = el.getAttribute("data-tab");
  106. const module = game.modules.get(moduleId);
  107. if (!module) return;
  108. if (!Array.from(module.authors).some((a) => a.name === "theripper93")) return;
  109. const title = el.querySelector("h2");
  110. title.style.display = "flex";
  111. const wikiButton = document.createElement("a");
  112. wikiButton.style.marginLeft = "auto";
  113. wikiButton.classList.add("wiki-button");
  114. const status = module.download ? "free" : "paid";
  115. wikiButton.setAttribute("href", `https://api.theripper93.com/modulewiki/${moduleId}/${status}`);
  116. wikiButton.setAttribute("target", "_blank");
  117. wikiButton.innerHTML = `<i data-tooltip="Open Documentation" class="fas fa-book"></i>`;
  118. title.appendChild(wikiButton);
  119. const supportButton = document.createElement("a");
  120. supportButton.style.marginLeft = "0.5rem";
  121. supportButton.classList.add("wiki-button");
  122. supportButton.innerHTML = `<i data-tooltip="Generate Support Report" class="fas fa-question-circle"></i>`;
  123. supportButton.addEventListener("click", (e) => {
  124. e.preventDefault();
  125. generateSupportReport(moduleId);
  126. });
  127. title.appendChild(supportButton);
  128. const troubleshootButton = document.createElement("a");
  129. troubleshootButton.style.marginLeft = "0.5rem";
  130. troubleshootButton.classList.add("wiki-button");
  131. troubleshootButton.innerHTML = `<i data-tooltip="Troubleshoot" class="fas fa-tools"></i>`;
  132. troubleshootButton.addEventListener("click", (e) => {
  133. e.preventDefault();
  134. game.theripperpremiumhub.troubleshoot(moduleId);
  135. });
  136. title.appendChild(troubleshootButton);
  137. });
  138. const menuSetting = html.find(`input[name="theripper-premium-hub.checkDisabled"]`).closest(".form-group");
  139. const button = $(`
  140. ${game.theripperpremiumhub.announcementsHtml}
  141. <div class="form-group">
  142. <a style="text-align: center;" href="https://theripper93.com/" target="_blank" rel="nofollow" title="https://theripper93.com/"><i class="fas fa-globe"></i> Visit my Website</a>
  143. <button type="button">
  144. <i class="fas fa-cogs"></i>
  145. <label>Check for Updates</label>
  146. </button>
  147. </div>
  148. `);
  149. button.find("button").click((e) => {
  150. e.preventDefault();
  151. game.theripperpremiumhub.displayOutdated(true);
  152. });
  153. menuSetting.after(button);
  154. html[0].querySelectorAll(".item.category-tab").forEach((el) => {
  155. const modId = el.dataset.tab;
  156. const outdated = game.theripperpremiumhub.outdatedModules[modId];
  157. if (!outdated) return;
  158. el.innerHTML = el.innerHTML.replace(outdated.title, `<span><i style="color: var(--color-level-warning)" class="fas fa-circle-info"></i> ${outdated.title}</span>`);
  159. el.dataset.tooltip = game.i18n.format("SETUP.UpdateAvailable", { channel: outdated.title, version: outdated.version });
  160. });
  161. });