mirror of
https://github.com/goatcorp/Dalamud.git
synced 2025-12-14 12:44:16 +01:00
Merge branch 'master' of https://github.com/goatcorp/Dalamud into feat/rxnet-improvements
This commit is contained in:
commit
d295fa1494
7 changed files with 155 additions and 36 deletions
|
|
@ -8,7 +8,7 @@
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
<PropertyGroup Label="Feature">
|
<PropertyGroup Label="Feature">
|
||||||
<DalamudVersion>7.4.4.1</DalamudVersion>
|
<DalamudVersion>7.4.5.0</DalamudVersion>
|
||||||
<Description>XIV Launcher addon framework</Description>
|
<Description>XIV Launcher addon framework</Description>
|
||||||
<AssemblyVersion>$(DalamudVersion)</AssemblyVersion>
|
<AssemblyVersion>$(DalamudVersion)</AssemblyVersion>
|
||||||
<Version>$(DalamudVersion)</Version>
|
<Version>$(DalamudVersion)</Version>
|
||||||
|
|
|
||||||
|
|
@ -41,6 +41,9 @@ internal class DalamudChangelogEntry : IChangelogEntry
|
||||||
/// <inheritdoc/>
|
/// <inheritdoc/>
|
||||||
public string Text { get; init; }
|
public string Text { get; init; }
|
||||||
|
|
||||||
|
/// <inheritdoc/>
|
||||||
|
public string? Author { get; private set; } = null;
|
||||||
|
|
||||||
/// <inheritdoc/>
|
/// <inheritdoc/>
|
||||||
public DateTime Date => this.changelog.Date;
|
public DateTime Date => this.changelog.Date;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,24 +1,39 @@
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
using System.Net.Http;
|
using System.Net.Http;
|
||||||
using System.Net.Http.Json;
|
using System.Net.Http.Json;
|
||||||
|
using System.Threading;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
using Dalamud.Plugin.Internal;
|
||||||
|
using Serilog;
|
||||||
|
|
||||||
namespace Dalamud.Interface.Internal.Windows.PluginInstaller;
|
namespace Dalamud.Interface.Internal.Windows.PluginInstaller;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Class responsible for managing Dalamud changelogs.
|
/// Class responsible for managing Dalamud changelogs.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
internal class DalamudChangelogManager : IDisposable
|
internal class DalamudChangelogManager
|
||||||
{
|
{
|
||||||
private const string ChangelogUrl = "https://kamori.goats.dev/Plugin/CoreChangelog";
|
private const string DalamudChangelogUrl = "https://kamori.goats.dev/Dalamud/Release/Changelog";
|
||||||
|
private const string PluginChangelogUrl = "https://kamori.goats.dev/Plugin/History/{0}?track={1}";
|
||||||
|
|
||||||
private readonly HttpClient client = new();
|
private readonly PluginManager manager;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Initializes a new instance of the <see cref="DalamudChangelogManager"/> class.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="manager">The responsible PluginManager.</param>
|
||||||
|
public DalamudChangelogManager(PluginManager manager)
|
||||||
|
{
|
||||||
|
this.manager = manager;
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets a list of all available changelogs.
|
/// Gets a list of all available changelogs.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public IReadOnlyList<DalamudChangelog>? Changelogs { get; private set; }
|
public IReadOnlyList<IChangelogEntry>? Changelogs { get; private set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Reload the changelog list.
|
/// Reload the changelog list.
|
||||||
|
|
@ -26,12 +41,58 @@ internal class DalamudChangelogManager : IDisposable
|
||||||
/// <returns>A <see cref="Task"/> representing the asynchronous operation.</returns>
|
/// <returns>A <see cref="Task"/> representing the asynchronous operation.</returns>
|
||||||
public async Task ReloadChangelogAsync()
|
public async Task ReloadChangelogAsync()
|
||||||
{
|
{
|
||||||
this.Changelogs = await this.client.GetFromJsonAsync<List<DalamudChangelog>>(ChangelogUrl);
|
using var client = new HttpClient();
|
||||||
|
this.Changelogs = null;
|
||||||
|
|
||||||
|
var dalamudChangelogs = await client.GetFromJsonAsync<List<DalamudChangelog>>(DalamudChangelogUrl);
|
||||||
|
var changelogs = dalamudChangelogs.Select(x => new DalamudChangelogEntry(x)).Cast<IChangelogEntry>();
|
||||||
|
|
||||||
|
foreach (var plugin in this.manager.InstalledPlugins)
|
||||||
|
{
|
||||||
|
if (plugin.Manifest.IsThirdParty || !plugin.Manifest.IsDip17Plugin)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
var pluginChangelogs = await client.GetFromJsonAsync<PluginHistory>(string.Format(
|
||||||
|
PluginChangelogUrl,
|
||||||
|
plugin.Manifest.InternalName,
|
||||||
|
plugin.Manifest.Dip17Channel));
|
||||||
|
|
||||||
|
changelogs = changelogs.Concat(pluginChangelogs.Versions
|
||||||
|
.Where(x => x.Dip17Track == plugin.Manifest.Dip17Channel)
|
||||||
|
.Select(x => new PluginChangelogEntry(plugin, x)));
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <inheritdoc/>
|
this.Changelogs = changelogs.OrderByDescending(x => x.Date).ToList();
|
||||||
public void Dispose()
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// API response for a history of plugin versions.
|
||||||
|
/// </summary>
|
||||||
|
internal class PluginHistory
|
||||||
{
|
{
|
||||||
this.client.Dispose();
|
/// <summary>
|
||||||
|
/// Gets or sets the version history of the plugin.
|
||||||
|
/// </summary>
|
||||||
|
public List<PluginVersion> Versions { get; set; } = null!;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// A single plugin version.
|
||||||
|
/// </summary>
|
||||||
|
internal class PluginVersion
|
||||||
|
{
|
||||||
|
#pragma warning disable SA1600
|
||||||
|
public string Version { get; set; } = null!;
|
||||||
|
|
||||||
|
public string Dip17Track { get; set; } = null!;
|
||||||
|
|
||||||
|
public string? Changelog { get; set; }
|
||||||
|
|
||||||
|
public DateTime PublishedAt { get; set; }
|
||||||
|
|
||||||
|
public int? PrNumber { get; set; }
|
||||||
|
|
||||||
|
public string? PublishedBy { get; set; }
|
||||||
|
#pragma warning restore SA1600
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -22,6 +22,11 @@ internal interface IChangelogEntry
|
||||||
/// </summary>
|
/// </summary>
|
||||||
string Text { get; }
|
string Text { get; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the author of the changelog.
|
||||||
|
/// </summary>
|
||||||
|
string? Author { get; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets the date of the entry.
|
/// Gets the date of the entry.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
using System;
|
using System;
|
||||||
|
|
||||||
|
using CheapLoc;
|
||||||
using Dalamud.Plugin.Internal.Types;
|
using Dalamud.Plugin.Internal.Types;
|
||||||
using Dalamud.Utility;
|
|
||||||
|
|
||||||
namespace Dalamud.Interface.Internal.Windows.PluginInstaller;
|
namespace Dalamud.Interface.Internal.Windows.PluginInstaller;
|
||||||
|
|
||||||
|
|
@ -14,16 +14,15 @@ internal class PluginChangelogEntry : IChangelogEntry
|
||||||
/// Initializes a new instance of the <see cref="PluginChangelogEntry"/> class.
|
/// Initializes a new instance of the <see cref="PluginChangelogEntry"/> class.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="plugin">The plugin manifest.</param>
|
/// <param name="plugin">The plugin manifest.</param>
|
||||||
public PluginChangelogEntry(LocalPlugin plugin)
|
/// <param name="history">The changelog history entry.</param>
|
||||||
|
public PluginChangelogEntry(LocalPlugin plugin, DalamudChangelogManager.PluginHistory.PluginVersion history)
|
||||||
{
|
{
|
||||||
this.Plugin = plugin;
|
this.Plugin = plugin;
|
||||||
|
|
||||||
if (plugin.Manifest.Changelog.IsNullOrEmpty())
|
this.Version = history.Version;
|
||||||
throw new ArgumentException("Manifest has no changelog.");
|
this.Text = history.Changelog ?? Loc.Localize("ChangelogNoText", "No changelog for this version.");
|
||||||
|
this.Author = history.PublishedBy;
|
||||||
var version = plugin.Manifest.EffectiveVersion;
|
this.Date = history.PublishedAt;
|
||||||
|
|
||||||
this.Version = version!.ToString();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
|
@ -35,11 +34,14 @@ internal class PluginChangelogEntry : IChangelogEntry
|
||||||
public string Title => this.Plugin.Manifest.Name;
|
public string Title => this.Plugin.Manifest.Name;
|
||||||
|
|
||||||
/// <inheritdoc/>
|
/// <inheritdoc/>
|
||||||
public string Version { get; init; }
|
public string Version { get; private set; }
|
||||||
|
|
||||||
/// <inheritdoc/>
|
/// <inheritdoc/>
|
||||||
public string Text => this.Plugin.Manifest.Changelog!;
|
public string Text { get; private set; }
|
||||||
|
|
||||||
/// <inheritdoc/>
|
/// <inheritdoc/>
|
||||||
public DateTime Date => DateTimeOffset.FromUnixTimeSeconds(this.Plugin.Manifest.LastUpdate).DateTime;
|
public string? Author { get; private set; }
|
||||||
|
|
||||||
|
/// <inheritdoc/>
|
||||||
|
public DateTime Date { get; private set; }
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -6,6 +6,7 @@ using System.Diagnostics.CodeAnalysis;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Numerics;
|
using System.Numerics;
|
||||||
|
using System.Threading;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
using CheapLoc;
|
using CheapLoc;
|
||||||
|
|
@ -40,7 +41,6 @@ internal class PluginInstallerWindow : Window, IDisposable
|
||||||
|
|
||||||
private readonly PluginImageCache imageCache;
|
private readonly PluginImageCache imageCache;
|
||||||
private readonly PluginCategoryManager categoryManager = new();
|
private readonly PluginCategoryManager categoryManager = new();
|
||||||
private readonly DalamudChangelogManager dalamudChangelogManager = new();
|
|
||||||
|
|
||||||
private readonly List<int> openPluginCollapsibles = new();
|
private readonly List<int> openPluginCollapsibles = new();
|
||||||
|
|
||||||
|
|
@ -48,6 +48,10 @@ internal class PluginInstallerWindow : Window, IDisposable
|
||||||
|
|
||||||
private readonly object listLock = new();
|
private readonly object listLock = new();
|
||||||
|
|
||||||
|
private DalamudChangelogManager? dalamudChangelogManager;
|
||||||
|
private Task? dalamudChangelogRefreshTask;
|
||||||
|
private CancellationTokenSource? dalamudChangelogRefreshTaskCts;
|
||||||
|
|
||||||
#region Image Tester State
|
#region Image Tester State
|
||||||
|
|
||||||
private string[] testerImagePaths = new string[5];
|
private string[] testerImagePaths = new string[5];
|
||||||
|
|
@ -132,6 +136,8 @@ internal class PluginInstallerWindow : Window, IDisposable
|
||||||
if (pluginManager.PluginsReady)
|
if (pluginManager.PluginsReady)
|
||||||
this.OnInstalledPluginsChanged();
|
this.OnInstalledPluginsChanged();
|
||||||
|
|
||||||
|
this.dalamudChangelogManager = new(pluginManager);
|
||||||
|
|
||||||
pluginManager.OnAvailablePluginsChanged += this.OnAvailablePluginsChanged;
|
pluginManager.OnAvailablePluginsChanged += this.OnAvailablePluginsChanged;
|
||||||
pluginManager.OnInstalledPluginsChanged += this.OnInstalledPluginsChanged;
|
pluginManager.OnInstalledPluginsChanged += this.OnInstalledPluginsChanged;
|
||||||
|
|
||||||
|
|
@ -179,6 +185,8 @@ internal class PluginInstallerWindow : Window, IDisposable
|
||||||
/// <inheritdoc/>
|
/// <inheritdoc/>
|
||||||
public void Dispose()
|
public void Dispose()
|
||||||
{
|
{
|
||||||
|
this.dalamudChangelogRefreshTaskCts?.Cancel();
|
||||||
|
|
||||||
var pluginManager = Service<PluginManager>.GetNullable();
|
var pluginManager = Service<PluginManager>.GetNullable();
|
||||||
if (pluginManager != null)
|
if (pluginManager != null)
|
||||||
{
|
{
|
||||||
|
|
@ -193,7 +201,6 @@ internal class PluginInstallerWindow : Window, IDisposable
|
||||||
var pluginManager = Service<PluginManager>.Get();
|
var pluginManager = Service<PluginManager>.Get();
|
||||||
|
|
||||||
_ = pluginManager.ReloadPluginMastersAsync();
|
_ = pluginManager.ReloadPluginMastersAsync();
|
||||||
_ = this.dalamudChangelogManager.ReloadChangelogAsync();
|
|
||||||
|
|
||||||
this.searchText = string.Empty;
|
this.searchText = string.Empty;
|
||||||
this.sortKind = PluginSortKind.Alphabetical;
|
this.sortKind = PluginSortKind.Alphabetical;
|
||||||
|
|
@ -837,30 +844,40 @@ internal class PluginInstallerWindow : Window, IDisposable
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
var pluginChangelogs = this.pluginListInstalled
|
if (this.dalamudChangelogRefreshTask?.IsFaulted == true ||
|
||||||
.Where(plugin => !this.IsManifestFiltered(plugin.Manifest)
|
this.dalamudChangelogRefreshTask?.IsCanceled == true)
|
||||||
&& !plugin.Manifest.Changelog.IsNullOrEmpty())
|
|
||||||
.Select(x =>
|
|
||||||
{
|
{
|
||||||
var changelog = new PluginChangelogEntry(x);
|
ImGui.TextColored(ImGuiColors.DalamudGrey, Locs.TabBody_ChangelogError);
|
||||||
return (IChangelogEntry)changelog;
|
return;
|
||||||
});
|
}
|
||||||
|
|
||||||
|
if (this.dalamudChangelogManager?.Changelogs == null)
|
||||||
|
{
|
||||||
|
ImGui.TextColored(ImGuiColors.DalamudGrey, Locs.TabBody_LoadingPlugins);
|
||||||
|
|
||||||
|
if (this.dalamudChangelogManager != null &&
|
||||||
|
this.dalamudChangelogRefreshTask == null)
|
||||||
|
{
|
||||||
|
this.dalamudChangelogRefreshTaskCts = new CancellationTokenSource();
|
||||||
|
this.dalamudChangelogRefreshTask =
|
||||||
|
Task.Run(this.dalamudChangelogManager.ReloadChangelogAsync, this.dalamudChangelogRefreshTaskCts.Token);
|
||||||
|
}
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
IEnumerable<IChangelogEntry> changelogs = null;
|
IEnumerable<IChangelogEntry> changelogs = null;
|
||||||
if (displayDalamud && displayPlugins && this.dalamudChangelogManager.Changelogs != null)
|
if (displayDalamud && displayPlugins && this.dalamudChangelogManager.Changelogs != null)
|
||||||
{
|
{
|
||||||
changelogs = pluginChangelogs
|
changelogs = this.dalamudChangelogManager.Changelogs;
|
||||||
.Concat(this.dalamudChangelogManager.Changelogs.Select(
|
|
||||||
x => new DalamudChangelogEntry(x)));
|
|
||||||
}
|
}
|
||||||
else if (displayDalamud && this.dalamudChangelogManager.Changelogs != null)
|
else if (displayDalamud && this.dalamudChangelogManager.Changelogs != null)
|
||||||
{
|
{
|
||||||
changelogs = this.dalamudChangelogManager.Changelogs.Select(
|
changelogs = this.dalamudChangelogManager.Changelogs.OfType<DalamudChangelogEntry>();
|
||||||
x => new DalamudChangelogEntry(x));
|
|
||||||
}
|
}
|
||||||
else if (displayPlugins)
|
else if (displayPlugins)
|
||||||
{
|
{
|
||||||
changelogs = pluginChangelogs;
|
changelogs = this.dalamudChangelogManager.Changelogs.OfType<PluginChangelogEntry>();
|
||||||
}
|
}
|
||||||
|
|
||||||
var sortedChangelogs = changelogs?.OrderByDescending(x => x.Date).ToList();
|
var sortedChangelogs = changelogs?.OrderByDescending(x => x.Date).ToList();
|
||||||
|
|
@ -2898,6 +2915,8 @@ internal class PluginInstallerWindow : Window, IDisposable
|
||||||
|
|
||||||
public static string TabBody_ChangelogNone => Loc.Localize("InstallerNoChangelog", "None of your installed plugins have a changelog.");
|
public static string TabBody_ChangelogNone => Loc.Localize("InstallerNoChangelog", "None of your installed plugins have a changelog.");
|
||||||
|
|
||||||
|
public static string TabBody_ChangelogError => Loc.Localize("InstallerChangelogError", "Could not download changelogs.");
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
#region Plugin title text
|
#region Plugin title text
|
||||||
|
|
|
||||||
|
|
@ -1299,6 +1299,35 @@ Thanks and have fun!";
|
||||||
return this.bannedPlugins.LastOrDefault(ban => ban.Name == manifest.InternalName).Reason;
|
return this.bannedPlugins.LastOrDefault(ban => ban.Name == manifest.InternalName).Reason;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Get the plugin that called this method by walking the stack,
|
||||||
|
/// or null, if it cannot be determined.
|
||||||
|
/// At the time, this is naive and shouldn't be used for security-critical checks.
|
||||||
|
/// </summary>
|
||||||
|
/// <returns>The calling plugin, or null.</returns>
|
||||||
|
public LocalPlugin? FindCallingPlugin()
|
||||||
|
{
|
||||||
|
var trace = new StackTrace();
|
||||||
|
foreach (var frame in trace.GetFrames())
|
||||||
|
{
|
||||||
|
var declaringType = frame.GetMethod()?.DeclaringType;
|
||||||
|
if (declaringType == null)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
lock (this.pluginListLock)
|
||||||
|
{
|
||||||
|
foreach (var plugin in this.InstalledPlugins)
|
||||||
|
{
|
||||||
|
if (plugin.AssemblyName != null &&
|
||||||
|
plugin.AssemblyName.FullName == declaringType.Assembly.GetName().FullName)
|
||||||
|
return plugin;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
private void DetectAvailablePluginUpdates()
|
private void DetectAvailablePluginUpdates()
|
||||||
{
|
{
|
||||||
var updatablePlugins = new List<AvailablePluginUpdate>();
|
var updatablePlugins = new List<AvailablePluginUpdate>();
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue