diff --git a/Dalamud.Injector/Dalamud.Injector.csproj b/Dalamud.Injector/Dalamud.Injector.csproj
index 60dd15240..379a5a34a 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.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/Dalamud.csproj b/Dalamud/Dalamud.csproj
index a444bf0a6..32d68979d 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/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;
}
///
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();
+ }
+ }
+}
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;