All user data for FoundryVTT. Includes worlds, systems, modules, and any asset in the "foundryuserdata" directory. Does NOT include the FoundryVTT installation itself.

157 lines
5.8 KiB

  1. class TheRipperPremiumHUB {
  2. constructor() {
  3. this.outdatedModules = {};
  4. this.announcementsHtml = ""
  5. this._debug = false;
  6. this.init();
  7. }
  8. async init() {
  9. this.moduleData = await this.fetchData();
  10. this.announcements = this.moduleData.announcements;
  11. delete this.moduleData.announcements;
  12. this.getOutdatedModules();
  13. if (game.settings.get("theripper-premium-hub", "autoCheck")) {
  14. this.displayOutdated(false);
  15. }
  16. this.displayAnnouncements();
  17. }
  18. getOutdatedModules() {
  19. const checkDisabled = game.settings.get(
  20. "theripper-premium-hub",
  21. "checkDisabled"
  22. );
  23. for (let [k, v] of Object.entries(this.moduleData)) {
  24. const installedModule = game.modules.get(k);
  25. if(!installedModule) continue;
  26. if (!checkDisabled && !installedModule?.active) continue;
  27. if (isNewerVersion(v.version, installedModule.version) || this._debug) {
  28. this.outdatedModules[k] = v;
  29. this.outdatedModules[k].title = installedModule.title;
  30. this.outdatedModules[k].currentVersion = installedModule.version;
  31. }
  32. }
  33. }
  34. async displayOutdated(notify = false) {
  35. if (Object.keys(this.outdatedModules).length === 0)
  36. return notify
  37. ? ui.notifications.info(`No outdated modules found.`)
  38. : null;
  39. let displayUpdated = {}
  40. if(!notify) {
  41. const viewedUpdates = game.settings.get("theripper-premium-hub", "viewedUpdates");
  42. for(let [k, v] of Object.entries(this.outdatedModules)) {
  43. if(viewedUpdates[k] && v.version === viewedUpdates[k]) continue;
  44. displayUpdated[k] = v;
  45. }
  46. }else{
  47. displayUpdated = this.outdatedModules;
  48. }
  49. if (Object.keys(displayUpdated).length === 0) return null;
  50. const html = await renderTemplate(
  51. "modules/theripper-premium-hub/templates/modlist.hbs",
  52. displayUpdated
  53. );
  54. Dialog.prompt({
  55. title: "TheRipper93 Premium HUB - Updates Available!",
  56. content: html,
  57. rejectClose: false,
  58. callback: () => {
  59. const viewedUpdates = game.settings.get("theripper-premium-hub", "viewedUpdates");
  60. for(let [k, v] of Object.entries(this.outdatedModules)){
  61. viewedUpdates[k] = v.version;
  62. }
  63. game.settings.set("theripper-premium-hub", "viewedUpdates", viewedUpdates);
  64. },
  65. close: () => {},
  66. });
  67. }
  68. async displayAnnouncements() {
  69. const announcements = this.announcements;
  70. if (!announcements) return;
  71. const ids = Object.keys(announcements);
  72. const viewedAnnouncements = game.settings.get("theripper-premium-hub", "viewedAnnouncements") ?? "";
  73. const allViewed = ids.every(id => viewedAnnouncements.includes(id));
  74. const html = await renderTemplate(
  75. "modules/theripper-premium-hub/templates/announcements.hbs",
  76. announcements
  77. );
  78. this.announcementsHtml = html;
  79. if (allViewed && !this._debug) return;
  80. game.settings.set("theripper-premium-hub", "viewedAnnouncements", ids.join(","));
  81. Dialog.prompt({
  82. title: "TheRipper93 Premium HUB - Announcement!",
  83. content: html + ` <p style="text-align: center;">Want to support me and get access to premium modules?</p><hr>
  84. <p style="text-align: center;"><a href="https://theripper93.com/" target="_blank" rel="nofollow" title="https://theripper93.com/">Check out my Website</a></p>`,
  85. rejectClose: false,
  86. callback: () => {},
  87. close: () => {},
  88. });
  89. }
  90. async fetchData() {
  91. return await fetch(
  92. `https://api.theripper93.com/moduleListing/latest`, { cache: "no-cache" }
  93. )
  94. .then((response) => response.json())
  95. .then((data) => data);
  96. }
  97. _getdataforfile() {
  98. const mods = {};
  99. game.modules.forEach((v, k) => {
  100. if(v.authors && v.authors.some(a => a.name === "theripper93") && (!v.data?.download || v.data?.url === "https://github.com/theripper93/name")){
  101. mods[k] = {
  102. title: v.title,
  103. version: v.version,
  104. downloadURL: this.moduleData[k]?.downloadURL ?? ""
  105. };
  106. }
  107. });
  108. return mods;
  109. }
  110. getDependencies(moduleId) {
  111. const rootModule = game.modules.get(moduleId);
  112. const dependencies = new Set();
  113. const addDependecies = (module) => {
  114. const moduleDependencies = Array.from(module.relationships.requires).map((m) => game.modules.get(m.id));
  115. moduleDependencies.forEach((m) => {
  116. dependencies.add(m);
  117. addDependecies(m);
  118. });
  119. };
  120. addDependecies(rootModule);
  121. return dependencies;
  122. }
  123. async troubleshoot(moduleId) {
  124. console.log(moduleId);
  125. const confirm = await Dialog.confirm({
  126. title: "TheRipper93 Premium HUB - Troubleshoot",
  127. content: `<p>Do you want to start the troubleshoot for ${game.modules.get(moduleId).title}?</p><br><p>This will disable all modules except the one you selected and its dependencies. You will be prompted to restore your modules after the troubleshoot.</p>`,
  128. yes: () => {
  129. return true;
  130. },
  131. no: () => {
  132. return false;
  133. },
  134. });
  135. if (!confirm) return;
  136. const dependencies = this.getDependencies(moduleId);
  137. const dependenciesIds = [...Array.from(dependencies).map((m) => m.id) ,moduleId,"theripper-premium-hub"];
  138. const modulesSetting = game.settings.get("core", ModuleManagement.CONFIG_SETTING);
  139. const currentlyEnabled = [];
  140. for (let [k, v] of Object.entries(modulesSetting)) {
  141. if (v) currentlyEnabled.push(k);
  142. if (dependenciesIds.includes(k)) continue;
  143. modulesSetting[k] = false;
  144. }
  145. await game.settings.set("theripper-premium-hub", "prevEnabledModules", currentlyEnabled);
  146. await game.settings.set("core", ModuleManagement.CONFIG_SETTING, modulesSetting);
  147. debouncedReload();
  148. }
  149. }