diff --git a/.gitmodules b/.gitmodules index f063dd0b3..b43c5aff6 100644 --- a/.gitmodules +++ b/.gitmodules @@ -3,7 +3,4 @@ url = https://github.com/goatcorp/ImGuiScene [submodule "lib/FFXIVClientStructs"] path = lib/FFXIVClientStructs - url = https://github.com/goatcorp/FFXIVClientStructs.git -[submodule "lib/SharpDX.Desktop"] - path = lib/SharpDX.Desktop - url = https://github.com/goatcorp/SharpDX.Desktop.git + url = https://github.com/goatcorp/FFXIVClientStructs.git \ No newline at end of file diff --git a/Dalamud.CorePlugin/Dalamud.CorePlugin.csproj b/Dalamud.CorePlugin/Dalamud.CorePlugin.csproj index 8c714785c..aaeee5979 100644 --- a/Dalamud.CorePlugin/Dalamud.CorePlugin.csproj +++ b/Dalamud.CorePlugin/Dalamud.CorePlugin.csproj @@ -11,23 +11,22 @@ IDE0003 - - true - full - false - $(appData)\XIVLauncher\devPlugins\ + + $(AppData)\XIVLauncher\devPlugins\Dalamud.CorePlugin DEBUG;TRACE prompt 4 - + + true + full + false + + + pdbonly true - $(appData)\XIVLauncher\devPlugins\ - TRACE - prompt - 4 diff --git a/Dalamud.CorePlugin/PluginImpl.cs b/Dalamud.CorePlugin/PluginImpl.cs index 4d635eeb5..f23544cc0 100644 --- a/Dalamud.CorePlugin/PluginImpl.cs +++ b/Dalamud.CorePlugin/PluginImpl.cs @@ -2,6 +2,7 @@ using System; using System.IO; using Dalamud.Interface.Windowing; +using Dalamud.Logging; using Dalamud.Plugin; namespace Dalamud.CorePlugin diff --git a/Dalamud.CorePlugin/PluginWindow.cs b/Dalamud.CorePlugin/PluginWindow.cs index e604389ba..9147e9d93 100644 --- a/Dalamud.CorePlugin/PluginWindow.cs +++ b/Dalamud.CorePlugin/PluginWindow.cs @@ -11,8 +11,6 @@ namespace Dalamud.CorePlugin /// internal class PluginWindow : Window, IDisposable { - private static readonly ModuleLog Log = new("CorePlugin"); - private readonly Dalamud dalamud; /// @@ -20,13 +18,13 @@ namespace Dalamud.CorePlugin /// /// The Dalamud instance. public PluginWindow(Dalamud dalamud) - : base("CorePlugin", ImGuiWindowFlags.NoCollapse | ImGuiWindowFlags.NoResize | ImGuiWindowFlags.NoScrollbar) + : base("CorePlugin") { this.dalamud = dalamud; this.IsOpen = true; this.Size = new Vector2(810, 520); - this.SizeCondition = ImGuiCond.Always; + this.SizeCondition = ImGuiCond.FirstUseEver; } /// diff --git a/Dalamud.Injector/Dalamud.Injector.csproj b/Dalamud.Injector/Dalamud.Injector.csproj index eac9f1009..b2ad61f79 100644 --- a/Dalamud.Injector/Dalamud.Injector.csproj +++ b/Dalamud.Injector/Dalamud.Injector.csproj @@ -51,7 +51,8 @@ - IDE1006;CS1591;CS1701;CS1702 + IDE0003;IDE0044;IDE1006;CS1591;CS1701;CS1702 + @@ -59,9 +60,9 @@ - + - + @@ -84,6 +85,5 @@ - diff --git a/Dalamud.Injector/EntryPoint.cs b/Dalamud.Injector/EntryPoint.cs index eff8b81a9..5501d073c 100644 --- a/Dalamud.Injector/EntryPoint.cs +++ b/Dalamud.Injector/EntryPoint.cs @@ -8,7 +8,6 @@ using System.Text; using System.Threading; using Dalamud.Game; -using Dalamud.Interface.Internal; using Newtonsoft.Json; using Reloaded.Memory.Buffers; using Serilog; @@ -129,13 +128,58 @@ namespace Dalamud.Injector levelSwitch.MinimumLevel = LogEventLevel.Information; #endif + CullLogFile(logPath, 1 * 1024 * 1024); + Log.Logger = new LoggerConfiguration() .WriteTo.Async(a => a.File(logPath)) - .WriteTo.Sink(SerilogEventSink.Instance) .MinimumLevel.ControlledBy(levelSwitch) .CreateLogger(); } + private static void CullLogFile(string logPath, int cullingFileSize) + { + try + { + var bufferSize = 4096; + + var logFile = new FileInfo(logPath); + + if (!logFile.Exists) + logFile.Create(); + + if (logFile.Length <= cullingFileSize) + return; + + var amountToCull = logFile.Length - cullingFileSize; + + if (amountToCull < bufferSize) + return; + + using var reader = new BinaryReader(logFile.Open(FileMode.Open, FileAccess.Read, FileShare.ReadWrite)); + using var writer = new BinaryWriter(logFile.Open(FileMode.Open, FileAccess.Write, FileShare.ReadWrite)); + + reader.BaseStream.Seek(amountToCull, SeekOrigin.Begin); + + var read = -1; + var total = 0; + var buffer = new byte[bufferSize]; + while (read != 0) + { + read = reader.Read(buffer, 0, buffer.Length); + writer.Write(buffer, 0, read); + total += read; + } + + writer.BaseStream.SetLength(total); + } + catch (Exception ex) + { + var caption = "XIVLauncher Error"; + var message = $"Log cull threw an exception: {ex.Message}\n{ex.StackTrace ?? string.Empty}"; + _ = MessageBoxW(IntPtr.Zero, message, caption, MessageBoxType.IconError | MessageBoxType.Ok); + } + } + private static Process GetProcess(string arg) { Process process; diff --git a/Dalamud.Injector/Injector.cs b/Dalamud.Injector/Injector.cs index 3f9c14046..20a668047 100644 --- a/Dalamud.Injector/Injector.cs +++ b/Dalamud.Injector/Injector.cs @@ -11,6 +11,7 @@ using PeNet.Header.Pe; using Reloaded.Memory.Buffers; using Reloaded.Memory.Sources; using Reloaded.Memory.Utilities; +using Serilog; using static Dalamud.Injector.NativeFunctions; using static Iced.Intel.AssemblerRegisters; @@ -27,7 +28,7 @@ namespace Dalamud.Injector private readonly Process targetProcess; private readonly ExternalMemory extMemory; private readonly CircularBuffer circularBuffer; - private readonly PrivateMemoryBuffer privateBuffer; + private readonly PrivateMemoryBuffer memoryBuffer; private IntPtr loadLibraryShellPtr; private IntPtr loadLibraryRetPtr; @@ -45,7 +46,7 @@ namespace Dalamud.Injector this.extMemory = new ExternalMemory(targetProcess); this.circularBuffer = new CircularBuffer(4096, this.extMemory); - this.privateBuffer = new MemoryBufferHelper(targetProcess).CreatePrivateMemoryBuffer(4096); + this.memoryBuffer = new MemoryBufferHelper(targetProcess).CreatePrivateMemoryBuffer(4096); using var kernel32Module = this.GetProcessModule("KERNEL32.DLL"); var kernel32PeFile = new PeFile(kernel32Module.FileName); @@ -67,7 +68,7 @@ namespace Dalamud.Injector this.targetProcess?.Dispose(); this.circularBuffer?.Dispose(); - this.privateBuffer?.Dispose(); + this.memoryBuffer?.Dispose(); } /// @@ -82,6 +83,8 @@ namespace Dalamud.Injector if (lpParameter == IntPtr.Zero) throw new Exception("Unable to allocate LoadLibraryW parameter"); + Log.Verbose($"CreateRemoteThread: call 0x{this.loadLibraryShellPtr.ToInt64():X} with 0x{lpParameter.ToInt64():X}"); + var threadHandle = CreateRemoteThread( this.targetProcess.Handle, IntPtr.Zero, @@ -93,7 +96,7 @@ namespace Dalamud.Injector _ = WaitForSingleObject(threadHandle, uint.MaxValue); - this.extMemory.Read(this.loadLibraryRetPtr, out address); + address = this.extMemory.Read(this.loadLibraryRetPtr); if (address == IntPtr.Zero) throw new Exception($"Error calling LoadLibraryW with {modulePath}"); @@ -107,7 +110,8 @@ namespace Dalamud.Injector /// Address to the function. public void GetFunctionAddress(IntPtr module, string functionName, out IntPtr address) { - var getProcAddressParams = new GetProcAddressParams(module, this.WriteNullTerminatedASCIIString(functionName)); + var functionNamePtr = this.WriteNullTerminatedASCIIString(functionName); + var getProcAddressParams = new GetProcAddressParams(module, functionNamePtr); var lpParameter = this.circularBuffer.Add(ref getProcAddressParams); if (lpParameter == IntPtr.Zero) @@ -151,19 +155,25 @@ namespace Dalamud.Injector _ = WaitForSingleObject(threadHandle, uint.MaxValue); GetExitCodeThread(threadHandle, out exitCode); + + CloseHandle(threadHandle); } private void SetupLoadLibrary(ProcessModule kernel32Module, ExportFunction[] kernel32Exports) { var offset = this.GetExportedFunctionOffset(kernel32Exports, "LoadLibraryW"); var functionAddr = kernel32Module.BaseAddress + (int)offset; - var functionPtr = this.privateBuffer.Add(ref functionAddr); + Log.Verbose($"LoadLibraryW: 0x{functionAddr.ToInt64():X}"); + + var functionPtr = this.memoryBuffer.Add(ref functionAddr); + Log.Verbose($"LoadLibraryPtr: 0x{functionPtr.ToInt64():X}"); if (functionPtr == IntPtr.Zero) throw new Exception("Unable to allocate LoadLibraryW function ptr"); - var dummy = 0L; - this.loadLibraryRetPtr = this.privateBuffer.Add(ref dummy); + var dummy = IntPtr.Zero; + this.loadLibraryRetPtr = this.memoryBuffer.Add(ref dummy); + Log.Verbose($"LoadLibraryRetPtr: 0x{this.loadLibraryRetPtr.ToInt64():X}"); if (this.loadLibraryRetPtr == IntPtr.Zero) throw new Exception("Unable to allocate LoadLibraryW return value"); @@ -180,23 +190,41 @@ namespace Dalamud.Injector asm.ret(); // ret // Restore stack ptr. (Callee cleanup) var bytes = this.Assemble(asm); - this.loadLibraryShellPtr = this.privateBuffer.Add(bytes); + this.loadLibraryShellPtr = this.memoryBuffer.Add(bytes); + Log.Verbose($"LoadLibraryShellPtr: 0x{this.loadLibraryShellPtr.ToInt64():X}"); if (this.loadLibraryShellPtr == IntPtr.Zero) throw new Exception("Unable to allocate LoadLibraryW shellcode"); + + this.extMemory.ChangePermission(this.loadLibraryShellPtr, bytes.Length, Reloaded.Memory.Kernel32.Kernel32.MEM_PROTECTION.PAGE_EXECUTE_READWRITE); + +#if DEBUG + var outFunctionPtr = this.extMemory.Read(functionPtr); + Log.Verbose($"LoadLibraryPtr: {this.GetResultMarker(outFunctionPtr == functionAddr)}"); + + var outRetPtr = this.extMemory.Read(this.loadLibraryRetPtr); + Log.Verbose($"LoadLibraryRet: {this.GetResultMarker(dummy == outRetPtr)}"); + + this.extMemory.ReadRaw(this.loadLibraryShellPtr, out var outBytes, bytes.Length); + Log.Verbose($"LoadLibraryShellPtr: {this.GetResultMarker(Enumerable.SequenceEqual(bytes, outBytes))}"); +#endif } private void SetupGetProcAddress(ProcessModule kernel32Module, ExportFunction[] kernel32Exports) { var offset = this.GetExportedFunctionOffset(kernel32Exports, "GetProcAddress"); var functionAddr = kernel32Module.BaseAddress + (int)offset; - var functionPtr = this.privateBuffer.Add(ref functionAddr); + Log.Verbose($"GetProcAddress: 0x{functionAddr.ToInt64():X}"); + + var functionPtr = this.memoryBuffer.Add(ref functionAddr); + Log.Verbose($"GetProcAddressPtr: 0x{functionPtr.ToInt64():X}"); if (functionPtr == IntPtr.Zero) throw new Exception("Unable to allocate GetProcAddress function ptr"); - var dummy = 0L; - this.getProcAddressRetPtr = this.privateBuffer.Add(ref dummy); + var dummy = IntPtr.Zero; + this.getProcAddressRetPtr = this.memoryBuffer.Add(ref dummy); + Log.Verbose($"GetProcAddressRetPtr: 0x{this.loadLibraryRetPtr.ToInt64():X}"); if (this.getProcAddressRetPtr == IntPtr.Zero) throw new Exception("Unable to allocate GetProcAddress return value"); @@ -215,10 +243,24 @@ namespace Dalamud.Injector asm.ret(); // ret // Restore stack ptr. (Callee cleanup) var bytes = this.Assemble(asm); - this.getProcAddressShellPtr = this.privateBuffer.Add(bytes); + this.getProcAddressShellPtr = this.memoryBuffer.Add(bytes); + Log.Verbose($"GetProcAddressShellPtr: 0x{this.getProcAddressShellPtr.ToInt64():X}"); if (this.getProcAddressShellPtr == IntPtr.Zero) throw new Exception("Unable to allocate GetProcAddress shellcode"); + + this.extMemory.ChangePermission(this.getProcAddressShellPtr, bytes.Length, Reloaded.Memory.Kernel32.Kernel32.MEM_PROTECTION.PAGE_EXECUTE_READWRITE); + +#if DEBUG + var outFunctionPtr = this.extMemory.Read(functionPtr); + Log.Verbose($"GetProcAddressPtr: {this.GetResultMarker(outFunctionPtr == functionAddr)}"); + + var outRetPtr = this.extMemory.Read(this.loadLibraryRetPtr); + Log.Verbose($"GetProcAddressRet: {this.GetResultMarker(dummy == outRetPtr)}"); + + this.extMemory.ReadRaw(this.getProcAddressShellPtr, out var outBytes, bytes.Length); + Log.Verbose($"GetProcAddressShellPtr: {this.GetResultMarker(Enumerable.SequenceEqual(bytes, outBytes))}"); +#endif } private byte[] Assemble(Assembler assembler) @@ -264,28 +306,42 @@ namespace Dalamud.Injector return exportFunction.Address; } - private IntPtr WriteNullTerminatedASCIIString(string libraryPath) + private IntPtr WriteNullTerminatedASCIIString(string value) { - var libraryNameBytes = Encoding.ASCII.GetBytes(libraryPath + '\0'); - var value = this.circularBuffer.Add(libraryNameBytes); + var bytes = Encoding.ASCII.GetBytes(value + '\0'); + var address = this.circularBuffer.Add(bytes); - if (value == IntPtr.Zero) + if (address == IntPtr.Zero) throw new Exception("Unable to write ASCII string to buffer"); - return value; +#if DEBUG + this.extMemory.ReadRaw(address, out var outBytes, bytes.Length); + Log.Verbose($"WriteASCII: {this.GetResultMarker(Enumerable.SequenceEqual(bytes, outBytes))} 0x{address.ToInt64():X} {value}"); +#endif + + return address; } - private IntPtr WriteNullTerminatedUnicodeString(string libraryPath) + private IntPtr WriteNullTerminatedUnicodeString(string value) { - var libraryNameBytes = Encoding.Unicode.GetBytes(libraryPath + '\0'); - var value = this.circularBuffer.Add(libraryNameBytes); + var bytes = Encoding.Unicode.GetBytes(value + '\0'); + var address = this.circularBuffer.Add(bytes); - if (value == IntPtr.Zero) + if (address == IntPtr.Zero) throw new Exception("Unable to write Unicode string to buffer"); - return value; +#if DEBUG + this.extMemory.ReadRaw(address, out var outBytes, bytes.Length); + Log.Verbose($"WriteUnicode: {this.GetResultMarker(Enumerable.SequenceEqual(bytes, outBytes))} 0x{address.ToInt64():X} {value}"); +#endif + + return address; } +#if DEBUG + private string GetResultMarker(bool result) => result ? "✅" : "❌"; +#endif + [StructLayout(LayoutKind.Sequential)] private struct GetProcAddressParams { diff --git a/Dalamud.Injector/NativeFunctions.cs b/Dalamud.Injector/NativeFunctions.cs index 46da6728c..b9ed9f33d 100644 --- a/Dalamud.Injector/NativeFunctions.cs +++ b/Dalamud.Injector/NativeFunctions.cs @@ -582,6 +582,22 @@ namespace Dalamud.Injector WAIT_FAILED = 0xFFFFFFF, } + /// + /// Closes an open object handle. + /// + /// + /// A valid handle to an open object. + /// + /// + /// If the function succeeds, the return value is nonzero. If the function fails, the return value is zero. To get extended error + /// information, call GetLastError. If the application is running under a debugger, the function will throw an exception if it receives + /// either a handle value that is not valid or a pseudo-handle value. This can happen if you close a handle twice, or if you call + /// CloseHandle on a handle returned by the FindFirstFile function instead of calling the FindClose function. + /// + [DllImport("kernel32.dll", SetLastError = true)] + [return: MarshalAs(UnmanagedType.Bool)] + public static extern bool CloseHandle(IntPtr hObject); + /// /// Creates a thread that runs in the virtual address space of another process. Use the CreateRemoteThreadEx function /// to create a thread that runs in the virtual address space of another process and optionally specify extended attributes. @@ -651,6 +667,34 @@ namespace Dalamud.Injector [return: MarshalAs(UnmanagedType.Bool)] public static extern bool GetExitCodeThread(IntPtr hThread, out uint lpExitCode); + /// + /// Opens an existing local process object. + /// + /// + /// The access to the process object. This access right is checked against the security descriptor for the process. This parameter can be one or + /// more of the process access rights. If the caller has enabled the SeDebugPrivilege privilege, the requested access is granted regardless of the + /// contents of the security descriptor. + /// + /// + /// If this value is TRUE, processes created by this process will inherit the handle. Otherwise, the processes do not inherit this handle. + /// + /// + /// The identifier of the local process to be opened. If the specified process is the System Idle Process(0x00000000), the function fails and the + /// last error code is ERROR_INVALID_PARAMETER.If the specified process is the System process or one of the Client Server Run-Time Subsystem(CSRSS) + /// processes, this function fails and the last error code is ERROR_ACCESS_DENIED because their access restrictions prevent user-level code from + /// opening them. If you are using GetCurrentProcessId as an argument to this function, consider using GetCurrentProcess instead of OpenProcess, for + /// improved performance. + /// + /// + /// If the function succeeds, the return value is an open handle to the specified process. + /// If the function fails, the return value is NULL.To get extended error information, call GetLastError. + /// + [DllImport("kernel32.dll", SetLastError = true)] + public static extern IntPtr OpenProcess( + ProcessAccessFlags dwDesiredAccess, + bool bInheritHandle, + int dwProcessId); + /// /// See https://docs.microsoft.com/en-us/windows/win32/api/memoryapi/nf-memoryapi-virtualallocex. /// Reserves, commits, or changes the state of a region of memory within the virtual address space of a specified process. diff --git a/Dalamud.Injector/RemotePinnedData.cs b/Dalamud.Injector/RemotePinnedData.cs deleted file mode 100644 index fc713639f..000000000 --- a/Dalamud.Injector/RemotePinnedData.cs +++ /dev/null @@ -1,79 +0,0 @@ -using System; -using System.Diagnostics; -using System.Runtime.InteropServices; -using System.Text; - -using static Dalamud.Injector.NativeFunctions; - -namespace Dalamud.Injector -{ - /// - /// Pin an arbitrary string to a remote process. - /// - internal class RemotePinnedData : IDisposable - { - private readonly Process process; - private readonly byte[] data; - private readonly IntPtr allocAddr; - - /// - /// Initializes a new instance of the class. - /// - /// Process to write in. - /// Data to write. - public unsafe RemotePinnedData(Process process, byte[] data) - { - this.process = process; - this.data = data; - - this.allocAddr = VirtualAllocEx( - this.process.Handle, - IntPtr.Zero, - this.data.Length, - AllocationType.Commit, - MemoryProtection.ReadWrite); - - if (this.allocAddr == IntPtr.Zero || Marshal.GetLastWin32Error() != 0) - { - throw new Exception("Error allocating memory"); - } - - var result = WriteProcessMemory( - this.process.Handle, - this.allocAddr, - this.data, - this.data.Length, - out _); - - if (!result || Marshal.GetLastWin32Error() != 0) - { - throw new Exception("Error writing memory"); - } - } - - /// - /// Gets the address of the pinned data. - /// - public IntPtr Address => this.allocAddr; - - /// - public void Dispose() - { - if (this.allocAddr == IntPtr.Zero) - { - return; - } - - var result = VirtualFreeEx( - this.process.Handle, - this.allocAddr, - 0, - AllocationType.Release); - - if (!result || Marshal.GetLastWin32Error() != 0) - { - throw new Exception("Error freeing memory"); - } - } - } -} diff --git a/Dalamud/Configuration/Internal/DalamudConfiguration.cs b/Dalamud/Configuration/Internal/DalamudConfiguration.cs index ed10572e4..4eb6e3b03 100644 --- a/Dalamud/Configuration/Internal/DalamudConfiguration.cs +++ b/Dalamud/Configuration/Internal/DalamudConfiguration.cs @@ -47,12 +47,12 @@ namespace Dalamud.Configuration.Internal /// /// Gets or sets the language code to load Dalamud localization with. /// - public string LanguageOverride { get; set; } + public string LanguageOverride { get; set; } = null; /// /// Gets or sets the last loaded Dalamud version. /// - public string LastVersion { get; set; } + public string LastVersion { get; set; } = null; /// /// Gets or sets the chat type used by default for plugin messages. @@ -62,17 +62,17 @@ namespace Dalamud.Configuration.Internal /// /// Gets or sets a value indicating whether or not plugin testing builds should be shown. /// - public bool DoPluginTest { get; set; } + public bool DoPluginTest { get; set; } = false; /// /// Gets or sets a value indicating whether or not Dalamud testing builds should be used. /// - public bool DoDalamudTest { get; set; } + public bool DoDalamudTest { get; set; } = false; /// /// Gets or sets a value indicating whether or not XL should download the Dalamud .NET runtime. /// - public bool DoDalamudRuntime { get; set; } + public bool DoDalamudRuntime { get; set; } = false; /// /// Gets or sets a list of custom repos. diff --git a/Dalamud/Dalamud.csproj b/Dalamud/Dalamud.csproj index 2de2bcb7c..85d8d9c86 100644 --- a/Dalamud/Dalamud.csproj +++ b/Dalamud/Dalamud.csproj @@ -59,9 +59,9 @@ - - - + + + diff --git a/Dalamud/EntryPoint.cs b/Dalamud/EntryPoint.cs index 7cfe03443..378f841fd 100644 --- a/Dalamud/EntryPoint.cs +++ b/Dalamud/EntryPoint.cs @@ -6,12 +6,14 @@ using System.Threading; using System.Threading.Tasks; using Dalamud.Configuration.Internal; -using Dalamud.Interface.Internal; +using Dalamud.Logging.Internal; using Newtonsoft.Json; using Serilog; using Serilog.Core; using Serilog.Events; +using static Dalamud.NativeFunctions; + namespace Dalamud { /// @@ -43,11 +45,16 @@ namespace Dalamud /// The containing information needed to initialize Dalamud. private static void RunThread(DalamudStartInfo info) { + // Setup logger + var levelSwitch = InitLogging(info.WorkingDirectory); + // Load configuration first to get some early persistent state, like log level var configuration = DalamudConfiguration.Load(info.ConfigurationPath); - // Setup logger - var levelSwitch = InitLogging(info.WorkingDirectory, configuration); + // Set the appropriate logging level from the configuration +#if !DEBUG + levelSwitch.MinimumLevel = configuration.LogLevel; +#endif // Log any unhandled exception. AppDomain.CurrentDomain.UnhandledException += OnUnhandledException; @@ -88,30 +95,96 @@ namespace Dalamud } } - private static LoggingLevelSwitch InitLogging(string baseDirectory, DalamudConfiguration configuration) + private static LoggingLevelSwitch InitLogging(string baseDirectory) { #if DEBUG var logPath = Path.Combine(baseDirectory, "dalamud.log"); + var oldPath = Path.Combine(baseDirectory, "dalamud.log.old"); #else var logPath = Path.Combine(baseDirectory, "..", "..", "..", "dalamud.log"); + var oldPath = Path.Combine(baseDirectory, "..", "..", "..", "dalamud.log.old"); #endif - var levelSwitch = new LoggingLevelSwitch(); + CullLogFile(logPath, oldPath, 1 * 1024 * 1024); + CullLogFile(oldPath, null, 10 * 1024 * 1024); -#if DEBUG - levelSwitch.MinimumLevel = LogEventLevel.Verbose; -#else - levelSwitch.MinimumLevel = configuration.LogLevel; -#endif + var levelSwitch = new LoggingLevelSwitch(LogEventLevel.Verbose); Log.Logger = new LoggerConfiguration() - .WriteTo.Async(a => a.File(logPath, fileSizeLimitBytes: 5 * 1024 * 1024, rollOnFileSizeLimit: true)) - .WriteTo.Sink(SerilogEventSink.Instance) - .MinimumLevel.ControlledBy(levelSwitch) - .CreateLogger(); + .WriteTo.Async(a => a.File(logPath)) + .WriteTo.Sink(SerilogEventSink.Instance) + .MinimumLevel.ControlledBy(levelSwitch) + .CreateLogger(); return levelSwitch; } + private static void CullLogFile(string logPath, string? oldPath, int cullingFileSize) + { + try + { + var bufferSize = 4096; + + var logFile = new FileInfo(logPath); + + if (!logFile.Exists) + logFile.Create(); + + if (logFile.Length <= cullingFileSize) + return; + + var amountToCull = logFile.Length - cullingFileSize; + + if (amountToCull < bufferSize) + return; + + if (oldPath != null) + { + var oldFile = new FileInfo(oldPath); + + if (!oldFile.Exists) + oldFile.Create(); + + using var reader = new BinaryReader(logFile.Open(FileMode.Open, FileAccess.Read)); + using var writer = new BinaryWriter(oldFile.Open(FileMode.Append, FileAccess.Write)); + + var read = -1; + var total = 0; + var buffer = new byte[bufferSize]; + while (read != 0 && total < amountToCull) + { + read = reader.Read(buffer, 0, buffer.Length); + writer.Write(buffer, 0, read); + total += read; + } + } + + { + using var reader = new BinaryReader(logFile.Open(FileMode.Open, FileAccess.Read, FileShare.ReadWrite)); + using var writer = new BinaryWriter(logFile.Open(FileMode.Open, FileAccess.Write, FileShare.ReadWrite)); + + reader.BaseStream.Seek(amountToCull, SeekOrigin.Begin); + + var read = -1; + var total = 0; + var buffer = new byte[bufferSize]; + while (read != 0) + { + read = reader.Read(buffer, 0, buffer.Length); + writer.Write(buffer, 0, read); + total += read; + } + + writer.BaseStream.SetLength(total); + } + } + catch (Exception ex) + { + var caption = "XIVLauncher Error"; + var message = $"Log cull threw an exception: {ex.Message}\n{ex.StackTrace ?? string.Empty}"; + _ = MessageBoxW(IntPtr.Zero, message, caption, MessageBoxType.IconError | MessageBoxType.Ok); + } + } + private static void OnUnhandledException(object sender, UnhandledExceptionEventArgs args) { switch (args.ExceptionObject) diff --git a/Dalamud/Game/Internal/Network/GameNetwork.cs b/Dalamud/Game/Internal/Network/GameNetwork.cs index 947a4651c..dff3ac535 100644 --- a/Dalamud/Game/Internal/Network/GameNetwork.cs +++ b/Dalamud/Game/Internal/Network/GameNetwork.cs @@ -2,6 +2,7 @@ using System; using System.Collections.Generic; using System.Runtime.InteropServices; +using Dalamud.Game.Network; using Dalamud.Hooking; using Serilog; diff --git a/Dalamud/Game/Network/MarketBoardUploaders/IMarketBoardUploader.cs b/Dalamud/Game/Network/Internal/MarketBoardUploaders/IMarketBoardUploader.cs similarity index 93% rename from Dalamud/Game/Network/MarketBoardUploaders/IMarketBoardUploader.cs rename to Dalamud/Game/Network/Internal/MarketBoardUploaders/IMarketBoardUploader.cs index 9820ac237..a867261f2 100644 --- a/Dalamud/Game/Network/MarketBoardUploaders/IMarketBoardUploader.cs +++ b/Dalamud/Game/Network/Internal/MarketBoardUploaders/IMarketBoardUploader.cs @@ -1,6 +1,6 @@ using Dalamud.Game.Network.Structures; -namespace Dalamud.Game.Network.MarketBoardUploaders +namespace Dalamud.Game.Network.Internal.MarketBoardUploaders { /// /// An interface binding for the Universalis uploader. diff --git a/Dalamud/Game/Network/Internal/MarketBoardUploaders/MarketBoardItemRequest.cs b/Dalamud/Game/Network/Internal/MarketBoardUploaders/MarketBoardItemRequest.cs new file mode 100644 index 000000000..63d51f0e1 --- /dev/null +++ b/Dalamud/Game/Network/Internal/MarketBoardUploaders/MarketBoardItemRequest.cs @@ -0,0 +1,42 @@ +using System.Collections.Generic; + +using Dalamud.Game.Network.Structures; + +namespace Dalamud.Game.Network.Internal.MarketBoardUploaders +{ + /// + /// This represents a submission to a marketboard aggregation website. + /// + internal class MarketBoardItemRequest + { + /// + /// Gets or sets the catalog ID. + /// + public uint CatalogId { get; set; } + + /// + /// Gets or sets the amount to arrive. + /// + public byte AmountToArrive { get; set; } + + /// + /// Gets or sets the offered item listings. + /// + public List Listings { get; set; } + + /// + /// Gets or sets the historical item listings. + /// + public List History { get; set; } + + /// + /// Gets or sets the listing request ID. + /// + public int ListingsRequestId { get; set; } = -1; + + /// + /// Gets a value indicating whether the upload is complete. + /// + public bool IsDone => this.Listings.Count == this.AmountToArrive && this.History.Count != 0; + } +} diff --git a/Dalamud/Game/Network/MarketBoardUploaders/Universalis/UniversalisHistoryEntry.cs b/Dalamud/Game/Network/Internal/MarketBoardUploaders/Universalis/Types/UniversalisHistoryEntry.cs similarity index 95% rename from Dalamud/Game/Network/MarketBoardUploaders/Universalis/UniversalisHistoryEntry.cs rename to Dalamud/Game/Network/Internal/MarketBoardUploaders/Universalis/Types/UniversalisHistoryEntry.cs index ba60d484d..37467377c 100644 --- a/Dalamud/Game/Network/MarketBoardUploaders/Universalis/UniversalisHistoryEntry.cs +++ b/Dalamud/Game/Network/Internal/MarketBoardUploaders/Universalis/Types/UniversalisHistoryEntry.cs @@ -1,6 +1,6 @@ using Newtonsoft.Json; -namespace Dalamud.Game.Network.MarketBoardUploaders.Universalis +namespace Dalamud.Game.Network.Internal.MarketBoardUploaders.Universalis.Types { /// /// A Universalis API structure. diff --git a/Dalamud/Game/Network/MarketBoardUploaders/Universalis/UniversalisHistoryUploadRequest.cs b/Dalamud/Game/Network/Internal/MarketBoardUploaders/Universalis/Types/UniversalisHistoryUploadRequest.cs similarity index 91% rename from Dalamud/Game/Network/MarketBoardUploaders/Universalis/UniversalisHistoryUploadRequest.cs rename to Dalamud/Game/Network/Internal/MarketBoardUploaders/Universalis/Types/UniversalisHistoryUploadRequest.cs index 1c92171af..afa8bf417 100644 --- a/Dalamud/Game/Network/MarketBoardUploaders/Universalis/UniversalisHistoryUploadRequest.cs +++ b/Dalamud/Game/Network/Internal/MarketBoardUploaders/Universalis/Types/UniversalisHistoryUploadRequest.cs @@ -2,7 +2,7 @@ using System.Collections.Generic; using Newtonsoft.Json; -namespace Dalamud.Game.Network.MarketBoardUploaders.Universalis +namespace Dalamud.Game.Network.Internal.MarketBoardUploaders.Universalis.Types { /// /// A Universalis API structure. diff --git a/Dalamud/Game/Network/MarketBoardUploaders/Universalis/UniversalisItemListingDeleteRequest.cs b/Dalamud/Game/Network/Internal/MarketBoardUploaders/Universalis/Types/UniversalisItemListingDeleteRequest.cs similarity index 88% rename from Dalamud/Game/Network/MarketBoardUploaders/Universalis/UniversalisItemListingDeleteRequest.cs rename to Dalamud/Game/Network/Internal/MarketBoardUploaders/Universalis/Types/UniversalisItemListingDeleteRequest.cs index f6994e60f..ea96f934a 100644 --- a/Dalamud/Game/Network/MarketBoardUploaders/Universalis/UniversalisItemListingDeleteRequest.cs +++ b/Dalamud/Game/Network/Internal/MarketBoardUploaders/Universalis/Types/UniversalisItemListingDeleteRequest.cs @@ -1,11 +1,11 @@ using Newtonsoft.Json; -namespace Dalamud.Game.Network.MarketBoardUploaders.Universalis +namespace Dalamud.Game.Network.Internal.MarketBoardUploaders.Universalis.Types { /// /// Request payload for market board purchases. /// - public class UniversalisItemListingDeleteRequest + internal class UniversalisItemListingDeleteRequest { /// /// Gets or sets the object ID of the retainer associated with the sale. diff --git a/Dalamud/Game/Network/MarketBoardUploaders/Universalis/UniversalisItemListingsEntry.cs b/Dalamud/Game/Network/Internal/MarketBoardUploaders/Universalis/Types/UniversalisItemListingsEntry.cs similarity index 97% rename from Dalamud/Game/Network/MarketBoardUploaders/Universalis/UniversalisItemListingsEntry.cs rename to Dalamud/Game/Network/Internal/MarketBoardUploaders/Universalis/Types/UniversalisItemListingsEntry.cs index 745c2a66e..42ff15668 100644 --- a/Dalamud/Game/Network/MarketBoardUploaders/Universalis/UniversalisItemListingsEntry.cs +++ b/Dalamud/Game/Network/Internal/MarketBoardUploaders/Universalis/Types/UniversalisItemListingsEntry.cs @@ -2,7 +2,7 @@ using System.Collections.Generic; using Newtonsoft.Json; -namespace Dalamud.Game.Network.MarketBoardUploaders.Universalis +namespace Dalamud.Game.Network.Internal.MarketBoardUploaders.Universalis.Types { /// /// A Universalis API structure. diff --git a/Dalamud/Game/Network/MarketBoardUploaders/Universalis/UniversalisItemListingsUploadRequest.cs b/Dalamud/Game/Network/Internal/MarketBoardUploaders/Universalis/Types/UniversalisItemListingsUploadRequest.cs similarity index 91% rename from Dalamud/Game/Network/MarketBoardUploaders/Universalis/UniversalisItemListingsUploadRequest.cs rename to Dalamud/Game/Network/Internal/MarketBoardUploaders/Universalis/Types/UniversalisItemListingsUploadRequest.cs index 3623769c9..c055b30d9 100644 --- a/Dalamud/Game/Network/MarketBoardUploaders/Universalis/UniversalisItemListingsUploadRequest.cs +++ b/Dalamud/Game/Network/Internal/MarketBoardUploaders/Universalis/Types/UniversalisItemListingsUploadRequest.cs @@ -2,7 +2,7 @@ using System.Collections.Generic; using Newtonsoft.Json; -namespace Dalamud.Game.Network.MarketBoardUploaders.Universalis +namespace Dalamud.Game.Network.Internal.MarketBoardUploaders.Universalis.Types { /// /// A Universalis API structure. diff --git a/Dalamud/Game/Network/MarketBoardUploaders/Universalis/UniversalisItemMateria.cs b/Dalamud/Game/Network/Internal/MarketBoardUploaders/Universalis/Types/UniversalisItemMateria.cs similarity index 85% rename from Dalamud/Game/Network/MarketBoardUploaders/Universalis/UniversalisItemMateria.cs rename to Dalamud/Game/Network/Internal/MarketBoardUploaders/Universalis/Types/UniversalisItemMateria.cs index 5c2cae7c6..8c9c99bb5 100644 --- a/Dalamud/Game/Network/MarketBoardUploaders/Universalis/UniversalisItemMateria.cs +++ b/Dalamud/Game/Network/Internal/MarketBoardUploaders/Universalis/Types/UniversalisItemMateria.cs @@ -1,6 +1,6 @@ using Newtonsoft.Json; -namespace Dalamud.Game.Network.MarketBoardUploaders.Universalis +namespace Dalamud.Game.Network.Internal.MarketBoardUploaders.Universalis.Types { /// /// A Universalis API structure. diff --git a/Dalamud/Game/Network/MarketBoardUploaders/Universalis/UniversalisTaxData.cs b/Dalamud/Game/Network/Internal/MarketBoardUploaders/Universalis/Types/UniversalisTaxData.cs similarity index 93% rename from Dalamud/Game/Network/MarketBoardUploaders/Universalis/UniversalisTaxData.cs rename to Dalamud/Game/Network/Internal/MarketBoardUploaders/Universalis/Types/UniversalisTaxData.cs index dd56a25ed..0a93f788b 100644 --- a/Dalamud/Game/Network/MarketBoardUploaders/Universalis/UniversalisTaxData.cs +++ b/Dalamud/Game/Network/Internal/MarketBoardUploaders/Universalis/Types/UniversalisTaxData.cs @@ -1,6 +1,6 @@ using Newtonsoft.Json; -namespace Dalamud.Game.Network.MarketBoardUploaders.Universalis +namespace Dalamud.Game.Network.Internal.MarketBoardUploaders.Universalis.Types { /// /// A Universalis API structure. diff --git a/Dalamud/Game/Network/MarketBoardUploaders/Universalis/UniversalisTaxUploadRequest.cs b/Dalamud/Game/Network/Internal/MarketBoardUploaders/Universalis/Types/UniversalisTaxUploadRequest.cs similarity index 90% rename from Dalamud/Game/Network/MarketBoardUploaders/Universalis/UniversalisTaxUploadRequest.cs rename to Dalamud/Game/Network/Internal/MarketBoardUploaders/Universalis/Types/UniversalisTaxUploadRequest.cs index bdf9715a0..a11ac0e89 100644 --- a/Dalamud/Game/Network/MarketBoardUploaders/Universalis/UniversalisTaxUploadRequest.cs +++ b/Dalamud/Game/Network/Internal/MarketBoardUploaders/Universalis/Types/UniversalisTaxUploadRequest.cs @@ -1,6 +1,6 @@ using Newtonsoft.Json; -namespace Dalamud.Game.Network.MarketBoardUploaders.Universalis +namespace Dalamud.Game.Network.Internal.MarketBoardUploaders.Universalis.Types { /// /// A Universalis API structure. diff --git a/Dalamud/Game/Network/MarketBoardUploaders/Universalis/UniversalisMarketBoardUploader.cs b/Dalamud/Game/Network/Internal/MarketBoardUploaders/Universalis/UniversalisMarketBoardUploader.cs similarity index 62% rename from Dalamud/Game/Network/MarketBoardUploaders/Universalis/UniversalisMarketBoardUploader.cs rename to Dalamud/Game/Network/Internal/MarketBoardUploaders/Universalis/UniversalisMarketBoardUploader.cs index 58c7810ad..5e4ac76e1 100644 --- a/Dalamud/Game/Network/MarketBoardUploaders/Universalis/UniversalisMarketBoardUploader.cs +++ b/Dalamud/Game/Network/Internal/MarketBoardUploaders/Universalis/UniversalisMarketBoardUploader.cs @@ -1,14 +1,15 @@ using System; using System.Collections.Generic; -using System.Net; +using System.Net.Http; +using System.Net.Http.Headers; +using System.Text; -using Dalamud.Game.Network.MarketBoardUploaders; -using Dalamud.Game.Network.MarketBoardUploaders.Universalis; +using Dalamud.Game.Network.Internal.MarketBoardUploaders.Universalis.Types; using Dalamud.Game.Network.Structures; using Newtonsoft.Json; using Serilog; -namespace Dalamud.Game.Network.Universalis.MarketBoardUploaders +namespace Dalamud.Game.Network.Internal.MarketBoardUploaders.Universalis { /// /// This class represents an uploader for contributing data to Universalis. @@ -16,8 +17,8 @@ namespace Dalamud.Game.Network.Universalis.MarketBoardUploaders internal class UniversalisMarketBoardUploader : IMarketBoardUploader { private const string ApiBase = "https://universalis.app"; - // private const string ApiBase = "https://127.0.0.1:443"; + private const string ApiKey = "GGD6RdSfGyRiHM5WDnAo0Nj9Nv7aC5NDhMj3BebT"; private readonly Dalamud dalamud; @@ -34,14 +35,14 @@ namespace Dalamud.Game.Network.Universalis.MarketBoardUploaders /// public void Upload(MarketBoardItemRequest request) { - using var client = new WebClient(); - - client.Headers.Add(HttpRequestHeader.ContentType, "application/json"); + using var client = new HttpClient(); Log.Verbose("Starting Universalis upload."); var uploader = this.dalamud.ClientState.LocalContentId; - var listingsRequestObject = new UniversalisItemListingsUploadRequest + // ==================================================================================== + + var listingsUploadObject = new UniversalisItemListingsUploadRequest { WorldId = this.dalamud.ClientState.LocalPlayer?.CurrentWorld.Id ?? 0, UploaderId = uploader.ToString(), @@ -76,14 +77,17 @@ namespace Dalamud.Game.Network.Universalis.MarketBoardUploaders }); } - listingsRequestObject.Listings.Add(universalisListing); + listingsUploadObject.Listings.Add(universalisListing); } - var upload = JsonConvert.SerializeObject(listingsRequestObject); - Log.Verbose(upload); - client.UploadString(ApiBase + $"/upload/{ApiKey}", "POST", upload); + var listingPath = "/upload"; + var listingUpload = JsonConvert.SerializeObject(listingsUploadObject); + Log.Verbose($"{listingPath}: {listingUpload}"); + client.PostAsync($"{ApiBase}{listingPath}/{ApiKey}", new StringContent(listingUpload, Encoding.UTF8, "application/json")).GetAwaiter().GetResult(); - var historyRequestObject = new UniversalisHistoryUploadRequest + // ==================================================================================== + + var historyUploadObject = new UniversalisHistoryUploadRequest { WorldId = this.dalamud.ClientState.LocalPlayer?.CurrentWorld.Id ?? 0, UploaderId = uploader.ToString(), @@ -93,7 +97,7 @@ namespace Dalamud.Game.Network.Universalis.MarketBoardUploaders foreach (var marketBoardHistoryListing in request.History) { - historyRequestObject.Entries.Add(new UniversalisHistoryEntry + historyUploadObject.Entries.Add(new UniversalisHistoryEntry { BuyerName = marketBoardHistoryListing.BuyerName, Hq = marketBoardHistoryListing.IsHq, @@ -104,11 +108,12 @@ namespace Dalamud.Game.Network.Universalis.MarketBoardUploaders }); } - client.Headers.Add(HttpRequestHeader.ContentType, "application/json"); + var historyPath = "/upload"; + var historyUpload = JsonConvert.SerializeObject(historyUploadObject); + Log.Verbose($"{historyPath}: {historyUpload}"); + client.PostAsync($"{ApiBase}{historyPath}/{ApiKey}", new StringContent(historyUpload, Encoding.UTF8, "application/json")).GetAwaiter().GetResult(); - var historyUpload = JsonConvert.SerializeObject(historyRequestObject); - Log.Verbose(historyUpload); - client.UploadString(ApiBase + $"/upload/{ApiKey}", "POST", historyUpload); + // ==================================================================================== Log.Verbose("Universalis data upload for item#{0} completed.", request.CatalogId); } @@ -116,9 +121,11 @@ namespace Dalamud.Game.Network.Universalis.MarketBoardUploaders /// public void UploadTax(MarketTaxRates taxRates) { - using var client = new WebClient(); + using var client = new HttpClient(); - var taxRatesRequest = new UniversalisTaxUploadRequest + // ==================================================================================== + + var taxUploadObject = new UniversalisTaxUploadRequest { WorldId = this.dalamud.ClientState.LocalPlayer?.CurrentWorld.Id ?? 0, UploaderId = this.dalamud.ClientState.LocalContentId.ToString(), @@ -133,26 +140,35 @@ namespace Dalamud.Game.Network.Universalis.MarketBoardUploaders }, }; - client.Headers.Add(HttpRequestHeader.ContentType, "application/json"); + var taxPath = "/upload"; + var taxUpload = JsonConvert.SerializeObject(taxUploadObject); + Log.Verbose($"{taxPath}: {taxUpload}"); - var historyUpload = JsonConvert.SerializeObject(taxRatesRequest); - Log.Verbose(historyUpload); - client.UploadString(ApiBase + $"/upload/{ApiKey}", "POST", historyUpload); + client.PostAsync($"{ApiBase}{taxPath}/{ApiKey}", new StringContent(taxUpload, Encoding.UTF8, "application/json")).GetAwaiter().GetResult(); + + // ==================================================================================== Log.Verbose("Universalis tax upload completed."); } /// + /// + /// It may seem backwards that an upload only performs a delete request, however this is not trying + /// to track the available listings, that is done via the listings packet. All this does is remove + /// a listing, or delete it, when a purchase has been made. + /// public void UploadPurchase(MarketBoardPurchaseHandler purchaseHandler) { - using var client = new WebClient(); - client.Headers.Add(HttpRequestHeader.ContentType, "application/json"); - client.Headers.Add(HttpRequestHeader.Authorization, ApiKey); + using var client = new HttpClient(); + + client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue(ApiKey); var itemId = purchaseHandler.CatalogId; var worldId = this.dalamud.ClientState.LocalPlayer?.CurrentWorld.Id ?? 0; - var purchaseRequest = new UniversalisItemListingDeleteRequest + // ==================================================================================== + + var deleteListingObject = new UniversalisItemListingDeleteRequest { PricePerUnit = purchaseHandler.PricePerUnit, Quantity = purchaseHandler.ItemQuantity, @@ -161,11 +177,13 @@ namespace Dalamud.Game.Network.Universalis.MarketBoardUploaders UploaderId = this.dalamud.ClientState.LocalContentId.ToString(), }; - var requestPath = ApiBase + $"/api/{worldId}/{itemId}/delete"; - var purchaseUpload = JsonConvert.SerializeObject(purchaseRequest); - Log.Verbose($"Making request to {requestPath}"); - Log.Verbose(purchaseUpload); - client.UploadString(requestPath, "POST", purchaseUpload); + var deletePath = $"/api/{worldId}/{itemId}/delete"; + var deleteListing = JsonConvert.SerializeObject(deleteListingObject); + Log.Verbose($"{deletePath}: {deleteListing}"); + + client.PostAsync($"{ApiBase}{deletePath}", new StringContent(deleteListing, Encoding.UTF8, "application/json")).GetAwaiter().GetResult(); + + // ==================================================================================== Log.Verbose("Universalis purchase upload completed."); } diff --git a/Dalamud/Game/Network/NetworkHandlers.cs b/Dalamud/Game/Network/Internal/NetworkHandlers.cs similarity index 92% rename from Dalamud/Game/Network/NetworkHandlers.cs rename to Dalamud/Game/Network/Internal/NetworkHandlers.cs index 0b7aa7694..bf20122b0 100644 --- a/Dalamud/Game/Network/NetworkHandlers.cs +++ b/Dalamud/Game/Network/Internal/NetworkHandlers.cs @@ -5,14 +5,13 @@ using System.Linq; using System.Runtime.InteropServices; using System.Threading.Tasks; -using Dalamud.Game.Internal.Network; -using Dalamud.Game.Network.MarketBoardUploaders; +using Dalamud.Game.Network.Internal.MarketBoardUploaders; +using Dalamud.Game.Network.Internal.MarketBoardUploaders.Universalis; using Dalamud.Game.Network.Structures; -using Dalamud.Game.Network.Universalis.MarketBoardUploaders; using Lumina.Excel.GeneratedSheets; using Serilog; -namespace Dalamud.Game.Network +namespace Dalamud.Game.Network.Internal { /// /// This class handles network notifications and uploading market board data. @@ -141,7 +140,7 @@ namespace Dalamud.Game.Network var request = this.marketBoardRequests.LastOrDefault(r => r.CatalogId == listing.ItemListings[0].CatalogId && !r.IsDone); - if (request == null) + if (request == default) { Log.Error($"Market Board data arrived without a corresponding request: item#{listing.ItemListings[0].CatalogId}"); return; @@ -207,17 +206,15 @@ namespace Dalamud.Game.Network var request = this.marketBoardRequests.LastOrDefault(r => r.CatalogId == listing.CatalogId); - if (request == null) + if (request == default) { - Log.Error( - $"Market Board data arrived without a corresponding request: item#{listing.CatalogId}"); + Log.Error($"Market Board data arrived without a corresponding request: item#{listing.CatalogId}"); return; } if (request.ListingsRequestId != -1) { - Log.Error( - $"Market Board data history sequence break: {request.ListingsRequestId}, {request.Listings.Count}"); + Log.Error($"Market Board data history sequence break: {request.ListingsRequestId}, {request.Listings.Count}"); return; } @@ -243,6 +240,7 @@ namespace Dalamud.Game.Network if (opCode == this.dalamud.Data.ServerOpCodes["MarketTaxRates"]) { var category = (uint)Marshal.ReadInt32(dataPtr); + // Result dialog packet does not contain market tax rates if (category != 720905) { @@ -279,9 +277,9 @@ namespace Dalamud.Game.Network // Transaction succeeded if (purchase.ItemQuantity == this.marketBoardPurchaseHandler.ItemQuantity && (purchase.CatalogId == this.marketBoardPurchaseHandler.CatalogId - || purchase.CatalogId == this.marketBoardPurchaseHandler.CatalogId + 1000000)) + || purchase.CatalogId == this.marketBoardPurchaseHandler.CatalogId + 1_000_000)) { // HQ - Log.Information("Bought " + purchase.ItemQuantity + "x " + this.marketBoardPurchaseHandler.CatalogId + " for " + (this.marketBoardPurchaseHandler.PricePerUnit * purchase.ItemQuantity) + " gils, listing id is " + this.marketBoardPurchaseHandler.ListingId); + Log.Verbose($"Bought {purchase.ItemQuantity}x {this.marketBoardPurchaseHandler.CatalogId} for {this.marketBoardPurchaseHandler.PricePerUnit * purchase.ItemQuantity} gils, listing id is {this.marketBoardPurchaseHandler.ListingId}"); var handler = this.marketBoardPurchaseHandler; // Capture the object so that we don't pass in a null one when the task starts. Task.Run(() => this.uploader.UploadPurchase(handler)); } diff --git a/Dalamud/Game/Network/MarketBoardItemRequest.cs b/Dalamud/Game/Network/MarketBoardItemRequest.cs deleted file mode 100644 index df08ce09e..000000000 --- a/Dalamud/Game/Network/MarketBoardItemRequest.cs +++ /dev/null @@ -1,21 +0,0 @@ -using System.Collections.Generic; - -using Dalamud.Game.Network.Structures; - -namespace Dalamud.Game.Network -{ - internal class MarketBoardItemRequest - { - public uint CatalogId { get; set; } - - public byte AmountToArrive { get; set; } - - public List Listings { get; set; } - - public List History { get; set; } - - public int ListingsRequestId { get; set; } = -1; - - public bool IsDone => this.Listings.Count == this.AmountToArrive && this.History.Count != 0; - } -} diff --git a/Dalamud/Game/Internal/Network/NetworkMessageDirection.cs b/Dalamud/Game/Network/NetworkMessageDirection.cs similarity index 89% rename from Dalamud/Game/Internal/Network/NetworkMessageDirection.cs rename to Dalamud/Game/Network/NetworkMessageDirection.cs index 22de9cb54..79d9d2df2 100644 --- a/Dalamud/Game/Internal/Network/NetworkMessageDirection.cs +++ b/Dalamud/Game/Network/NetworkMessageDirection.cs @@ -1,4 +1,4 @@ -namespace Dalamud.Game.Internal.Network +namespace Dalamud.Game.Network { /// /// This represents the direction of a network message. diff --git a/Dalamud/Game/Network/Structures/MarketBoardCurrentOfferings.cs b/Dalamud/Game/Network/Structures/MarketBoardCurrentOfferings.cs index 2ac0f8886..ad19f48c5 100644 --- a/Dalamud/Game/Network/Structures/MarketBoardCurrentOfferings.cs +++ b/Dalamud/Game/Network/Structures/MarketBoardCurrentOfferings.cs @@ -5,14 +5,43 @@ using System.Text; namespace Dalamud.Game.Network.Structures { + /// + /// This class represents the current market board offerings from a game network packet. + /// public class MarketBoardCurrentOfferings { - public List ItemListings; + /// + /// Initializes a new instance of the class. + /// + internal MarketBoardCurrentOfferings() + { + } - public int ListingIndexEnd; - public int ListingIndexStart; - public int RequestId; + /// + /// Gets the list of individual item listings. + /// + public List ItemListings { get; internal set; } + /// + /// Gets the listing end index. + /// + public int ListingIndexEnd { get; internal set; } + + /// + /// Gets the listing start index. + /// + public int ListingIndexStart { get; internal set; } + + /// + /// Gets the request ID. + /// + public int RequestId { get; internal set; } + + /// + /// Read a object from memory. + /// + /// Address to read. + /// A new object. public static unsafe MarketBoardCurrentOfferings Read(IntPtr dataPtr) { var output = new MarketBoardCurrentOfferings(); @@ -80,32 +109,124 @@ namespace Dalamud.Game.Network.Structures return output; } + /// + /// This class represents the current market board offering of a single item from the network packet. + /// public class MarketBoardItemListing { - public ulong ArtisanId; - public uint CatalogId; - public bool IsHq; - public uint ItemQuantity; - public DateTime LastReviewTime; - public ulong ListingId; + /// + /// Initializes a new instance of the class. + /// + internal MarketBoardItemListing() + { + } - public List Materia; - public int MateriaCount; - public bool OnMannequin; - public string PlayerName; - public uint PricePerUnit; - public int RetainerCityId; - public ulong RetainerId; + /// + /// Gets the artisan ID. + /// + public ulong ArtisanId { get; internal set; } - public string RetainerName; - public ulong RetainerOwnerId; - public int StainId; - public uint TotalTax; + /// + /// Gets the catalog ID. + /// + public uint CatalogId { get; internal set; } + /// + /// Gets a value indicating whether the item is HQ. + /// + public bool IsHq { get; internal set; } + + /// + /// Gets the item quantity. + /// + public uint ItemQuantity { get; internal set; } + + /// + /// Gets the time this offering was last reviewed. + /// + public DateTime LastReviewTime { get; internal set; } + + /// + /// Gets the listing ID. + /// + public ulong ListingId { get; internal set; } + + /// + /// Gets the list of materia attached to this item. + /// + public List Materia { get; internal set; } + + /// + /// Gets the amount of attached materia. + /// + public int MateriaCount { get; internal set; } + + /// + /// Gets a value indicating whether this item is on a mannequin. + /// + public bool OnMannequin { get; internal set; } + + /// + /// Gets the player name. + /// + public string PlayerName { get; internal set; } + + /// + /// Gets the price per unit. + /// + public uint PricePerUnit { get; internal set; } + + /// + /// Gets the city ID of the retainer selling the item. + /// + public int RetainerCityId { get; internal set; } + + /// + /// Gets the ID of the retainer selling the item. + /// + public ulong RetainerId { get; internal set; } + + /// + /// Gets the name of the retainer. + /// + public string RetainerName { get; internal set; } + + /// + /// Gets the ID of the retainer's owner. + /// + public ulong RetainerOwnerId { get; internal set; } + + /// + /// Gets the stain or applied dye of the item. + /// + public int StainId { get; internal set; } + + /// + /// Gets the total tax. + /// + public uint TotalTax { get; internal set; } + + /// + /// This represents the materia slotted to an . + /// public class ItemMateria { - public int Index; - public int MateriaId; + /// + /// Initializes a new instance of the class. + /// + internal ItemMateria() + { + } + + /// + /// Gets the materia index. + /// + public int Index { get; internal set; } + + /// + /// Gets the materia ID. + /// + public int MateriaId { get; internal set; } } } } diff --git a/Dalamud/Game/Network/Structures/MarketBoardHistory.cs b/Dalamud/Game/Network/Structures/MarketBoardHistory.cs index b2f3e3ad0..c73529da3 100644 --- a/Dalamud/Game/Network/Structures/MarketBoardHistory.cs +++ b/Dalamud/Game/Network/Structures/MarketBoardHistory.cs @@ -5,13 +5,38 @@ using System.Text; namespace Dalamud.Game.Network.Structures { + /// + /// This class represents the market board history from a game network packet. + /// public class MarketBoardHistory { - public uint CatalogId; - public uint CatalogId2; + /// + /// Initializes a new instance of the class. + /// + internal MarketBoardHistory() + { + } - public List HistoryListings; + /// + /// Gets the catalog ID. + /// + public uint CatalogId { get; internal set; } + /// + /// Gets the second catalog ID. + /// + public uint CatalogId2 { get; internal set; } + + /// + /// Gets the list of individual item history listings. + /// + public List HistoryListings { get; internal set; } + + /// + /// Read a object from memory. + /// + /// Address to read. + /// A new object. public static unsafe MarketBoardHistory Read(IntPtr dataPtr) { var output = new MarketBoardHistory(); @@ -47,16 +72,52 @@ namespace Dalamud.Game.Network.Structures return output; } + /// + /// This class represents the market board history of a single item from the network packet. + /// public class MarketBoardHistoryListing { - public string BuyerName; + /// + /// Initializes a new instance of the class. + /// + internal MarketBoardHistoryListing() + { + } - public uint CatalogId; - public bool IsHq; - public bool OnMannequin; - public DateTime PurchaseTime; - public uint Quantity; - public uint SalePrice; + /// + /// Gets the buyer's name. + /// + public string BuyerName { get; internal set; } + + /// + /// Gets the catalog ID. + /// + public uint CatalogId { get; internal set; } + + /// + /// Gets a value indicating whether the item is HQ. + /// + public bool IsHq { get; internal set; } + + /// + /// Gets a value indicating whether the item is on a mannequin. + /// + public bool OnMannequin { get; internal set; } + + /// + /// Gets the time of purchase. + /// + public DateTime PurchaseTime { get; internal set; } + + /// + /// Gets the quantity. + /// + public uint Quantity { get; internal set; } + + /// + /// Gets the sale price. + /// + public uint SalePrice { get; internal set; } } } } diff --git a/Dalamud/Game/Network/Structures/MarketTaxRates.cs b/Dalamud/Game/Network/Structures/MarketTaxRates.cs index 4a79c0242..5b27b9415 100644 --- a/Dalamud/Game/Network/Structures/MarketTaxRates.cs +++ b/Dalamud/Game/Network/Structures/MarketTaxRates.cs @@ -3,15 +3,53 @@ using System.IO; namespace Dalamud.Game.Network.Structures { + /// + /// This class represents the market tax rates from a game network packet. + /// public class MarketTaxRates { - public uint LimsaLominsaTax; - public uint GridaniaTax; - public uint UldahTax; - public uint IshgardTax; - public uint KuganeTax; - public uint CrystariumTax; + /// + /// Initializes a new instance of the class. + /// + internal MarketTaxRates() + { + } + /// + /// Gets the tax rate in Limsa Lominsa. + /// + public uint LimsaLominsaTax { get; internal set; } + + /// + /// Gets the tax rate in Gridania. + /// + public uint GridaniaTax { get; internal set; } + + /// + /// Gets the tax rate in Ul'dah. + /// + public uint UldahTax { get; internal set; } + + /// + /// Gets the tax rate in Ishgard. + /// + public uint IshgardTax { get; internal set; } + + /// + /// Gets the tax rate in Kugane. + /// + public uint KuganeTax { get; internal set; } + + /// + /// Gets the tax rate in the Crystarium. + /// + public uint CrystariumTax { get; internal set; } + + /// + /// Read a object from memory. + /// + /// Address to read. + /// A new object. public static unsafe MarketTaxRates Read(IntPtr dataPtr) { var output = new MarketTaxRates(); diff --git a/Dalamud/Hooking/Internal/HookManager.cs b/Dalamud/Hooking/Internal/HookManager.cs index 5741b7d29..ecf03f1af 100644 --- a/Dalamud/Hooking/Internal/HookManager.cs +++ b/Dalamud/Hooking/Internal/HookManager.cs @@ -1,6 +1,7 @@ using System; using System.Collections.Generic; +using Dalamud.Logging.Internal; using Dalamud.Memory; using Microsoft.Win32; diff --git a/Dalamud/Interface/Internal/DalamudInterface.cs b/Dalamud/Interface/Internal/DalamudInterface.cs index 47225e815..630f01296 100644 --- a/Dalamud/Interface/Internal/DalamudInterface.cs +++ b/Dalamud/Interface/Internal/DalamudInterface.cs @@ -6,7 +6,8 @@ using System.Runtime.InteropServices; using Dalamud.Interface.Internal.Windows; using Dalamud.Interface.Windowing; -using Dalamud.Plugin; +using Dalamud.Logging; +using Dalamud.Logging.Internal; using Dalamud.Plugin.Internal; using ImGuiNET; using Serilog.Events; diff --git a/Dalamud/Interface/Internal/Scratchpad/ScratchMacroProcessor.cs b/Dalamud/Interface/Internal/Scratchpad/ScratchMacroProcessor.cs index ad20b493e..4fdbd64f5 100644 --- a/Dalamud/Interface/Internal/Scratchpad/ScratchMacroProcessor.cs +++ b/Dalamud/Interface/Internal/Scratchpad/ScratchMacroProcessor.cs @@ -3,7 +3,7 @@ using System.Collections.Generic; using System.Linq; using System.Text.RegularExpressions; -using Dalamud.Plugin; +using Dalamud.Logging; namespace Dalamud.Interface.Internal.Scratchpad { diff --git a/Dalamud/Interface/Internal/UiDebug.cs b/Dalamud/Interface/Internal/UiDebug.cs index 3e7310633..3a2847b99 100644 --- a/Dalamud/Interface/Internal/UiDebug.cs +++ b/Dalamud/Interface/Internal/UiDebug.cs @@ -273,8 +273,11 @@ namespace Dalamud.Interface.Internal ImGui.Text($"texture type: {texType} part_id={imageNode->PartId} part_id_count={imageNode->PartsList->PartCount}"); if (texType == TextureType.Resource) { - var texFileNamePtr = textureInfo->AtkTexture.Resource->TexFileResourceHandle->ResourceHandle.FileName; - var texString = Marshal.PtrToStringAnsi(new IntPtr(texFileNamePtr)); + var texFileNameStdString = &textureInfo->AtkTexture.Resource->TexFileResourceHandle->ResourceHandle.FileName; + var texString = texFileNameStdString->Length < 16 + ? Marshal.PtrToStringAnsi((IntPtr)texFileNameStdString->Buffer) + : Marshal.PtrToStringAnsi((IntPtr)texFileNameStdString->BufferPtr); + ImGui.Text($"texture path: {texString}"); var kernelTexture = textureInfo->AtkTexture.Resource->KernelTextureObject; @@ -327,7 +330,7 @@ namespace Dalamud.Interface.Internal var childCount = componentInfo.NodeListCount; - var objectInfo = (ULDComponentInfo*)componentInfo.Objects; + var objectInfo = (AtkUldComponentInfo*)componentInfo.Objects; if (ImGui.TreeNode($"{treePrefix}{objectInfo->ComponentType} Component Node (ptr = {(long)node:X}, component ptr = {(long)compNode->Component:X}) child count = {childCount} ###{(long)node}")) { if (ImGui.IsItemHovered()) diff --git a/Dalamud/Interface/Internal/Windows/ConsoleWindow.cs b/Dalamud/Interface/Internal/Windows/ConsoleWindow.cs index 92aa1a0c9..f9aa2c901 100644 --- a/Dalamud/Interface/Internal/Windows/ConsoleWindow.cs +++ b/Dalamud/Interface/Internal/Windows/ConsoleWindow.cs @@ -6,10 +6,9 @@ using System.Numerics; using System.Runtime.InteropServices; using System.Text; -using Dalamud.Configuration.Internal; -using Dalamud.Game.Command; using Dalamud.Interface.Colors; using Dalamud.Interface.Windowing; +using Dalamud.Logging.Internal; using ImGuiNET; using Serilog; using Serilog.Events; @@ -307,7 +306,7 @@ namespace Dalamud.Interface.Internal.Windows try { this.historyPos = -1; - for (int i = this.history.Count - 1; i >= 0; i--) + for (var i = this.history.Count - 1; i >= 0; i--) { if (this.history[i] == this.commandText) { diff --git a/Dalamud/Interface/Internal/Windows/PluginInstallerWindow.cs b/Dalamud/Interface/Internal/Windows/PluginInstallerWindow.cs index 3b6d97bb2..f5d34b90f 100644 --- a/Dalamud/Interface/Internal/Windows/PluginInstallerWindow.cs +++ b/Dalamud/Interface/Internal/Windows/PluginInstallerWindow.cs @@ -14,6 +14,7 @@ using CheapLoc; using Dalamud.Interface.Colors; using Dalamud.Interface.Components; using Dalamud.Interface.Windowing; +using Dalamud.Logging.Internal; using Dalamud.Plugin; using Dalamud.Plugin.Internal; using Dalamud.Plugin.Internal.Exceptions; diff --git a/Dalamud/Interface/Windowing/WindowSystem.cs b/Dalamud/Interface/Windowing/WindowSystem.cs index f13797a17..608cd3c15 100644 --- a/Dalamud/Interface/Windowing/WindowSystem.cs +++ b/Dalamud/Interface/Windowing/WindowSystem.cs @@ -3,7 +3,6 @@ using System.Collections.Generic; using System.Linq; using ImGuiNET; -using Serilog; namespace Dalamud.Interface.Windowing { diff --git a/Dalamud/ModuleLog.cs b/Dalamud/Logging/Internal/ModuleLog.cs similarity index 99% rename from Dalamud/ModuleLog.cs rename to Dalamud/Logging/Internal/ModuleLog.cs index b78430a92..9ec951cad 100644 --- a/Dalamud/ModuleLog.cs +++ b/Dalamud/Logging/Internal/ModuleLog.cs @@ -1,6 +1,6 @@ using System; -namespace Dalamud +namespace Dalamud.Logging.Internal { /// /// Class offering various methods to allow for logging in Dalamud modules. diff --git a/Dalamud/Interface/Internal/SerilogEventSink.cs b/Dalamud/Logging/Internal/SerilogEventSink.cs similarity index 97% rename from Dalamud/Interface/Internal/SerilogEventSink.cs rename to Dalamud/Logging/Internal/SerilogEventSink.cs index ac2c522ba..518e6edca 100644 --- a/Dalamud/Interface/Internal/SerilogEventSink.cs +++ b/Dalamud/Logging/Internal/SerilogEventSink.cs @@ -3,7 +3,7 @@ using System; using Serilog.Core; using Serilog.Events; -namespace Dalamud.Interface.Internal +namespace Dalamud.Logging.Internal { /// /// Serilog event sink. diff --git a/Dalamud/Logging/PluginLog.cs b/Dalamud/Logging/PluginLog.cs new file mode 100644 index 000000000..fefb386c5 --- /dev/null +++ b/Dalamud/Logging/PluginLog.cs @@ -0,0 +1,113 @@ +using System; +using System.Reflection; + +namespace Dalamud.Logging +{ + /// + /// Class offering various static methods to allow for logging in plugins. + /// + public static class PluginLog + { + /// + /// Log a templated verbose message to the in-game debug log. + /// + /// The message template. + /// Values to log. + public static void Verbose(string messageTemplate, params object[] values) + => Serilog.Log.Verbose($"[{Assembly.GetCallingAssembly().GetName().Name}] {messageTemplate}", values); + + /// + /// Log a templated verbose message to the in-game debug log. + /// + /// The exception that caused the error. + /// The message template. + /// Values to log. + public static void Verbose(Exception exception, string messageTemplate, params object[] values) + => Serilog.Log.Verbose(exception, $"[{Assembly.GetCallingAssembly().GetName().Name}] {messageTemplate}", values); + + /// + /// Log a templated debug message to the in-game debug log. + /// + /// The message template. + /// Values to log. + public static void Debug(string messageTemplate, params object[] values) + => Serilog.Log.Debug($"[{Assembly.GetCallingAssembly().GetName().Name}] {messageTemplate}", values); + + /// + /// Log a templated debug message to the in-game debug log. + /// + /// The exception that caused the error. + /// The message template. + /// Values to log. + public static void Debug(Exception exception, string messageTemplate, params object[] values) + => Serilog.Log.Debug(exception, $"[{Assembly.GetCallingAssembly().GetName().Name}] {messageTemplate}", values); + + /// + /// Log a templated information message to the in-game debug log. + /// + /// The message template. + /// Values to log. + public static void Information(string messageTemplate, params object[] values) + => Serilog.Log.Information($"[{Assembly.GetCallingAssembly().GetName().Name}] {messageTemplate}", values); + + /// + /// Log a templated information message to the in-game debug log. + /// + /// The exception that caused the error. + /// The message template. + /// Values to log. + public static void Information(Exception exception, string messageTemplate, params object[] values) + => Serilog.Log.Information(exception, $"[{Assembly.GetCallingAssembly().GetName().Name}] {messageTemplate}", values); + + /// + /// Log a templated warning message to the in-game debug log. + /// + /// The message template. + /// Values to log. + public static void Warning(string messageTemplate, params object[] values) + => Serilog.Log.Warning($"[{Assembly.GetCallingAssembly().GetName().Name}] {messageTemplate}", values); + + /// + /// Log a templated warning message to the in-game debug log. + /// + /// The exception that caused the error. + /// The message template. + /// Values to log. + public static void Warning(Exception exception, string messageTemplate, params object[] values) + => Serilog.Log.Warning(exception, $"[{Assembly.GetCallingAssembly().GetName().Name}] {messageTemplate}", values); + + /// + /// Log a templated error message to the in-game debug log. + /// + /// The message template. + /// Values to log. + public static void Error(string messageTemplate, params object[] values) + => Serilog.Log.Error($"[{Assembly.GetCallingAssembly().GetName().Name}] {messageTemplate}", values); + + /// + /// Log a templated error message to the in-game debug log. + /// + /// The exception that caused the error. + /// The message template. + /// Values to log. + public static void Error(Exception exception, string messageTemplate, params object[] values) + => Serilog.Log.Error(exception, $"[{Assembly.GetCallingAssembly().GetName().Name}] {messageTemplate}", values); + + /// + /// Log a templated fatal message to the in-game debug log. + /// + /// The message template. + /// Values to log. + public static void Fatal(string messageTemplate, params object[] values) + => Serilog.Log.Fatal($"[{Assembly.GetCallingAssembly().GetName().Name}] {messageTemplate}", values); + + /// + /// Log a templated fatal message to the in-game debug log. + /// + /// The exception that caused the error. + /// The message template. + /// Values to log. + public static void Fatal(Exception exception, string messageTemplate, params object[] values) + => Serilog.Log.Fatal(exception, $"[{Assembly.GetCallingAssembly().GetName().Name}] {messageTemplate}", values); + } +} diff --git a/Dalamud/Plugin/DalamudPluginInterface.cs b/Dalamud/Plugin/DalamudPluginInterface.cs index 9ab55d24c..8814e494a 100644 --- a/Dalamud/Plugin/DalamudPluginInterface.cs +++ b/Dalamud/Plugin/DalamudPluginInterface.cs @@ -347,35 +347,6 @@ namespace Dalamud.Plugin #endregion - #region Logging - - /// - /// Log a templated message to the in-game debug log. - /// - /// The message template. - /// Values to log. - [Obsolete("Use PluginLog")] - public void Log(string messageTemplate, params object[] values) => Serilog.Log.Information(messageTemplate, values); - - /// - /// Log a templated error message to the in-game debug log. - /// - /// The message template. - /// Values to log. - [Obsolete("Use PluginLog")] - public void LogError(string messageTemplate, params object[] values) => Serilog.Log.Error(messageTemplate, values); - - /// - /// Log a templated error message to the in-game debug log. - /// - /// The exception that caused the error. - /// The message template. - /// Values to log. - [Obsolete("Use PluginLog")] - public void LogError(Exception exception, string messageTemplate, params object[] values) => Serilog.Log.Error(exception, messageTemplate, values); - - #endregion - /// /// Unregister your plugin and dispose all references. You have to call this when your IDalamudPlugin is disposed. /// diff --git a/Dalamud/Plugin/Internal/LocalDevPlugin.cs b/Dalamud/Plugin/Internal/LocalDevPlugin.cs index 77b3be253..f874267a8 100644 --- a/Dalamud/Plugin/Internal/LocalDevPlugin.cs +++ b/Dalamud/Plugin/Internal/LocalDevPlugin.cs @@ -1,10 +1,10 @@ using System; using System.IO; -using System.Linq; using System.Threading; using System.Threading.Tasks; using Dalamud.Configuration.Internal; +using Dalamud.Logging.Internal; using Dalamud.Plugin.Internal.Types; namespace Dalamud.Plugin.Internal diff --git a/Dalamud/Plugin/Internal/LocalPlugin.cs b/Dalamud/Plugin/Internal/LocalPlugin.cs index f7bbe9615..f5b3481f8 100644 --- a/Dalamud/Plugin/Internal/LocalPlugin.cs +++ b/Dalamud/Plugin/Internal/LocalPlugin.cs @@ -3,8 +3,8 @@ using System.IO; using System.Linq; using System.Reflection; -using Dalamud.Configuration.Internal; using Dalamud.Game; +using Dalamud.Logging.Internal; using Dalamud.Plugin.Internal.Exceptions; using Dalamud.Plugin.Internal.Types; using McMaster.NETCore.Plugins; diff --git a/Dalamud/Plugin/Internal/PluginManager.cs b/Dalamud/Plugin/Internal/PluginManager.cs index 5f1165742..a3f4f250e 100644 --- a/Dalamud/Plugin/Internal/PluginManager.cs +++ b/Dalamud/Plugin/Internal/PluginManager.cs @@ -14,6 +14,7 @@ using System.Threading.Tasks; using CheapLoc; using Dalamud.Configuration; using Dalamud.Game.Text; +using Dalamud.Logging.Internal; using Dalamud.Plugin.Internal.Exceptions; using Dalamud.Plugin.Internal.Types; using HarmonyLib; diff --git a/Dalamud/Plugin/Internal/PluginRepository.cs b/Dalamud/Plugin/Internal/PluginRepository.cs index 64769322d..e76aa67d1 100644 --- a/Dalamud/Plugin/Internal/PluginRepository.cs +++ b/Dalamud/Plugin/Internal/PluginRepository.cs @@ -1,9 +1,9 @@ using System.Collections.Generic; using System.Collections.ObjectModel; -using System.Linq; using System.Net; using System.Threading.Tasks; +using Dalamud.Logging.Internal; using Dalamud.Plugin.Internal.Types; using Newtonsoft.Json; diff --git a/Dalamud/Plugin/PluginLog.cs b/Dalamud/Plugin/PluginLog.cs deleted file mode 100644 index 3bfa0d904..000000000 --- a/Dalamud/Plugin/PluginLog.cs +++ /dev/null @@ -1,240 +0,0 @@ -using System; -using System.Reflection; - -namespace Dalamud.Plugin -{ - /// - /// Class offering various static methods to allow for logging in plugins. - /// - public static class PluginLog - { - #region "Log" prefixed Serilog style methods - - /// - /// Log a templated message to the in-game debug log. - /// - /// The message template. - /// Values to log. - public static void Log(string messageTemplate, params object[] values) - => Serilog.Log.Information($"[{Assembly.GetCallingAssembly().GetName().Name}] {messageTemplate}", values); - - /// - /// Log a templated message to the in-game debug log. - /// - /// The exception that caused the error. - /// The message template. - /// Values to log. - public static void Log(Exception exception, string messageTemplate, params object[] values) - => Serilog.Log.Information(exception, $"[{Assembly.GetCallingAssembly().GetName().Name}] {messageTemplate}", values); - - /// - /// Log a templated verbose message to the in-game debug log. - /// - /// The message template. - /// Values to log. - public static void LogVerbose(string messageTemplate, params object[] values) - => Serilog.Log.Verbose($"[{Assembly.GetCallingAssembly().GetName().Name}] {messageTemplate}", values); - - /// - /// Log a templated verbose message to the in-game debug log. - /// - /// The exception that caused the error. - /// The message template. - /// Values to log. - public static void LogVerbose(Exception exception, string messageTemplate, params object[] values) - => Serilog.Log.Verbose(exception, $"[{Assembly.GetCallingAssembly().GetName().Name}] {messageTemplate}", values); - - /// - /// Log a templated debug message to the in-game debug log. - /// - /// The message template. - /// Values to log. - public static void LogDebug(string messageTemplate, params object[] values) - => Serilog.Log.Debug($"[{Assembly.GetCallingAssembly().GetName().Name}] {messageTemplate}", values); - - /// - /// Log a templated debug message to the in-game debug log. - /// - /// The exception that caused the error. - /// The message template. - /// Values to log. - public static void LogDebug(Exception exception, string messageTemplate, params object[] values) - => Serilog.Log.Debug(exception, $"[{Assembly.GetCallingAssembly().GetName().Name}] {messageTemplate}", values); - - /// - /// Log a templated information message to the in-game debug log. - /// - /// The message template. - /// Values to log. - public static void LogInformation(string messageTemplate, params object[] values) - => Serilog.Log.Information($"[{Assembly.GetCallingAssembly().GetName().Name}] {messageTemplate}", values); - - /// - /// Log a templated information message to the in-game debug log. - /// - /// The exception that caused the error. - /// The message template. - /// Values to log. - public static void LogInformation(Exception exception, string messageTemplate, params object[] values) - => Serilog.Log.Information(exception, $"[{Assembly.GetCallingAssembly().GetName().Name}] {messageTemplate}", values); - - /// - /// Log a templated warning message to the in-game debug log. - /// - /// The message template. - /// Values to log. - public static void LogWarning(string messageTemplate, params object[] values) - => Serilog.Log.Warning($"[{Assembly.GetCallingAssembly().GetName().Name}] {messageTemplate}", values); - - /// - /// Log a templated warning message to the in-game debug log. - /// - /// The exception that caused the error. - /// The message template. - /// Values to log. - public static void LogWarning(Exception exception, string messageTemplate, params object[] values) - => Serilog.Log.Warning(exception, $"[{Assembly.GetCallingAssembly().GetName().Name}] {messageTemplate}", values); - - /// - /// Log a templated error message to the in-game debug log. - /// - /// The message template. - /// Values to log. - public static void LogError(string messageTemplate, params object[] values) - => Serilog.Log.Error($"[{Assembly.GetCallingAssembly().GetName().Name}] {messageTemplate}", values); - - /// - /// Log a templated error message to the in-game debug log. - /// - /// The exception that caused the error. - /// The message template. - /// Values to log. - public static void LogError(Exception exception, string messageTemplate, params object[] values) - => Serilog.Log.Error(exception, $"[{Assembly.GetCallingAssembly().GetName().Name}] {messageTemplate}", values); - - /// - /// Log a templated fatal message to the in-game debug log. - /// - /// The message template. - /// Values to log. - public static void LogFatal(string messageTemplate, params object[] values) - => Serilog.Log.Fatal($"[{Assembly.GetCallingAssembly().GetName().Name}] {messageTemplate}", values); - - /// - /// Log a templated fatal message to the in-game debug log. - /// - /// The exception that caused the error. - /// The message template. - /// Values to log. - public static void LogFatal(Exception exception, string messageTemplate, params object[] values) - => Serilog.Log.Fatal(exception, $"[{Assembly.GetCallingAssembly().GetName().Name}] {messageTemplate}", values); - - #endregion - - #region Serilog style methods - - /// - /// Log a templated verbose message to the in-game debug log. - /// - /// The message template. - /// Values to log. - public static void Verbose(string messageTemplate, params object[] values) - => Serilog.Log.Verbose($"[{Assembly.GetCallingAssembly().GetName().Name}] {messageTemplate}", values); - - /// - /// Log a templated verbose message to the in-game debug log. - /// - /// The exception that caused the error. - /// The message template. - /// Values to log. - public static void Verbose(Exception exception, string messageTemplate, params object[] values) - => Serilog.Log.Verbose(exception, $"[{Assembly.GetCallingAssembly().GetName().Name}] {messageTemplate}", values); - - /// - /// Log a templated debug message to the in-game debug log. - /// - /// The message template. - /// Values to log. - public static void Debug(string messageTemplate, params object[] values) - => Serilog.Log.Debug($"[{Assembly.GetCallingAssembly().GetName().Name}] {messageTemplate}", values); - - /// - /// Log a templated debug message to the in-game debug log. - /// - /// The exception that caused the error. - /// The message template. - /// Values to log. - public static void Debug(Exception exception, string messageTemplate, params object[] values) - => Serilog.Log.Debug(exception, $"[{Assembly.GetCallingAssembly().GetName().Name}] {messageTemplate}", values); - - /// - /// Log a templated information message to the in-game debug log. - /// - /// The message template. - /// Values to log. - public static void Information(string messageTemplate, params object[] values) - => Serilog.Log.Information($"[{Assembly.GetCallingAssembly().GetName().Name}] {messageTemplate}", values); - - /// - /// Log a templated information message to the in-game debug log. - /// - /// The exception that caused the error. - /// The message template. - /// Values to log. - public static void Information(Exception exception, string messageTemplate, params object[] values) - => Serilog.Log.Information(exception, $"[{Assembly.GetCallingAssembly().GetName().Name}] {messageTemplate}", values); - - /// - /// Log a templated warning message to the in-game debug log. - /// - /// The message template. - /// Values to log. - public static void Warning(string messageTemplate, params object[] values) - => Serilog.Log.Warning($"[{Assembly.GetCallingAssembly().GetName().Name}] {messageTemplate}", values); - - /// - /// Log a templated warning message to the in-game debug log. - /// - /// The exception that caused the error. - /// The message template. - /// Values to log. - public static void Warning(Exception exception, string messageTemplate, params object[] values) - => Serilog.Log.Warning(exception, $"[{Assembly.GetCallingAssembly().GetName().Name}] {messageTemplate}", values); - - /// - /// Log a templated error message to the in-game debug log. - /// - /// The message template. - /// Values to log. - public static void Error(string messageTemplate, params object[] values) - => Serilog.Log.Error($"[{Assembly.GetCallingAssembly().GetName().Name}] {messageTemplate}", values); - - /// - /// Log a templated error message to the in-game debug log. - /// - /// The exception that caused the error. - /// The message template. - /// Values to log. - public static void Error(Exception exception, string messageTemplate, params object[] values) - => Serilog.Log.Error(exception, $"[{Assembly.GetCallingAssembly().GetName().Name}] {messageTemplate}", values); - - /// - /// Log a templated fatal message to the in-game debug log. - /// - /// The message template. - /// Values to log. - public static void Fatal(string messageTemplate, params object[] values) - => Serilog.Log.Fatal($"[{Assembly.GetCallingAssembly().GetName().Name}] {messageTemplate}", values); - - /// - /// Log a templated fatal message to the in-game debug log. - /// - /// The exception that caused the error. - /// The message template. - /// Values to log. - public static void Fatal(Exception exception, string messageTemplate, params object[] values) - => Serilog.Log.Fatal(exception, $"[{Assembly.GetCallingAssembly().GetName().Name}] {messageTemplate}", values); - - #endregion - } -} diff --git a/Dalamud/corehook64.dll b/Dalamud/corehook64.dll deleted file mode 100644 index 9b21a40d1..000000000 Binary files a/Dalamud/corehook64.dll and /dev/null differ diff --git a/build/build.csproj b/build/build.csproj index b5403f5ce..a9b6c7ef0 100644 --- a/build/build.csproj +++ b/build/build.csproj @@ -9,6 +9,6 @@ .. - + diff --git a/lib/FFXIVClientStructs b/lib/FFXIVClientStructs index e3bec1189..cbbea8ea9 160000 --- a/lib/FFXIVClientStructs +++ b/lib/FFXIVClientStructs @@ -1 +1 @@ -Subproject commit e3bec118909b0eafdd0ee7c3312c646ce0c3f3dd +Subproject commit cbbea8ea911dda876d4a996f214f337e4db88a01 diff --git a/lib/ImGuiScene b/lib/ImGuiScene index 372419027..c6ed214c2 160000 --- a/lib/ImGuiScene +++ b/lib/ImGuiScene @@ -1 +1 @@ -Subproject commit 3724190279a24f638c9627688a837f9b61457668 +Subproject commit c6ed214c2f7b269c007e5f7f70788745e45e9eb3 diff --git a/lib/SharpDX.Desktop b/lib/SharpDX.Desktop deleted file mode 160000 index 7fc56bc0a..000000000 --- a/lib/SharpDX.Desktop +++ /dev/null @@ -1 +0,0 @@ -Subproject commit 7fc56bc0a240030d4736e6b16da33b08c73c3ba4