Merge branch 'net5'

This commit is contained in:
goat 2022-08-17 20:27:45 +02:00
commit bdd7f32c12
No known key found for this signature in database
GPG key ID: 49E2AA8C6A76498B
6 changed files with 135 additions and 36 deletions

View file

@ -24,9 +24,12 @@
PVOID g_veh_handle = nullptr; PVOID g_veh_handle = nullptr;
bool g_veh_do_full_dump = false; bool g_veh_do_full_dump = false;
HANDLE g_crashhandler_process = nullptr; HANDLE g_crashhandler_process = nullptr;
HANDLE g_crashhandler_pipe_write = nullptr; HANDLE g_crashhandler_pipe_write = nullptr;
std::recursive_mutex g_exception_handler_mutex;
std::chrono::time_point<std::chrono::system_clock> g_time_start; std::chrono::time_point<std::chrono::system_clock> g_time_start;
bool is_whitelist_exception(const DWORD code) bool is_whitelist_exception(const DWORD code)
@ -126,8 +129,6 @@ static void append_injector_launch_args(std::vector<std::wstring>& args)
LONG exception_handler(EXCEPTION_POINTERS* ex) LONG exception_handler(EXCEPTION_POINTERS* ex)
{ {
static std::recursive_mutex s_exception_handler_mutex;
if (ex->ExceptionRecord->ExceptionCode == 0x12345678) if (ex->ExceptionRecord->ExceptionCode == 0x12345678)
{ {
// pass // pass
@ -143,7 +144,7 @@ LONG exception_handler(EXCEPTION_POINTERS* ex)
} }
// block any other exceptions hitting the veh while the messagebox is open // block any other exceptions hitting the veh while the messagebox is open
const auto lock = std::lock_guard(s_exception_handler_mutex); const auto lock = std::lock_guard(g_exception_handler_mutex);
exception_info exinfo{}; exception_info exinfo{};
exinfo.pExceptionPointers = ex; exinfo.pExceptionPointers = ex;

View file

@ -8,7 +8,7 @@
</PropertyGroup> </PropertyGroup>
<PropertyGroup Label="Feature"> <PropertyGroup Label="Feature">
<DalamudVersion>6.4.0.42</DalamudVersion> <DalamudVersion>6.4.0.43</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>

View file

@ -44,6 +44,8 @@ namespace Dalamud.Interface.Internal.Windows.PluginInstaller
private readonly List<int> openPluginCollapsibles = new(); private readonly List<int> openPluginCollapsibles = new();
private readonly DateTime timeLoaded;
#region Image Tester State #region Image Tester State
private string[] testerImagePaths = new string[5]; private string[] testerImagePaths = new string[5];
@ -128,6 +130,8 @@ namespace Dalamud.Interface.Internal.Windows.PluginInstaller
this.testerImagePaths[i] = string.Empty; this.testerImagePaths[i] = string.Empty;
} }
}); });
this.timeLoaded = DateTime.Now;
} }
private enum OperationStatus private enum OperationStatus
@ -326,6 +330,15 @@ namespace Dalamud.Interface.Internal.Windows.PluginInstaller
throw new ArgumentOutOfRangeException(); throw new ArgumentOutOfRangeException();
} }
if (DateTime.Now - this.timeLoaded > TimeSpan.FromSeconds(90) && isWaitingManager)
{
ImGui.PushStyleColor(ImGuiCol.Text, ImGuiColors.DalamudRed);
ImGuiHelpers.CenteredText("This is embarrassing, but...");
ImGuiHelpers.CenteredText("one of your plugins may be blocking the installer.");
ImGuiHelpers.CenteredText("You should tell us about this, please keep this window open.");
ImGui.PopStyleColor();
}
ImGui.EndChild(); ImGui.EndChild();
} }
} }
@ -968,6 +981,27 @@ namespace Dalamud.Interface.Internal.Windows.PluginInstaller
return; return;
} }
var pm = Service<PluginManager>.Get();
if (pm.SafeMode)
{
ImGuiHelpers.ScaledDummy(10);
ImGui.PushStyleColor(ImGuiCol.Text, ImGuiColors.DalamudOrange);
ImGui.PushFont(InterfaceManager.IconFont);
ImGuiHelpers.CenteredText(FontAwesomeIcon.ExclamationTriangle.ToIconString());
ImGui.PopFont();
ImGui.PopStyleColor();
var lines = Locs.SafeModeDisclaimer.Split('\n');
foreach (var line in lines)
{
ImGuiHelpers.CenteredText(line);
}
ImGuiHelpers.ScaledDummy(10);
ImGui.Separator();
}
ImGui.PushStyleVar(ImGuiStyleVar.ItemSpacing, ImGuiHelpers.ScaledVector2(1, 3)); ImGui.PushStyleVar(ImGuiStyleVar.ItemSpacing, ImGuiHelpers.ScaledVector2(1, 3));
var groupInfo = this.categoryManager.GroupList[this.categoryManager.CurrentGroupIdx]; var groupInfo = this.categoryManager.GroupList[this.categoryManager.CurrentGroupIdx];
@ -2804,6 +2838,12 @@ namespace Dalamud.Interface.Internal.Windows.PluginInstaller
public static string ErrorModalButton_Ok => Loc.Localize("OK", "OK"); public static string ErrorModalButton_Ok => Loc.Localize("OK", "OK");
#endregion #endregion
#region Other
public static string SafeModeDisclaimer => Loc.Localize("SafeModeDisclaimer", "You enabled safe mode, no plugins will be loaded.\nYou may delete plugins from the \"Installed plugins\" tab.\nSimply restart your game to disable safe mode.");
#endregion
} }
} }
} }

