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.

258 lines
9.0 KiB

  1. using CustomUI.BeatSaber;
  2. using CustomUI.Utilities;
  3. using IPA.Loader;
  4. using IPA.Loader.Features;
  5. using IPA.Old;
  6. using System;
  7. using System.Collections.Generic;
  8. using System.Linq;
  9. using System.Text;
  10. using System.Threading.Tasks;
  11. using UnityEngine;
  12. namespace BSIPA_ModList.UI.ViewControllers
  13. {
  14. internal interface IClickableCell
  15. {
  16. void OnSelect(ModListController cntrl);
  17. void Update();
  18. }
  19. internal class BSIPAModCell : CustomCellInfo, IClickableCell
  20. {
  21. internal PluginLoader.PluginMetadata Plugin;
  22. private ModListController list;
  23. private PluginManager.PluginEnableDelegate enableDel;
  24. private PluginManager.PluginDisableDelegate disableDel;
  25. public BSIPAModCell(ModListController list, PluginLoader.PluginMetadata plugin)
  26. : base("", "", null)
  27. {
  28. Plugin = plugin;
  29. this.list = list;
  30. var thisWeakRef = new WeakReference<BSIPAModCell>(this);
  31. PluginManager.PluginDisableDelegate reflessDDel = null;
  32. reflessDDel = disableDel = (p, r) => PluginManager_PluginDisabled(p, r, thisWeakRef, reflessDDel); // some indirection to make it a weak link for GC
  33. PluginManager.PluginDisabled += reflessDDel;
  34. PluginManager.PluginEnableDelegate reflessEDel = null;
  35. reflessEDel = enableDel = (p, r) => PluginManager_PluginEnabled(p, r, thisWeakRef, reflessEDel); // some indirection to make it a weak link for GC
  36. PluginManager.PluginEnabled += reflessEDel;
  37. Update(propogate: false);
  38. }
  39. private static void PluginManager_PluginEnabled(PluginLoader.PluginInfo plugin, bool needsRestart, WeakReference<BSIPAModCell> _self, PluginManager.PluginEnableDelegate ownDel)
  40. {
  41. if (!_self.TryGetTarget(out var self))
  42. {
  43. PluginManager.PluginEnabled -= ownDel;
  44. return;
  45. }
  46. if (plugin.Metadata != self.Plugin) return;
  47. self.Update(true, needsRestart);
  48. }
  49. private static void PluginManager_PluginDisabled(PluginLoader.PluginMetadata plugin, bool needsRestart, WeakReference<BSIPAModCell> _self, PluginManager.PluginDisableDelegate ownDel)
  50. {
  51. if (!_self.TryGetTarget(out var self))
  52. PluginManager.PluginDisabled -= ownDel;
  53. if (plugin != self.Plugin) return;
  54. self.Update(false, needsRestart);
  55. }
  56. private ModInfoViewController infoView;
  57. public void OnSelect(ModListController cntrl)
  58. {
  59. Logger.log.Debug($"Selected BSIPAModCell {Plugin.Name} {Plugin.Version}");
  60. if (infoView == null)
  61. {
  62. var desc = Plugin.Manifest.Description;
  63. if (string.IsNullOrWhiteSpace(desc))
  64. desc = "*No description*";
  65. infoView = BeatSaberUI.CreateViewController<ModInfoViewController>();
  66. infoView.Init(icon, Plugin.Name, "v" + Plugin.Version.ToString(), subtext,
  67. desc, Plugin, Plugin.Manifest.Links, true, list.flow);
  68. }
  69. list.flow.SetSelected(infoView, immediate: list.flow.HasSelected);
  70. }
  71. void IClickableCell.Update() => Update(null, false, false);
  72. public void Update(bool? _enabled = null, bool needsRestart = false, bool propogate = true)
  73. {
  74. text = $"{Plugin.Name} <size=60%>v{Plugin.Version}";
  75. subtext = Plugin.Manifest.Author;
  76. if (string.IsNullOrWhiteSpace(subtext))
  77. subtext = "<color=#BFBFBF><i>Unspecified Author</i>";
  78. var enabled = _enabled ?? !PluginManager.IsDisabled(Plugin);
  79. if (!enabled)
  80. subtext += " <color=#C2C2C2>- <i>Disabled</i>";
  81. if (needsRestart)
  82. subtext += " <i>(Restart to apply)</i>";
  83. icon = Plugin.GetIcon();
  84. var desc = Plugin.Manifest.Description;
  85. if (string.IsNullOrWhiteSpace(desc))
  86. desc = "*No description*";
  87. infoView?.Reload(Plugin.Name, "v" + Plugin.Version.ToString(), subtext, desc);
  88. if (propogate)
  89. list.Reload();
  90. }
  91. }
  92. internal class BSIPAIgnoredModCell : CustomCellInfo, IClickableCell
  93. {
  94. internal PluginLoader.PluginMetadata Plugin;
  95. private ModListController list;
  96. private const string authorFormat = "{0} <color=#BFBFBF>- <i>Not loaded</i>";
  97. private string authorText;
  98. public BSIPAIgnoredModCell(ModListController list, PluginLoader.PluginMetadata plugin)
  99. : base($"<color=#878787>{plugin.Name} <size=60%>v{plugin.Version}", "", Utilities.DefaultBSIPAIcon)
  100. {
  101. Plugin = plugin;
  102. this.list = list;
  103. if (string.IsNullOrWhiteSpace(plugin.Manifest.Author))
  104. authorText = "<color=#BFBFBF><i>Unspecified Author</i>";
  105. else
  106. authorText = plugin.Manifest.Author;
  107. subtext = string.Format(authorFormat, authorText);
  108. }
  109. private ModInfoViewController infoView;
  110. public void OnSelect(ModListController cntrl)
  111. {
  112. Logger.log.Debug($"Selected BSIPAIgnoredModCell {Plugin.Name} {Plugin.Version}");
  113. if (infoView == null)
  114. {
  115. var desc = Plugin.Manifest.Description;
  116. if (string.IsNullOrWhiteSpace(desc))
  117. desc = "*No description*";
  118. infoView = BeatSaberUI.CreateViewController<ModInfoViewController>();
  119. infoView.Init(icon, Plugin.Name, "v" + Plugin.Version.ToString(), authorText,
  120. desc, Plugin, Plugin.Manifest.Links);
  121. }
  122. list.flow.SetSelected(infoView, immediate: list.flow.HasSelected);
  123. }
  124. public void Update()
  125. {
  126. }
  127. }
  128. internal class LibraryModCell : CustomCellInfo, IClickableCell
  129. {
  130. internal PluginLoader.PluginMetadata Plugin;
  131. private ModListController list;
  132. public LibraryModCell(ModListController list, PluginLoader.PluginMetadata plugin)
  133. : base($"{plugin.Name} <size=60%>v{plugin.Version}", plugin.Manifest.Author, null)
  134. {
  135. Plugin = plugin;
  136. this.list = list;
  137. if (string.IsNullOrWhiteSpace(subtext))
  138. subtext = "<color=#BFBFBF><i>Unspecified Author</i></color>";
  139. icon = Utilities.DefaultLibraryIcon;
  140. }
  141. private ModInfoViewController infoView;
  142. public void OnSelect(ModListController cntrl)
  143. {
  144. Logger.log.Debug($"Selected LibraryModCell {Plugin.Name} {Plugin.Version}");
  145. if (infoView == null)
  146. {
  147. var desc = Plugin.Manifest.Description;
  148. if (string.IsNullOrWhiteSpace(desc))
  149. desc = "*No description*";
  150. infoView = BeatSaberUI.CreateViewController<ModInfoViewController>();
  151. infoView.Init(icon, Plugin.Name, "v" + Plugin.Version.ToString(), subtext,
  152. desc, Plugin, Plugin.Manifest.Links);
  153. }
  154. list.flow.SetSelected(infoView, immediate: list.flow.HasSelected);
  155. }
  156. public void Update()
  157. {
  158. }
  159. }
  160. #pragma warning disable CS0618
  161. internal class IPAModCell : CustomCellInfo, IClickableCell
  162. {
  163. internal IPlugin Plugin;
  164. private ModListController list;
  165. public IPAModCell(ModListController list, IPlugin plugin)
  166. : base($"{plugin.Name} <size=60%>{plugin.Version}", "<color=#BFBFBF><i>Legacy</i>", Utilities.DefaultIPAIcon)
  167. {
  168. Plugin = plugin;
  169. this.list = list;
  170. }
  171. private ModInfoViewController infoView;
  172. public void OnSelect(ModListController cntrl)
  173. {
  174. Logger.log.Debug($"Selected IPAModCell {Plugin.Name} {Plugin.Version}");
  175. if (infoView == null)
  176. {
  177. PluginLoader.PluginMetadata updateInfo = null;
  178. try
  179. {
  180. updateInfo = new PluginLoader.PluginMetadata
  181. {
  182. Name = Plugin.Name,
  183. Id = Plugin.Name,
  184. Version = new SemVer.Version(Plugin.Version)
  185. };
  186. }
  187. catch (Exception e)
  188. {
  189. Logger.log.Warn($"Could not generate fake update info for {Plugin.Name}");
  190. Logger.log.Warn(e);
  191. }
  192. infoView = BeatSaberUI.CreateViewController<ModInfoViewController>();
  193. infoView.Init(icon, Plugin.Name, "v" + Plugin.Version.ToString(), "<color=#BFBFBF><i>Unknown Author</i>",
  194. "This mod was written for IPA.\n===\n\n## No metadata is avaliable for this mod.\n\n" +
  195. "Please contact the mod author and ask them to port it to BSIPA to provide more information.", updateInfo);
  196. }
  197. list.flow.SetSelected(infoView, immediate: list.flow.HasSelected);
  198. }
  199. public void Update()
  200. {
  201. }
  202. }
  203. #pragma warning restore
  204. }