remove over debug, and fix mainui login, and reinvent handlers

This commit is contained in:
rfi 2023-10-14 20:00:56 +07:00
parent 630b0aab84
commit 6fb53b1c46
6 changed files with 456 additions and 669 deletions

View File

@ -8,7 +8,7 @@
<ItemGroup>
<PackageReference Include="Config.Net" Version="5.1.5" />
<PackageReference Include="MessagePack" Version="2.5.129" />
<PackageReference Include="MessagePack" Version="2.4.59" />
<PackageReference Include="MongoDB.Driver" Version="2.21.0" />
</ItemGroup>

View File

@ -1,4 +1,6 @@
#pragma warning disable CS8618 // Non-nullable field must contain a non-null value when exiting constructor. Consider declaring as nullable.
using MessagePack;
namespace AscNet.Common.MsgPack
{
[global::MessagePack.MessagePackObject(true)]
@ -37,7 +39,7 @@ namespace AscNet.Common.MsgPack
{
public Int32 Code { get; set; }
public Int32 UtcOffset { get; set; }
public UInt32 UtcServerTime { get; set; }
public Int64 UtcServerTime { get; set; }
public String ReconnectToken { get; set; }
}
@ -49,246 +51,292 @@ namespace AscNet.Common.MsgPack
}
[global::MessagePack.MessagePackObject(true)]
public class NotifyLogin
[MessagePackObject(true)]
public partial class BaseEquipLoginData
{
[global::MessagePack.MessagePackObject(true)]
public class NotifyLoginPlayerData
{
public UInt32 Id { get; set; }
public String Name { get; set; }
public Int32 Level { get; set; }
public String Sign { get; set; }
public UInt32 DisplayCharId { get; set; }
[global::MessagePack.MessagePackObject(true)]
public class NotifyLoginPlayerDataBirthday
{
public Int32 Mon { get; set; }
public Int32 Day { get; set; }
public object[] BaseEquipList { get; set; }
public object[] DressedList { get; set; }
}
public NotifyLoginPlayerDataBirthday Birthday { get; set; }
public Int32 HonorLevel { get; set; }
public String ServerId { get; set; }
public Int32 Likes { get; set; }
public Int32 CurrTeamId { get; set; }
public Int32 ChallengeEventId { get; set; }
public UInt32 CurrHeadPortraitId { get; set; }
public Int32 CurrHeadFrameId { get; set; }
public Int32 CurrMedalId { get; set; }
public Int32 AppearanceShowType { get; set; }
public Int32 DailyReceiveGiftCount { get; set; }
public Int32 DailyActivenessRewardStatus { get; set; }
public Int32 WeeklyActivenessRewardStatus { get; set; }
public List<Int32> Marks { get; set; } = new();
public List<UInt32> GuideData { get; set; } = new();
public List<Int32> Communications { get; set; } = new();
public List<dynamic> ShowCharacters { get; set; } = new();
public List<dynamic> ShieldFuncList { get; set; } = new();
[global::MessagePack.MessagePackObject(true)]
public class NotifyLoginPlayerDataAppearanceSettingInfo
[MessagePackObject(true)]
public partial class ChangePlayerMarkResponse
{
public Int32 TitleType { get; set; }
public Int32 CharacterType { get; set; }
public Int32 FashionType { get; set; }
public Int32 WeaponFashionType { get; set; }
public Int32 DormitoryType { get; set; }
public UInt32 DormitoryId { get; set; }
public int Code { get; set; }
}
public NotifyLoginPlayerDataAppearanceSettingInfo AppearanceSettingInfo { get; set; }
public UInt32 CreateTime { get; set; }
public UInt32 LastLoginTime { get; set; }
public Int32 ReportTime { get; set; }
public UInt32 ChangeNameTime { get; set; }
public Int32 Flags { get; set; }
}
public NotifyLoginPlayerData PlayerData { get; set; }
[global::MessagePack.MessagePackObject(true)]
public class NotifyLoginTimeLimitCtrlConfig
[MessagePackObject(true)]
public partial class LoginCharacterList
{
public Int32 Id { get; set; }
public UInt32 StartTime { get; set; }
public UInt32 EndTime { get; set; }
public long Id { get; set; }
public long Level { get; set; }
public long Exp { get; set; }
public long Quality { get; set; }
public long InitQuality { get; set; }
public long Star { get; set; }
public long Grade { get; set; }
public SkillList[] SkillList { get; set; }
public object[] EnhanceSkillList { get; set; }
public long FashionId { get; set; }
public long CreateTime { get; set; }
public long TrustLv { get; set; }
public long TrustExp { get; set; }
public long Ability { get; set; }
public long LiberateLv { get; set; }
public CharacterHeadInfo CharacterHeadInfo { get; set; }
}
public List<NotifyLoginTimeLimitCtrlConfig> TimeLimitCtrlConfigList { get; set; } = new();
[global::MessagePack.MessagePackObject(true)]
public class NotifyLoginSharePlatformConfig
[MessagePackObject(true)]
public partial class CharacterHeadInfo
{
public Int32 Id { get; set; }
public List<Int32> SdkId { get; set; } = new();
public long HeadFashionId { get; set; }
public long HeadFashionType { get; set; }
}
public List<NotifyLoginSharePlatformConfig> SharePlatformConfigList { get; set; } = new();
[global::MessagePack.MessagePackObject(true)]
public class NotifyLoginItem
[MessagePackObject(true)]
public partial class SkillList
{
public Int32 Id { get; set; }
public UInt32 Count { get; set; }
public Int32 BuyTimes { get; set; }
public Int32 TotalBuyTimes { get; set; }
public Int32 LastBuyTime { get; set; }
public UInt32 RefreshTime { get; set; }
public UInt32 CreateTime { get; set; }
public long Id { get; set; }
public long Level { get; set; }
}
public List<NotifyLoginItem> ItemList { get; set; } = new();
public Dictionary<dynamic, dynamic> ItemRecycleDict { get; set; }
[global::MessagePack.MessagePackObject(true)]
public class NotifyLoginCharacter
[MessagePackObject(true)]
public partial class EquipList
{
public UInt32 Id { get; set; }
public Int32 Level { get; set; }
public Int32 Exp { get; set; }
public Int32 Quality { get; set; }
public Int32 InitQuality { get; set; }
public Int32 Star { get; set; }
public Int32 Grade { get; set; }
[global::MessagePack.MessagePackObject(true)]
public class NotifyLoginCharacterSkill
public long Id { get; set; }
public long TemplateId { get; set; }
public long CharacterId { get; set; }
public long Level { get; set; }
public long Exp { get; set; }
public long Breakthrough { get; set; }
public ResonanceInfo[] ResonanceInfo { get; set; }
public object[] UnconfirmedResonanceInfo { get; set; }
public object[] AwakeSlotList { get; set; }
public bool IsLock { get; set; }
public long CreateTime { get; set; }
public bool IsRecycle { get; set; }
}
[MessagePackObject(true)]
public partial class ResonanceInfo
{
public UInt32 Id { get; set; }
public Int32 Level { get; set; }
public long Slot { get; set; }
public long Type { get; set; }
public long CharacterId { get; set; }
public long TemplateId { get; set; }
}
public List<NotifyLoginCharacterSkill> SkillList { get; set; } = new();
public List<dynamic> EnhanceSkillList { get; set; } = new();
public UInt32 FashionId { get; set; }
public UInt32 CreateTime { get; set; }
public Int32 TrustLv { get; set; }
public Int32 TrustExp { get; set; }
public UInt32 Ability { get; set; }
public Int32 LiberateLv { get; set; }
[global::MessagePack.MessagePackObject(true)]
public class NotifyLoginCharacterCharacterHeadInfo
[MessagePackObject(true)]
public partial class FashionList
{
public UInt32 HeadFashionId { get; set; }
public Int32 HeadFashionType { get; set; }
public long Id { get; set; }
public bool IsLock { get; set; }
}
public NotifyLoginCharacterCharacterHeadInfo CharacterHeadInfo { get; set; }
}
public List<NotifyLoginCharacter> CharacterList { get; set; } = new();
[global::MessagePack.MessagePackObject(true)]
public class NotifyLoginEquip
[MessagePackObject(true)]
public partial class FubenLoginData
{
public Int32 Id { get; set; }
public UInt32 TemplateId { get; set; }
public Int32 CharacterId { get; set; }
public Int32 Level { get; set; }
public Int32 Exp { get; set; }
public Int32 Breakthrough { get; set; }
public List<dynamic> ResonanceInfo { get; set; } = new();
public List<dynamic> UnconfirmedResonanceInfo { get; set; } = new();
public List<dynamic> AwakeSlotList { get; set; } = new();
public Boolean IsLock { get; set; }
public UInt32 CreateTime { get; set; }
public Boolean IsRecycle { get; set; }
public object[] TreasureData { get; set; }
public object[] LastPassStage { get; set; }
public object[] ChapterEventInfos { get; set; }
}
public List<NotifyLoginEquip> EquipList { get; set; } = new();
[global::MessagePack.MessagePackObject(true)]
public class NotifyLoginFashion
[MessagePackObject(true)]
public partial class FubenData
{
public UInt32 Id { get; set; }
public Boolean IsLock { get; set; }
public Dictionary<int, StageDatum> StageData { get; set; }
public FubenBaseData FubenBaseData { get; set; }
public object[] UnlockHideStages { get; set; }
public object[] StageDifficulties { get; set; }
}
public List<NotifyLoginFashion> FashionList { get; set; } = new();
[global::MessagePack.MessagePackObject(true)]
public class NotifyLoginHeadPortrait
[MessagePackObject(true)]
public partial class FubenBaseData
{
public UInt32 Id { get; set; }
public Int32 LeftCount { get; set; }
public UInt32 BeginTime { get; set; }
public long RefreshTime { get; set; }
public long SelectedCharId { get; set; }
public long UrgentAlarmCount { get; set; }
public long WeeklyUrgentCount { get; set; }
public object DayUrgentCount { get; set; }
}
public List<NotifyLoginHeadPortrait> HeadPortraitList { get; set; } = new();
[global::MessagePack.MessagePackObject(true)]
public class NotifyLoginBaseEquipLoginData
[MessagePackObject(true)]
public partial class ItemRecycleData
{
public List<dynamic> BaseEquipList { get; set; } = new();
public List<dynamic> DressedList { get; set; } = new();
public int Id { get; set; }
public long RecycleTime { get; set; }
public int RecycleCount { get; set; }
}
public NotifyLoginBaseEquipLoginData BaseEquipLoginData { get; set; }
[global::MessagePack.MessagePackObject(true)]
public class NotifyLoginFubenData
[MessagePackObject(true)]
public partial class StageDatum
{
public Dictionary<dynamic, dynamic> StageData { get; set; }
[global::MessagePack.MessagePackObject(true)]
public class NotifyLoginFubenDataFubenBaseData
public long StageId { get; set; }
public long StarsMark { get; set; }
public bool Passed { get; set; }
public long PassTimesToday { get; set; }
public long PassTimesTotal { get; set; }
public long BuyCount { get; set; }
public long Score { get; set; }
public long LastPassTime { get; set; }
public long RefreshTime { get; set; }
public long CreateTime { get; set; }
public long BestRecordTime { get; set; }
public long LastRecordTime { get; set; }
public long[] BestCardIds { get; set; }
public long[] LastCardIds { get; set; }
}
[MessagePackObject(true)]
public partial class FubenMainLineData
{
public Int32 RefreshTime { get; set; }
public UInt32 SelectedCharId { get; set; }
public Int32 UrgentAlarmCount { get; set; }
public Int32 WeeklyUrgentCount { get; set; }
public dynamic? DayUrgentCount { get; set; }
public long[] TreasureData { get; set; }
public Dictionary<int, long> LastPassStage { get; set; }
public object[] MainChapterEventInfos { get; set; }
}
public NotifyLoginFubenDataFubenBaseData FubenBaseData { get; set; }
public List<dynamic> UnlockHideStages { get; set; } = new();
public List<dynamic> StageDifficulties { get; set; } = new();
}
public NotifyLoginFubenData FubenData { get; set; }
[global::MessagePack.MessagePackObject(true)]
public class NotifyLoginFubenMainLineData
[MessagePackObject(true)]
public partial class FubenUrgentEventData
{
public List<UInt32> TreasureData { get; set; } = new();
public Dictionary<dynamic, dynamic> LastPassStage { get; set; }
public List<dynamic> MainChapterEventInfos { get; set; } = new();
public object UrgentEventData { get; set; }
}
public NotifyLoginFubenMainLineData FubenMainLineData { get; set; }
[global::MessagePack.MessagePackObject(true)]
public class NotifyLoginFubenChapterExtraLoginData
[MessagePackObject(true)]
public partial class HeadPortraitList
{
public List<dynamic> TreasureData { get; set; } = new();
public List<dynamic> LastPassStage { get; set; } = new();
public List<dynamic> ChapterEventInfos { get; set; } = new();
public long Id { get; set; }
public long LeftCount { get; set; }
public long BeginTime { get; set; }
}
public NotifyLoginFubenChapterExtraLoginData FubenChapterExtraLoginData { get; set; }
[global::MessagePack.MessagePackObject(true)]
public class NotifyLoginFubenUrgentEventData
[MessagePackObject(true)]
public partial class ItemList
{
public dynamic? UrgentEventData { get; set; }
public long Id { get; set; }
public long Count { get; set; }
public long BuyTimes { get; set; }
public long TotalBuyTimes { get; set; }
public long LastBuyTime { get; set; }
public long RefreshTime { get; set; }
public long CreateTime { get; set; }
}
public NotifyLoginFubenUrgentEventData FubenUrgentEventData { get; set; }
public List<dynamic> AutoFightRecords { get; set; } = new();
public Dictionary<dynamic, dynamic> TeamGroupData { get; set; }
public dynamic? TeamPrefabData { get; set; }
[global::MessagePack.MessagePackObject(true)]
public class NotifyLoginSignInfo
[MessagePackObject(true)]
public partial class PlayerData
{
public Int32 Id { get; set; }
public Int32 Round { get; set; }
public Int32 Day { get; set; }
public Boolean Got { get; set; }
public UInt32 FinishDay { get; set; }
public long Id { get; set; }
public string Name { get; set; }
public long Level { get; set; }
public string Sign { get; set; }
public long DisplayCharId { get; set; }
public Birthday Birthday { get; set; }
public long HonorLevel { get; set; }
public string ServerId { get; set; }
public long Likes { get; set; }
public long CurrTeamId { get; set; }
public long ChallengeEventId { get; set; }
public long CurrHeadPortraitId { get; set; }
public long CurrHeadFrameId { get; set; }
public long CurrMedalId { get; set; }
public long AppearanceShowType { get; set; }
public long DailyReceiveGiftCount { get; set; }
public long DailyActivenessRewardStatus { get; set; }
public long WeeklyActivenessRewardStatus { get; set; }
public long[] Marks { get; set; }
public long[] GuideData { get; set; }
public long[] Communications { get; set; }
public long[] ShowCharacters { get; set; }
public object[] ShieldFuncList { get; set; }
public AppearanceSettingInfo AppearanceSettingInfo { get; set; }
public long CreateTime { get; set; }
public long LastLoginTime { get; set; }
public long ReportTime { get; set; }
public long ChangeNameTime { get; set; }
public long Flags { get; set; }
}
public List<NotifyLoginSignInfo> SignInfos { get; set; } = new();
public List<dynamic> AssignChapterRecord { get; set; } = new();
public List<dynamic> WeaponFashionList { get; set; } = new();
public List<dynamic> PartnerList { get; set; } = new();
public List<dynamic> ShieldedProtocolList { get; set; } = new();
public dynamic? LimitedLoginData { get; set; }
public UInt32 UseBackgroundId { get; set; }
[global::MessagePack.MessagePackObject(true)]
public class NotifyLoginFubenShortStoryLoginData
[MessagePackObject(true)]
public partial class AppearanceSettingInfo
{
public List<dynamic> TreasureData { get; set; } = new();
public List<dynamic> LastPassStage { get; set; } = new();
public List<dynamic> ChapterEventInfos { get; set; } = new();
public long TitleType { get; set; }
public long CharacterType { get; set; }
public long FashionType { get; set; }
public long WeaponFashionType { get; set; }
public long DormitoryType { get; set; }
public long DormitoryId { get; set; }
}
public NotifyLoginFubenShortStoryLoginData FubenShortStoryLoginData { get; set; }
[MessagePackObject(true)]
public partial class Birthday
{
public long Mon { get; set; }
public long Day { get; set; }
}
[MessagePackObject(true)]
public partial class SharePlatformConfigList
{
public long Id { get; set; }
public long[] SdkId { get; set; }
}
[MessagePackObject(true)]
public partial class SignInfo
{
public long Id { get; set; }
public long Round { get; set; }
public long Day { get; set; }
public bool Got { get; set; }
public long FinishDay { get; set; }
}
[MessagePackObject(true)]
public partial class TeamGroupDatum
{
public long TeamType { get; set; }
public long TeamId { get; set; }
public long CaptainPos { get; set; }
public long FirstFightPos { get; set; }
public Dictionary<int, long> TeamData { get; set; }
public object TeamName { get; set; }
}
[MessagePackObject(true)]
public partial class TimeLimitCtrlConfigList
{
public long Id { get; set; }
public long StartTime { get; set; }
public long EndTime { get; set; }
}
[MessagePackObject(true)]
public partial class NotifyLogin
{
public PlayerData PlayerData { get; set; }
public TimeLimitCtrlConfigList[] TimeLimitCtrlConfigList { get; set; }
public SharePlatformConfigList[] SharePlatformConfigList { get; set; }
public ItemList[] ItemList { get; set; }
public Dictionary<int, ItemRecycleData[]> ItemRecycleDict { get; set; }
public LoginCharacterList[] CharacterList { get; set; }
public EquipList[] EquipList { get; set; }
public FashionList[] FashionList { get; set; }
public HeadPortraitList[] HeadPortraitList { get; set; }
public BaseEquipLoginData BaseEquipLoginData { get; set; }
public FubenData FubenData { get; set; }
public FubenMainLineData FubenMainLineData { get; set; }
public FubenLoginData FubenChapterExtraLoginData { get; set; }
public FubenUrgentEventData FubenUrgentEventData { get; set; }
public object[] AutoFightRecords { get; set; }
public Dictionary<int, TeamGroupDatum> TeamGroupData { get; set; }
public object TeamPrefabData { get; set; }
public SignInfo[] SignInfos { get; set; }
public object[] AssignChapterRecord { get; set; }
public object[] WeaponFashionList { get; set; }
public object[] PartnerList { get; set; }
public object[] ShieldedProtocolList { get; set; }
public object LimitedLoginData { get; set; }
public long UseBackgroundId { get; set; }
public FubenLoginData FubenShortStoryLoginData { get; set; }
}
@ -866,6 +914,17 @@ namespace AscNet.Common.MsgPack
public int Id { get; set; }
}
[MessagePack.MessagePackObject(true)]
public class GuideOpenRequest
{
public int GuideGroupId { get; set; }
}
[MessagePack.MessagePackObject(true)]
public class GuideOpenResponse
{
public int Code { get; set; }
}
[MessagePack.MessagePackObject(true)]
public class SignInResponse
@ -1967,7 +2026,7 @@ namespace AscNet.Common.MsgPack
[global::MessagePack.MessagePackObject(true)]
public class HeartbeatResponse
{
public UInt32 UtcServerTime { get; set; }
public long UtcServerTime { get; set; }
}

