diff --git a/Dalamud/Configuration/DalamudConfiguration.cs b/Dalamud/Configuration/DalamudConfiguration.cs index 752865f51..60c83f8cf 100644 --- a/Dalamud/Configuration/DalamudConfiguration.cs +++ b/Dalamud/Configuration/DalamudConfiguration.cs @@ -31,6 +31,8 @@ namespace Dalamud public Dictionary PluginConfigurations { get; set; } + public bool WelcomeGuideDismissed; + public static DalamudConfiguration Load(string path) { return JsonConvert.DeserializeObject(File.ReadAllText(path)); } diff --git a/Dalamud/Dalamud.cs b/Dalamud/Dalamud.cs index 99b66e01c..d84c426fc 100644 --- a/Dalamud/Dalamud.cs +++ b/Dalamud/Dalamud.cs @@ -97,65 +97,6 @@ namespace Dalamud { } } - private bool isImguiDrawDemoWindow = false; - private bool isImguiDrawWelcome = true; - -#if DEBUG - private bool isImguiDrawDevMenu = true; -#else - private bool isImguiDrawDevMenu = false; -#endif - - private bool neverDrawWelcome = false; - - private void BuildDalamudUi() { - if (this.isImguiDrawDevMenu) { - if (ImGui.BeginMainMenuBar()) { - if (ImGui.BeginMenu("Dalamud DEBUG")) { - if (ImGui.MenuItem("Open Log window")) { - - } - - ImGui.MenuItem("Draw ImGui demo", "", ref this.isImguiDrawDemoWindow); - - ImGui.Separator(); - - if (ImGui.MenuItem("Unload Dalamud")) - { - Unload(); - } - - if (ImGui.MenuItem("Kill game")) - { - Process.GetCurrentProcess().Kill(); - } - } - } - } - - if (this.isImguiDrawDemoWindow) - ImGui.ShowDemoWindow(); - - if (this.isImguiDrawWelcome) { - if (!ImGui.Begin("Welcome to XIVLauncher", ImGuiWindowFlags.Modal | ImGuiWindowFlags.NoCollapse | ImGuiWindowFlags.NoResize)) - { - // Early out if the window is collapsed, as an optimization. - ImGui.End(); - } else { - ImGui.Text($"dalamud says hello. ({this.assemblyVersion})"); - ImGui.Checkbox("Don't show this message again", ref this.neverDrawWelcome); - ImGui.Spacing(); - ImGui.Spacing(); - - if (ImGui.Button("Close")) { - this.isImguiDrawWelcome = false; - } - - ImGui.End(); - } - } - } - public void Start() { Framework.Enable(); @@ -182,6 +123,95 @@ namespace Dalamud { this.WinSock2.Dispose(); } + #region Interface + + private bool isImguiDrawDemoWindow = false; + private bool isImguiDrawWelcome = true; + +#if DEBUG + private bool isImguiDrawDevMenu = true; +#else + private bool isImguiDrawDevMenu = false; +#endif + + private bool isImguiDrawLogWindow = false; + + private bool neverDrawWelcome = false; + + private DalamudLogWindow logWindow; + + private void BuildDalamudUi() + { + if (this.isImguiDrawDevMenu) + { + if (ImGui.BeginMainMenuBar()) + { + if (ImGui.BeginMenu("Dalamud DEBUG")) + { + ImGui.MenuItem("Draw Dalamud dev menu", "", ref this.isImguiDrawDevMenu); + + if (ImGui.MenuItem("Open Log window")) + { + this.logWindow = new DalamudLogWindow(); + this.isImguiDrawLogWindow = true; + } + + ImGui.MenuItem("Draw ImGui demo", "", ref this.isImguiDrawDemoWindow); + + ImGui.Separator(); + + if (ImGui.MenuItem("Unload Dalamud")) + { + Unload(); + } + + if (ImGui.MenuItem("Kill game")) + { + Process.GetCurrentProcess().Kill(); + } + } + } + } + + if (this.isImguiDrawLogWindow) + { + this.isImguiDrawLogWindow = this.logWindow != null && this.logWindow.Draw(); + + if (this.isImguiDrawLogWindow == false) + { + this.logWindow?.Dispose(); + } + } + + if (this.isImguiDrawDemoWindow) + ImGui.ShowDemoWindow(); + + if (!this.Configuration.WelcomeGuideDismissed) + { + if (!ImGui.Begin("Welcome to XIVLauncher", ImGuiWindowFlags.Modal | ImGuiWindowFlags.NoCollapse | ImGuiWindowFlags.NoResize)) + { + // Early out if the window is collapsed, as an optimization. + ImGui.End(); + } + else + { + ImGui.Text($"dalamud says hello. ({this.assemblyVersion})"); + ImGui.Spacing(); + ImGui.Spacing(); + + if (ImGui.Button("Close")) + { + this.Configuration.WelcomeGuideDismissed = true; + this.Configuration.Save(this.StartInfo.ConfigurationPath); + } + + ImGui.End(); + } + } + } + + #endregion + private void SetupCommands() { CommandManager.AddHandler("/xldclose", new CommandInfo(OnUnloadCommand) { HelpMessage = "Unloads XIVLauncher in-game addon.", @@ -250,8 +280,8 @@ namespace Dalamud { HelpMessage = "Notify when a roulette has a bonus you specified. Run without parameters for more info. Usage: /xlbonus " }); - CommandManager.AddHandler("/xlduidrawdemo", new CommandInfo(OnDebugDrawImGuiDemo) { - HelpMessage = "Open ImGUI demo window", + CommandManager.AddHandler("/xldev", new CommandInfo(OnDebugDrawDevMenu) { + HelpMessage = "Draw dev menu DEBUG", ShowInHelp = false }); } @@ -471,8 +501,8 @@ namespace Dalamud { "Possible values for role: tank, dps, healer, all, none/reset"); } - private void OnDebugDrawImGuiDemo(string command, string arguments) { - this.isImguiDrawDemoWindow = true; + private void OnDebugDrawDevMenu(string command, string arguments) { + this.isImguiDrawDevMenu = true; } private int RouletteSlugToKey(string slug) => slug.ToLower() switch { diff --git a/Dalamud/EntryPoint.cs b/Dalamud/EntryPoint.cs index 680de45e0..62949d32b 100644 --- a/Dalamud/EntryPoint.cs +++ b/Dalamud/EntryPoint.cs @@ -1,5 +1,6 @@ using System; using System.IO; +using Dalamud.Interface; using EasyHook; using Serilog; using Serilog.Core; @@ -42,6 +43,7 @@ namespace Dalamud { return new LoggerConfiguration() .WriteTo.Async(a => a.File(logPath)) + .WriteTo.EventSink() #if DEBUG .MinimumLevel.Verbose() #else diff --git a/Dalamud/Interface/DalamudLogWindow.cs b/Dalamud/Interface/DalamudLogWindow.cs new file mode 100644 index 000000000..da3676290 --- /dev/null +++ b/Dalamud/Interface/DalamudLogWindow.cs @@ -0,0 +1,85 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Numerics; +using System.Text; +using System.Threading.Tasks; +using ImGuiNET; + +namespace Dalamud.Interface +{ + class DalamudLogWindow : IDisposable { + private bool autoScroll = true; + private string logText = string.Empty; + + public DalamudLogWindow() { + SerilogEventSink.Instance.OnLogLine += Serilog_OnLogLine; + } + + public void Dispose() { + SerilogEventSink.Instance.OnLogLine -= Serilog_OnLogLine; + } + + private void Serilog_OnLogLine(object sender, string e) + { + AddLog(e + "\n"); + } + + public void Clear() { + this.logText = string.Empty; + } + + public void AddLog(string line) { + this.logText += line; + } + + public bool Draw() { + ImGui.SetNextWindowSize(new Vector2(500, 400), ImGuiCond.FirstUseEver); + + var isOpen = true; + + if (!ImGui.Begin("Dalamud LOG", ref isOpen, ImGuiWindowFlags.NoCollapse)) + { + ImGui.End(); + return false; + } + + // Options menu + if (ImGui.BeginPopup("Options")) + { + ImGui.Checkbox("Auto-scroll", ref this.autoScroll); + ImGui.EndPopup(); + } + + // Main window + if (ImGui.Button("Options")) + ImGui.OpenPopup("Options"); + ImGui.SameLine(); + var clear = ImGui.Button("Clear"); + ImGui.SameLine(); + var copy = ImGui.Button("Copy"); + ImGui.SameLine(); + + ImGui.BeginChild("scrolling", new Vector2(0, 0), false, ImGuiWindowFlags.HorizontalScrollbar); + + if (clear) + Clear(); + if (copy) + ImGui.LogToClipboard(); + + ImGui.PushStyleVar(ImGuiStyleVar.ItemSpacing, new Vector2(0, 0)); + + ImGui.TextUnformatted(this.logText); + + ImGui.PopStyleVar(); + + if (this.autoScroll && ImGui.GetScrollY() >= ImGui.GetScrollMaxY()) + ImGui.SetScrollHereY(1.0f); + + ImGui.EndChild(); + ImGui.End(); + + return isOpen; + } + } +} diff --git a/Dalamud/Interface/SerilogEventSink.cs b/Dalamud/Interface/SerilogEventSink.cs new file mode 100644 index 000000000..4cd905a66 --- /dev/null +++ b/Dalamud/Interface/SerilogEventSink.cs @@ -0,0 +1,44 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using Serilog; +using Serilog.Configuration; +using Serilog.Core; +using Serilog.Events; + +namespace Dalamud.Interface +{ + public class SerilogEventSink : ILogEventSink + { + private readonly IFormatProvider _formatProvider; + + public static SerilogEventSink Instance; + + public event EventHandler OnLogLine; + + public SerilogEventSink(IFormatProvider formatProvider) + { + _formatProvider = formatProvider; + + Instance = this; + } + + public void Emit(LogEvent logEvent) + { + var message = logEvent.RenderMessage(_formatProvider); + OnLogLine?.Invoke(this, DateTimeOffset.Now.ToString() + " " + message); + } + } + + public static class MySinkExtensions + { + public static LoggerConfiguration EventSink( + this LoggerSinkConfiguration loggerConfiguration, + IFormatProvider formatProvider = null) + { + return loggerConfiguration.Sink(new SerilogEventSink(formatProvider)); + } + } +}