From 364ab40b3fa381f8e2ed8c0d514d47bf19dadbe2 Mon Sep 17 00:00:00 2001 From: Filip Maj Date: Wed, 24 Aug 2016 15:41:54 -0400 Subject: [PATCH] Added decompression/compression of packets. Cleaned up handshaking. --- FFXIVClassic Common Class Lib/BasePacket.cs | 23 +++++++++ FFXIVClassic Common Class Lib/packages.config | 1 + .../DataObjects/Session.cs | 9 ++-- .../FFXIVClassic World Server.csproj | 3 ++ FFXIVClassic Proxy Server/PacketProcessor.cs | 47 ++++--------------- .../Packets/Send/_0x2Packet.cs | 44 +++++++++++++++++ .../Packets/Send/_0x7Packet.cs | 37 +++++++++++++++ ...0x7ResponsePacket.cs => _0x8PingPacket.cs} | 2 +- 8 files changed, 123 insertions(+), 43 deletions(-) create mode 100644 FFXIVClassic Proxy Server/Packets/Send/_0x2Packet.cs create mode 100644 FFXIVClassic Proxy Server/Packets/Send/_0x7Packet.cs rename FFXIVClassic Proxy Server/Packets/Send/{0x7ResponsePacket.cs => _0x8PingPacket.cs} (96%) diff --git a/FFXIVClassic Common Class Lib/BasePacket.cs b/FFXIVClassic Common Class Lib/BasePacket.cs index 384dbc88..a6fb2a89 100644 --- a/FFXIVClassic Common Class Lib/BasePacket.cs +++ b/FFXIVClassic Common Class Lib/BasePacket.cs @@ -5,6 +5,7 @@ using System.IO; using System.Runtime.InteropServices; using NLog; using NLog.Targets; +using Ionic.Zlib; namespace FFXIVClassic.Common { @@ -346,6 +347,28 @@ namespace FFXIVClassic.Common } } + public static unsafe void DecompressPacket(ref BasePacket packet) + { + using (var compressedStream = new MemoryStream(packet.data)) + using (var zipStream = new ZlibStream(compressedStream, Ionic.Zlib.CompressionMode.Decompress)) + using (var resultStream = new MemoryStream()) + { + zipStream.CopyTo(resultStream); + packet.data = resultStream.ToArray(); + } + } + + public static unsafe void CompressPacket(ref BasePacket packet) + { + using (var compressedStream = new MemoryStream(packet.data)) + using (var zipStream = new ZlibStream(compressedStream, Ionic.Zlib.CompressionMode.Compress)) + using (var resultStream = new MemoryStream()) + { + zipStream.CopyTo(resultStream); + packet.data = resultStream.ToArray(); + } + } + #endregion } diff --git a/FFXIVClassic Common Class Lib/packages.config b/FFXIVClassic Common Class Lib/packages.config index 8b2d1420..5436126a 100644 --- a/FFXIVClassic Common Class Lib/packages.config +++ b/FFXIVClassic Common Class Lib/packages.config @@ -1,5 +1,6 @@  + \ No newline at end of file diff --git a/FFXIVClassic Proxy Server/DataObjects/Session.cs b/FFXIVClassic Proxy Server/DataObjects/Session.cs index 80e9011c..31f29e9d 100644 --- a/FFXIVClassic Proxy Server/DataObjects/Session.cs +++ b/FFXIVClassic Proxy Server/DataObjects/Session.cs @@ -11,16 +11,17 @@ namespace FFXIVClassic_World_Server.DataObjects { public enum Channel {ZONE, CHAT}; - public readonly ulong sessionId; - public readonly ClientConnection clientSocket; + public readonly uint sessionId; + public readonly ClientConnection clientConnection; public readonly Channel type; public ZoneServer routing1, routing2; - public Session(ulong sessionId, ClientConnection socket, Channel type) + public Session(ulong sessionId, ClientConnection connection, Channel type) { this.sessionId = sessionId; - this.clientSocket = socket; + this.clientConnection = connection; this.type = type; + connection.owner = this; } } diff --git a/FFXIVClassic Proxy Server/FFXIVClassic World Server.csproj b/FFXIVClassic Proxy Server/FFXIVClassic World Server.csproj index 403e4f77..52bf2d63 100644 --- a/FFXIVClassic Proxy Server/FFXIVClassic World Server.csproj +++ b/FFXIVClassic Proxy Server/FFXIVClassic World Server.csproj @@ -67,6 +67,9 @@ + + + diff --git a/FFXIVClassic Proxy Server/PacketProcessor.cs b/FFXIVClassic Proxy Server/PacketProcessor.cs index 0e385e63..6b57605c 100644 --- a/FFXIVClassic Proxy Server/PacketProcessor.cs +++ b/FFXIVClassic Proxy Server/PacketProcessor.cs @@ -1,11 +1,11 @@ using FFXIVClassic.Common; using FFXIVClassic_World_Server.DataObjects; using FFXIVClassic_World_Server.Packets.Receive; +using FFXIVClassic_World_Server.Packets.Send; using FFXIVClassic_World_Server.Packets.Send.Login; using System; using System.Collections.Generic; using System.IO; -using System.Text; namespace FFXIVClassic_World_Server { @@ -27,7 +27,6 @@ namespace FFXIVClassic_World_Server Server mServer; - List mConnections; public PacketProcessor(Server server) { @@ -36,57 +35,29 @@ namespace FFXIVClassic_World_Server public void ProcessPacket(ClientConnection client, BasePacket packet) { - //if (packet.header.isCompressed == 0x01) - // BasePacket.DecryptPacket(client.blowfish, ref packet); + if (packet.header.isCompressed == 0x01) + BasePacket.DecompressPacket(ref packet); List subPackets = packet.GetSubpackets(); foreach (SubPacket subpacket in subPackets) { //Initial Connect Packet, Create session if (subpacket.header.type == 0x01) - { - - #region Hardcoded replies - packet.DebugPrintPacket(); - byte[] reply1Data = { - 0x01, 0x00, 0x00, 0x00, 0x28, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x18, 0x00, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7F, 0xFD, 0xFF, 0xFF, - 0xE5, 0x6E, 0x01, 0xE0, 0x00, 0x00, 0x00, 0x0 - }; - - byte[] reply2Data = { - 0x01, 0x00, 0x00, 0x00, 0x28, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x38, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x50, 0x2B, 0x5F, 0x26, - 0x66, 0x00, 0x00, 0x00, 0xC8, 0xD6, 0xAF, 0x2B, 0x38, 0x2B, 0x5F, 0x26, 0xB8, 0x8D, 0xF0, 0x2B, - 0xC8, 0xFD, 0x85, 0xFE, 0xA8, 0x7C, 0x5B, 0x09, 0x38, 0x2B, 0x5F, 0x26, 0xC8, 0xD6, 0xAF, 0x2B, - 0xB8, 0x8D, 0xF0, 0x2B, 0x88, 0xAF, 0x5E, 0x26 - }; - - BasePacket reply1 = new BasePacket(reply1Data); - BasePacket reply2 = new BasePacket(reply2Data); - - //Write Timestamp into Reply1 - using (MemoryStream mem = new MemoryStream(reply1.data)) - { - using (BinaryWriter binReader = new BinaryWriter(mem)) - { - binReader.BaseStream.Seek(0x14, SeekOrigin.Begin); - binReader.Write((UInt32)Utils.UnixTimeStampUTC()); - } - } - #endregion - + { HelloPacket hello = new HelloPacket(packet.data); if (packet.header.connectionType == BasePacket.TYPE_ZONE) mServer.AddSession(client, Session.Channel.ZONE, hello.sessionId); else if (packet.header.connectionType == BasePacket.TYPE_CHAT) - mServer.AddSession(client, Session.Channel.CHAT, hello.sessionId); + mServer.AddSession(client, Session.Channel.CHAT, hello.sessionId); + + client.QueuePacket(_0x7Packet.BuildPacket(0x0E016EE5), true, false); + client.QueuePacket(_0x2Packet.BuildPacket(hello.sessionId), true, false); } //Ping from World Server else if (subpacket.header.type == 0x07) { - SubPacket init = Login0x7ResponsePacket.BuildPacket(0x50); + SubPacket init = _0x8PingPacket.BuildPacket(client.owner.sessionId); client.QueuePacket(BasePacket.CreatePacket(init, true, false)); } //Zoning Related diff --git a/FFXIVClassic Proxy Server/Packets/Send/_0x2Packet.cs b/FFXIVClassic Proxy Server/Packets/Send/_0x2Packet.cs new file mode 100644 index 00000000..3497e935 --- /dev/null +++ b/FFXIVClassic Proxy Server/Packets/Send/_0x2Packet.cs @@ -0,0 +1,44 @@ +using FFXIVClassic.Common; +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace FFXIVClassic_World_Server.Packets.Send +{ + class _0x2Packet + { + public const ushort OPCODE = 0x0002; + public const uint PACKET_SIZE = 0x38; + + public static SubPacket BuildPacket(uint actorID) + { + byte[] data = new byte[PACKET_SIZE]; + + using (MemoryStream mem = new MemoryStream(data)) + { + using (BinaryWriter binWriter = new BinaryWriter(mem)) + { + try + { + binWriter.Write((UInt32)actorID); + } + catch (Exception) + { } + } + } + + byte[] reply2Data = { + 0x66, 0x00, 0x00, 0x00, 0xC8, 0xD6, 0xAF, 0x2B, 0x38, 0x2B, 0x5F, 0x26, 0xB8, 0x8D, 0xF0, 0x2B, + 0xC8, 0xFD, 0x85, 0xFE, 0xA8, 0x7C, 0x5B, 0x09, 0x38, 0x2B, 0x5F, 0x26, 0xC8, 0xD6, 0xAF, 0x2B, + 0xB8, 0x8D, 0xF0, 0x2B, 0x88, 0xAF, 0x5E, 0x26 + }; + + data = reply2Data; + + return new SubPacket(false, OPCODE, 0, 0, data); + } + } +} diff --git a/FFXIVClassic Proxy Server/Packets/Send/_0x7Packet.cs b/FFXIVClassic Proxy Server/Packets/Send/_0x7Packet.cs new file mode 100644 index 00000000..f0854229 --- /dev/null +++ b/FFXIVClassic Proxy Server/Packets/Send/_0x7Packet.cs @@ -0,0 +1,37 @@ +using FFXIVClassic.Common; +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace FFXIVClassic_World_Server.Packets.Send +{ + class _0x7Packet + { + public const ushort OPCODE = 0x0007; + public const uint PACKET_SIZE = 0x18; + + public static SubPacket BuildPacket(uint actorID) + { + byte[] data = new byte[PACKET_SIZE]; + + using (MemoryStream mem = new MemoryStream(data)) + { + using (BinaryWriter binWriter = new BinaryWriter(mem)) + { + try + { + binWriter.Write((UInt32)actorID); + binWriter.Write((UInt32)Utils.UnixTimeStampUTC()); + } + catch (Exception) + { } + } + } + + return new SubPacket(false, OPCODE, 0, 0, data); + } + } +} diff --git a/FFXIVClassic Proxy Server/Packets/Send/0x7ResponsePacket.cs b/FFXIVClassic Proxy Server/Packets/Send/_0x8PingPacket.cs similarity index 96% rename from FFXIVClassic Proxy Server/Packets/Send/0x7ResponsePacket.cs rename to FFXIVClassic Proxy Server/Packets/Send/_0x8PingPacket.cs index 7f3b2dc7..21061c7e 100644 --- a/FFXIVClassic Proxy Server/Packets/Send/0x7ResponsePacket.cs +++ b/FFXIVClassic Proxy Server/Packets/Send/_0x8PingPacket.cs @@ -4,7 +4,7 @@ using System.IO; namespace FFXIVClassic_World_Server.Packets.Send.Login { - class Login0x7ResponsePacket + class _0x8PingPacket { public const ushort OPCODE = 0x0008; public const uint PACKET_SIZE = 0x18;