View File

@ -7,7 +7,7 @@
</PropertyGroup>
<ItemGroup>
<PackageReference Include="MessagePack" Version="2.5.129" />
<PackageReference Include="MessagePack" Version="2.4.59" />
<PackageReference Include="Newtonsoft.Json" Version="13.0.3" />
</ItemGroup>

File diff suppressed because one or more lines are too long

View File

@ -77,24 +77,29 @@ namespace AscNet.GameServer
#pragma warning restore CS8618 // Non-nullable field must contain a non-null value when exiting constructor. Consider declaring as nullable.
[AttributeUsage(AttributeTargets.Method)]
public class PacketHandler : Attribute
public class RequestPacketHandler : Attribute
{
public string Name { get; }
public PacketHandler(string name)
public RequestPacketHandler(string name)
{
Name = name;
}
}
public delegate void PacketHandlerDelegate(Session session, byte[] packet);
public delegate void RequestPacketHandlerDelegate(Session session, Packet.Request packet);
public static class PacketFactory
{
public static readonly Dictionary<string, PacketHandlerDelegate> Handlers = new();
public static readonly Dictionary<string, RequestPacketHandlerDelegate> ReqHandlers = new();
static readonly Logger c = new("Factory", ConsoleColor.Yellow);
public static void LoadPacketHandlers()
{
LoadRequestPacketHandlers();
}
private static void LoadRequestPacketHandlers()
{
c.Log("Loading Packet Handlers...");
@ -103,9 +108,9 @@ namespace AscNet.GameServer
foreach (var method in classes.SelectMany(t => t.GetMethods(BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic)))
{
var attr = method.GetCustomAttribute<PacketHandler>(false);
if (attr == null || Handlers.ContainsKey(attr.Name)) continue;
Handlers.Add(attr.Name, (PacketHandlerDelegate)Delegate.CreateDelegate(typeof(PacketHandlerDelegate), method));
var attr = method.GetCustomAttribute<RequestPacketHandler>(false);
if (attr == null || ReqHandlers.ContainsKey(attr.Name)) continue;
ReqHandlers.Add(attr.Name, (RequestPacketHandlerDelegate)Delegate.CreateDelegate(typeof(RequestPacketHandlerDelegate), method));
#if DEBUG
c.Log($"Loaded {method.Name}");
#endif
@ -114,9 +119,9 @@ namespace AscNet.GameServer
c.Log("Finished Loading Packet Handlers");
}
public static PacketHandlerDelegate? GetPacketHandler(string name)
public static RequestPacketHandlerDelegate? GetRequestPacketHandler(string name)
{
Handlers.TryGetValue(name, out PacketHandlerDelegate? handler);
ReqHandlers.TryGetValue(name, out RequestPacketHandlerDelegate? handler);
return handler;
}
}

View File

@ -12,7 +12,7 @@ namespace AscNet.GameServer
public readonly TcpClient client;
public readonly Logger c;
private long lastPacketTime = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds();
private ushort packetNo = 1;
private ushort packetNo = 0;
private readonly MessagePackSerializerOptions lz4Options = MessagePackSerializerOptions.Standard.WithCompression(MessagePackCompression.Lz4Block);
public Session(string id, TcpClient tcpClient)
@ -76,12 +76,21 @@ namespace AscNet.GameServer
case Packet.ContentType.Request:
Packet.Request request = MessagePackSerializer.Deserialize<Packet.Request>(packet.Content);
debugContent = request.Content;
PacketFactory.GetPacketHandler(request.Name)?.Invoke(this, request.Content);
RequestPacketHandlerDelegate? requestPacketHandler = PacketFactory.GetRequestPacketHandler(request.Name);
if (requestPacketHandler is not null)
{
c.Log(request.Name);
requestPacketHandler.Invoke(this, request);
}
else
c.Warn($"{request.Name} handler not found!");
break;
case Packet.ContentType.Push:
Packet.Push push = MessagePackSerializer.Deserialize<Packet.Push>(packet.Content);
debugContent = push.Content;
PacketFactory.GetPacketHandler(push.Name)?.Invoke(this, push.Content);
c.Log(push.Name);
throw new NotImplementedException($"Packet push handlers not implemented ({push.Name})");
break;
case Packet.ContentType.Exception:
Packet.Exception exception = MessagePackSerializer.Deserialize<Packet.Exception>(packet.Content);
@ -122,30 +131,44 @@ namespace AscNet.GameServer
};
Send(new Packet()
{
No = packetNo,
No = ++packetNo,
Type = Packet.ContentType.Push,
Content = MessagePackSerializer.Serialize(packet)
});
c.Log(packet.Name + " " + JsonConvert.SerializeObject(push));
packetNo++;
c.Log(packet.Name);
}
public void SendResponse<T>(T response)
public void SendPush(string name, byte[] push)
{
Packet.Push packet = new()
{
Name = name,
Content = push
};
Send(new Packet()
{
No = ++packetNo,
Type = Packet.ContentType.Push,
Content = MessagePackSerializer.Serialize(packet)
});
c.Log(packet.Name);
}
public void SendResponse<T>(T response, int clientSeq = 0)
{
Packet.Response packet = new()
{
Id = 1,
Name = typeof(T).Name,
Id = clientSeq,
Name = response!.GetType().Name,
Content = MessagePackSerializer.Serialize(response)
};
Send(new Packet()
{
No = packetNo,
No = 0,
Type = Packet.ContentType.Response,
Content = MessagePackSerializer.Serialize(packet)
});
c.Log(packet.Name + " " + JsonConvert.SerializeObject(response));
packetNo++;
c.Log(packet.Name);
}
private void Send(Packet packet)