mirror of
https://github.com/goatcorp/Dalamud.git
synced 2025-12-14 20:54:16 +01:00
Merge pull request #407 from goaaats/show_old
This commit is contained in:
commit
70e283f53d
3 changed files with 154 additions and 76 deletions
|
|
@ -523,7 +523,8 @@ namespace Dalamud.Interface.Internal.Windows
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (ImGui.Button(Locs.PluginButton_InstallVersion(versionString)))
|
var buttonText = Locs.PluginButton_InstallVersion(versionString);
|
||||||
|
if (ImGui.Button($"{buttonText}##{buttonText}{index}"))
|
||||||
{
|
{
|
||||||
this.installStatus = OperationStatus.InProgress;
|
this.installStatus = OperationStatus.InProgress;
|
||||||
|
|
||||||
|
|
@ -591,8 +592,9 @@ namespace Dalamud.Interface.Internal.Windows
|
||||||
label += Locs.PluginTitleMod_UnloadError;
|
label += Locs.PluginTitleMod_UnloadError;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var availablePluginUpdate = this.pluginListUpdatable.FirstOrDefault(up => up.InstalledPlugin == plugin);
|
||||||
// Update available
|
// Update available
|
||||||
if (this.pluginListUpdatable.FirstOrDefault(up => up.InstalledPlugin == plugin) != default)
|
if (availablePluginUpdate != default)
|
||||||
{
|
{
|
||||||
label += Locs.PluginTitleMod_HasUpdate;
|
label += Locs.PluginTitleMod_HasUpdate;
|
||||||
}
|
}
|
||||||
|
|
@ -614,6 +616,12 @@ namespace Dalamud.Interface.Internal.Windows
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Outdated API level
|
||||||
|
if (plugin.Manifest.DalamudApiLevel < PluginManager.DalamudApiLevel)
|
||||||
|
{
|
||||||
|
label += Locs.PluginTitleMod_OutdatedError;
|
||||||
|
}
|
||||||
|
|
||||||
if (ImGui.CollapsingHeader($"{label}###Header{index}{plugin.Manifest.InternalName}"))
|
if (ImGui.CollapsingHeader($"{label}###Header{index}{plugin.Manifest.InternalName}"))
|
||||||
{
|
{
|
||||||
var manifest = plugin.Manifest;
|
var manifest = plugin.Manifest;
|
||||||
|
|
@ -644,6 +652,13 @@ namespace Dalamud.Interface.Internal.Windows
|
||||||
ImGui.TextWrapped(manifest.Description);
|
ImGui.TextWrapped(manifest.Description);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (plugin.Manifest.DalamudApiLevel < PluginManager.DalamudApiLevel)
|
||||||
|
{
|
||||||
|
ImGui.PushStyleColor(ImGuiCol.Text, ImGuiColors.DalamudRed);
|
||||||
|
ImGui.TextWrapped(Locs.PluginBody_Outdated);
|
||||||
|
ImGui.PopStyleColor();
|
||||||
|
}
|
||||||
|
|
||||||
// Available commands (if loaded)
|
// Available commands (if loaded)
|
||||||
if (plugin.IsLoaded)
|
if (plugin.IsLoaded)
|
||||||
{
|
{
|
||||||
|
|
@ -663,6 +678,9 @@ namespace Dalamud.Interface.Internal.Windows
|
||||||
this.DrawDevPluginButtons(plugin);
|
this.DrawDevPluginButtons(plugin);
|
||||||
this.DrawVisitRepoUrlButton(plugin.Manifest.RepoUrl);
|
this.DrawVisitRepoUrlButton(plugin.Manifest.RepoUrl);
|
||||||
|
|
||||||
|
if (availablePluginUpdate != default)
|
||||||
|
this.DrawUpdateSinglePluginButton(plugin, availablePluginUpdate);
|
||||||
|
|
||||||
ImGui.SameLine();
|
ImGui.SameLine();
|
||||||
ImGui.TextColored(ImGuiColors.DalamudGrey3, $" v{plugin.Manifest.AssemblyVersion}");
|
ImGui.TextColored(ImGuiColors.DalamudGrey3, $" v{plugin.Manifest.AssemblyVersion}");
|
||||||
|
|
||||||
|
|
@ -681,6 +699,9 @@ namespace Dalamud.Interface.Internal.Windows
|
||||||
// Disable everything if the updater is running or another plugin is operating
|
// Disable everything if the updater is running or another plugin is operating
|
||||||
var disabled = this.updateStatus == OperationStatus.InProgress || this.installStatus == OperationStatus.InProgress;
|
var disabled = this.updateStatus == OperationStatus.InProgress || this.installStatus == OperationStatus.InProgress;
|
||||||
|
|
||||||
|
// Disable everything if the plugin is outdated
|
||||||
|
disabled = disabled || (plugin.Manifest.DalamudApiLevel < PluginManager.DalamudApiLevel && !this.dalamud.Configuration.LoadAllApiLevels);
|
||||||
|
|
||||||
if (plugin.State == PluginState.InProgress)
|
if (plugin.State == PluginState.InProgress)
|
||||||
{
|
{
|
||||||
ImGuiComponents.DisabledButton(Locs.PluginButton_Working);
|
ImGuiComponents.DisabledButton(Locs.PluginButton_Working);
|
||||||
|
|
@ -760,6 +781,34 @@ namespace Dalamud.Interface.Internal.Windows
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void DrawUpdateSinglePluginButton(LocalPlugin plugin, AvailablePluginUpdate update)
|
||||||
|
{
|
||||||
|
ImGui.SameLine();
|
||||||
|
|
||||||
|
if (ImGuiComponents.IconButton(FontAwesomeIcon.Download))
|
||||||
|
{
|
||||||
|
this.installStatus = OperationStatus.InProgress;
|
||||||
|
|
||||||
|
Task.Run(() => this.dalamud.PluginManager.UpdateSinglePlugin(update, false))
|
||||||
|
.ContinueWith(task =>
|
||||||
|
{
|
||||||
|
// There is no need to set as Complete for an individual plugin installation
|
||||||
|
this.installStatus = OperationStatus.Idle;
|
||||||
|
|
||||||
|
var errorMessage = Locs.ErrorModal_SingleUpdateFail(update.UpdateManifest.Name);
|
||||||
|
this.DisplayErrorContinuation(task, errorMessage);
|
||||||
|
|
||||||
|
if (!task.Result.WasUpdated)
|
||||||
|
{
|
||||||
|
ShowErrorModal(errorMessage);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ImGui.IsItemHovered())
|
||||||
|
ImGui.SetTooltip(Locs.PluginButtonToolTip_UpdateSingle(update.UpdateManifest.AssemblyVersion.ToString()));
|
||||||
|
}
|
||||||
|
|
||||||
private void DrawOpenPluginSettingsButton(LocalPlugin plugin)
|
private void DrawOpenPluginSettingsButton(LocalPlugin plugin)
|
||||||
{
|
{
|
||||||
if (plugin.DalamudInterface?.UiBuilder?.HasConfigUi ?? false)
|
if (plugin.DalamudInterface?.UiBuilder?.HasConfigUi ?? false)
|
||||||
|
|
@ -952,7 +1001,7 @@ namespace Dalamud.Interface.Internal.Windows
|
||||||
{
|
{
|
||||||
if (task.IsFaulted)
|
if (task.IsFaulted)
|
||||||
{
|
{
|
||||||
this.errorModalMessage = state as string;
|
var errorModalMessage = state as string;
|
||||||
|
|
||||||
foreach (var ex in task.Exception.InnerExceptions)
|
foreach (var ex in task.Exception.InnerExceptions)
|
||||||
{
|
{
|
||||||
|
|
@ -961,7 +1010,7 @@ namespace Dalamud.Interface.Internal.Windows
|
||||||
Log.Error(ex, "Plugin installer threw an error");
|
Log.Error(ex, "Plugin installer threw an error");
|
||||||
#if DEBUG
|
#if DEBUG
|
||||||
if (!string.IsNullOrEmpty(ex.Message))
|
if (!string.IsNullOrEmpty(ex.Message))
|
||||||
this.errorModalMessage += $"\n\n{ex.Message}";
|
errorModalMessage += $"\n\n{ex.Message}";
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
|
@ -969,13 +1018,12 @@ namespace Dalamud.Interface.Internal.Windows
|
||||||
Log.Error(ex, "Plugin installer threw an unexpected error");
|
Log.Error(ex, "Plugin installer threw an unexpected error");
|
||||||
#if DEBUG
|
#if DEBUG
|
||||||
if (!string.IsNullOrEmpty(ex.Message))
|
if (!string.IsNullOrEmpty(ex.Message))
|
||||||
this.errorModalMessage += $"\n\n{ex.Message}";
|
errorModalMessage += $"\n\n{ex.Message}";
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
this.errorModalDrawing = true;
|
this.ShowErrorModal(errorModalMessage);
|
||||||
this.errorModalOnNextFrame = true;
|
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
@ -983,6 +1031,13 @@ namespace Dalamud.Interface.Internal.Windows
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void ShowErrorModal(string message)
|
||||||
|
{
|
||||||
|
this.errorModalMessage = message;
|
||||||
|
this.errorModalDrawing = true;
|
||||||
|
this.errorModalOnNextFrame = true;
|
||||||
|
}
|
||||||
|
|
||||||
[SuppressMessage("StyleCop.CSharp.OrderingRules", "SA1201:Elements should appear in the correct order", Justification = "Disregard here")]
|
[SuppressMessage("StyleCop.CSharp.OrderingRules", "SA1201:Elements should appear in the correct order", Justification = "Disregard here")]
|
||||||
private static class Locs
|
private static class Locs
|
||||||
{
|
{
|
||||||
|
|
@ -1062,6 +1117,8 @@ namespace Dalamud.Interface.Internal.Windows
|
||||||
|
|
||||||
public static string PluginTitleMod_UnloadError => Loc.Localize("InstallerUnloadError", " (unload error)");
|
public static string PluginTitleMod_UnloadError => Loc.Localize("InstallerUnloadError", " (unload error)");
|
||||||
|
|
||||||
|
public static string PluginTitleMod_OutdatedError => Loc.Localize("InstallerOutdatedError", " (outdated)");
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
#region Plugin context menu
|
#region Plugin context menu
|
||||||
|
|
@ -1082,6 +1139,8 @@ namespace Dalamud.Interface.Internal.Windows
|
||||||
|
|
||||||
public static string PluginBody_DeleteDevPlugin => Loc.Localize("InstallerDeleteDevPlugin ", " To delete this plugin, please remove it from the devPlugins folder.");
|
public static string PluginBody_DeleteDevPlugin => Loc.Localize("InstallerDeleteDevPlugin ", " To delete this plugin, please remove it from the devPlugins folder.");
|
||||||
|
|
||||||
|
public static string PluginBody_Outdated => Loc.Localize("InstallerOutdatedPluginBody ", "This plugin is outdated and incompatible at the moment. Please wait for it to be updated by its author.");
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
#region Plugin buttons
|
#region Plugin buttons
|
||||||
|
|
@ -1110,6 +1169,8 @@ namespace Dalamud.Interface.Internal.Windows
|
||||||
|
|
||||||
public static string PluginButtonToolTip_VisitPluginUrl => Loc.Localize("InstallerVisitPluginUrl", "Visit plugin URL");
|
public static string PluginButtonToolTip_VisitPluginUrl => Loc.Localize("InstallerVisitPluginUrl", "Visit plugin URL");
|
||||||
|
|
||||||
|
public static string PluginButtonToolTip_UpdateSingle(string version) => Loc.Localize("InstallerUpdateSingle", "Update to {0}").Format(version);
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
#region Footer
|
#region Footer
|
||||||
|
|
@ -1136,6 +1197,8 @@ namespace Dalamud.Interface.Internal.Windows
|
||||||
|
|
||||||
public static string ErrorModal_InstallFail(string name) => Loc.Localize("InstallerInstallFail", "Failed to install plugin {0}.").Format(name);
|
public static string ErrorModal_InstallFail(string name) => Loc.Localize("InstallerInstallFail", "Failed to install plugin {0}.").Format(name);
|
||||||
|
|
||||||
|
public static string ErrorModal_SingleUpdateFail(string name) => Loc.Localize("InstallerSingleUpdateFail", "Failed to update plugin {0}.").Format(name);
|
||||||
|
|
||||||
public static string ErrorModal_EnableFail(string name) => Loc.Localize("InstallerEnableFail", "Failed to enable plugin {0}.").Format(name);
|
public static string ErrorModal_EnableFail(string name) => Loc.Localize("InstallerEnableFail", "Failed to enable plugin {0}.").Format(name);
|
||||||
|
|
||||||
public static string ErrorModal_DisableFail(string name) => Loc.Localize("InstallerDisableFail", "Failed to disable plugin {0}.").Format(name);
|
public static string ErrorModal_DisableFail(string name) => Loc.Localize("InstallerDisableFail", "Failed to disable plugin {0}.").Format(name);
|
||||||
|
|
|
||||||
|
|
@ -17,6 +17,7 @@ using Dalamud.Game.Text;
|
||||||
using Dalamud.Plugin.Internal.Exceptions;
|
using Dalamud.Plugin.Internal.Exceptions;
|
||||||
using Dalamud.Plugin.Internal.Types;
|
using Dalamud.Plugin.Internal.Types;
|
||||||
using HarmonyLib;
|
using HarmonyLib;
|
||||||
|
using JetBrains.Annotations;
|
||||||
using Newtonsoft.Json;
|
using Newtonsoft.Json;
|
||||||
|
|
||||||
namespace Dalamud.Plugin.Internal
|
namespace Dalamud.Plugin.Internal
|
||||||
|
|
@ -198,9 +199,9 @@ namespace Dalamud.Plugin.Internal
|
||||||
{
|
{
|
||||||
// Not a plugin
|
// Not a plugin
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception)
|
||||||
{
|
{
|
||||||
Log.Error(ex, "During boot plugin load, an unexpected error occurred");
|
Log.Error("During boot plugin load, an unexpected error occurred");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -469,6 +470,10 @@ namespace Dalamud.Plugin.Internal
|
||||||
{
|
{
|
||||||
Log.Information(ex, $"Dev plugin failed to load, adding anyways: {dllFile.Name}");
|
Log.Information(ex, $"Dev plugin failed to load, adding anyways: {dllFile.Name}");
|
||||||
}
|
}
|
||||||
|
else if (plugin.Manifest.DalamudApiLevel < DalamudApiLevel)
|
||||||
|
{
|
||||||
|
Log.Information(ex, $"Plugin was outdated, adding anyways: {dllFile.Name}");
|
||||||
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
PluginLocations.Remove(plugin.AssemblyName.FullName);
|
PluginLocations.Remove(plugin.AssemblyName.FullName);
|
||||||
|
|
@ -492,6 +497,7 @@ namespace Dalamud.Plugin.Internal
|
||||||
this.installedPlugins.Remove(plugin);
|
this.installedPlugins.Remove(plugin);
|
||||||
PluginLocations.Remove(plugin.AssemblyName.FullName);
|
PluginLocations.Remove(plugin.AssemblyName.FullName);
|
||||||
|
|
||||||
|
this.NotifyAvailablePluginsChanged();
|
||||||
this.NotifyInstalledPluginsChanged();
|
this.NotifyInstalledPluginsChanged();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -558,7 +564,7 @@ namespace Dalamud.Plugin.Internal
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (manifest.DalamudApiLevel < DalamudApiLevel && !this.dalamud.Configuration.LoadAllApiLevels)
|
if (manifest.DalamudApiLevel < DalamudApiLevel - 1 && !this.dalamud.Configuration.LoadAllApiLevels)
|
||||||
{
|
{
|
||||||
Log.Information($"Lower API: cleaning up {versionDir.FullName}");
|
Log.Information($"Lower API: cleaning up {versionDir.FullName}");
|
||||||
versionDir.Delete(true);
|
versionDir.Delete(true);
|
||||||
|
|
@ -595,84 +601,93 @@ namespace Dalamud.Plugin.Internal
|
||||||
{
|
{
|
||||||
Log.Information("Starting plugin update");
|
Log.Information("Starting plugin update");
|
||||||
|
|
||||||
var listChanged = false;
|
|
||||||
|
|
||||||
var updatedList = new List<PluginUpdateStatus>();
|
var updatedList = new List<PluginUpdateStatus>();
|
||||||
|
|
||||||
// Prevent collection was modified errors
|
// Prevent collection was modified errors
|
||||||
for (var i = 0; i < this.updatablePlugins.Count; i++)
|
for (var i = 0; i < this.updatablePlugins.Count; i++)
|
||||||
{
|
{
|
||||||
var metadata = this.updatablePlugins[i];
|
updatedList.Add(this.UpdateSinglePlugin(this.updatablePlugins[i], dryRun));
|
||||||
|
|
||||||
var plugin = metadata.InstalledPlugin;
|
|
||||||
|
|
||||||
// Can't update that!
|
|
||||||
if (plugin is LocalDevPlugin)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
var updateStatus = new PluginUpdateStatus()
|
|
||||||
{
|
|
||||||
InternalName = plugin.Manifest.InternalName,
|
|
||||||
Name = plugin.Manifest.Name,
|
|
||||||
Version = metadata.UseTesting
|
|
||||||
? metadata.UpdateManifest.TestingAssemblyVersion
|
|
||||||
: metadata.UpdateManifest.AssemblyVersion,
|
|
||||||
};
|
|
||||||
|
|
||||||
if (dryRun)
|
|
||||||
{
|
|
||||||
updateStatus.WasUpdated = true;
|
|
||||||
updatedList.Add(updateStatus);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// Unload if loaded
|
|
||||||
if (plugin.State == PluginState.Loaded || plugin.State == PluginState.LoadError)
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
plugin.Unload();
|
|
||||||
}
|
|
||||||
catch (Exception ex)
|
|
||||||
{
|
|
||||||
Log.Error(ex, "Error during unload (update)");
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
try
|
|
||||||
{
|
|
||||||
plugin.Disable();
|
|
||||||
this.installedPlugins.Remove(plugin);
|
|
||||||
listChanged = true;
|
|
||||||
}
|
|
||||||
catch (Exception ex)
|
|
||||||
{
|
|
||||||
Log.Error(ex, "Error during disable (update)");
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
try
|
|
||||||
{
|
|
||||||
this.InstallPlugin(metadata.UpdateManifest, metadata.UseTesting, PluginLoadReason.Update);
|
|
||||||
listChanged = true;
|
|
||||||
}
|
|
||||||
catch (Exception ex)
|
|
||||||
{
|
|
||||||
Log.Error(ex, "Error during install (update)");
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (listChanged)
|
this.NotifyInstalledPluginsChanged();
|
||||||
this.NotifyInstalledPluginsChanged();
|
|
||||||
|
|
||||||
Log.Information("Plugin update OK.");
|
Log.Information("Plugin update OK.");
|
||||||
|
|
||||||
return updatedList;
|
return updatedList;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Update a single plugin, provided a valid <see cref="AvailablePluginUpdate"/>.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="metadata">The available plugin update.</param>
|
||||||
|
/// <param name="dryRun">Whether or not to actually perform the update, or just indicate success.</param>
|
||||||
|
/// <returns>The status of the update.</returns>
|
||||||
|
[CanBeNull]
|
||||||
|
public PluginUpdateStatus UpdateSinglePlugin(AvailablePluginUpdate metadata, bool dryRun)
|
||||||
|
{
|
||||||
|
var plugin = metadata.InstalledPlugin;
|
||||||
|
|
||||||
|
// Can't update that!
|
||||||
|
if (plugin is LocalDevPlugin)
|
||||||
|
return null;
|
||||||
|
|
||||||
|
var updateStatus = new PluginUpdateStatus
|
||||||
|
{
|
||||||
|
InternalName = plugin.Manifest.InternalName,
|
||||||
|
Name = plugin.Manifest.Name,
|
||||||
|
Version = metadata.UseTesting ? metadata.UpdateManifest.TestingAssemblyVersion : metadata.UpdateManifest.AssemblyVersion,
|
||||||
|
};
|
||||||
|
|
||||||
|
if (dryRun)
|
||||||
|
{
|
||||||
|
updateStatus.WasUpdated = true;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
updateStatus.WasUpdated = true;
|
||||||
|
|
||||||
|
// Unload if loaded
|
||||||
|
if (plugin.State == PluginState.Loaded || plugin.State == PluginState.LoadError)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
plugin.Unload();
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
Log.Error(ex, "Error during unload (update)");
|
||||||
|
updateStatus.WasUpdated = false;
|
||||||
|
return updateStatus;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
plugin.Disable();
|
||||||
|
this.installedPlugins.Remove(plugin);
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
Log.Error(ex, "Error during disable (update)");
|
||||||
|
updateStatus.WasUpdated = false;
|
||||||
|
return updateStatus;
|
||||||
|
}
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
this.InstallPlugin(metadata.UpdateManifest, metadata.UseTesting, PluginLoadReason.Update);
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
Log.Error(ex, "Error during install (update)");
|
||||||
|
updateStatus.WasUpdated = false;
|
||||||
|
return updateStatus;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return updateStatus;
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Print to chat any plugin updates and whether they were successful.
|
/// Print to chat any plugin updates and whether they were successful.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
|
|
||||||
|
|
@ -52,7 +52,7 @@ namespace Dalamud
|
||||||
public PluginManifest[] LoadedPlugins { get; set; }
|
public PluginManifest[] LoadedPlugins { get; set; }
|
||||||
|
|
||||||
public string DalamudVersion { get; set; }
|
public string DalamudVersion { get; set; }
|
||||||
|
|
||||||
public string DalamudGitHash { get; set; }
|
public string DalamudGitHash { get; set; }
|
||||||
|
|
||||||
public string GameVersion { get; set; }
|
public string GameVersion { get; set; }
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue