mirror of
https://github.com/goatcorp/Dalamud.git
synced 2026-01-01 21:33:39 +01:00
Merge branch 'net5' of github.com:goatcorp/Dalamud into net5
This commit is contained in:
commit
f9ab1dbf26
22 changed files with 1363 additions and 655 deletions
|
|
@ -3,7 +3,6 @@ using System.Diagnostics;
|
|||
using System.IO;
|
||||
using System.Net;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Text;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
|
|
@ -41,11 +40,8 @@ namespace Dalamud
|
|||
/// <summary>
|
||||
/// A delegate used from VEH handler on exception which CoreCLR will fast fail by default.
|
||||
/// </summary>
|
||||
/// <param name="dumpPath">Path to minidump file created in UTF-16.</param>
|
||||
/// <param name="logPath">Path to log file to create in UTF-16.</param>
|
||||
/// <param name="log">Log text in UTF-16.</param>
|
||||
/// <returns>HGLOBAL for message.</returns>
|
||||
public delegate IntPtr VehDelegate(IntPtr dumpPath, IntPtr logPath, IntPtr log);
|
||||
public delegate IntPtr VehDelegate();
|
||||
|
||||
/// <summary>
|
||||
/// Initialize Dalamud.
|
||||
|
|
@ -64,43 +60,19 @@ namespace Dalamud
|
|||
}
|
||||
|
||||
/// <summary>
|
||||
/// Show error message along with stack trace and exit.
|
||||
/// Returns stack trace.
|
||||
/// </summary>
|
||||
/// <param name="dumpPath">Path to minidump file created in UTF-16.</param>
|
||||
/// <param name="logPath">Path to log file to create in UTF-16.</param>
|
||||
/// <param name="log">Log text in UTF-16.</param>
|
||||
public static IntPtr VehCallback(IntPtr dumpPath, IntPtr logPath, IntPtr log)
|
||||
/// <returns>HGlobal to wchar_t* stack trace c-string.</returns>
|
||||
public static IntPtr VehCallback()
|
||||
{
|
||||
string stackTrace;
|
||||
try
|
||||
{
|
||||
stackTrace = Environment.StackTrace;
|
||||
return Marshal.StringToHGlobalUni(Environment.StackTrace);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
stackTrace = "Fail: " + e.ToString();
|
||||
return Marshal.StringToHGlobalUni("Fail: " + e);
|
||||
}
|
||||
|
||||
var msg = "This may be caused by a faulty plugin, a broken TexTools modification, any other third-party tool or simply a bug in the game.\n\n"
|
||||
+ "Please attempt an integrity check in the XIVLauncher settings, and disabling plugins you don't need.";
|
||||
|
||||
try
|
||||
{
|
||||
File.WriteAllText(
|
||||
Marshal.PtrToStringUni(logPath),
|
||||
"Stack trace:\n" + stackTrace + "\n\n" + Marshal.PtrToStringUni(log));
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
msg += "\n\nAdditionally, failed to write file: " + e.ToString();
|
||||
}
|
||||
|
||||
msg = msg.Format(
|
||||
Marshal.PtrToStringUni(dumpPath),
|
||||
Marshal.PtrToStringUni(logPath),
|
||||
stackTrace);
|
||||
|
||||
return Marshal.StringToHGlobalUni(msg);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
|
|
|||
|
|
@ -305,7 +305,7 @@ namespace Dalamud.Game
|
|||
{
|
||||
if (this.configuration.AutoUpdatePlugins)
|
||||
{
|
||||
PluginManager.PrintUpdatedPlugins(updatedPlugins, Loc.Localize("DalamudPluginAutoUpdate", "Auto-update:"));
|
||||
Service<PluginManager>.Get().PrintUpdatedPlugins(updatedPlugins, Loc.Localize("DalamudPluginAutoUpdate", "Auto-update:"));
|
||||
notifications.AddNotification(Loc.Localize("NotificationUpdatedPlugins", "{0} of your plugins were updated.").Format(updatedPlugins.Count), Loc.Localize("NotificationAutoUpdate", "Auto-Update"), NotificationType.Info);
|
||||
}
|
||||
else
|
||||
|
|
|
|||
|
|
@ -250,6 +250,11 @@ namespace Dalamud.Interface.Internal
|
|||
/// </summary>
|
||||
public void OpenPluginInstaller() => this.pluginWindow.IsOpen = true;
|
||||
|
||||
/// <summary>
|
||||
/// Opens the <see cref="PluginInstallerWindow"/> on the plugin changelogs.
|
||||
/// </summary>
|
||||
public void OpenPluginInstallerPluginChangelogs() => this.pluginWindow.OpenPluginChangelogs();
|
||||
|
||||
/// <summary>
|
||||
/// Opens the <see cref="SettingsWindow"/>.
|
||||
/// </summary>
|
||||
|
|
@ -615,6 +620,16 @@ namespace Dalamud.Interface.Internal
|
|||
Service<Dalamud>.Get().Unload();
|
||||
}
|
||||
|
||||
if (ImGui.MenuItem("Restart game"))
|
||||
{
|
||||
[DllImport("kernel32.dll")]
|
||||
[return: MarshalAs(UnmanagedType.Bool)]
|
||||
static extern void RaiseException(uint dwExceptionCode, uint dwExceptionFlags, uint nNumberOfArguments, IntPtr lpArguments);
|
||||
|
||||
RaiseException(0x12345678, 0, 0, IntPtr.Zero);
|
||||
Process.GetCurrentProcess().Kill();
|
||||
}
|
||||
|
||||
if (ImGui.MenuItem("Kill game"))
|
||||
{
|
||||
Process.GetCurrentProcess().Kill();
|
||||
|
|
|
|||
|
|
@ -21,10 +21,7 @@ namespace Dalamud.Interface.Internal.Windows.PluginInstaller
|
|||
if (plugin.Manifest.Changelog.IsNullOrEmpty())
|
||||
throw new ArgumentException("Manifest has no changelog.");
|
||||
|
||||
var version = plugin.AssemblyName?.Version;
|
||||
version ??= plugin.Manifest.Testing
|
||||
? plugin.Manifest.TestingAssemblyVersion
|
||||
: plugin.Manifest.AssemblyVersion;
|
||||
var version = plugin.Manifest.EffectiveVersion;
|
||||
|
||||
this.Version = version!.ToString();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -217,6 +217,16 @@ namespace Dalamud.Interface.Internal.Windows.PluginInstaller
|
|||
this.imageCache.ClearIconCache();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Open the window on the plugin changelogs.
|
||||
/// </summary>
|
||||
public void OpenPluginChangelogs()
|
||||
{
|
||||
this.categoryManager.CurrentGroupIdx = 3;
|
||||
this.categoryManager.CurrentCategoryIdx = 2;
|
||||
this.IsOpen = true;
|
||||
}
|
||||
|
||||
private void DrawProgressOverlay()
|
||||
{
|
||||
var pluginManager = Service<PluginManager>.Get();
|
||||
|
|
@ -235,16 +245,19 @@ namespace Dalamud.Interface.Internal.Windows.PluginInstaller
|
|||
ImGui.SetCursorPos(Vector2.Zero);
|
||||
|
||||
var windowSize = ImGui.GetWindowSize();
|
||||
var titleHeight = ImGui.GetFontSize() + (ImGui.GetStyle().FramePadding.Y * 2);
|
||||
|
||||
ImGui.PushStyleVar(ImGuiStyleVar.WindowPadding, Vector2.Zero);
|
||||
ImGui.PushStyleVar(ImGuiStyleVar.FramePadding, Vector2.Zero);
|
||||
ImGui.PushStyleVar(ImGuiStyleVar.CellPadding, Vector2.Zero);;
|
||||
ImGui.PushStyleVar(ImGuiStyleVar.ChildBorderSize, 0);
|
||||
ImGui.PushStyleVar(ImGuiStyleVar.ChildRounding, 0);
|
||||
|
||||
ImGui.SetNextWindowBgAlpha(0.8f);
|
||||
if (ImGui.BeginChild("###installerLoadingFrame", new Vector2(-1, -1), false))
|
||||
{
|
||||
ImGui.GetWindowDrawList().PushClipRectFullScreen();
|
||||
ImGui.GetWindowDrawList().AddRectFilled(
|
||||
ImGui.GetWindowPos() + new Vector2(0, titleHeight),
|
||||
ImGui.GetWindowPos() + windowSize,
|
||||
0xCC000000,
|
||||
ImGui.GetStyle().WindowRounding,
|
||||
ImDrawFlags.RoundCornersBottom);
|
||||
ImGui.PopClipRect();
|
||||
|
||||
ImGui.SetCursorPosY(windowSize.Y / 2);
|
||||
|
||||
switch (this.loadingIndicatorKind)
|
||||
|
|
@ -303,6 +316,7 @@ namespace Dalamud.Interface.Internal.Windows.PluginInstaller
|
|||
|
||||
if (currentProgress != total)
|
||||
{
|
||||
ImGui.SetCursorPosX(windowSize.X / 3);
|
||||
ImGui.ProgressBar(currentProgress / (float)total, new Vector2(windowSize.X / 3, 50));
|
||||
}
|
||||
}
|
||||
|
|
@ -314,8 +328,6 @@ namespace Dalamud.Interface.Internal.Windows.PluginInstaller
|
|||
|
||||
ImGui.EndChild();
|
||||
}
|
||||
|
||||
ImGui.PopStyleVar(5);
|
||||
}
|
||||
|
||||
private void DrawHeader()
|
||||
|
|
@ -325,8 +337,8 @@ namespace Dalamud.Interface.Internal.Windows.PluginInstaller
|
|||
|
||||
ImGui.SetCursorPosY(ImGui.GetCursorPosY() - (5 * ImGuiHelpers.GlobalScale));
|
||||
|
||||
var searchInputWidth = 240 * ImGuiHelpers.GlobalScale;
|
||||
var searchClearButtonWidth = 40 * ImGuiHelpers.GlobalScale;
|
||||
var searchInputWidth = 180 * ImGuiHelpers.GlobalScale;
|
||||
var searchClearButtonWidth = 25 * ImGuiHelpers.GlobalScale;
|
||||
|
||||
var sortByText = Locs.SortBy_Label;
|
||||
var sortByTextWidth = ImGui.CalcTextSize(sortByText).X;
|
||||
|
|
@ -349,9 +361,10 @@ namespace Dalamud.Interface.Internal.Windows.PluginInstaller
|
|||
ImGui.SameLine();
|
||||
|
||||
// Shift down a little to align with the middle of the header text
|
||||
ImGui.SetCursorPosY(ImGui.GetCursorPosY() + (headerTextSize.Y / 4) - 2);
|
||||
var downShift = ImGui.GetCursorPosY() + (headerTextSize.Y / 4) - 2;
|
||||
ImGui.SetCursorPosY(downShift);
|
||||
|
||||
ImGui.SetCursorPosX(windowSize.X - sortSelectWidth - style.ItemSpacing.X - searchInputWidth - searchClearButtonWidth);
|
||||
ImGui.SetCursorPosX(windowSize.X - sortSelectWidth - (style.ItemSpacing.X * 2) - searchInputWidth - searchClearButtonWidth);
|
||||
|
||||
var searchTextChanged = false;
|
||||
ImGui.SetNextItemWidth(searchInputWidth);
|
||||
|
|
@ -362,6 +375,7 @@ namespace Dalamud.Interface.Internal.Windows.PluginInstaller
|
|||
100);
|
||||
|
||||
ImGui.SameLine();
|
||||
ImGui.SetCursorPosY(downShift);
|
||||
|
||||
ImGui.SetNextItemWidth(searchClearButtonWidth);
|
||||
if (ImGuiComponents.IconButton(FontAwesomeIcon.Times))
|
||||
|
|
@ -374,7 +388,7 @@ namespace Dalamud.Interface.Internal.Windows.PluginInstaller
|
|||
this.UpdateCategoriesOnSearchChange();
|
||||
|
||||
ImGui.SameLine();
|
||||
ImGui.SetCursorPosX(windowSize.X - sortSelectWidth);
|
||||
ImGui.SetCursorPosY(downShift);
|
||||
ImGui.SetNextItemWidth(selectableWidth);
|
||||
if (ImGui.BeginCombo(sortByText, this.filterText, ImGuiComboFlags.NoArrowButton))
|
||||
{
|
||||
|
|
@ -497,7 +511,7 @@ namespace Dalamud.Interface.Internal.Windows.PluginInstaller
|
|||
|
||||
if (this.updatePluginCount > 0)
|
||||
{
|
||||
PluginManager.PrintUpdatedPlugins(this.updatedPlugins, Locs.PluginUpdateHeader_Chatbox);
|
||||
Service<PluginManager>.Get().PrintUpdatedPlugins(this.updatedPlugins, Locs.PluginUpdateHeader_Chatbox);
|
||||
notifications.AddNotification(Locs.Notifications_UpdatesInstalled(this.updatePluginCount), Locs.Notifications_UpdatesInstalledTitle, NotificationType.Success);
|
||||
|
||||
var installedGroupIdx = this.categoryManager.GroupList.TakeWhile(
|
||||
|
|
@ -1674,6 +1688,12 @@ namespace Dalamud.Interface.Internal.Windows.PluginInstaller
|
|||
// Name
|
||||
var label = plugin.Manifest.Name;
|
||||
|
||||
// Dev
|
||||
if (plugin.IsDev)
|
||||
{
|
||||
label += Locs.PluginTitleMod_DevPlugin;
|
||||
}
|
||||
|
||||
// Testing
|
||||
if (plugin.Manifest.Testing)
|
||||
{
|
||||
|
|
@ -1841,12 +1861,6 @@ namespace Dalamud.Interface.Internal.Windows.PluginInstaller
|
|||
ImGui.SameLine();
|
||||
ImGui.TextColored(ImGuiColors.DalamudGrey3, $" v{plugin.Manifest.EffectiveVersion}");
|
||||
|
||||
if (plugin.IsDev)
|
||||
{
|
||||
ImGui.SameLine();
|
||||
ImGui.TextColored(ImGuiColors.DalamudRed, Locs.PluginBody_DeleteDevPlugin);
|
||||
}
|
||||
|
||||
ImGuiHelpers.ScaledDummy(5);
|
||||
|
||||
if (this.DrawPluginImages(plugin, manifest, isThirdParty, index))
|
||||
|
|
@ -2557,6 +2571,8 @@ namespace Dalamud.Interface.Internal.Windows.PluginInstaller
|
|||
|
||||
public static string PluginTitleMod_TestingVersion => Loc.Localize("InstallerTestingVersion", " (testing version)");
|
||||
|
||||
public static string PluginTitleMod_DevPlugin => Loc.Localize("InstallerDevPlugin", " (dev plugin)");
|
||||
|
||||
public static string PluginTitleMod_UpdateFailed => Loc.Localize("InstallerUpdateFailed", " (update failed)");
|
||||
|
||||
public static string PluginTitleMod_LoadError => Loc.Localize("InstallerLoadError", " (load error)");
|
||||
|
|
@ -2600,9 +2616,6 @@ namespace Dalamud.Interface.Internal.Windows.PluginInstaller
|
|||
public static string PluginBody_Plugin3rdPartyRepo(string url) => Loc.Localize("InstallerPlugin3rdPartyRepo", "From custom plugin repository {0}").Format(url);
|
||||
|
||||
public static string PluginBody_AvailableDevPlugin => Loc.Localize("InstallerDevPlugin", " This plugin is available in one of your repos, 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.");
|
||||
|
||||
public static string PluginBody_Orphaned => Loc.Localize("InstallerOrphanedPluginBody ", "This plugin's source repository is no longer available. You may need to reinstall it from its repository, or re-add the repository.");
|
||||
|
|
|
|||
|
|
@ -17,6 +17,8 @@ using Dalamud.Game;
|
|||
using Dalamud.Game.Gui;
|
||||
using Dalamud.Game.Gui.Dtr;
|
||||
using Dalamud.Game.Text;
|
||||
using Dalamud.Game.Text.SeStringHandling;
|
||||
using Dalamud.Game.Text.SeStringHandling.Payloads;
|
||||
using Dalamud.Interface.Internal;
|
||||
using Dalamud.Logging.Internal;
|
||||
using Dalamud.Plugin.Internal.Exceptions;
|
||||
|
|
@ -50,6 +52,8 @@ internal partial class PluginManager : IDisposable, IServiceType
|
|||
private readonly DirectoryInfo devPluginDirectory;
|
||||
private readonly BannedPlugin[]? bannedPlugins;
|
||||
|
||||
private readonly DalamudLinkPayload openInstallerWindowPluginChangelogsLink;
|
||||
|
||||
[ServiceManager.ServiceDependency]
|
||||
private readonly DalamudConfiguration configuration = Service<DalamudConfiguration>.Get();
|
||||
|
||||
|
|
@ -101,6 +105,11 @@ internal partial class PluginManager : IDisposable, IServiceType
|
|||
throw new InvalidDataException("Couldn't deserialize banned plugins manifest.");
|
||||
}
|
||||
|
||||
this.openInstallerWindowPluginChangelogsLink = Service<ChatGui>.Get().AddChatLinkHandler("Dalamud", 1003, (i, m) =>
|
||||
{
|
||||
Service<DalamudInterface>.GetNullable()?.OpenPluginInstallerPluginChangelogs();
|
||||
});
|
||||
|
||||
this.ApplyPatches();
|
||||
}
|
||||
|
||||
|
|
@ -169,25 +178,38 @@ internal partial class PluginManager : IDisposable, IServiceType
|
|||
/// </summary>
|
||||
/// <param name="updateMetadata">The list of updated plugin metadata.</param>
|
||||
/// <param name="header">The header text to send to chat prior to any update info.</param>
|
||||
public static void PrintUpdatedPlugins(List<PluginUpdateStatus>? updateMetadata, string header)
|
||||
public void PrintUpdatedPlugins(List<PluginUpdateStatus>? updateMetadata, string header)
|
||||
{
|
||||
var chatGui = Service<ChatGui>.Get();
|
||||
|
||||
if (updateMetadata is { Count: > 0 })
|
||||
{
|
||||
chatGui.Print(header);
|
||||
chatGui.PrintChat(new XivChatEntry
|
||||
{
|
||||
Message = new SeString(new List<Payload>()
|
||||
{
|
||||
new TextPayload(header),
|
||||
new TextPayload(" ["),
|
||||
new UIForegroundPayload(500),
|
||||
this.openInstallerWindowPluginChangelogsLink,
|
||||
new TextPayload(Loc.Localize("DalamudInstallerPluginChangelogHelp", "Open plugin changelogs") + " "),
|
||||
RawPayload.LinkTerminator,
|
||||
new UIForegroundPayload(0),
|
||||
new TextPayload("]"),
|
||||
}),
|
||||
});
|
||||
|
||||
foreach (var metadata in updateMetadata)
|
||||
{
|
||||
if (metadata.WasUpdated)
|
||||
{
|
||||
chatGui.Print(Locs.DalamudPluginUpdateSuccessful(metadata.Name, metadata.Version));
|
||||
chatGui.Print(Locs.DalamudPluginUpdateSuccessful(metadata.Name, metadata.Version) + (metadata.HasChangelog ? " " : string.Empty));
|
||||
}
|
||||
else
|
||||
{
|
||||
chatGui.PrintChat(new XivChatEntry
|
||||
{
|
||||
Message = Locs.DalamudPluginUpdateFailed(metadata.Name, metadata.Version),
|
||||
Message = Locs.DalamudPluginUpdateFailed(metadata.Name, metadata.Version) + (metadata.HasChangelog ? " " : string.Empty),
|
||||
Type = XivChatType.Urgent,
|
||||
});
|
||||
}
|
||||
|
|
@ -243,10 +265,12 @@ internal partial class PluginManager : IDisposable, IServiceType
|
|||
/// <inheritdoc/>
|
||||
public void Dispose()
|
||||
{
|
||||
if (this.InstalledPlugins.Any())
|
||||
var disposablePlugins =
|
||||
this.InstalledPlugins.Where(plugin => plugin.State is PluginState.Loaded or PluginState.LoadError).ToArray();
|
||||
if (disposablePlugins.Any())
|
||||
{
|
||||
// Unload them first, just in case some of plugin codes are still running via callbacks initiated externally.
|
||||
foreach (var plugin in this.InstalledPlugins.Where(plugin => !plugin.Manifest.CanUnloadAsync))
|
||||
foreach (var plugin in disposablePlugins.Where(plugin => !plugin.Manifest.CanUnloadAsync))
|
||||
{
|
||||
try
|
||||
{
|
||||
|
|
@ -258,7 +282,7 @@ internal partial class PluginManager : IDisposable, IServiceType
|
|||
}
|
||||
}
|
||||
|
||||
Task.WaitAll(this.InstalledPlugins
|
||||
Task.WaitAll(disposablePlugins
|
||||
.Where(plugin => plugin.Manifest.CanUnloadAsync)
|
||||
.Select(plugin => Task.Run(async () =>
|
||||
{
|
||||
|
|
@ -278,7 +302,7 @@ internal partial class PluginManager : IDisposable, IServiceType
|
|||
|
||||
// Now that we've waited enough, dispose the whole plugin.
|
||||
// Since plugins should have been unloaded above, this should be done quickly.
|
||||
foreach (var plugin in this.InstalledPlugins)
|
||||
foreach (var plugin in disposablePlugins)
|
||||
plugin.ExplicitDisposeIgnoreExceptions($"Error disposing {plugin.Name}", Log);
|
||||
}
|
||||
|
||||
|
|
@ -975,6 +999,7 @@ internal partial class PluginManager : IDisposable, IServiceType
|
|||
? metadata.UpdateManifest.TestingAssemblyVersion
|
||||
: metadata.UpdateManifest.AssemblyVersion)!,
|
||||
WasUpdated = true,
|
||||
HasChangelog = !metadata.UpdateManifest.Changelog.IsNullOrWhitespace(),
|
||||
};
|
||||
|
||||
if (!dryRun)
|
||||
|
|
|
|||
|
|
@ -138,9 +138,9 @@ internal class LocalDevPlugin : LocalPlugin, IDisposable
|
|||
return;
|
||||
}
|
||||
|
||||
if (this.State != PluginState.Loaded)
|
||||
if (this.State != PluginState.Loaded && this.State != PluginState.LoadError)
|
||||
{
|
||||
Log.Debug($"Skipping reload of {this.Name}, state ({this.State}) is not {PluginState.Loaded}.");
|
||||
Log.Debug($"Skipping reload of {this.Name}, state ({this.State}) is not {PluginState.Loaded} nor {PluginState.LoadError}.");
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -26,4 +26,9 @@ internal class PluginUpdateStatus
|
|||
/// Gets or sets a value indicating whether the plugin was updated.
|
||||
/// </summary>
|
||||
public bool WasUpdated { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets a value indicating whether the plugin has a changelog if it was updated.
|
||||
/// </summary>
|
||||
public bool HasChangelog { get; init; }
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue