mirror of
https://github.com/goatcorp/Dalamud.git
synced 2025-12-27 19:09:18 +01:00
Merge remote-tracking branch 'origin/master' into fools23
This commit is contained in:
commit
e710c43ab5
26 changed files with 367 additions and 183 deletions
19
.github/workflows/delete-artifacts.yml
vendored
19
.github/workflows/delete-artifacts.yml
vendored
|
|
@ -1,19 +0,0 @@
|
|||
name: Remove old artifacts
|
||||
|
||||
on:
|
||||
schedule:
|
||||
# Every day at 1am
|
||||
- cron: '0 1 * * *'
|
||||
|
||||
jobs:
|
||||
remove-old-artifacts:
|
||||
runs-on: ubuntu-latest
|
||||
timeout-minutes: 10
|
||||
|
||||
steps:
|
||||
- name: Remove old artifacts
|
||||
uses: c-hive/gha-remove-artifacts@v1.2.0
|
||||
with:
|
||||
age: '1 month'
|
||||
skip-tags: true
|
||||
skip-recent: 3
|
||||
2
.github/workflows/main.yml
vendored
2
.github/workflows/main.yml
vendored
|
|
@ -71,6 +71,7 @@ jobs:
|
|||
}
|
||||
|
||||
$newVersion = [System.IO.File]::ReadAllText("$(Get-Location)\scratch\TEMP_gitver.txt")
|
||||
$revision = [System.IO.File]::ReadAllText("$(Get-Location)\scratch\revision.txt")
|
||||
Remove-Item -Force -Recurse .\scratch
|
||||
|
||||
if (Test-Path -Path $branchName) {
|
||||
|
|
@ -82,6 +83,7 @@ jobs:
|
|||
Move-Item -Force ".\canary.zip" ".\${branchName}\latest.zip"
|
||||
$versionData.AssemblyVersion = $newVersion
|
||||
$versionData | add-member -Force -Name "GitSha" $newVersion -MemberType NoteProperty
|
||||
$versionData | add-member -Force -Name "Revision" $revision -MemberType NoteProperty
|
||||
$versionData | ConvertTo-Json -Compress | Out-File ".\${branchName}\version"
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -6,6 +6,8 @@
|
|||
#include "hooks.h"
|
||||
#include "logging.h"
|
||||
#include "utils.h"
|
||||
#include <iphlpapi.h>
|
||||
#include <icmpapi.h>
|
||||
|
||||
template<typename T>
|
||||
static std::span<T> assume_nonempty_span(std::span<T> t, const char* descr) {
|
||||
|
|
@ -554,6 +556,40 @@ void xivfixes::clr_failfast_hijack(bool bApply)
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
void xivfixes::prevent_icmphandle_crashes(bool bApply) {
|
||||
static const char* LogTag = "[xivfixes:prevent_icmphandle_crashes]";
|
||||
|
||||
static std::optional<hooks::import_hook<decltype(IcmpCloseHandle)>> s_hookIcmpCloseHandle;
|
||||
|
||||
if (bApply) {
|
||||
if (!g_startInfo.BootEnabledGameFixes.contains("prevent_icmphandle_crashes")) {
|
||||
logging::I("{} Turned off via environment variable.", LogTag);
|
||||
return;
|
||||
}
|
||||
|
||||
s_hookIcmpCloseHandle.emplace("iphlpapi.dll!IcmpCloseHandle (import, prevent_icmphandle_crashes)", "iphlpapi.dll", "IcmpCloseHandle", 0);
|
||||
|
||||
s_hookIcmpCloseHandle->set_detour([](HANDLE IcmpHandle) noexcept {
|
||||
// this is exactly how windows behaves, however calling IcmpCloseHandle with
|
||||
// an invalid handle will segfault on wine...
|
||||
if (IcmpHandle == INVALID_HANDLE_VALUE) {
|
||||
logging::W("{} IcmpCloseHandle was called with INVALID_HANDLE_VALUE", LogTag);
|
||||
return FALSE;
|
||||
}
|
||||
return s_hookIcmpCloseHandle->call_original(IcmpHandle);
|
||||
});
|
||||
|
||||
logging::I("{} Enable", LogTag);
|
||||
}
|
||||
else {
|
||||
if (s_hookIcmpCloseHandle) {
|
||||
logging::I("{} Disable", LogTag);
|
||||
s_hookIcmpCloseHandle.reset();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void xivfixes::apply_all(bool bApply) {
|
||||
for (const auto& [taskName, taskFunction] : std::initializer_list<std::pair<const char*, void(*)(bool)>>
|
||||
{
|
||||
|
|
@ -562,7 +598,8 @@ void xivfixes::apply_all(bool bApply) {
|
|||
{ "disable_game_openprocess_access_check", &disable_game_openprocess_access_check },
|
||||
{ "redirect_openprocess", &redirect_openprocess },
|
||||
{ "backup_userdata_save", &backup_userdata_save },
|
||||
{ "clr_failfast_hijack", &clr_failfast_hijack }
|
||||
{ "clr_failfast_hijack", &clr_failfast_hijack },
|
||||
{ "prevent_icmphandle_crashes", &prevent_icmphandle_crashes }
|
||||
}
|
||||
) {
|
||||
try {
|
||||
|
|
|
|||
|
|
@ -7,6 +7,7 @@ namespace xivfixes {
|
|||
void redirect_openprocess(bool bApply);
|
||||
void backup_userdata_save(bool bApply);
|
||||
void clr_failfast_hijack(bool bApply);
|
||||
void prevent_icmphandle_crashes(bool bApply);
|
||||
|
||||
void apply_all(bool bApply);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -325,7 +325,7 @@ namespace Dalamud.Injector
|
|||
startInfo.BootShowConsole = args.Contains("--console");
|
||||
startInfo.BootEnableEtw = args.Contains("--etw");
|
||||
startInfo.BootLogPath = GetLogPath("dalamud.boot", startInfo.LogName);
|
||||
startInfo.BootEnabledGameFixes = new List<string> { "prevent_devicechange_crashes", "disable_game_openprocess_access_check", "redirect_openprocess", "backup_userdata_save", "clr_failfast_hijack" };
|
||||
startInfo.BootEnabledGameFixes = new List<string> { "prevent_devicechange_crashes", "disable_game_openprocess_access_check", "redirect_openprocess", "backup_userdata_save", "clr_failfast_hijack", "prevent_icmphandle_crashes" };
|
||||
startInfo.BootDotnetOpenProcessHookMode = 0;
|
||||
startInfo.BootWaitMessageBox |= args.Contains("--msgbox1") ? 1 : 0;
|
||||
startInfo.BootWaitMessageBox |= args.Contains("--msgbox2") ? 2 : 0;
|
||||
|
|
|
|||
|
|
@ -244,6 +244,11 @@ internal sealed class DalamudConfiguration : IServiceType
|
|||
/// </summary>
|
||||
public int? PluginWaitBeforeFree { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets a value indicating whether or not crashes during shutdown should be reported.
|
||||
/// </summary>
|
||||
public bool ReportShutdownCrashes { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets a list of saved styles.
|
||||
/// </summary>
|
||||
|
|
|
|||
|
|
@ -11,6 +11,7 @@ using Dalamud.Game.Gui.Internal;
|
|||
using Dalamud.Interface.Internal;
|
||||
using Dalamud.Plugin.Internal;
|
||||
using Dalamud.Utility;
|
||||
using PInvoke;
|
||||
using Serilog;
|
||||
|
||||
#if DEBUG
|
||||
|
|
@ -103,6 +104,16 @@ internal sealed class Dalamud : IServiceType
|
|||
public void Unload()
|
||||
{
|
||||
Log.Information("Trigger unload");
|
||||
|
||||
var reportCrashesSetting = Service<DalamudConfiguration>.GetNullable()?.ReportShutdownCrashes ?? true;
|
||||
var pmHasDevPlugins = Service<PluginManager>.GetNullable()?.InstalledPlugins.Any(x => x.IsDev) ?? false;
|
||||
if (!reportCrashesSetting && !pmHasDevPlugins)
|
||||
{
|
||||
// Leaking on purpose for now
|
||||
var attribs = Kernel32.SECURITY_ATTRIBUTES.Create();
|
||||
Kernel32.CreateMutex(attribs, false, "DALAMUD_CRASHES_NO_MORE");
|
||||
}
|
||||
|
||||
this.unloadSignal.Set();
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -8,7 +8,7 @@
|
|||
</PropertyGroup>
|
||||
|
||||
<PropertyGroup Label="Feature">
|
||||
<DalamudVersion>7.4.7.5</DalamudVersion>
|
||||
<DalamudVersion>7.4.9.0</DalamudVersion>
|
||||
<Description>XIV Launcher addon framework</Description>
|
||||
<AssemblyVersion>$(DalamudVersion)</AssemblyVersion>
|
||||
<Version>$(DalamudVersion)</Version>
|
||||
|
|
@ -124,6 +124,7 @@
|
|||
<PropertyGroup>
|
||||
<!-- Needed temporarily for CI -->
|
||||
<TempVerFile>$(OutputPath)TEMP_gitver.txt</TempVerFile>
|
||||
<DalamudRevisionFile>$(OutputPath)revision.txt</DalamudRevisionFile>
|
||||
</PropertyGroup>
|
||||
|
||||
<Target Name="GetGitCommitCount" BeforeTargets="WriteGitHash" Condition="'$(CommitCount)'==''">
|
||||
|
|
@ -135,6 +136,8 @@
|
|||
<PropertyGroup>
|
||||
<CommitCount>$([System.Text.RegularExpressions.Regex]::Replace($(DalamudGitCommitCount), @"\t|\n|\r", ""))</CommitCount>
|
||||
</PropertyGroup>
|
||||
|
||||
<Exec Command="echo|set /P ="$(CommitCount)" > $(DalamudRevisionFile)" IgnoreExitCode="true" />
|
||||
</Target>
|
||||
|
||||
<Target Name="GetGitHash" BeforeTargets="WriteGitHash" Condition="'$(BuildHash)'=='' And '$(Configuration)'=='Release'">
|
||||
|
|
|
|||
|
|
@ -23,6 +23,7 @@ namespace Dalamud.Game.ClientState;
|
|||
[ServiceManager.BlockingEarlyLoadedService]
|
||||
public sealed class ClientState : IDisposable, IServiceType
|
||||
{
|
||||
private readonly GameLifecycle lifecycle;
|
||||
private readonly ClientStateAddressResolver address;
|
||||
private readonly Hook<SetupTerritoryTypeDelegate> setupTerritoryTypeHook;
|
||||
|
||||
|
|
@ -36,8 +37,9 @@ public sealed class ClientState : IDisposable, IServiceType
|
|||
private bool lastFramePvP = false;
|
||||
|
||||
[ServiceManager.ServiceConstructor]
|
||||
private ClientState(SigScanner sigScanner, DalamudStartInfo startInfo)
|
||||
private ClientState(SigScanner sigScanner, DalamudStartInfo startInfo, GameLifecycle lifecycle)
|
||||
{
|
||||
this.lifecycle = lifecycle;
|
||||
this.address = new ClientStateAddressResolver();
|
||||
this.address.Setup(sigScanner);
|
||||
|
||||
|
|
@ -174,6 +176,8 @@ public sealed class ClientState : IDisposable, IServiceType
|
|||
this.IsLoggedIn = true;
|
||||
this.Login?.InvokeSafely(this, null);
|
||||
gameGui.ResetUiHideState();
|
||||
|
||||
this.lifecycle.ResetLogout();
|
||||
}
|
||||
|
||||
if (!condition.Any() && this.lastConditionNone == false)
|
||||
|
|
@ -183,6 +187,8 @@ public sealed class ClientState : IDisposable, IServiceType
|
|||
this.IsLoggedIn = false;
|
||||
this.Logout?.InvokeSafely(this, null);
|
||||
gameGui.ResetUiHideState();
|
||||
|
||||
this.lifecycle.SetLogout();
|
||||
}
|
||||
|
||||
this.IsPvP = GameMain.IsInPvPArea();
|
||||
|
|
|
|||
|
|
@ -25,6 +25,8 @@ namespace Dalamud.Game;
|
|||
[ServiceManager.BlockingEarlyLoadedService]
|
||||
public sealed class Framework : IDisposable, IServiceType
|
||||
{
|
||||
private readonly GameLifecycle lifecycle;
|
||||
|
||||
private static Stopwatch statsStopwatch = new();
|
||||
|
||||
private readonly Stopwatch updateStopwatch = new();
|
||||
|
|
@ -41,10 +43,11 @@ public sealed class Framework : IDisposable, IServiceType
|
|||
|
||||
[ServiceManager.ServiceDependency]
|
||||
private readonly DalamudConfiguration configuration = Service<DalamudConfiguration>.Get();
|
||||
|
||||
|
||||
[ServiceManager.ServiceConstructor]
|
||||
private Framework(SigScanner sigScanner)
|
||||
private Framework(SigScanner sigScanner, GameLifecycle lifecycle)
|
||||
{
|
||||
this.lifecycle = lifecycle;
|
||||
this.hitchDetector = new HitchDetector("FrameworkUpdate", this.configuration.FrameworkUpdateHitch);
|
||||
|
||||
this.Address = new FrameworkAddressResolver();
|
||||
|
|
@ -489,6 +492,10 @@ public sealed class Framework : IDisposable, IServiceType
|
|||
this.IsFrameworkUnloading = true;
|
||||
this.DispatchUpdateEvents = false;
|
||||
|
||||
// All the same, for now...
|
||||
this.lifecycle.SetShuttingDown();
|
||||
this.lifecycle.SetUnloading();
|
||||
|
||||
Log.Information("Framework::Destroy!");
|
||||
Service<Dalamud>.Get().Unload();
|
||||
this.RunPendingTickTasks();
|
||||
|
|
|
|||
63
Dalamud/Game/GameLifecycle.cs
Normal file
63
Dalamud/Game/GameLifecycle.cs
Normal file
|
|
@ -0,0 +1,63 @@
|
|||
using System.Threading;
|
||||
|
||||
using Dalamud.IoC;
|
||||
using Dalamud.IoC.Internal;
|
||||
|
||||
namespace Dalamud.Game;
|
||||
|
||||
/// <summary>
|
||||
/// Class offering cancellation tokens for common gameplay events.
|
||||
/// </summary>
|
||||
[PluginInterface]
|
||||
[InterfaceVersion("1.0")]
|
||||
[ServiceManager.BlockingEarlyLoadedService]
|
||||
public class GameLifecycle : IServiceType
|
||||
{
|
||||
private readonly CancellationTokenSource dalamudUnloadCts = new();
|
||||
private readonly CancellationTokenSource gameShutdownCts = new();
|
||||
|
||||
private CancellationTokenSource logoutCts = new();
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="GameLifecycle"/> class.
|
||||
/// </summary>
|
||||
[ServiceManager.ServiceConstructor]
|
||||
internal GameLifecycle()
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets a token that is cancelled when Dalamud is unloading.
|
||||
/// </summary>
|
||||
public CancellationToken DalamudUnloadingToken => this.dalamudUnloadCts.Token;
|
||||
|
||||
/// <summary>
|
||||
/// Gets a token that is cancelled when the game is shutting down.
|
||||
/// </summary>
|
||||
public CancellationToken GameShuttingDownToken => this.gameShutdownCts.Token;
|
||||
|
||||
/// <summary>
|
||||
/// Gets a token that is cancelled when a character is logging out.
|
||||
/// </summary>
|
||||
public CancellationToken LogoutToken => this.logoutCts.Token;
|
||||
|
||||
/// <summary>
|
||||
/// Mark an unload.
|
||||
/// </summary>
|
||||
internal void SetUnloading() => this.dalamudUnloadCts.Cancel();
|
||||
|
||||
/// <summary>
|
||||
/// Mark a shutdown.
|
||||
/// </summary>
|
||||
internal void SetShuttingDown() => this.gameShutdownCts.Cancel();
|
||||
|
||||
/// <summary>
|
||||
/// Mark a logout.
|
||||
/// </summary>
|
||||
internal void SetLogout() => this.logoutCts.Cancel();
|
||||
|
||||
/// <summary>
|
||||
/// Unmark a logout.
|
||||
/// </summary>
|
||||
internal void ResetLogout() => this.logoutCts = new();
|
||||
}
|
||||
|
|
@ -61,6 +61,14 @@ public class SwapChainVtableResolver : BaseAddressResolver, ISwapChainAddressRes
|
|||
{
|
||||
if (processModule.FileName != null && processModule.FileName.EndsWith("game\\dxgi.dll"))
|
||||
{
|
||||
var fileInfo = FileVersionInfo.GetVersionInfo(processModule.FileName);
|
||||
|
||||
if (fileInfo.FileDescription == null)
|
||||
break;
|
||||
|
||||
if (!fileInfo.FileDescription.Contains("GShade") && !fileInfo.FileDescription.Contains("ReShade"))
|
||||
break;
|
||||
|
||||
// reshade master@4232872 RVA
|
||||
// var p = processModule.BaseAddress + 0x82C7E0; // DXGISwapChain::Present
|
||||
// var p = processModule.BaseAddress + 0x82FAC0; // DXGISwapChain::runtime_present
|
||||
|
|
@ -72,8 +80,6 @@ public class SwapChainVtableResolver : BaseAddressResolver, ISwapChainAddressRes
|
|||
|
||||
try
|
||||
{
|
||||
var fileInfo = FileVersionInfo.GetVersionInfo(processModule.FileName);
|
||||
|
||||
// Looks like this sig only works for GShade 4
|
||||
if (fileInfo.FileDescription?.Contains("GShade 4.") == true)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -5,6 +5,7 @@ using System.Diagnostics.CodeAnalysis;
|
|||
using System.Numerics;
|
||||
|
||||
using Dalamud.Game.ClientState.Keys;
|
||||
using Dalamud.Interface.Raii;
|
||||
using ImGuiNET;
|
||||
using ImGuiScene;
|
||||
|
||||
|
|
@ -161,9 +162,10 @@ public static class ImGuiHelpers
|
|||
/// <param name="text">The text to write.</param>
|
||||
public static void SafeTextColoredWrapped(Vector4 color, string text)
|
||||
{
|
||||
ImGui.PushStyleColor(ImGuiCol.Text, color);
|
||||
ImGui.TextWrapped(text.Replace("%", "%%"));
|
||||
ImGui.PopStyleColor();
|
||||
using (ImRaii.PushColor(ImGuiCol.Text, color))
|
||||
{
|
||||
ImGui.TextWrapped(text.Replace("%", "%%"));
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
|
|
|||
|
|
@ -21,6 +21,7 @@ using Dalamud.Interface.Internal.Windows.PluginInstaller;
|
|||
using Dalamud.Interface.Internal.Windows.SelfTest;
|
||||
using Dalamud.Interface.Internal.Windows.Settings;
|
||||
using Dalamud.Interface.Internal.Windows.StyleEditor;
|
||||
using Dalamud.Interface.Raii;
|
||||
using Dalamud.Interface.Style;
|
||||
using Dalamud.Interface.Windowing;
|
||||
using Dalamud.Logging;
|
||||
|
|
@ -538,7 +539,8 @@ internal class DalamudInterface : IDisposable, IServiceType
|
|||
|
||||
private void DrawCreditsDarkeningAnimation()
|
||||
{
|
||||
ImGui.PushStyleVar(ImGuiStyleVar.WindowRounding, 0f);
|
||||
using var style = ImRaii.PushStyle(ImGuiStyleVar.WindowRounding, 0f);
|
||||
|
||||
ImGui.SetNextWindowPos(new Vector2(0, 0));
|
||||
ImGui.SetNextWindowSize(ImGuiHelpers.MainViewport.Size);
|
||||
ImGuiHelpers.ForceNextWindowMainViewport();
|
||||
|
|
@ -552,8 +554,6 @@ internal class DalamudInterface : IDisposable, IServiceType
|
|||
ImGuiWindowFlags.NoResize | ImGuiWindowFlags.NoFocusOnAppearing | ImGuiWindowFlags.NoBringToFrontOnFocus |
|
||||
ImGuiWindowFlags.NoNav);
|
||||
ImGui.End();
|
||||
|
||||
ImGui.PopStyleVar();
|
||||
}
|
||||
|
||||
private void DrawHiddenDevMenuOpener()
|
||||
|
|
@ -562,18 +562,17 @@ internal class DalamudInterface : IDisposable, IServiceType
|
|||
|
||||
if (!this.isImGuiDrawDevMenu && !condition.Any())
|
||||
{
|
||||
ImGui.PushStyleColor(ImGuiCol.Button, Vector4.Zero);
|
||||
ImGui.PushStyleColor(ImGuiCol.ButtonActive, Vector4.Zero);
|
||||
ImGui.PushStyleColor(ImGuiCol.ButtonHovered, Vector4.Zero);
|
||||
ImGui.PushStyleColor(ImGuiCol.TextSelectedBg, new Vector4(0, 0, 0, 1));
|
||||
ImGui.PushStyleColor(ImGuiCol.Border, new Vector4(0, 0, 0, 1));
|
||||
ImGui.PushStyleColor(ImGuiCol.BorderShadow, new Vector4(0, 0, 0, 1));
|
||||
ImGui.PushStyleColor(ImGuiCol.WindowBg, new Vector4(0, 0, 0, 1));
|
||||
using var color = ImRaii.PushColor(ImGuiCol.Button, Vector4.Zero);
|
||||
color.Push(ImGuiCol.ButtonActive, Vector4.Zero);
|
||||
color.Push(ImGuiCol.ButtonHovered, Vector4.Zero);
|
||||
color.Push(ImGuiCol.TextSelectedBg, new Vector4(0, 0, 0, 1));
|
||||
color.Push(ImGuiCol.Border, new Vector4(0, 0, 0, 1));
|
||||
color.Push(ImGuiCol.BorderShadow, new Vector4(0, 0, 0, 1));
|
||||
color.Push(ImGuiCol.WindowBg, new Vector4(0, 0, 0, 1));
|
||||
|
||||
ImGui.PushStyleVar(ImGuiStyleVar.WindowPadding, Vector2.Zero);
|
||||
ImGui.PushStyleVar(ImGuiStyleVar.FramePadding, Vector2.Zero);
|
||||
ImGui.PushStyleVar(ImGuiStyleVar.WindowBorderSize, 0);
|
||||
ImGui.PushStyleVar(ImGuiStyleVar.FrameBorderSize, 0);
|
||||
using var style = ImRaii.PushStyle(ImGuiStyleVar.WindowPadding, Vector2.Zero);
|
||||
style.Push(ImGuiStyleVar.WindowBorderSize, 0);
|
||||
style.Push(ImGuiStyleVar.FrameBorderSize, 0);
|
||||
|
||||
var windowPos = ImGui.GetMainViewport().Pos + new Vector2(20);
|
||||
ImGui.SetNextWindowPos(windowPos, ImGuiCond.Always);
|
||||
|
|
@ -605,9 +604,6 @@ internal class DalamudInterface : IDisposable, IServiceType
|
|||
|
||||
ImGui.End();
|
||||
}
|
||||
|
||||
ImGui.PopStyleVar(4);
|
||||
ImGui.PopStyleColor(7);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -775,6 +771,12 @@ internal class DalamudInterface : IDisposable, IServiceType
|
|||
}
|
||||
}
|
||||
|
||||
if (ImGui.MenuItem("Report crashes at shutdown", null, configuration.ReportShutdownCrashes))
|
||||
{
|
||||
configuration.ReportShutdownCrashes = !configuration.ReportShutdownCrashes;
|
||||
configuration.QueueSave();
|
||||
}
|
||||
|
||||
ImGui.Separator();
|
||||
|
||||
if (ImGui.MenuItem("Open Dalamud branch switcher"))
|
||||
|
|
|
|||
|
|
@ -21,6 +21,14 @@ public class DalamudTextureWrap : TextureWrap
|
|||
this.wrappedWrap = wrappingWrap;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Finalizes an instance of the <see cref="DalamudTextureWrap"/> class.
|
||||
/// </summary>
|
||||
~DalamudTextureWrap()
|
||||
{
|
||||
this.Dispose(false);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the ImGui handle of the texture.
|
||||
/// </summary>
|
||||
|
|
@ -41,7 +49,8 @@ public class DalamudTextureWrap : TextureWrap
|
|||
/// </summary>
|
||||
public void Dispose()
|
||||
{
|
||||
Service<InterfaceManager>.Get().EnqueueDeferredDispose(this);
|
||||
this.Dispose(true);
|
||||
GC.SuppressFinalize(this);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
|
@ -51,4 +60,12 @@ public class DalamudTextureWrap : TextureWrap
|
|||
{
|
||||
this.wrappedWrap.Dispose();
|
||||
}
|
||||
|
||||
private void Dispose(bool disposing)
|
||||
{
|
||||
if (disposing)
|
||||
{
|
||||
Service<InterfaceManager>.GetNullable()?.EnqueueDeferredDispose(this);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -606,12 +606,16 @@ internal class InterfaceManager : IDisposable, IServiceType
|
|||
|
||||
this.RenderImGui();
|
||||
|
||||
foreach (var texture in this.deferredDisposeTextures)
|
||||
if (this.deferredDisposeTextures.Count > 0)
|
||||
{
|
||||
texture.RealDispose();
|
||||
}
|
||||
Log.Verbose("[IM] Disposing {Count} textures", this.deferredDisposeTextures.Count);
|
||||
foreach (var texture in this.deferredDisposeTextures)
|
||||
{
|
||||
texture.RealDispose();
|
||||
}
|
||||
|
||||
this.deferredDisposeTextures.Clear();
|
||||
this.deferredDisposeTextures.Clear();
|
||||
}
|
||||
|
||||
return this.presentHook.Original(swapChain, syncInterval, presentFlags);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -348,46 +348,46 @@ internal class PluginInstallerWindow : Window, IDisposable
|
|||
ImGuiHelpers.CenteredText("Installing plugin...");
|
||||
break;
|
||||
case LoadingIndicatorKind.Manager:
|
||||
{
|
||||
if (pluginManager.PluginsReady && !pluginManager.ReposReady)
|
||||
{
|
||||
ImGuiHelpers.CenteredText("Loading repositories...");
|
||||
}
|
||||
else if (!pluginManager.PluginsReady && pluginManager.ReposReady)
|
||||
{
|
||||
ImGuiHelpers.CenteredText("Loading installed plugins...");
|
||||
}
|
||||
else
|
||||
{
|
||||
ImGuiHelpers.CenteredText("Loading repositories and plugins...");
|
||||
}
|
||||
if (pluginManager.PluginsReady && !pluginManager.ReposReady)
|
||||
{
|
||||
ImGuiHelpers.CenteredText("Loading repositories...");
|
||||
}
|
||||
else if (!pluginManager.PluginsReady && pluginManager.ReposReady)
|
||||
{
|
||||
ImGuiHelpers.CenteredText("Loading installed plugins...");
|
||||
}
|
||||
else
|
||||
{
|
||||
ImGuiHelpers.CenteredText("Loading repositories and plugins...");
|
||||
}
|
||||
|
||||
var currentProgress = 0;
|
||||
var total = 0;
|
||||
var currentProgress = 0;
|
||||
var total = 0;
|
||||
|
||||
var pendingRepos = pluginManager.Repos.ToArray()
|
||||
.Where(x => (x.State != PluginRepositoryState.Success &&
|
||||
x.State != PluginRepositoryState.Fail) &&
|
||||
x.IsEnabled)
|
||||
.ToArray();
|
||||
var allRepoCount =
|
||||
pluginManager.Repos.Count(x => x.State != PluginRepositoryState.Fail && x.IsEnabled);
|
||||
var pendingRepos = pluginManager.Repos.ToArray()
|
||||
.Where(x => (x.State != PluginRepositoryState.Success &&
|
||||
x.State != PluginRepositoryState.Fail) &&
|
||||
x.IsEnabled)
|
||||
.ToArray();
|
||||
var allRepoCount =
|
||||
pluginManager.Repos.Count(x => x.State != PluginRepositoryState.Fail && x.IsEnabled);
|
||||
|
||||
foreach (var repo in pendingRepos)
|
||||
{
|
||||
ImGuiHelpers.CenteredText($"{repo.PluginMasterUrl}: {repo.State}");
|
||||
foreach (var repo in pendingRepos)
|
||||
{
|
||||
ImGuiHelpers.CenteredText($"{repo.PluginMasterUrl}: {repo.State}");
|
||||
}
|
||||
|
||||
currentProgress += allRepoCount - pendingRepos.Length;
|
||||
total += allRepoCount;
|
||||
|
||||
if (currentProgress != total)
|
||||
{
|
||||
ImGui.SetCursorPosX(windowSize.X / 3);
|
||||
ImGui.ProgressBar(currentProgress / (float)total, new Vector2(windowSize.X / 3, 50));
|
||||
}
|
||||
}
|
||||
|
||||
currentProgress += allRepoCount - pendingRepos.Length;
|
||||
total += allRepoCount;
|
||||
|
||||
if (currentProgress != total)
|
||||
{
|
||||
ImGui.SetCursorPosX(windowSize.X / 3);
|
||||
ImGui.ProgressBar(currentProgress / (float)total, new Vector2(windowSize.X / 3, 50));
|
||||
}
|
||||
}
|
||||
|
||||
break;
|
||||
default:
|
||||
throw new ArgumentOutOfRangeException();
|
||||
|
|
@ -2199,9 +2199,12 @@ internal class PluginInstallerWindow : Window, IDisposable
|
|||
ImGui.TextColored(ImGuiColors.DalamudGrey3, downloadText);
|
||||
|
||||
var isThirdParty = manifest.IsThirdParty;
|
||||
var canFeedback = !isThirdParty && !plugin.IsDev &&
|
||||
var canFeedback = !isThirdParty &&
|
||||
!plugin.IsDev &&
|
||||
!plugin.IsOrphaned &&
|
||||
plugin.Manifest.DalamudApiLevel == PluginManager.DalamudApiLevel &&
|
||||
plugin.Manifest.AcceptsFeedback && availablePluginUpdate == default;
|
||||
plugin.Manifest.AcceptsFeedback &&
|
||||
availablePluginUpdate == default;
|
||||
|
||||
// Installed from
|
||||
if (plugin.IsDev)
|
||||
|
|
|
|||
|
|
@ -5,6 +5,7 @@ using CheapLoc;
|
|||
using Dalamud.Configuration.Internal;
|
||||
using Dalamud.Interface.Colors;
|
||||
using Dalamud.Interface.Internal.Windows.Settings.Tabs;
|
||||
using Dalamud.Interface.Raii;
|
||||
using Dalamud.Interface.Windowing;
|
||||
using Dalamud.Plugin.Internal;
|
||||
using Dalamud.Utility;
|
||||
|
|
@ -159,33 +160,27 @@ internal class SettingsWindow : Window
|
|||
|
||||
if (ImGui.BeginChild("###settingsFinishButton"))
|
||||
{
|
||||
ImGui.PushStyleVar(ImGuiStyleVar.FrameRounding, 100f);
|
||||
ImGui.PushFont(InterfaceManager.IconFont);
|
||||
using var disabled = ImRaii.Disabled(this.tabs.Any(x => x.Entries.Any(y => !y.IsValid)));
|
||||
|
||||
var invalid = this.tabs.Any(x => x.Entries.Any(y => !y.IsValid));
|
||||
if (invalid)
|
||||
ImGui.BeginDisabled();
|
||||
|
||||
if (ImGui.Button(FontAwesomeIcon.Save.ToIconString(), new Vector2(40)))
|
||||
using (ImRaii.PushStyle(ImGuiStyleVar.FrameRounding, 100f))
|
||||
{
|
||||
this.Save();
|
||||
using var font = ImRaii.PushFont(InterfaceManager.IconFont);
|
||||
|
||||
if (!ImGui.IsKeyDown(ImGuiKey.ModShift))
|
||||
this.IsOpen = false;
|
||||
if (ImGui.Button(FontAwesomeIcon.Save.ToIconString(), new Vector2(40)))
|
||||
{
|
||||
this.Save();
|
||||
|
||||
if (!ImGui.IsKeyDown(ImGuiKey.ModShift))
|
||||
this.IsOpen = false;
|
||||
}
|
||||
}
|
||||
|
||||
ImGui.PopStyleVar();
|
||||
ImGui.PopFont();
|
||||
|
||||
if (ImGui.IsItemHovered())
|
||||
{
|
||||
ImGui.SetTooltip(!ImGui.IsKeyDown(ImGuiKey.ModShift)
|
||||
? Loc.Localize("DalamudSettingsSaveAndExit", "Save changes and close")
|
||||
: Loc.Localize("DalamudSettingsSaveAndExit", "Save changes"));
|
||||
}
|
||||
|
||||
if (invalid)
|
||||
ImGui.EndDisabled();
|
||||
}
|
||||
|
||||
ImGui.EndChild();
|
||||
|
|
|
|||
|
|
@ -8,6 +8,7 @@ using System.Numerics;
|
|||
using CheapLoc;
|
||||
using Dalamud.Game.Gui;
|
||||
using Dalamud.Interface.GameFonts;
|
||||
using Dalamud.Interface.Raii;
|
||||
using Dalamud.Plugin.Internal;
|
||||
using Dalamud.Utility;
|
||||
using FFXIVClientStructs.FFXIV.Client.Game.UI;
|
||||
|
|
@ -243,46 +244,45 @@ Contribute at: https://github.com/goatcorp/Dalamud
|
|||
this.resetNow = false;
|
||||
}
|
||||
|
||||
ImGui.PushStyleVar(ImGuiStyleVar.ItemSpacing, Vector2.Zero);
|
||||
|
||||
ImGuiHelpers.ScaledDummy(0, windowSize.Y + 20f);
|
||||
ImGui.Text(string.Empty);
|
||||
|
||||
const float imageSize = 190f;
|
||||
ImGui.SameLine((ImGui.GetWindowWidth() / 2) - (imageSize / 2));
|
||||
ImGui.Image(this.logoTexture.ImGuiHandle, ImGuiHelpers.ScaledVector2(imageSize));
|
||||
|
||||
ImGuiHelpers.ScaledDummy(0, 20f);
|
||||
|
||||
var windowX = ImGui.GetWindowSize().X;
|
||||
|
||||
foreach (var creditsLine in this.creditsText.Split(new[] { "\r\n", "\r", "\n" }, StringSplitOptions.None))
|
||||
using (ImRaii.PushStyle(ImGuiStyleVar.ItemSpacing, Vector2.Zero))
|
||||
{
|
||||
var lineLenX = ImGui.CalcTextSize(creditsLine).X;
|
||||
ImGuiHelpers.ScaledDummy(0, windowSize.Y + 20f);
|
||||
ImGui.Text(string.Empty);
|
||||
|
||||
ImGui.Dummy(new Vector2((windowX / 2) - (lineLenX / 2), 0f));
|
||||
ImGui.SameLine();
|
||||
ImGui.TextUnformatted(creditsLine);
|
||||
const float imageSize = 190f;
|
||||
ImGui.SameLine((ImGui.GetWindowWidth() / 2) - (imageSize / 2));
|
||||
ImGui.Image(this.logoTexture.ImGuiHandle, ImGuiHelpers.ScaledVector2(imageSize));
|
||||
|
||||
ImGuiHelpers.ScaledDummy(0, 20f);
|
||||
|
||||
var windowX = ImGui.GetWindowSize().X;
|
||||
|
||||
foreach (var creditsLine in this.creditsText.Split(new[] { "\r\n", "\r", "\n" }, StringSplitOptions.None))
|
||||
{
|
||||
var lineLenX = ImGui.CalcTextSize(creditsLine).X;
|
||||
|
||||
ImGui.Dummy(new Vector2((windowX / 2) - (lineLenX / 2), 0f));
|
||||
ImGui.SameLine();
|
||||
ImGui.TextUnformatted(creditsLine);
|
||||
}
|
||||
|
||||
ImGuiHelpers.ScaledDummy(0, 40f);
|
||||
|
||||
if (this.thankYouFont != null)
|
||||
{
|
||||
ImGui.PushFont(this.thankYouFont.ImFont);
|
||||
var thankYouLenX = ImGui.CalcTextSize(ThankYouText).X;
|
||||
|
||||
ImGui.Dummy(new Vector2((windowX / 2) - (thankYouLenX / 2), 0f));
|
||||
ImGui.SameLine();
|
||||
ImGui.TextUnformatted(ThankYouText);
|
||||
|
||||
ImGui.PopFont();
|
||||
}
|
||||
|
||||
ImGuiHelpers.ScaledDummy(0, windowSize.Y + 50f);
|
||||
}
|
||||
|
||||
ImGuiHelpers.ScaledDummy(0, 40f);
|
||||
|
||||
if (this.thankYouFont != null)
|
||||
{
|
||||
ImGui.PushFont(this.thankYouFont.ImFont);
|
||||
var thankYouLenX = ImGui.CalcTextSize(ThankYouText).X;
|
||||
|
||||
ImGui.Dummy(new Vector2((windowX / 2) - (thankYouLenX / 2), 0f));
|
||||
ImGui.SameLine();
|
||||
ImGui.TextUnformatted(ThankYouText);
|
||||
|
||||
ImGui.PopFont();
|
||||
}
|
||||
|
||||
ImGuiHelpers.ScaledDummy(0, windowSize.Y + 50f);
|
||||
|
||||
ImGui.PopStyleVar();
|
||||
|
||||
if (this.creditsThrottler.Elapsed.TotalMilliseconds > (1000.0f / CreditFps))
|
||||
{
|
||||
var curY = ImGui.GetScrollY();
|
||||
|
|
|
|||
|
|
@ -27,7 +27,8 @@ public class SettingsTabGeneral : SettingsTab
|
|||
return Loc.Localize("DalamudSettingsChannelNone", "Do not pick \"None\".");
|
||||
|
||||
return null;
|
||||
}),
|
||||
},
|
||||
fallbackValue: XivChatType.Debug),
|
||||
|
||||
new GapSettingsEntry(5),
|
||||
|
||||
|
|
|
|||
|
|
@ -10,6 +10,7 @@ using Dalamud.Configuration;
|
|||
using Dalamud.Configuration.Internal;
|
||||
using Dalamud.Interface.Colors;
|
||||
using Dalamud.Interface.Components;
|
||||
using Dalamud.Interface.Raii;
|
||||
using Dalamud.Plugin.Internal;
|
||||
using ImGuiNET;
|
||||
|
||||
|
|
@ -57,10 +58,11 @@ public class DevPluginsSettingsEntry : SettingsEntry
|
|||
ImGui.Text(this.Name);
|
||||
if (this.devPluginLocationsChanged)
|
||||
{
|
||||
ImGui.PushStyleColor(ImGuiCol.Text, ImGuiColors.HealerGreen);
|
||||
ImGui.SameLine();
|
||||
ImGui.Text(Loc.Localize("DalamudSettingsChanged", "(Changed)"));
|
||||
ImGui.PopStyleColor();
|
||||
using (ImRaii.PushColor(ImGuiCol.Text, ImGuiColors.HealerGreen))
|
||||
{
|
||||
ImGui.SameLine();
|
||||
ImGui.Text(Loc.Localize("DalamudSettingsChanged", "(Changed)"));
|
||||
}
|
||||
}
|
||||
|
||||
ImGuiHelpers.SafeTextColoredWrapped(ImGuiColors.DalamudGrey, Loc.Localize("DalamudSettingsDevPluginLocationsHint", "Add additional dev plugin load locations.\nThese can be either the directory or DLL path."));
|
||||
|
|
|
|||
|
|
@ -7,6 +7,7 @@ using System.Linq;
|
|||
using Dalamud.Configuration.Internal;
|
||||
|
||||
using Dalamud.Interface.Colors;
|
||||
using Dalamud.Interface.Raii;
|
||||
using Dalamud.Utility;
|
||||
using ImGuiNET;
|
||||
|
||||
|
|
@ -20,8 +21,10 @@ internal sealed class SettingsEntry<T> : SettingsEntry
|
|||
private readonly Action<T?>? change;
|
||||
|
||||
private object? valueBacking;
|
||||
private object? fallbackValue;
|
||||
|
||||
public SettingsEntry(string name, string description, LoadSettingDelegate load, SaveSettingDelegate save, Action<T?>? change = null, Func<T?, string?>? warning = null, Func<T?, string?>? validity = null, Func<bool>? visibility = null)
|
||||
public SettingsEntry(string name, string description, LoadSettingDelegate load, SaveSettingDelegate save, Action<T?>? change = null, Func<T?, string?>? warning = null, Func<T?, string?>? validity = null, Func<bool>? visibility = null,
|
||||
object? fallbackValue = null)
|
||||
{
|
||||
this.load = load;
|
||||
this.save = save;
|
||||
|
|
@ -31,6 +34,8 @@ internal sealed class SettingsEntry<T> : SettingsEntry
|
|||
this.CheckWarning = warning;
|
||||
this.CheckValidity = validity;
|
||||
this.CheckVisibility = visibility;
|
||||
|
||||
this.fallbackValue = fallbackValue;
|
||||
}
|
||||
|
||||
public delegate T? LoadSettingDelegate(DalamudConfiguration config);
|
||||
|
|
@ -97,6 +102,12 @@ internal sealed class SettingsEntry<T> : SettingsEntry
|
|||
var descriptions =
|
||||
values.Cast<Enum>().ToDictionary(x => x, x => x.GetAttribute<SettingsAnnotationAttribute>() ?? new SettingsAnnotationAttribute(x.ToString(), string.Empty));
|
||||
|
||||
if (!descriptions.ContainsKey(idx))
|
||||
{
|
||||
idx = (Enum)this.fallbackValue ?? throw new Exception("No fallback value for enum");
|
||||
this.valueBacking = idx;
|
||||
}
|
||||
|
||||
if (ImGui.BeginCombo($"###{this.Id.ToString()}", descriptions[idx].FriendlyName))
|
||||
{
|
||||
foreach (Enum value in values)
|
||||
|
|
@ -111,9 +122,10 @@ internal sealed class SettingsEntry<T> : SettingsEntry
|
|||
}
|
||||
}
|
||||
|
||||
ImGui.PushStyleColor(ImGuiCol.Text, ImGuiColors.DalamudGrey);
|
||||
ImGuiHelpers.SafeTextWrapped(this.Description);
|
||||
ImGui.PopStyleColor();
|
||||
using (ImRaii.PushColor(ImGuiCol.Text, ImGuiColors.DalamudGrey))
|
||||
{
|
||||
ImGuiHelpers.SafeTextWrapped(this.Description);
|
||||
}
|
||||
|
||||
if (this.CheckValidity != null)
|
||||
{
|
||||
|
|
@ -122,9 +134,10 @@ internal sealed class SettingsEntry<T> : SettingsEntry
|
|||
|
||||
if (!this.IsValid)
|
||||
{
|
||||
ImGui.PushStyleColor(ImGuiCol.Text, ImGuiColors.DalamudRed);
|
||||
ImGui.Text(validityMsg);
|
||||
ImGui.PopStyleColor();
|
||||
using (ImRaii.PushColor(ImGuiCol.Text, ImGuiColors.DalamudRed))
|
||||
{
|
||||
ImGui.Text(validityMsg);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
|
|
@ -136,9 +149,10 @@ internal sealed class SettingsEntry<T> : SettingsEntry
|
|||
|
||||
if (warningMessage != null)
|
||||
{
|
||||
ImGui.PushStyleColor(ImGuiCol.Text, ImGuiColors.DalamudRed);
|
||||
ImGui.Text(warningMessage);
|
||||
ImGui.PopStyleColor();
|
||||
using (ImRaii.PushColor(ImGuiCol.Text, ImGuiColors.DalamudRed))
|
||||
{
|
||||
ImGui.Text(warningMessage);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -10,6 +10,7 @@ using Dalamud.Configuration;
|
|||
using Dalamud.Configuration.Internal;
|
||||
using Dalamud.Interface.Colors;
|
||||
using Dalamud.Interface.Components;
|
||||
using Dalamud.Interface.Raii;
|
||||
using Dalamud.Plugin.Internal;
|
||||
using ImGuiNET;
|
||||
|
||||
|
|
@ -53,10 +54,11 @@ public class ThirdRepoSettingsEntry : SettingsEntry
|
|||
ImGui.Text(Loc.Localize("DalamudSettingsCustomRepo", "Custom Plugin Repositories"));
|
||||
if (this.thirdRepoListChanged)
|
||||
{
|
||||
ImGui.PushStyleColor(ImGuiCol.Text, ImGuiColors.HealerGreen);
|
||||
ImGui.SameLine();
|
||||
ImGui.Text(Loc.Localize("DalamudSettingsChanged", "(Changed)"));
|
||||
ImGui.PopStyleColor();
|
||||
using (ImRaii.PushColor(ImGuiCol.Text, ImGuiColors.HealerGreen))
|
||||
{
|
||||
ImGui.SameLine();
|
||||
ImGui.Text(Loc.Localize("DalamudSettingsChanged", "(Changed)"));
|
||||
}
|
||||
}
|
||||
|
||||
ImGuiHelpers.SafeTextColoredWrapped(ImGuiColors.DalamudGrey, Loc.Localize("DalamudSettingCustomRepoHint", "Add custom plugin repositories."));
|
||||
|
|
|
|||
|
|
@ -9,6 +9,7 @@ using Dalamud.Game;
|
|||
using Dalamud.Game.ClientState;
|
||||
using Dalamud.Game.Gui;
|
||||
using Dalamud.Interface.Animation.EasingFunctions;
|
||||
using Dalamud.Interface.Raii;
|
||||
using Dalamud.Interface.Windowing;
|
||||
using ImGuiNET;
|
||||
using ImGuiScene;
|
||||
|
|
@ -169,23 +170,22 @@ internal class TitleScreenMenuWindow : Window, IDisposable
|
|||
|
||||
this.fadeOutEasing.Update();
|
||||
|
||||
ImGui.PushStyleVar(ImGuiStyleVar.Alpha, (float)this.fadeOutEasing.Value);
|
||||
|
||||
for (var i = 0; i < tsm.Entries.Count; i++)
|
||||
using (ImRaii.PushStyle(ImGuiStyleVar.Alpha, (float)this.fadeOutEasing.Value))
|
||||
{
|
||||
var entry = tsm.Entries[i];
|
||||
for (var i = 0; i < tsm.Entries.Count; i++)
|
||||
{
|
||||
var entry = tsm.Entries[i];
|
||||
|
||||
var finalPos = (i + 1) * this.shadeTexture.Height * scale;
|
||||
var finalPos = (i + 1) * this.shadeTexture.Height * scale;
|
||||
|
||||
this.DrawEntry(entry, i != 0, true, i == 0, false, false);
|
||||
this.DrawEntry(entry, i != 0, true, i == 0, false, false);
|
||||
|
||||
var cursor = ImGui.GetCursorPos();
|
||||
cursor.Y = finalPos;
|
||||
ImGui.SetCursorPos(cursor);
|
||||
var cursor = ImGui.GetCursorPos();
|
||||
cursor.Y = finalPos;
|
||||
ImGui.SetCursorPos(cursor);
|
||||
}
|
||||
}
|
||||
|
||||
ImGui.PopStyleVar();
|
||||
|
||||
var isHover = ImGui.IsWindowHovered(ImGuiHoveredFlags.RootAndChildWindows |
|
||||
ImGuiHoveredFlags.AllowWhenBlockedByActiveItem);
|
||||
|
||||
|
|
@ -254,9 +254,11 @@ internal class TitleScreenMenuWindow : Window, IDisposable
|
|||
|
||||
var initialCursor = ImGui.GetCursorPos();
|
||||
|
||||
ImGui.PushStyleVar(ImGuiStyleVar.Alpha, (float)shadeEasing.Value);
|
||||
ImGui.Image(this.shadeTexture.ImGuiHandle, new Vector2(this.shadeTexture.Width * scale, this.shadeTexture.Height * scale));
|
||||
ImGui.PopStyleVar();
|
||||
|
||||
using (ImRaii.PushStyle(ImGuiStyleVar.Alpha, (float)shadeEasing.Value))
|
||||
{
|
||||
ImGui.Image(this.shadeTexture.ImGuiHandle, new Vector2(this.shadeTexture.Width * scale, this.shadeTexture.Height * scale));
|
||||
}
|
||||
|
||||
var isHover = ImGui.IsItemHovered();
|
||||
if (isHover && (!shadeEasing.IsRunning || (shadeEasing.IsDone && shadeEasing.IsInverse)) && !inhibitFadeout)
|
||||
|
|
@ -331,15 +333,15 @@ internal class TitleScreenMenuWindow : Window, IDisposable
|
|||
}
|
||||
|
||||
// Drop shadow
|
||||
ImGui.PushStyleColor(ImGuiCol.Text, 0xFF000000);
|
||||
for (int i = 0, i_ = (int)Math.Ceiling(1 * scale); i < i_; i++)
|
||||
using (ImRaii.PushColor(ImGuiCol.Text, 0xFF000000))
|
||||
{
|
||||
ImGui.SetCursorPos(new Vector2(cursor.X, cursor.Y + i));
|
||||
ImGui.Text(entry.Name);
|
||||
for (int i = 0, i_ = (int)Math.Ceiling(1 * scale); i < i_; i++)
|
||||
{
|
||||
ImGui.SetCursorPos(new Vector2(cursor.X, cursor.Y + i));
|
||||
ImGui.Text(entry.Name);
|
||||
}
|
||||
}
|
||||
|
||||
ImGui.PopStyleColor();
|
||||
|
||||
ImGui.SetCursorPos(cursor);
|
||||
ImGui.Text(entry.Name);
|
||||
|
||||
|
|
|
|||
|
|
@ -251,7 +251,7 @@ Thanks and have fun!";
|
|||
new TextPayload(" ["),
|
||||
new UIForegroundPayload(500),
|
||||
this.openInstallerWindowPluginChangelogsLink,
|
||||
new TextPayload(Loc.Localize("DalamudInstallerPluginChangelogHelp", "Open plugin changelogs") + " "),
|
||||
new TextPayload(Loc.Localize("DalamudInstallerPluginChangelogHelp", "Open plugin changelogs")),
|
||||
RawPayload.LinkTerminator,
|
||||
new UIForegroundPayload(0),
|
||||
new TextPayload("]"),
|
||||
|
|
@ -262,13 +262,13 @@ Thanks and have fun!";
|
|||
{
|
||||
if (metadata.WasUpdated)
|
||||
{
|
||||
chatGui.Print(Locs.DalamudPluginUpdateSuccessful(metadata.Name, metadata.Version) + (metadata.HasChangelog ? " " : string.Empty));
|
||||
chatGui.Print(Locs.DalamudPluginUpdateSuccessful(metadata.Name, metadata.Version));
|
||||
}
|
||||
else
|
||||
{
|
||||
chatGui.PrintChat(new XivChatEntry
|
||||
{
|
||||
Message = Locs.DalamudPluginUpdateFailed(metadata.Name, metadata.Version) + (metadata.HasChangelog ? " " : string.Empty),
|
||||
Message = Locs.DalamudPluginUpdateFailed(metadata.Name, metadata.Version),
|
||||
Type = XivChatType.Urgent,
|
||||
});
|
||||
}
|
||||
|
|
|
|||
|
|
@ -739,6 +739,11 @@ int main() {
|
|||
|
||||
std::cout << "Crash triggered" << std::endl;
|
||||
|
||||
auto shutup_mutex = CreateMutex(NULL, false, L"DALAMUD_CRASHES_NO_MORE");
|
||||
bool shutup = false;
|
||||
if (shutup_mutex == NULL && GetLastError() == ERROR_ALREADY_EXISTS)
|
||||
shutup = true;
|
||||
|
||||
/*
|
||||
Hard won wisdom: changing symbol path with SymSetSearchPath() after modules
|
||||
have been loaded (invadeProcess=TRUE in SymInitialize() or SymRefreshModuleList())
|
||||
|
|
@ -795,7 +800,11 @@ int main() {
|
|||
std::wstring dumpError;
|
||||
if (dumpPath.empty()) {
|
||||
std::cout << "Skipping dump path, as log directory has not been specified" << std::endl;
|
||||
} else {
|
||||
} else if (shutup) {
|
||||
std::cout << "Skipping dump, was shutdown" << std::endl;
|
||||
}
|
||||
else
|
||||
{
|
||||
MINIDUMP_EXCEPTION_INFORMATION mdmp_info{};
|
||||
mdmp_info.ThreadId = GetThreadId(exinfo.hThreadHandle);
|
||||
mdmp_info.ExceptionPointers = exinfo.pExceptionPointers;
|
||||
|
|
@ -821,6 +830,10 @@ int main() {
|
|||
std::wostringstream log;
|
||||
log << std::format(L"Unhandled native exception occurred at {}", to_address_string(exinfo.ContextRecord.Rip, false)) << std::endl;
|
||||
log << std::format(L"Code: {:X}", exinfo.ExceptionRecord.ExceptionCode) << std::endl;
|
||||
|
||||
if (shutup)
|
||||
log << L"======= Crash handler was globally muted(shutdown?) =======" << std::endl;
|
||||
|
||||
if (dumpPath.empty())
|
||||
log << L"Dump skipped" << std::endl;
|
||||
else if (dumpError.empty())
|
||||
|
|
@ -971,6 +984,11 @@ int main() {
|
|||
submitThread = {};
|
||||
}
|
||||
|
||||
if (shutup) {
|
||||
TerminateProcess(g_hProcess, exinfo.ExceptionRecord.ExceptionCode);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int nButtonPressed = 0, nRadioButton = 0;
|
||||
if (FAILED(TaskDialogIndirect(&config, &nButtonPressed, &nRadioButton, nullptr))) {
|
||||
ResumeThread(exinfo.hThreadHandle);
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue