diff --git a/AscNet.GameServer/Packet.cs b/AscNet.GameServer/Packet.cs
index 1a0a3920..d709af8f 100644
--- a/AscNet.GameServer/Packet.cs
+++ b/AscNet.GameServer/Packet.cs
@@ -1,6 +1,4 @@
-using System.Net.Sockets;
-using System.Reflection;
-using AscNet.Common.MsgPack;
+using System.Reflection;
using AscNet.Logging;
using MessagePack;
diff --git a/AscNet.PcapParser/App.config b/AscNet.PcapParser/App.config
new file mode 100644
index 00000000..f802fd41
--- /dev/null
+++ b/AscNet.PcapParser/App.config
@@ -0,0 +1,22 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/AscNet.PcapParser/AscNet.PcapParser.csproj b/AscNet.PcapParser/AscNet.PcapParser.csproj
new file mode 100644
index 00000000..f61c7225
--- /dev/null
+++ b/AscNet.PcapParser/AscNet.PcapParser.csproj
@@ -0,0 +1,102 @@
+
+
+
+
+ Debug
+ AnyCPU
+ {E2C4ED9F-8360-4D6D-888C-EF31B551C064}
+ Exe
+ AscNet.PcapParser
+ AscNet.PcapParser
+ v4.8.1
+ 512
+ true
+ true
+
+
+ AnyCPU
+ true
+ full
+ false
+ bin\Debug\
+ DEBUG;TRACE
+ prompt
+ 4
+
+
+ x64
+ pdbonly
+ true
+ bin\Release\
+ TRACE
+ prompt
+ 4
+
+
+
+ ..\packages\MessagePack.2.5.140\lib\netstandard2.0\MessagePack.dll
+
+
+ ..\packages\MessagePack.Annotations.2.5.140\lib\netstandard2.0\MessagePack.Annotations.dll
+
+
+ ..\packages\Microsoft.Bcl.AsyncInterfaces.6.0.0\lib\net461\Microsoft.Bcl.AsyncInterfaces.dll
+
+
+ ..\packages\Microsoft.NET.StringTools.17.6.3\lib\net472\Microsoft.NET.StringTools.dll
+
+
+ ..\packages\Newtonsoft.Json.13.0.3\lib\net45\Newtonsoft.Json.dll
+
+
+ ..\packages\Pcap.Net.x64.1.0.4.1\lib\net45\PcapDotNet.Base.dll
+
+
+ ..\packages\Pcap.Net.x64.1.0.4.1\lib\net45\PcapDotNet.Core.dll
+
+
+ ..\packages\Pcap.Net.x64.1.0.4.1\lib\net45\PcapDotNet.Core.Extensions.dll
+
+
+ ..\packages\Pcap.Net.x64.1.0.4.1\lib\net45\PcapDotNet.Packets.dll
+
+
+
+ ..\packages\System.Buffers.4.5.1\lib\net461\System.Buffers.dll
+
+
+ ..\packages\System.Collections.Immutable.6.0.0\lib\net461\System.Collections.Immutable.dll
+
+
+
+ ..\packages\System.Memory.4.5.5\lib\net461\System.Memory.dll
+
+
+
+ ..\packages\System.Numerics.Vectors.4.5.0\lib\net46\System.Numerics.Vectors.dll
+
+
+ ..\packages\System.Runtime.CompilerServices.Unsafe.6.0.0\lib\net461\System.Runtime.CompilerServices.Unsafe.dll
+
+
+ ..\packages\System.Threading.Tasks.Extensions.4.5.4\lib\net461\System.Threading.Tasks.Extensions.dll
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/AscNet.PcapParser/Crypto.cs b/AscNet.PcapParser/Crypto.cs
new file mode 100644
index 00000000..ae87f948
--- /dev/null
+++ b/AscNet.PcapParser/Crypto.cs
@@ -0,0 +1,91 @@
+using System;
+using System.Security.Cryptography;
+
+namespace AscNet.Common.Util
+{
+ public static class Crypto
+ {
+ public static byte[] XORCrypt(byte[] data, byte[] key)
+ {
+ byte[] encryptedData = new byte[data.Length];
+
+ for (int i = 0; i < data.Length; i++)
+ encryptedData[i] = (byte)(data[i] ^ key[i % key.Length]);
+
+ return encryptedData;
+ }
+
+ public static class HaruCrypt
+ {
+ private static readonly byte[] key = new byte[] { 103, 40, 227, 236, 173, 175, 148, 243, 66, 252, 58, 22, 68, 192, 159, 15, 187, 15, 15, 29, 209, 209, 212, 66, 104, 16, 252, 194, 227, 14, 116, 112, 196, 221, 5, 1, 4, 173, 165, 69, 45, 193, 95, 10, 67, 38, 167, 239, 96, 184, 133, 75, 152, 196, 36, 121, 251, 7, 73, 82, 219, 25, 118, 70, 153, 232, 120, 120, 147, 10, 88, 106, 214, 187, 216, 49, 224, 57, 1, 233, 110, 40, 65, 85, 246, 197, 4, 20, 56, 74, 245, 41, 63, 169, 188, 104, 89, 49, 115, 254, 100, 77, 79, 11, 148, 242, 95, 88, 241, 111, 48, 130, 169, 200, 224, 135, 121, 161, 72, 84, 5, 100, 135, 70, 141, 94, 244, 114, 58, 28, 87, 181, 205, 221, 154, 184, 197, 98, 210, 202, 252, 124, 144, 9, 112, 163, 24, 254, 119, 188, 5, 230, 40, 79, 171, 17, 156, 212, 134, 41, 79, 134, 26, 251, 123, 219, 191, 136, 21, 84, 192, 91, 24, 33, 68, 101, 85, 61, 186, 215, 191, 37, 45, 51, 117, 227, 14, 145, 56, 43, 32, 67, 48, 98, 192, 41, 136, 223, 50, 163, 97, 251, 174, 59, 59, 147, 237, 177, 31, 159, 52, 243, 245, 247, 148, 139, 21, 92, 139, 80, 47, 4, 105, 59, 227, 220, 180, 231, 176, 187, 205, 203, 148, 121, 98, 90, 87, 131, 245, 3, 63, 239, 57, 117, 102, 134, 40, 172, 60, 128, 108, 102, 216, 247, 133, 102 };
+ private static readonly RSACryptoServiceProvider rsa = new RSACryptoServiceProvider();
+ private static readonly byte[] signature = new byte[128];
+#pragma warning disable SYSLIB0021 // Type or member is obsolete
+ private static readonly SHA1 sha = new SHA1CryptoServiceProvider();
+#pragma warning restore SYSLIB0021 // Type or member is obsolete
+ private const string PUBLIC_KEY = "kZE/f0ifi0DH3uP3KCWOPqTyQ3MsQKHf9X4Z65S36s226RkdkZL2kHTz20n+IlOvGChi3ByDMFLawlyB0MCW94WDnc1Mc/PtVKo6D8gBEcSvdjDbhC4Ly0f2hMHS/SNdGPMAMkEWGNvIvfuT1TEaWTPsxRLZbfASp2KPG7Wjdck=AQAB";
+
+ static HaruCrypt()
+ {
+ rsa.FromXmlString(PUBLIC_KEY);
+ }
+
+ public static void Encrypt(byte[] content)
+ {
+ Encrypt(content, 0, content.Length);
+ }
+
+ public static void Encrypt(byte[] content, int offset, int count)
+ {
+ int num = count % key.Length;
+ for (int i = 0; i < count; i++)
+ {
+ int num2 = i + offset;
+ int num3 = (int)content[num2];
+ num3 ^= (int)key[num];
+ if (i > 0)
+ {
+ num3 ^= (int)content[num2 - 1];
+ }
+ num3 ^= (int)key[i % key.Length];
+ int num4 = ((int)((i + 1 < count) ? content[num2 + 1] : 0) + count) % 8;
+ num3 = (num3 << 8 - num4 | num3 >> num4);
+ content[num2] = (byte)num3;
+ }
+ }
+
+ public static void Decrypt(byte[] content)
+ {
+ Decrypt(content, 0, content.Length);
+ }
+
+ private static void Decrypt(byte[] bytes, int offset, int count)
+ {
+ int num = count % key.Length;
+ for (int i = count - 1; i >= 0; i--)
+ {
+ int num2 = i + offset;
+ int num3 = (int)bytes[num2];
+ int num4 = ((int)((i + 1 < count) ? bytes[num2 + 1] : 0) + count) % 8;
+ num3 = (num3 >> 8 - num4 | num3 << num4);
+ num3 ^= (int)key[i % key.Length];
+ if (num2 > offset)
+ {
+ num3 ^= (int)bytes[num2 - 1];
+ }
+ num3 ^= (int)key[num];
+ bytes[num2] = (byte)num3;
+ }
+ }
+
+ private static bool Verify(byte[] content, ref int offset, ref int count)
+ {
+ Buffer.BlockCopy(content, offset, signature, 0, signature.Length);
+ offset += signature.Length;
+ count -= signature.Length;
+ byte[] hash = sha.ComputeHash(content, offset, count);
+ return rsa.VerifyHash(hash, signature, HashAlgorithmName.SHA1, RSASignaturePadding.Pkcs1);
+ }
+ }
+ }
+}
diff --git a/AscNet.PcapParser/Packet.cs b/AscNet.PcapParser/Packet.cs
new file mode 100644
index 00000000..a6a389ed
--- /dev/null
+++ b/AscNet.PcapParser/Packet.cs
@@ -0,0 +1,104 @@
+using MessagePack;
+
+namespace AscNet.PcapParser
+{
+ [MessagePackObject(false)]
+ public class Packet
+ {
+ [Key(0)]
+ public int No;
+
+ [Key(1)]
+ public ContentType Type;
+
+ [Key(2)]
+ public byte[] Content;
+
+ public enum ContentType
+ {
+ Request,
+ Response,
+ Push,
+ Exception
+ }
+
+ [MessagePackObject(false)]
+ public class Request
+ {
+ [Key(0)]
+ public int Id;
+
+ [Key(1)]
+ public string Name;
+
+ [Key(2)]
+ public byte[] Content;
+
+ public T Deserialize()
+ {
+ return MessagePackSerializer.Deserialize(Content);
+ }
+
+ public object Deserialize()
+ {
+ return MessagePackSerializer.Typeless.Deserialize(Content);
+ }
+ }
+
+ [MessagePackObject(false)]
+ public class Response
+ {
+ [Key(0)]
+ public int Id;
+
+ [Key(1)]
+ public string Name;
+
+ [Key(2)]
+ public byte[] Content;
+
+ public T Deserialize()
+ {
+ return MessagePackSerializer.Deserialize(Content);
+ }
+
+ public object Deserialize()
+ {
+ return MessagePackSerializer.Typeless.Deserialize(Content);
+ }
+ }
+
+ [MessagePackObject(false)]
+ public class Push
+ {
+ [Key(0)]
+ public string Name;
+
+ [Key(1)]
+ public byte[] Content;
+
+ public T Deserialize()
+ {
+ return MessagePackSerializer.Deserialize(Content);
+ }
+
+ public object Deserialize()
+ {
+ return MessagePackSerializer.Typeless.Deserialize(Content);
+ }
+ }
+
+ [MessagePackObject(false)]
+ public class Exception
+ {
+ [Key(0)]
+ public int Id;
+
+ [Key(1)]
+ public int Code;
+
+ [Key(2)]
+ public string Message;
+ }
+ }
+}
diff --git a/AscNet.PcapParser/PcapParser.cs b/AscNet.PcapParser/PcapParser.cs
new file mode 100644
index 00000000..8c81f85d
--- /dev/null
+++ b/AscNet.PcapParser/PcapParser.cs
@@ -0,0 +1,240 @@
+using Newtonsoft.Json;
+using PcapDotNet.Core;
+using System.IO;
+using System;
+using System.Linq;
+using System.Buffers.Binary;
+using System.Runtime.InteropServices;
+using AscNet.Common.Util;
+using MessagePack;
+using System.Collections.Generic;
+using PcapDotNet.Packets.IpV4;
+
+namespace AscNet.PcapParser
+{
+ class PcapParser
+ {
+ private static readonly MessagePackSerializerOptions lz4Options = MessagePackSerializerOptions.Standard.WithCompression(MessagePackCompression.Lz4Block);
+ private static readonly Dictionary buffer = new Dictionary();
+ private static readonly MemoryStream memoryStream = new MemoryStream();
+ private static readonly List