View file

@ -429,84 +429,133 @@ internal partial class PluginManager : IDisposable, IServiceType
} }
} }
void LoadPluginsSync(string logPrefix, IEnumerable<PluginDef> pluginDefsList) async Task LoadPluginsSync(string logPrefix, IEnumerable<PluginDef> pluginDefsList)
{ {
Log.Information("============= LoadPluginsSync START =============");
foreach (var pluginDef in pluginDefsList) foreach (var pluginDef in pluginDefsList)
LoadPluginOnBoot(logPrefix, pluginDef).Wait(); await LoadPluginOnBoot(logPrefix, pluginDef);
Log.Information("============= LoadPluginsSync END =============");
} }
Task LoadPluginsAsync(string logPrefix, IEnumerable<PluginDef> pluginDefsList) Task LoadPluginsAsync(string logPrefix, IEnumerable<PluginDef> pluginDefsList)
{ {
Log.Information("============= LoadPluginsAsync START =============");
return Task.WhenAll( return Task.WhenAll(
pluginDefsList pluginDefsList
.Select(pluginDef => Task.Run(Timings.AttachTimingHandle( .Select(pluginDef => Task.Run(Timings.AttachTimingHandle(
() => LoadPluginOnBoot(logPrefix, pluginDef)))) () => LoadPluginOnBoot(logPrefix, pluginDef))))
.ToArray()); .ToArray()).ContinueWith(t => Log.Information($"============= LoadPluginsAsync END {t.IsCompletedSuccessfully} ============="));
} }
var syncPlugins = pluginDefs.Where(def => def.Manifest?.LoadSync == true).ToList(); var syncPlugins = pluginDefs.Where(def => def.Manifest?.LoadSync == true).ToList();
var asyncPlugins = pluginDefs.Where(def => def.Manifest?.LoadSync != true).ToList(); var asyncPlugins = pluginDefs.Where(def => def.Manifest?.LoadSync != true).ToList();
var loadTasks = new List<Task>(); var loadTasks = new List<Task>();
var tokenSource = new CancellationTokenSource(TimeSpan.FromMinutes(5));
// Load plugins that can be loaded anytime // Load plugins that can be loaded anytime
LoadPluginsSync( LoadPluginsSync(
"AnytimeSync", "AnytimeSync",
syncPlugins.Where(def => def.Manifest?.LoadRequiredState == 2)); syncPlugins.Where(def => def.Manifest?.LoadRequiredState == 2)).GetAwaiter().GetResult();
loadTasks.Add( loadTasks.Add(
LoadPluginsAsync( Task.Run(
"AnytimeAsync", () => LoadPluginsAsync(
asyncPlugins.Where(def => def.Manifest?.LoadRequiredState == 2))); "AnytimeAsync",
asyncPlugins.Where(def => def.Manifest?.LoadRequiredState == 2)),
tokenSource.Token));
// Load plugins that want to be loaded during Framework.Tick // Load plugins that want to be loaded during Framework.Tick
loadTasks.Add( loadTasks.Add(
Service<Framework> Task.Run(
.GetAsync() () => Service<Framework>
.ContinueWith( .GetAsync()
x => x.Result.RunOnTick( .ContinueWith(
() => LoadPluginsSync( x => x.Result.RunOnTick(
"FrameworkTickSync", () => LoadPluginsSync(
syncPlugins.Where(def => def.Manifest?.LoadRequiredState == 1))), "FrameworkTickSync",
TaskContinuationOptions.RunContinuationsAsynchronously) syncPlugins.Where(def => def.Manifest?.LoadRequiredState == 1)),
.Unwrap() cancellationToken: tokenSource.Token),
.ContinueWith( tokenSource.Token,
_ => LoadPluginsAsync( TaskContinuationOptions.RunContinuationsAsynchronously,
"FrameworkTickAsync", TaskScheduler.Default)
asyncPlugins.Where(def => def.Manifest?.LoadRequiredState == 1)), .Unwrap()
TaskContinuationOptions.RunContinuationsAsynchronously) .ContinueWith(
.Unwrap()); _ => LoadPluginsAsync(
"FrameworkTickAsync",
asyncPlugins.Where(def => def.Manifest?.LoadRequiredState == 1)),
tokenSource.Token,
TaskContinuationOptions.RunContinuationsAsynchronously,
TaskScheduler.Default)
.Unwrap(),
tokenSource.Token));
// Load plugins that want to be loaded during Framework.Tick, when drawing facilities are available // Load plugins that want to be loaded during Framework.Tick, when drawing facilities are available
loadTasks.Add( loadTasks.Add(
Service<InterfaceManager.InterfaceManagerWithScene> Task.Run(
() => Service<InterfaceManager.InterfaceManagerWithScene>
.GetAsync() .GetAsync()
.ContinueWith( .ContinueWith(
_ => Service<Framework>.Get().RunOnTick( _ => Service<Framework>.Get().RunOnTick(
() => LoadPluginsSync( () => LoadPluginsSync(
"DrawAvailableSync", "DrawAvailableSync",
syncPlugins.Where(def => def.Manifest?.LoadRequiredState is 0 or null)))) syncPlugins.Where(def => def.Manifest?.LoadRequiredState is 0 or null)),
cancellationToken: tokenSource.Token),
tokenSource.Token)
.Unwrap() .Unwrap()
.ContinueWith( .ContinueWith(
_ => LoadPluginsAsync( _ => LoadPluginsAsync(
"DrawAvailableAsync", "DrawAvailableAsync",
asyncPlugins.Where(def => def.Manifest?.LoadRequiredState is 0 or null))) asyncPlugins.Where(def => def.Manifest?.LoadRequiredState is 0 or null)),
.Unwrap()); tokenSource.Token)
.Unwrap(),
tokenSource.Token));
// Save signatures when all plugins are done loading, successful or not. // Save signatures when all plugins are done loading, successful or not.
_ = Task _ = Task
.WhenAll(loadTasks) .WhenAll(loadTasks)
.ContinueWith( .ContinueWith(
_ => Service<SigScanner>.GetAsync(), t =>
TaskContinuationOptions.RunContinuationsAsynchronously) {
Log.Information("Task.WhenAll continuing");
if (!t.IsCompletedSuccessfully)
{
foreach (var loadTask in loadTasks)
{
if (!loadTask.IsCompletedSuccessfully)
{
if (loadTask.Exception != null)
{
Log.Error(loadTask.Exception, " => Exception during load");
}
else
{
Log.Error($" => Task failed, canceled: {t.IsCanceled} faulted: {t.IsFaulted}");
}
}
}
}
return Service<SigScanner>.GetAsync();
},
tokenSource.Token,
TaskContinuationOptions.RunContinuationsAsynchronously,
TaskScheduler.Default)
.Unwrap() .Unwrap()
.ContinueWith( .ContinueWith(
sigScannerTask => sigScannerTask =>
{ {
Log.Information("sigScannerTask continuing");
this.PluginsReady = true; this.PluginsReady = true;
this.NotifyInstalledPluginsChanged(); this.NotifyInstalledPluginsChanged();
sigScannerTask.Result.Save(); sigScannerTask.Result.Save();
}, },
TaskContinuationOptions.RunContinuationsAsynchronously) tokenSource.Token,
TaskContinuationOptions.RunContinuationsAsynchronously,
TaskScheduler.Default)
.ConfigureAwait(false); .ConfigureAwait(false);
} }

