diff --git a/Dalamud.Injector/Program.cs b/Dalamud.Injector/Program.cs index 6f0e1fa1d..ebf861e6b 100644 --- a/Dalamud.Injector/Program.cs +++ b/Dalamud.Injector/Program.cs @@ -86,6 +86,8 @@ namespace Dalamud.Injector { @"\XIVLauncher\plugins", DefaultPluginDirectory = Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData) + @"\XIVLauncher\defaultplugins", + + GameVersion = "2020.02.11.0000.0000", Language = ClientLanguage.English }; @@ -93,7 +95,8 @@ namespace Dalamud.Injector { $"ConfigurationPath: {startInfo.ConfigurationPath}\n" + $"PluginDirectory: {startInfo.PluginDirectory}\n" + $"DefaultPluginDirectory: {startInfo.DefaultPluginDirectory}\n" + - $"Language: {startInfo.Language}"); + $"Language: {startInfo.Language}\n" + + $"GameVersion: {startInfo.GameVersion}"); return startInfo; } diff --git a/Dalamud/Dalamud.cs b/Dalamud/Dalamud.cs index 20a4fe595..10497c33d 100644 --- a/Dalamud/Dalamud.cs +++ b/Dalamud/Dalamud.cs @@ -43,7 +43,7 @@ namespace Dalamud { public readonly DiscordBotManager BotManager; - public readonly PluginManager PluginManager; + public PluginManager PluginManager { get; private set; } public readonly ClientState ClientState; @@ -88,8 +88,6 @@ namespace Dalamud { this.BotManager = new DiscordBotManager(this, this.Configuration.DiscordFeatureConfig); - this.PluginManager = new PluginManager(this, info.PluginDirectory); - this.WinSock2 = new WinSockHandlers(); try { @@ -112,6 +110,7 @@ namespace Dalamud { this.BotManager.Start(); try { + this.PluginManager = new PluginManager(this, this.StartInfo.PluginDirectory, this.StartInfo.DefaultPluginDirectory); this.PluginManager.LoadPlugins(); } catch (Exception ex) { this.Framework.Gui.Chat.PrintError( @@ -211,7 +210,7 @@ namespace Dalamud { { if (ImGui.MenuItem("Open Plugin installer")) { - this.pluginWindow = new PluginInstallerWindow(this.PluginManager, this.StartInfo.PluginDirectory); + this.pluginWindow = new PluginInstallerWindow(this.PluginManager, this.StartInfo.PluginDirectory, this.StartInfo.GameVersion); this.isImguiDrawPluginWindow = true; } if (ImGui.MenuItem("Print plugin info")) { diff --git a/Dalamud/DalamudStartInfo.cs b/Dalamud/DalamudStartInfo.cs index 16d43e5fa..8cd60d92f 100644 --- a/Dalamud/DalamudStartInfo.cs +++ b/Dalamud/DalamudStartInfo.cs @@ -11,6 +11,8 @@ namespace Dalamud { public string PluginDirectory; public string DefaultPluginDirectory; public ClientLanguage Language; + + public string GameVersion; } public enum ClientLanguage diff --git a/Dalamud/Plugin/PluginDefinition.cs b/Dalamud/Plugin/PluginDefinition.cs index 29b373b75..6e3c97d94 100644 --- a/Dalamud/Plugin/PluginDefinition.cs +++ b/Dalamud/Plugin/PluginDefinition.cs @@ -13,5 +13,6 @@ namespace Dalamud.Plugin public string InternalName { get; set; } public string AssemblyVersion { get; set; } public string Description { get; set; } + public string ApplicableGameVersion { get; set; } } } diff --git a/Dalamud/Plugin/PluginInstallerWindow.cs b/Dalamud/Plugin/PluginInstallerWindow.cs index 6626239f7..6dd8458e3 100644 --- a/Dalamud/Plugin/PluginInstallerWindow.cs +++ b/Dalamud/Plugin/PluginInstallerWindow.cs @@ -21,6 +21,7 @@ namespace Dalamud.Plugin private PluginManager manager; private string pluginDirectory; + private string gameVersion; private ReadOnlyCollection pluginMaster; private bool errorModalDrawing = true; private bool errorModalOnNextFrame = false; @@ -36,9 +37,10 @@ namespace Dalamud.Plugin private bool masterDownloadFailed = false; - public PluginInstallerWindow(PluginManager manager, string pluginDirectory) { + public PluginInstallerWindow(PluginManager manager, string pluginDirectory, string gameVersion) { this.manager = manager; this.pluginDirectory = pluginDirectory; + this.gameVersion = gameVersion; Task.Run(CachePluginMaster).ContinueWith(t => { this.masterDownloadFailed = this.masterDownloadFailed || t.IsFaulted; this.errorModalDrawing = this.masterDownloadFailed; @@ -68,7 +70,7 @@ namespace Dalamud.Plugin if (disabledFile.Exists) disabledFile.Delete(); - this.manager.LoadPluginFromAssembly(dllFile); + this.manager.LoadPluginFromAssembly(dllFile, false); this.installStatus = PluginInstallStatus.Success; return; } @@ -87,7 +89,7 @@ namespace Dalamud.Plugin ZipFile.ExtractToDirectory(path, outputDir.FullName); this.installStatus = PluginInstallStatus.Success; - this.manager.LoadPluginFromAssembly(dllFile); + this.manager.LoadPluginFromAssembly(dllFile, false); } catch (Exception e) { Log.Error(e, "Plugin download failed hard."); this.installStatus = PluginInstallStatus.Fail; @@ -97,7 +99,7 @@ namespace Dalamud.Plugin public bool Draw() { var windowOpen = true; - ImGui.SetNextWindowSize(new Vector2(750, 520)); + ImGui.SetNextWindowSize(new Vector2(750, 518)); ImGui.Begin("Plugin Installer", ref windowOpen, ImGuiWindowFlags.NoCollapse | ImGuiWindowFlags.NoResize | ImGuiWindowFlags.NoScrollbar); @@ -117,10 +119,12 @@ namespace Dalamud.Plugin } else { - foreach (var pluginDefinition in this.pluginMaster) - { - if (ImGui.CollapsingHeader(pluginDefinition.Name)) - { + foreach (var pluginDefinition in this.pluginMaster) { + if (pluginDefinition.ApplicableGameVersion != this.gameVersion && + pluginDefinition.ApplicableGameVersion != "any") + continue; + + if (ImGui.CollapsingHeader(pluginDefinition.Name)) { ImGui.Indent(); ImGui.Text(pluginDefinition.Name); @@ -129,41 +133,42 @@ namespace Dalamud.Plugin ImGui.Text(pluginDefinition.Description); - var isInstalled = this.manager.Plugins.Where(x=> x.Definition != null).Any( + var isInstalled = this.manager.Plugins.Where(x => x.Definition != null).Any( x => x.Definition.InternalName == pluginDefinition.InternalName); if (!isInstalled) { if (this.installStatus == PluginInstallStatus.InProgress) { - ImGui.Button($"Install in progress..."); + ImGui.Button("Install in progress..."); } else { - if (ImGui.Button($"Install v{pluginDefinition.AssemblyVersion}")) - { + if (ImGui.Button($"Install v{pluginDefinition.AssemblyVersion}")) { this.installStatus = PluginInstallStatus.InProgress; Task.Run(() => InstallPlugin(pluginDefinition)).ContinueWith(t => { - this.installStatus = t.IsFaulted ? PluginInstallStatus.Fail : this.installStatus; + this.installStatus = + t.IsFaulted ? PluginInstallStatus.Fail : this.installStatus; this.errorModalDrawing = this.installStatus == PluginInstallStatus.Fail; this.errorModalOnNextFrame = this.installStatus == PluginInstallStatus.Fail; }); } } - } else { var installedPlugin = this.manager.Plugins.Where(x => x.Definition != null).First( - x => x.Definition.InternalName == pluginDefinition.InternalName); + x => x.Definition.InternalName == + pluginDefinition.InternalName); if (ImGui.Button("Disable")) - { - this.manager.DisablePlugin(installedPlugin.Definition); - } + try { + this.manager.DisablePlugin(installedPlugin.Definition); + } catch (Exception exception) { + Log.Error(exception, "Could not disable plugin."); + this.errorModalDrawing = true; + this.errorModalOnNextFrame = true; + } if (installedPlugin.Plugin is IHasConfigUi v2Plugin && v2Plugin.OpenConfigUi != null) { ImGui.SameLine(); - if (ImGui.Button("Open Configuration")) - { - v2Plugin.OpenConfigUi?.Invoke(null, null); - } + if (ImGui.Button("Open Configuration")) v2Plugin.OpenConfigUi?.Invoke(null, null); } } @@ -197,12 +202,6 @@ namespace Dalamud.Plugin windowOpen = false; } - if (ImGui.Button("test modal")) { - this.installStatus = PluginInstallStatus.Fail; - this.errorModalDrawing = true; - this.errorModalOnNextFrame = true; - } - ImGui.Spacing(); if (ImGui.BeginPopupModal("Installer failed", ref this.errorModalDrawing, ImGuiWindowFlags.AlwaysAutoResize)) diff --git a/Dalamud/Plugin/PluginManager.cs b/Dalamud/Plugin/PluginManager.cs index 70db2506a..663d47732 100644 --- a/Dalamud/Plugin/PluginManager.cs +++ b/Dalamud/Plugin/PluginManager.cs @@ -5,6 +5,9 @@ using System.Linq; using System.Reflection; using System.Text; using System.Threading.Tasks; +using Dalamud.Interface; +using Dalamud.Plugin.Features; +using ImGuiNET; using Newtonsoft.Json; using Serilog; @@ -13,14 +16,28 @@ namespace Dalamud.Plugin public class PluginManager { private readonly Dalamud dalamud; private readonly string pluginDirectory; + private readonly string devPluginDirectory; private readonly Type interfaceType = typeof(IDalamudPlugin); - public readonly List<(IDalamudPlugin Plugin, PluginDefinition Definition)> Plugins = new List<(IDalamudPlugin plugin, PluginDefinition def)>(); + public readonly List<(IDalamudPlugin Plugin, PluginDefinition Definition, DalamudPluginInterface PluginInterface)> Plugins = new List<(IDalamudPlugin plugin, PluginDefinition def, DalamudPluginInterface PluginInterface)>(); - public PluginManager(Dalamud dalamud, string pluginDirectory) { + public PluginManager(Dalamud dalamud, string pluginDirectory, string devPluginDirectory) { this.dalamud = dalamud; this.pluginDirectory = pluginDirectory; + this.devPluginDirectory = devPluginDirectory; + + this.dalamud.InterfaceManager.OnDraw += InterfaceManagerOnOnDraw; + } + + private void InterfaceManagerOnOnDraw() { + foreach (var plugin in this.Plugins) { + if (plugin.Plugin is IHasUi uiPlugin) { + ImGui.PushID(plugin.Definition.InternalName); + uiPlugin.Draw(plugin.PluginInterface.UiBuilder); + ImGui.PopID(); + } + } } public void UnloadPlugins() { @@ -35,7 +52,8 @@ namespace Dalamud.Plugin } public void LoadPlugins() { - LoadPluginsAt(new DirectoryInfo(this.pluginDirectory)); + LoadPluginsAt(new DirectoryInfo(this.pluginDirectory), false); + LoadPluginsAt(new DirectoryInfo(this.devPluginDirectory), true); } public void DisablePlugin(PluginDefinition definition) { @@ -50,7 +68,7 @@ namespace Dalamud.Plugin this.Plugins.Remove(thisPlugin); } - public void LoadPluginFromAssembly(FileInfo dllFile) { + public void LoadPluginFromAssembly(FileInfo dllFile, bool raw) { Log.Information("Loading assembly at {0}", dllFile); var assemblyName = AssemblyName.GetAssemblyName(dllFile.FullName); var pluginAssembly = Assembly.Load(assemblyName); @@ -70,7 +88,7 @@ namespace Dalamud.Plugin { var disabledFile = new FileInfo(Path.Combine(dllFile.Directory.FullName, ".disabled")); - if (disabledFile.Exists) { + if (disabledFile.Exists && !raw) { Log.Information("Plugin {0} is disabled.", dllFile.FullName); return; } @@ -78,7 +96,7 @@ namespace Dalamud.Plugin var defJsonFile = new FileInfo(Path.Combine(dllFile.Directory.FullName, $"{Path.GetFileNameWithoutExtension(dllFile.Name)}.json")); PluginDefinition pluginDef = null; - if (defJsonFile.Exists) + if (defJsonFile.Exists && !raw) { Log.Information("Loading definition for plugin DLL {0}", dllFile.FullName); @@ -97,13 +115,13 @@ namespace Dalamud.Plugin var dalamudInterface = new DalamudPluginInterface(this.dalamud, type.Assembly.GetName().Name); plugin.Initialize(dalamudInterface); Log.Information("Loaded plugin: {0}", plugin.Name); - this.Plugins.Add((plugin, pluginDef)); + this.Plugins.Add((plugin, pluginDef, dalamudInterface)); } } } } - private void LoadPluginsAt(DirectoryInfo folder) { + private void LoadPluginsAt(DirectoryInfo folder, bool raw) { if (folder.Exists) { Log.Information("Loading plugins at {0}", folder); @@ -111,7 +129,7 @@ namespace Dalamud.Plugin var pluginDlls = folder.GetFiles("*.dll", SearchOption.AllDirectories); foreach (var dllFile in pluginDlls) { - LoadPluginFromAssembly(dllFile); + LoadPluginFromAssembly(dllFile, raw); } } }