From d0209fe6a34dc856bc78d0346ddca2b273de1d14 Mon Sep 17 00:00:00 2001 From: Mino Date: Sun, 17 Nov 2019 00:03:54 +0900 Subject: [PATCH 1/3] Bump .NET framework version to 4.8 --- Dalamud.Injector/Dalamud.Injector.csproj | 6 +++--- Dalamud/Dalamud.csproj | 6 +++--- Dalamud/Hooking/Hook.cs | 4 ++-- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/Dalamud.Injector/Dalamud.Injector.csproj b/Dalamud.Injector/Dalamud.Injector.csproj index c78eb8453..f20b29a6e 100644 --- a/Dalamud.Injector/Dalamud.Injector.csproj +++ b/Dalamud.Injector/Dalamud.Injector.csproj @@ -1,8 +1,8 @@ AnyCPU - net471 - 7.2 + net48 + 8.0 AnyCPU;x64 @@ -26,4 +26,4 @@ - \ No newline at end of file + diff --git a/Dalamud/Dalamud.csproj b/Dalamud/Dalamud.csproj index d99acb87b..3775b7ad8 100644 --- a/Dalamud/Dalamud.csproj +++ b/Dalamud/Dalamud.csproj @@ -1,8 +1,8 @@  AnyCPU - net471 - 7.3 + net48 + 8.0 AnyCPU;x64 @@ -68,4 +68,4 @@ - \ No newline at end of file + diff --git a/Dalamud/Hooking/Hook.cs b/Dalamud/Hooking/Hook.cs index 4101d5912..c6311a79d 100644 --- a/Dalamud/Hooking/Hook.cs +++ b/Dalamud/Hooking/Hook.cs @@ -1,4 +1,4 @@ -using System; +using System; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using EasyHook; @@ -9,7 +9,7 @@ namespace Dalamud.Hooking { /// This class is basically a thin wrapper around the LocalHook type to provide helper functions. /// /// Delegate type to represents a function prototype. This must be the same prototype as original function do. - public sealed class Hook : IDisposable where T : class { + public sealed class Hook : IDisposable where T : Delegate { private bool isDisposed; private readonly IntPtr address; From 642c84f0e52d1c813da8ef8b2531556ae3cbf6de Mon Sep 17 00:00:00 2001 From: Mino Date: Sun, 17 Nov 2019 00:04:12 +0900 Subject: [PATCH 2/3] Enable TCP_NODELAY --- Dalamud/Dalamud.cs | 8 +++- Dalamud/Game/Network/WinSockHandlers.cs | 55 +++++++++++++++++++++++++ 2 files changed, 62 insertions(+), 1 deletion(-) create mode 100644 Dalamud/Game/Network/WinSockHandlers.cs diff --git a/Dalamud/Dalamud.cs b/Dalamud/Dalamud.cs index b0952d8da..f9d0132ec 100644 --- a/Dalamud/Dalamud.cs +++ b/Dalamud/Dalamud.cs @@ -46,6 +46,8 @@ namespace Dalamud { public readonly DalamudConfiguration Configuration; + internal readonly WinSockHandlers WinSock2; + public Dalamud(DalamudStartInfo info) { this.StartInfo = info; this.Configuration = DalamudConfiguration.Load(info.ConfigurationPath); @@ -75,7 +77,9 @@ namespace Dalamud { this.PluginManager = new PluginManager(this, info.PluginDirectory, info.DefaultPluginDirectory); this.IconReplacer = new IconReplacer(this, this.sigScanner); - + + this.WinSock2 = new WinSockHandlers(); + try { this.PluginManager.LoadPlugins(); } catch (Exception ex) { @@ -109,6 +113,8 @@ namespace Dalamud { this.unloadSignal.Dispose(); + this.WinSock2.Dispose(); + if (this.Configuration.ComboPresets != CustomComboPreset.None) this.IconReplacer.Dispose(); } diff --git a/Dalamud/Game/Network/WinSockHandlers.cs b/Dalamud/Game/Network/WinSockHandlers.cs new file mode 100644 index 000000000..bd75ccff5 --- /dev/null +++ b/Dalamud/Game/Network/WinSockHandlers.cs @@ -0,0 +1,55 @@ +using Dalamud.Hooking; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Net.Sockets; +using System.Runtime.InteropServices; +using System.Text; +using System.Threading.Tasks; + +namespace Dalamud.Game +{ + internal sealed class WinSockHandlers : IDisposable + { + [UnmanagedFunctionPointer(CallingConvention.Winapi)] + private delegate IntPtr SocketDelegate(int af, int type, int protocol); + private Hook ws2SocketHook; + + [DllImport("ws2_32.dll", CallingConvention = CallingConvention.Winapi)] + private static extern int setsockopt(IntPtr socket, SocketOptionLevel level, SocketOptionName optName, ref IntPtr optVal, int optLen); + + public WinSockHandlers() { + ws2SocketHook = Hook.FromSymbol("ws2_32.dll", "socket", new SocketDelegate(OnSocket)); + ws2SocketHook.Enable(); + } + + private IntPtr OnSocket(int af, int type, int protocol) + { + var socket = ws2SocketHook.Original(af, type, protocol); + + // IPPROTO_TCP + if (type == 1) + { + // INVALID_SOCKET + if (socket != new IntPtr(-1)) + { + // In case you're not aware of it: (albeit you should) + // https://linux.die.net/man/7/tcp + // https://assets.extrahop.com/whitepapers/TCP-Optimization-Guide-by-ExtraHop.pdf + var value = new IntPtr(1); + setsockopt(socket, SocketOptionLevel.Tcp, SocketOptionName.NoDelay, ref value, 4); + + // Enable tcp_quickack option. This option is undocumented in MSDN but it is supported in Windows 7 and onwards. + value = new IntPtr(1); + setsockopt(socket, SocketOptionLevel.Tcp, (SocketOptionName)12, ref value, 4); + } + } + + return socket; + } + + public void Dispose() { + ws2SocketHook.Dispose(); + } + } +} From 90817b9a0572784d405b6537631897a0cbc184e2 Mon Sep 17 00:00:00 2001 From: meli <57847713+ff-meli@users.noreply.github.com> Date: Sun, 17 Nov 2019 17:04:50 -0800 Subject: [PATCH 3/3] include return value from hooked chat handler; this seems to fix the content menu issues --- Dalamud/Game/Internal/Gui/ChatGui.cs | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/Dalamud/Game/Internal/Gui/ChatGui.cs b/Dalamud/Game/Internal/Gui/ChatGui.cs index ab59c4b00..4d254a71c 100644 --- a/Dalamud/Game/Internal/Gui/ChatGui.cs +++ b/Dalamud/Game/Internal/Gui/ChatGui.cs @@ -10,7 +10,7 @@ using Serilog; namespace Dalamud.Game.Internal.Gui { public sealed class ChatGui : IDisposable { [UnmanagedFunctionPointer(CallingConvention.ThisCall)] - private delegate void PrintMessageDelegate(IntPtr manager, XivChatType chatType, IntPtr senderName, + private delegate IntPtr PrintMessageDelegate(IntPtr manager, XivChatType chatType, IntPtr senderName, IntPtr message, uint senderId, IntPtr parameter); @@ -79,8 +79,10 @@ namespace Dalamud.Game.Internal.Gui { } } - private void HandlePrintMessageDetour(IntPtr manager, XivChatType chattype, IntPtr pSenderName, IntPtr pMessage, + private IntPtr HandlePrintMessageDetour(IntPtr manager, XivChatType chattype, IntPtr pSenderName, IntPtr pMessage, uint senderid, IntPtr parameter) { + IntPtr retVal = IntPtr.Zero; + try { var senderName = StdString.ReadFromPointer(pSenderName); var message = StdString.ReadFromPointer(pMessage); @@ -105,7 +107,7 @@ namespace Dalamud.Game.Internal.Gui { // Print the original chat if it's handled. if (!isHandled) - this.printMessageHook.Original(manager, chattype, pSenderName, messagePtr, senderid, parameter); + retVal = this.printMessageHook.Original(manager, chattype, pSenderName, messagePtr, senderid, parameter); if (this.baseAddress == IntPtr.Zero) this.baseAddress = manager; @@ -113,8 +115,10 @@ namespace Dalamud.Game.Internal.Gui { allocatedString?.Dispose(); } catch (Exception ex) { Log.Error(ex, "Exception on OnChatMessage hook."); - this.printMessageHook.Original(manager, chattype, pSenderName, pMessage, senderid, parameter); + retVal = this.printMessageHook.Original(manager, chattype, pSenderName, pMessage, senderid, parameter); } + + return retVal; } ///