View file

@ -564,10 +564,17 @@ int main() {
config.cRadioButtons = ARRAYSIZE(radios); config.cRadioButtons = ARRAYSIZE(radios);
config.nDefaultRadioButton = IdRadioRestartNormal; config.nDefaultRadioButton = IdRadioRestartNormal;
config.cxWidth = 300; config.cxWidth = 300;
#if _DEBUG
config.pszFooter = (L"" config.pszFooter = (L""
R"aa(<a href="help">Help</a> | <a href="logdir">Open log directory</a> | <a href="logfile">Open log file</a> | <a href="resume">Attempt to resume</a>)aa" R"aa(<a href="help">Help</a> | <a href="logdir">Open log directory</a> | <a href="logfile">Open log file</a> | <a href="resume">Attempt to resume</a>)aa"
); );
#else
config.pszFooter = (L""
R"aa(<a href="help">Help</a> | <a href="logdir">Open log directory</a> | <a href="logfile">Open log file</a>)aa"
);
#endif
// Can't do this, xiv stops pumping messages here // Can't do this, xiv stops pumping messages here
//config.hwndParent = FindWindowA("FFXIVGAME", NULL); //config.hwndParent = FindWindowA("FFXIVGAME", NULL);

View file

@ -58,6 +58,7 @@
<FunctionLevelLinking>true</FunctionLevelLinking> <FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>false</IntrinsicFunctions> <IntrinsicFunctions>false</IntrinsicFunctions>
<PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions> <PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
</ClCompile> </ClCompile>
<Link> <Link>
<EnableCOMDATFolding>false</EnableCOMDATFolding> <EnableCOMDATFolding>false</EnableCOMDATFolding>
@ -69,6 +70,7 @@
<FunctionLevelLinking>true</FunctionLevelLinking> <FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions> <IntrinsicFunctions>true</IntrinsicFunctions>
<PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions> <PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
</ClCompile> </ClCompile>
<Link> <Link>
<EnableCOMDATFolding>true</EnableCOMDATFolding> <EnableCOMDATFolding>true</EnableCOMDATFolding>
@ -91,4 +93,4 @@
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" /> <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets"> <ImportGroup Label="ExtensionTargets">
</ImportGroup> </ImportGroup>
</Project> </Project>