mirror of
https://github.com/goatcorp/Dalamud.git
synced 2025-12-13 12:14: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 Label="Feature">
|
||||
<DalamudVersion>7.4.4.1</DalamudVersion>
|
||||
<DalamudVersion>7.4.5.0</DalamudVersion>
|
||||
<Description>XIV Launcher addon framework</Description>
|
||||
<AssemblyVersion>$(DalamudVersion)</AssemblyVersion>
|
||||
<Version>$(DalamudVersion)</Version>
|
||||
|
|
|
|||
|
|
@ -41,6 +41,9 @@ internal class DalamudChangelogEntry : IChangelogEntry
|
|||
/// <inheritdoc/>
|
||||
public string Text { get; init; }
|
||||
|
||||
/// <inheritdoc/>
|
||||
public string? Author { get; private set; } = null;
|
||||
|
||||
/// <inheritdoc/>
|
||||
public DateTime Date => this.changelog.Date;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,24 +1,39 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Net.Http;
|
||||
using System.Net.Http.Json;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
using Dalamud.Plugin.Internal;
|
||||
using Serilog;
|
||||
|
||||
namespace Dalamud.Interface.Internal.Windows.PluginInstaller;
|
||||
|
||||
/// <summary>
|
||||
/// Class responsible for managing Dalamud changelogs.
|
||||
/// </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>
|
||||
/// Gets a list of all available changelogs.
|
||||
/// </summary>
|
||||
public IReadOnlyList<DalamudChangelog>? Changelogs { get; private set; }
|
||||
public IReadOnlyList<IChangelogEntry>? Changelogs { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Reload the changelog list.
|
||||
|
|
@ -26,12 +41,58 @@ internal class DalamudChangelogManager : IDisposable
|
|||
/// <returns>A <see cref="Task"/> representing the asynchronous operation.</returns>
|
||||
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)));
|
||||
}
|
||||
|
||||
this.Changelogs = changelogs.OrderByDescending(x => x.Date).ToList();
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
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>
|
||||
string Text { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the author of the changelog.
|
||||
/// </summary>
|
||||
string? Author { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the date of the entry.
|
||||
/// </summary>
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
using System;
|
||||
|
||||
using CheapLoc;
|
||||
using Dalamud.Plugin.Internal.Types;
|
||||
using Dalamud.Utility;
|
||||
|
||||
namespace Dalamud.Interface.Internal.Windows.PluginInstaller;
|
||||
|
||||
|
|
@ -14,16 +14,15 @@ internal class PluginChangelogEntry : IChangelogEntry
|
|||
/// Initializes a new instance of the <see cref="PluginChangelogEntry"/> class.
|
||||
/// </summary>
|
||||
/// <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;
|
||||
|
||||
if (plugin.Manifest.Changelog.IsNullOrEmpty())
|
||||
throw new ArgumentException("Manifest has no changelog.");
|
||||
|
||||
var version = plugin.Manifest.EffectiveVersion;
|
||||
|
||||
this.Version = version!.ToString();
|
||||
this.Version = history.Version;
|
||||
this.Text = history.Changelog ?? Loc.Localize("ChangelogNoText", "No changelog for this version.");
|
||||
this.Author = history.PublishedBy;
|
||||
this.Date = history.PublishedAt;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
|
@ -35,11 +34,14 @@ internal class PluginChangelogEntry : IChangelogEntry
|
|||
public string Title => this.Plugin.Manifest.Name;
|
||||
|
||||
/// <inheritdoc/>
|
||||
public string Version { get; init; }
|
||||
public string Version { get; private set; }
|
||||
|
||||
/// <inheritdoc/>
|
||||
public string Text => this.Plugin.Manifest.Changelog!;
|
||||
public string Text { get; private set; }
|
||||
|
||||
/// <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.Linq;
|
||||
using System.Numerics;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
using CheapLoc;
|
||||
|
|
@ -40,7 +41,6 @@ internal class PluginInstallerWindow : Window, IDisposable
|
|||
|
||||
private readonly PluginImageCache imageCache;
|
||||
private readonly PluginCategoryManager categoryManager = new();
|
||||
private readonly DalamudChangelogManager dalamudChangelogManager = new();
|
||||
|
||||
private readonly List<int> openPluginCollapsibles = new();
|
||||
|
||||
|
|
@ -48,6 +48,10 @@ internal class PluginInstallerWindow : Window, IDisposable
|
|||
|
||||
private readonly object listLock = new();
|
||||
|
||||
private DalamudChangelogManager? dalamudChangelogManager;
|
||||
private Task? dalamudChangelogRefreshTask;
|
||||
private CancellationTokenSource? dalamudChangelogRefreshTaskCts;
|
||||
|
||||
#region Image Tester State
|
||||
|
||||
private string[] testerImagePaths = new string[5];
|
||||
|
|
@ -132,6 +136,8 @@ internal class PluginInstallerWindow : Window, IDisposable
|
|||
if (pluginManager.PluginsReady)
|
||||
this.OnInstalledPluginsChanged();
|
||||
|
||||
this.dalamudChangelogManager = new(pluginManager);
|
||||
|
||||
pluginManager.OnAvailablePluginsChanged += this.OnAvailablePluginsChanged;
|
||||
pluginManager.OnInstalledPluginsChanged += this.OnInstalledPluginsChanged;
|
||||
|
||||
|
|
@ -179,6 +185,8 @@ internal class PluginInstallerWindow : Window, IDisposable
|
|||
/// <inheritdoc/>
|
||||
public void Dispose()
|
||||
{
|
||||
this.dalamudChangelogRefreshTaskCts?.Cancel();
|
||||
|
||||
var pluginManager = Service<PluginManager>.GetNullable();
|
||||
if (pluginManager != null)
|
||||
{
|
||||
|
|
@ -193,7 +201,6 @@ internal class PluginInstallerWindow : Window, IDisposable
|
|||
var pluginManager = Service<PluginManager>.Get();
|
||||
|
||||
_ = pluginManager.ReloadPluginMastersAsync();
|
||||
_ = this.dalamudChangelogManager.ReloadChangelogAsync();
|
||||
|
||||
this.searchText = string.Empty;
|
||||
this.sortKind = PluginSortKind.Alphabetical;
|
||||
|
|
@ -837,30 +844,40 @@ internal class PluginInstallerWindow : Window, IDisposable
|
|||
return;
|
||||
}
|
||||
|
||||
var pluginChangelogs = this.pluginListInstalled
|
||||
.Where(plugin => !this.IsManifestFiltered(plugin.Manifest)
|
||||
&& !plugin.Manifest.Changelog.IsNullOrEmpty())
|
||||
.Select(x =>
|
||||
{
|
||||
var changelog = new PluginChangelogEntry(x);
|
||||
return (IChangelogEntry)changelog;
|
||||
});
|
||||
if (this.dalamudChangelogRefreshTask?.IsFaulted == true ||
|
||||
this.dalamudChangelogRefreshTask?.IsCanceled == true)
|
||||
{
|
||||
ImGui.TextColored(ImGuiColors.DalamudGrey, Locs.TabBody_ChangelogError);
|
||||
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;
|
||||
if (displayDalamud && displayPlugins && this.dalamudChangelogManager.Changelogs != null)
|
||||
{
|
||||
changelogs = pluginChangelogs
|
||||
.Concat(this.dalamudChangelogManager.Changelogs.Select(
|
||||
x => new DalamudChangelogEntry(x)));
|
||||
changelogs = this.dalamudChangelogManager.Changelogs;
|
||||
}
|
||||
else if (displayDalamud && this.dalamudChangelogManager.Changelogs != null)
|
||||
{
|
||||
changelogs = this.dalamudChangelogManager.Changelogs.Select(
|
||||
x => new DalamudChangelogEntry(x));
|
||||
changelogs = this.dalamudChangelogManager.Changelogs.OfType<DalamudChangelogEntry>();
|
||||
}
|
||||
else if (displayPlugins)
|
||||
{
|
||||
changelogs = pluginChangelogs;
|
||||
changelogs = this.dalamudChangelogManager.Changelogs.OfType<PluginChangelogEntry>();
|
||||
}
|
||||
|
||||
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_ChangelogError => Loc.Localize("InstallerChangelogError", "Could not download changelogs.");
|
||||
|
||||
#endregion
|
||||
|
||||
#region Plugin title text
|
||||
|
|
|
|||
|
|
@ -1299,6 +1299,35 @@ Thanks and have fun!";
|
|||
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()
|
||||
{
|
||||
var updatablePlugins = new List<AvailablePluginUpdate>();
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue