ProtoBuff 0 GC :引入reset的protobuff代码生成,池化protobuff,并修改网络消息的注册方式为泛型,用完后回池

This commit is contained in:
sin365 2025-11-04 16:28:46 +08:00
parent 3d9bfe4493
commit 54f1db897e
14 changed files with 914 additions and 95 deletions

View File

@ -1,21 +1,33 @@
using Google.Protobuf; using AxibugEmuOnline.Client.Network;
using Google.Protobuf;
using System; using System;
namespace AxibugEmuOnline.Client.Common namespace AxibugEmuOnline.Client.Common
{ {
public static class ProtoBufHelper public static class ProtoBufHelper
{ {
private static ProtobufferMsgPool _msgPool = new ProtobufferMsgPool();
public static byte[] Serizlize(IMessage msg) public static byte[] Serizlize(IMessage msg)
{ {
return msg.ToByteArray(); return msg.ToByteArray();
} }
public static T DeSerizlize<T>(byte[] bytes) public static T DeSerizlizeFromPool<T>(byte[] bytes)
{ {
var msgType = typeof(T); var msgType = typeof(T);
object msg = Activator.CreateInstance(msgType); object msg = _msgPool.Get(msgType);
((IMessage)msg).MergeFrom(bytes); ((IMessage)msg).MergeFrom(bytes);
return (T)msg; return (T)msg;
} }
public static IMessage DeSerizlizeFromPool(byte[] bytes, Type protoType)
{
var msgType = protoType;
object msg = _msgPool.Get(msgType);
((IMessage)msg).MergeFrom(bytes);
return (IMessage)msg;
}
public static void ReleaseToPool(IMessage msg)
{
_msgPool.Release(msg);
}
} }
} }

View File

@ -2,12 +2,17 @@ using System;
using AxibugProtobuf; using AxibugProtobuf;
using AxibugEmuOnline.Client.Common; using AxibugEmuOnline.Client.Common;
/// <summary>
/// 用ProtoBuff记录存档
/// </summary>
public class UEGSaveByteConvert : IAxiEssgssStatusBytesCover public class UEGSaveByteConvert : IAxiEssgssStatusBytesCover
{ {
public AxiEssgssStatusData ToAxiEssgssStatusData(byte[] byteArray) public AxiEssgssStatusData ToAxiEssgssStatusData(byte[] byteArray)
{ {
pb_AxiEssgssStatusData pbdata = ProtoBufHelper.DeSerizlize<pb_AxiEssgssStatusData>(byteArray); pb_AxiEssgssStatusData dataFromPool = ProtoBufHelper.DeSerizlizeFromPool<pb_AxiEssgssStatusData>(byteArray);
return pbAxiEssgssStatusDataToSrcData(pbdata); AxiEssgssStatusData data = pbAxiEssgssStatusDataToSrcData(dataFromPool);
ProtoBufHelper.ReleaseToPool(dataFromPool);
return data;
} }
public byte[] ToByteArray(AxiEssgssStatusData data) public byte[] ToByteArray(AxiEssgssStatusData data)
{ {

View File

@ -10,7 +10,7 @@ namespace AxibugEmuOnline.Client.Manager
{ {
public AppChat() public AppChat()
{ {
NetMsg.Instance.RegNetMsgEvent((int)CommandID.CmdChatmsg, RecvChatMsg); NetMsg.Instance.RegNetMsgEvent<Protobuf_ChatMsg_RESP>((int)CommandID.CmdChatmsg, RecvChatMsg);
} }
public void SendChatMsg(string ChatMsg) public void SendChatMsg(string ChatMsg)
@ -22,9 +22,8 @@ namespace AxibugEmuOnline.Client.Manager
App.network.SendToServer((int)CommandID.CmdChatmsg, ProtoBufHelper.Serizlize(msg)); App.network.SendToServer((int)CommandID.CmdChatmsg, ProtoBufHelper.Serizlize(msg));
} }
public void RecvChatMsg(byte[] reqData) public void RecvChatMsg(Protobuf_ChatMsg_RESP msg)
{ {
Protobuf_ChatMsg_RESP msg = ProtoBufHelper.DeSerizlize<Protobuf_ChatMsg_RESP>(reqData);
Eventer.Instance.PostEvent(EEvent.OnChatMsg, msg.NickName, msg.ChatMsg); Eventer.Instance.PostEvent(EEvent.OnChatMsg, msg.NickName, msg.ChatMsg);
} }
} }

View File

@ -14,7 +14,7 @@ namespace AxibugEmuOnline.Client.Manager
public AppLogin() public AppLogin()
{ {
NetMsg.Instance.RegNetMsgEvent((int)CommandID.CmdLogin, RecvLoginMsg); NetMsg.Instance.RegNetMsgEvent<Protobuf_Login_RESP>((int)CommandID.CmdLogin, RecvLoginMsg);
} }
public void Login() public void Login()
@ -67,9 +67,8 @@ namespace AxibugEmuOnline.Client.Manager
App.network.SendToServer((int)CommandID.CmdLogin, ProtoBufHelper.Serizlize(msg)); App.network.SendToServer((int)CommandID.CmdLogin, ProtoBufHelper.Serizlize(msg));
} }
public void RecvLoginMsg(byte[] reqData) public void RecvLoginMsg(Protobuf_Login_RESP msg)
{ {
Protobuf_Login_RESP msg = ProtoBufHelper.DeSerizlize<Protobuf_Login_RESP>(reqData);
if (msg.Status == LoginResultStatus.Ok) if (msg.Status == LoginResultStatus.Ok)
{ {
App.log.Info("登录成功"); App.log.Info("登录成功");

View File

@ -41,17 +41,17 @@ namespace AxibugEmuOnline.Client.Manager
Protobuf_Screnn_Frame _Protobuf_Screnn_Frame = new Protobuf_Screnn_Frame(); Protobuf_Screnn_Frame _Protobuf_Screnn_Frame = new Protobuf_Screnn_Frame();
public AppRoom() public AppRoom()
{ {
NetMsg.Instance.RegNetMsgEvent((int)CommandID.CmdRoomList, RecvGetRoomList); NetMsg.Instance.RegNetMsgEvent<Protobuf_Room_List_RESP>((int)CommandID.CmdRoomList, RecvGetRoomList);
NetMsg.Instance.RegNetMsgEvent((int)CommandID.CmdRoomListUpdate, RecvGetRoomListUpdate); NetMsg.Instance.RegNetMsgEvent<Protobuf_Room_Update_RESP>((int)CommandID.CmdRoomListUpdate, RecvGetRoomListUpdate);
NetMsg.Instance.RegNetMsgEvent((int)CommandID.CmdRoomGetScreen, RecvRoomGetScreen); NetMsg.Instance.RegNetMsgEvent<Protobuf_Room_Get_Screen_RESP>((int)CommandID.CmdRoomGetScreen, RecvRoomGetScreen);
NetMsg.Instance.RegNetMsgEvent((int)CommandID.CmdRoomCreate, RecvCreateRoom); NetMsg.Instance.RegNetMsgEvent<Protobuf_Room_Create_RESP>((int)CommandID.CmdRoomCreate, RecvCreateRoom);
NetMsg.Instance.RegNetMsgEvent((int)CommandID.CmdRoomJoin, RecvJoinRoom); NetMsg.Instance.RegNetMsgEvent<Protobuf_Room_Join_RESP>((int)CommandID.CmdRoomJoin, RecvJoinRoom);
NetMsg.Instance.RegNetMsgEvent((int)CommandID.CmdRoomLeave, RecvLeavnRoom); NetMsg.Instance.RegNetMsgEvent<Protobuf_Room_Leave_RESP>((int)CommandID.CmdRoomLeave, RecvLeavnRoom);
NetMsg.Instance.RegNetMsgEvent((int)CommandID.CmdRoomMyRoomStateChanged, RecvRoomMyRoomStateChange); NetMsg.Instance.RegNetMsgEvent<Protobuf_Room_MyRoom_State_Change>((int)CommandID.CmdRoomMyRoomStateChanged, RecvRoomMyRoomStateChange);
NetMsg.Instance.RegNetMsgEvent((int)CommandID.CmdRoomWaitStep, RecvRoom_WaitStep); NetMsg.Instance.RegNetMsgEvent<Protobuf_Room_WaitStep_RESP>((int)CommandID.CmdRoomWaitStep, RecvRoom_WaitStep);
NetMsg.Instance.RegNetMsgEvent((int)CommandID.CmdRoomHostPlayerUpdateStateRaw, RecvHostPlayer_UpdateStateRaw); NetMsg.Instance.RegNetMsgEvent<Protobuf_Room_HostPlayer_UpdateStateRaw_RESP>((int)CommandID.CmdRoomHostPlayerUpdateStateRaw, RecvHostPlayer_UpdateStateRaw);
NetMsg.Instance.RegNetMsgEvent((int)CommandID.CmdRoomSynPlayerInput, RecvHostSyn_RoomFrameAllInputData); NetMsg.Instance.RegNetMsgEvent<Protobuf_Room_Syn_RoomFrameAllInputData>((int)CommandID.CmdRoomSynPlayerInput, RecvHostSyn_RoomFrameAllInputData);
NetMsg.Instance.RegNetMsgEvent((int)CommandID.CmdScreen, OnScreen); NetMsg.Instance.RegNetMsgEvent<Protobuf_Screnn_Frame>((int)CommandID.CmdScreen, OnScreen);
} }
#region #region
@ -153,10 +153,9 @@ namespace AxibugEmuOnline.Client.Manager
/// 获取所有房间列表 /// 获取所有房间列表
/// </summary> /// </summary>
/// <param name="reqData"></param> /// <param name="reqData"></param>
void RecvGetRoomList(byte[] reqData) void RecvGetRoomList(Protobuf_Room_List_RESP msg)
{ {
App.log.Info("取得完整房间列表"); App.log.Info("取得完整房间列表");
Protobuf_Room_List_RESP msg = ProtoBufHelper.DeSerizlize<Protobuf_Room_List_RESP>(reqData);
dictRoomListID2Info.Clear(); dictRoomListID2Info.Clear();
for (int i = 0; i < msg.RoomMiniInfoList.Count; i++) for (int i = 0; i < msg.RoomMiniInfoList.Count; i++)
AddOrUpdateRoomList(msg.RoomMiniInfoList[i]); AddOrUpdateRoomList(msg.RoomMiniInfoList[i]);
@ -167,10 +166,9 @@ namespace AxibugEmuOnline.Client.Manager
/// 获取单个列表更新 /// 获取单个列表更新
/// </summary> /// </summary>
/// <param name="reqData"></param> /// <param name="reqData"></param>
void RecvGetRoomListUpdate(byte[] reqData) void RecvGetRoomListUpdate(Protobuf_Room_Update_RESP msg)
{ {
App.log.Debug("单个房间状态更新"); App.log.Debug("单个房间状态更新");
Protobuf_Room_Update_RESP msg = ProtoBufHelper.DeSerizlize<Protobuf_Room_Update_RESP>(reqData);
if (msg.UpdateType == 0) if (msg.UpdateType == 0)
{ {
if (AddOrUpdateRoomList(msg.RoomMiniInfo)) if (AddOrUpdateRoomList(msg.RoomMiniInfo))
@ -203,10 +201,9 @@ namespace AxibugEmuOnline.Client.Manager
/// 获取单个房间画面 /// 获取单个房间画面
/// </summary> /// </summary>
/// <param name="reqData"></param> /// <param name="reqData"></param>
void RecvRoomGetScreen(byte[] reqData) void RecvRoomGetScreen(Protobuf_Room_Get_Screen_RESP msg)
{ {
App.log.Debug("单个房间状态更新"); App.log.Debug("单个房间状态更新");
Protobuf_Room_Get_Screen_RESP msg = ProtoBufHelper.DeSerizlize<Protobuf_Room_Get_Screen_RESP>(reqData);
//解压 //解压
byte[] data = Helper.DecompressByteArray(msg.RawBitmap.ToArray()); byte[] data = Helper.DecompressByteArray(msg.RawBitmap.ToArray());
Eventer.Instance.PostEvent(EEvent.OnRoomGetRoomScreen, msg.RoomID, data); Eventer.Instance.PostEvent(EEvent.OnRoomGetRoomScreen, msg.RoomID, data);
@ -230,10 +227,9 @@ namespace AxibugEmuOnline.Client.Manager
/// 创建房间成功 /// 创建房间成功
/// </summary> /// </summary>
/// <param name="reqData"></param> /// <param name="reqData"></param>
void RecvCreateRoom(byte[] reqData) void RecvCreateRoom(Protobuf_Room_Create_RESP msg)
{ {
App.log.Debug("创建房间成功"); App.log.Debug("创建房间成功");
Protobuf_Room_Create_RESP msg = ProtoBufHelper.DeSerizlize<Protobuf_Room_Create_RESP>(reqData);
mineRoomMiniInfo = msg.RoomMiniInfo; mineRoomMiniInfo = msg.RoomMiniInfo;
InitRePlay(); InitRePlay();
Eventer.Instance.PostEvent(EEvent.OnMineRoomCreated); Eventer.Instance.PostEvent(EEvent.OnMineRoomCreated);
@ -258,10 +254,9 @@ namespace AxibugEmuOnline.Client.Manager
/// 加入房间成功 /// 加入房间成功
/// </summary> /// </summary>
/// <param name="reqData"></param> /// <param name="reqData"></param>
void RecvJoinRoom(byte[] reqData) void RecvJoinRoom(Protobuf_Room_Join_RESP msg)
{ {
App.log.Debug("加入房间成功"); App.log.Debug("加入房间成功");
Protobuf_Room_Join_RESP msg = ProtoBufHelper.DeSerizlize<Protobuf_Room_Join_RESP>(reqData);
mineRoomMiniInfo = msg.RoomMiniInfo; mineRoomMiniInfo = msg.RoomMiniInfo;
InitRePlay(); InitRePlay();
{ {
@ -287,25 +282,22 @@ namespace AxibugEmuOnline.Client.Manager
/// 离开房间成功 /// 离开房间成功
/// </summary> /// </summary>
/// <param name="reqData"></param> /// <param name="reqData"></param>
void RecvLeavnRoom(byte[] reqData) void RecvLeavnRoom(Protobuf_Room_Leave_RESP msg)
{ {
App.log.Debug("离开房间成功"); App.log.Debug("离开房间成功");
Protobuf_Room_Leave_RESP msg = ProtoBufHelper.DeSerizlize<Protobuf_Room_Leave_RESP>(reqData);
ReleaseRePlay(); ReleaseRePlay();
mineRoomMiniInfo = null; mineRoomMiniInfo = null;
Eventer.Instance.PostEvent(EEvent.OnMineLeavnRoom); Eventer.Instance.PostEvent(EEvent.OnMineLeavnRoom);
OverlayManager.PopTip($"你已经离开房间"); OverlayManager.PopTip($"你已经离开房间");
} }
void RecvRoomMyRoomStateChange(byte[] reqData) void RecvRoomMyRoomStateChange(Protobuf_Room_MyRoom_State_Change msg)
{ {
if (mineRoomMiniInfo == null) if (mineRoomMiniInfo == null)
{ {
App.log.Error("RecvRoomMyRoomStateChange 时 mineRoomMiniInfo 为空"); App.log.Error("RecvRoomMyRoomStateChange 时 mineRoomMiniInfo 为空");
return; return;
} }
Protobuf_Room_MyRoom_State_Change msg = ProtoBufHelper.DeSerizlize<Protobuf_Room_MyRoom_State_Change>(reqData);
long[] oldRoomPlayer = GetRoom4PlayerUIDs(); long[] oldRoomPlayer = GetRoom4PlayerUIDs();
Protobuf_Room_GamePlaySlot[] oldslotArr = GetRoom4GameSlotMiniInfos(); Protobuf_Room_GamePlaySlot[] oldslotArr = GetRoom4GameSlotMiniInfos();
mineRoomMiniInfo = msg.RoomMiniInfo; mineRoomMiniInfo = msg.RoomMiniInfo;
@ -464,9 +456,8 @@ namespace AxibugEmuOnline.Client.Manager
App.network.SendToServer((int)CommandID.CmdRoomHostPlayerUpdateStateRaw, ProtoBufHelper.Serizlize(msg)); App.network.SendToServer((int)CommandID.CmdRoomHostPlayerUpdateStateRaw, ProtoBufHelper.Serizlize(msg));
} }
void RecvRoom_WaitStep(byte[] reqData) void RecvRoom_WaitStep(Protobuf_Room_WaitStep_RESP msg)
{ {
Protobuf_Room_WaitStep_RESP msg = ProtoBufHelper.DeSerizlize<Protobuf_Room_WaitStep_RESP>(reqData);
if (WaitStep != msg.WaitStep) if (WaitStep != msg.WaitStep)
{ {
WaitStep = msg.WaitStep; WaitStep = msg.WaitStep;
@ -481,10 +472,9 @@ namespace AxibugEmuOnline.Client.Manager
} }
} }
void RecvHostPlayer_UpdateStateRaw(byte[] reqData) void RecvHostPlayer_UpdateStateRaw(Protobuf_Room_HostPlayer_UpdateStateRaw_RESP msg)
{ {
Protobuf_Room_HostPlayer_UpdateStateRaw_RESP msg = ProtoBufHelper.DeSerizlize<Protobuf_Room_HostPlayer_UpdateStateRaw_RESP>(reqData); App.log.Info($"即时存档上报成功");
App.log.Info($"鸡翅孙当上报成功");
} }
/// <summary> /// <summary>
@ -515,9 +505,8 @@ namespace AxibugEmuOnline.Client.Manager
} }
ulong TestAllData = 0; ulong TestAllData = 0;
void RecvHostSyn_RoomFrameAllInputData(byte[] reqData) void RecvHostSyn_RoomFrameAllInputData(Protobuf_Room_Syn_RoomFrameAllInputData msg)
{ {
Protobuf_Room_Syn_RoomFrameAllInputData msg = ProtoBufHelper.DeSerizlize<Protobuf_Room_Syn_RoomFrameAllInputData>(reqData);
if (TestAllData != msg.InputData) if (TestAllData != msg.InputData)
{ {
TestAllData = msg.InputData; TestAllData = msg.InputData;
@ -535,9 +524,8 @@ namespace AxibugEmuOnline.Client.Manager
App.network.SendToServer((int)CommandID.CmdScreen, ProtoBufHelper.Serizlize(_Protobuf_Screnn_Frame)); App.network.SendToServer((int)CommandID.CmdScreen, ProtoBufHelper.Serizlize(_Protobuf_Screnn_Frame));
} }
public void OnScreen(byte[] reqData) public void OnScreen(Protobuf_Screnn_Frame msg)
{ {
Protobuf_Screnn_Frame msg = ProtoBufHelper.DeSerizlize<Protobuf_Screnn_Frame>(reqData);
//解压 //解压
byte[] data = Helper.DecompressByteArray(msg.RawBitmap.ToArray()); byte[] data = Helper.DecompressByteArray(msg.RawBitmap.ToArray());
} }

View File

@ -11,8 +11,8 @@ namespace AxibugEmuOnline.Client.Manager
{ {
public AppShare() public AppShare()
{ {
NetMsg.Instance.RegNetMsgEvent((int)CommandID.CmdGameMark, RecvGameStar); NetMsg.Instance.RegNetMsgEvent<Protobuf_Game_Mark_RESP>((int)CommandID.CmdGameMark, RecvGameStar);
NetMsg.Instance.RegNetMsgEvent((int)CommandID.CmdGamescreenImgUpload, RecvGamescreenImgUpload); NetMsg.Instance.RegNetMsgEvent<Protobuf_GameScreen_Img_Upload_RESP>((int)CommandID.CmdGamescreenImgUpload, RecvGamescreenImgUpload);
} }
/// <summary> /// <summary>
@ -35,9 +35,8 @@ namespace AxibugEmuOnline.Client.Manager
/// 收藏 /// 收藏
/// </summary> /// </summary>
/// <param name="reqData"></param> /// <param name="reqData"></param>
void RecvGameStar(byte[] reqData) void RecvGameStar(Protobuf_Game_Mark_RESP msg)
{ {
Protobuf_Game_Mark_RESP msg = ProtoBufHelper.DeSerizlize<Protobuf_Game_Mark_RESP>(reqData);
Eventer.Instance.PostEvent(EEvent.OnRomStarStateChanged, msg.RomID, msg.IsStar == 1); Eventer.Instance.PostEvent(EEvent.OnRomStarStateChanged, msg.RomID, msg.IsStar == 1);
} }
@ -63,7 +62,7 @@ namespace AxibugEmuOnline.Client.Manager
App.network.SendToServer((int)CommandID.CmdGamescreenImgUpload, ProtoBufHelper.Serizlize(req)); App.network.SendToServer((int)CommandID.CmdGamescreenImgUpload, ProtoBufHelper.Serizlize(req));
} }
private void RecvGamescreenImgUpload(byte[] data) private void RecvGamescreenImgUpload(Protobuf_GameScreen_Img_Upload_RESP msg)
{ {
OverlayManager.PopTip("封面图上传成功"); OverlayManager.PopTip("封面图上传成功");
} }

View File

@ -20,9 +20,9 @@ namespace AxibugEmuOnline.Client
public SavCloudApi() public SavCloudApi()
{ {
NetMsg.Instance.RegNetMsgEvent((int)CommandID.CmdGamesavGetGameSavList, RecvGetGameSavList); NetMsg.Instance.RegNetMsgEvent<Protobuf_Mine_GetGameSavList_RESP>((int)CommandID.CmdGamesavGetGameSavList, RecvGetGameSavList);
NetMsg.Instance.RegNetMsgEvent((int)CommandID.CmdGamesavDelGameSav, RecvDelGameSavList); NetMsg.Instance.RegNetMsgEvent<Protobuf_Mine_DelGameSav_RESP>((int)CommandID.CmdGamesavDelGameSav, RecvDelGameSavList);
NetMsg.Instance.RegNetMsgEvent((int)CommandID.CmdGamesavUploadGameSav, RecvUpLoadGameSav); NetMsg.Instance.RegNetMsgEvent<Protobuf_Mine_UpLoadGameSav_RESP>((int)CommandID.CmdGamesavUploadGameSav, RecvUpLoadGameSav);
} }
private HashSet<int> m_fetchingRomIDs = new HashSet<int>(); private HashSet<int> m_fetchingRomIDs = new HashSet<int>();
@ -42,10 +42,8 @@ namespace AxibugEmuOnline.Client
App.network.SendToServer((int)CommandID.CmdGamesavGetGameSavList, ProtoBufHelper.Serizlize(req)); App.network.SendToServer((int)CommandID.CmdGamesavGetGameSavList, ProtoBufHelper.Serizlize(req));
} }
void RecvGetGameSavList(byte[] reqData) void RecvGetGameSavList(Protobuf_Mine_GetGameSavList_RESP msg)
{ {
Protobuf_Mine_GetGameSavList_RESP msg = ProtoBufHelper.DeSerizlize<Protobuf_Mine_GetGameSavList_RESP>(reqData);
if (m_fetchingRomIDs.Remove(msg.RomID)) return; if (m_fetchingRomIDs.Remove(msg.RomID)) return;
Protobuf_Mine_GameSavInfo[] savArr = new Protobuf_Mine_GameSavInfo[4]; Protobuf_Mine_GameSavInfo[] savArr = new Protobuf_Mine_GameSavInfo[4];
@ -73,9 +71,8 @@ namespace AxibugEmuOnline.Client
App.network.SendToServer((int)CommandID.CmdGamesavDelGameSav, ProtoBufHelper.Serizlize(req)); App.network.SendToServer((int)CommandID.CmdGamesavDelGameSav, ProtoBufHelper.Serizlize(req));
} }
void RecvDelGameSavList(byte[] reqData) void RecvDelGameSavList(Protobuf_Mine_DelGameSav_RESP msg)
{ {
Protobuf_Mine_DelGameSav_RESP msg = ProtoBufHelper.DeSerizlize<Protobuf_Mine_DelGameSav_RESP>(reqData);
Eventer.Instance.PostEvent(EEvent.OnNetGameSavDeleted, msg.RomID, msg.SavDataIdx); Eventer.Instance.PostEvent(EEvent.OnNetGameSavDeleted, msg.RomID, msg.SavDataIdx);
} }
@ -108,9 +105,8 @@ namespace AxibugEmuOnline.Client
App.network.SendToServer((int)CommandID.CmdGamesavUploadGameSav, ProtoBufHelper.Serizlize(req)); App.network.SendToServer((int)CommandID.CmdGamesavUploadGameSav, ProtoBufHelper.Serizlize(req));
} }
void RecvUpLoadGameSav(byte[] reqData) void RecvUpLoadGameSav(Protobuf_Mine_UpLoadGameSav_RESP msg)
{ {
Protobuf_Mine_UpLoadGameSav_RESP msg = ProtoBufHelper.DeSerizlize<Protobuf_Mine_UpLoadGameSav_RESP>(reqData);
OnUploadedSavData?.Invoke(msg.RomID, msg.SavDataIdx, msg.UploadSevInfo); OnUploadedSavData?.Invoke(msg.RomID, msg.SavDataIdx, msg.UploadSevInfo);
} }

View File

@ -29,13 +29,13 @@ namespace AxibugEmuOnline.Client.Manager
App.network.OnReConnected += OnReConnected; App.network.OnReConnected += OnReConnected;
//网络事件注册 //网络事件注册
NetMsg.Instance.RegNetMsgEvent((int)CommandID.CmdUserOnlinelist, RecvUserOnlinelist); NetMsg.Instance.RegNetMsgEvent<Protobuf_UserList_RESP>((int)CommandID.CmdUserOnlinelist, RecvUserOnlinelist);
NetMsg.Instance.RegNetMsgEvent((int)CommandID.CmdUserJoin, RecvCmdUserJoin); NetMsg.Instance.RegNetMsgEvent<Protobuf_UserJoin_RESP>((int)CommandID.CmdUserJoin, RecvCmdUserJoin);
NetMsg.Instance.RegNetMsgEvent((int)CommandID.CmdUserLeave, RecvGetUserLeave); NetMsg.Instance.RegNetMsgEvent<Protobuf_UserLeave_RESP>((int)CommandID.CmdUserLeave, RecvGetUserLeave);
NetMsg.Instance.RegNetMsgEvent((int)CommandID.CmdModifyNickName, RecvModifyNickName); NetMsg.Instance.RegNetMsgEvent<Protobuf_Modify_NickName_RESP>((int)CommandID.CmdModifyNickName, RecvModifyNickName);
NetMsg.Instance.RegNetMsgEvent((int)CommandID.CmdUpdateSelfUserInfo, RecvUpdateSelfUserInfo); NetMsg.Instance.RegNetMsgEvent<Protobuf_Update_UserInfo_RESP>((int)CommandID.CmdUpdateSelfUserInfo, RecvUpdateSelfUserInfo);
NetMsg.Instance.RegNetMsgEvent((int)CommandID.CmdUpdateOtherUserInfo, RecvUpdateOtherUserInfo); NetMsg.Instance.RegNetMsgEvent<Protobuf_Update_OtherUserInfo_RESP>((int)CommandID.CmdUpdateOtherUserInfo, RecvUpdateOtherUserInfo);
} }
public MainUserDataBase userdata { get; private set; } = new MainUserDataBase(); public MainUserDataBase userdata { get; private set; } = new MainUserDataBase();
@ -153,9 +153,8 @@ namespace AxibugEmuOnline.Client.Manager
App.network.SendToServer((int)CommandID.CmdUserOnlinelist, ProtoBufHelper.Serizlize(msg)); App.network.SendToServer((int)CommandID.CmdUserOnlinelist, ProtoBufHelper.Serizlize(msg));
} }
public void RecvUserOnlinelist(byte[] reqData) public void RecvUserOnlinelist(Protobuf_UserList_RESP msg)
{ {
Protobuf_UserList_RESP msg = ProtoBufHelper.DeSerizlize<Protobuf_UserList_RESP>(reqData);
DictUID2User.Clear(); DictUID2User.Clear();
for (int i = 0; i < msg.UserList.Count; i++) for (int i = 0; i < msg.UserList.Count; i++)
{ {
@ -165,9 +164,8 @@ namespace AxibugEmuOnline.Client.Manager
} }
Eventer.Instance.PostEvent(EEvent.OnUserListAllUpdate); Eventer.Instance.PostEvent(EEvent.OnUserListAllUpdate);
} }
public void RecvCmdUserJoin(byte[] reqData) public void RecvCmdUserJoin(Protobuf_UserJoin_RESP msg)
{ {
Protobuf_UserJoin_RESP msg = ProtoBufHelper.DeSerizlize<Protobuf_UserJoin_RESP>(reqData);
bool isNewUser; bool isNewUser;
UpdateOrAddUser(msg.UserInfo, out isNewUser); UpdateOrAddUser(msg.UserInfo, out isNewUser);
if (isNewUser) if (isNewUser)
@ -177,9 +175,8 @@ namespace AxibugEmuOnline.Client.Manager
} }
} }
public void RecvGetUserLeave(byte[] reqData) public void RecvGetUserLeave(Protobuf_UserLeave_RESP msg)
{ {
Protobuf_UserLeave_RESP msg = ProtoBufHelper.DeSerizlize<Protobuf_UserLeave_RESP>(reqData);
RemoveUser(msg.UID); RemoveUser(msg.UID);
} }
@ -196,28 +193,23 @@ namespace AxibugEmuOnline.Client.Manager
App.network.SendToServer((int)CommandID.CmdModifyNickName, ProtoBufHelper.Serizlize(msg)); App.network.SendToServer((int)CommandID.CmdModifyNickName, ProtoBufHelper.Serizlize(msg));
} }
void RecvModifyNickName(byte[] reqData) void RecvModifyNickName(Protobuf_Modify_NickName_RESP msg)
{ {
Protobuf_Modify_NickName_RESP msg = ProtoBufHelper.DeSerizlize<Protobuf_Modify_NickName_RESP>(reqData);
} }
private void RecvUpdateSelfUserInfo(byte[] reqData) private void RecvUpdateSelfUserInfo(Protobuf_Update_UserInfo_RESP msg)
{ {
Protobuf_Update_UserInfo_RESP msg = ProtoBufHelper.DeSerizlize<Protobuf_Update_UserInfo_RESP>(reqData);
userdata.NickName = msg.UserInfo.NickName; userdata.NickName = msg.UserInfo.NickName;
Eventer.Instance.PostEvent(EEvent.OnSelfInfoUpdate); Eventer.Instance.PostEvent(EEvent.OnSelfInfoUpdate);
} }
private void RecvUpdateOtherUserInfo(byte[] reqData) private void RecvUpdateOtherUserInfo(Protobuf_Update_OtherUserInfo_RESP msg)
{ {
Protobuf_Update_OtherUserInfo_RESP msg = ProtoBufHelper.DeSerizlize<Protobuf_Update_OtherUserInfo_RESP>(reqData);
UserDataBase userdata = GetUserByUid(msg.UID); UserDataBase userdata = GetUserByUid(msg.UID);
if (userdata == null) if (userdata == null)
return; return;
userdata.NickName = msg.UserInfo.NickName; userdata.NickName = msg.UserInfo.NickName;
App.roomMgr.ChangeCurrRoomPlayerName(msg.UID); App.roomMgr.ChangeCurrRoomPlayerName(msg.UID);
Eventer.Instance.PostEvent(EEvent.OnOtherUserInfoUpdate, msg.UID); Eventer.Instance.PostEvent(EEvent.OnOtherUserInfoUpdate, msg.UID);
} }

View File

@ -26,8 +26,8 @@ namespace AxibugEmuOnline.Client
public const int NetAveDelayCount = 3; public const int NetAveDelayCount = 3;
private void Awake() private void Awake()
{ {
NetMsg.Instance.RegNetMsgEvent((int)CommandID.CmdPing, OnCmdPing); NetMsg.Instance.RegNetMsgEvent<Protobuf_Ping>((int)CommandID.CmdPing, OnCmdPing);
NetMsg.Instance.RegNetMsgEvent((int)CommandID.CmdPong, OnCmdPong); NetMsg.Instance.RegNetMsgEvent<Protobuf_Pong>((int)CommandID.CmdPong, OnCmdPong);
LoopAction_3s += Ping; LoopAction_3s += Ping;
@ -97,10 +97,9 @@ namespace AxibugEmuOnline.Client
} }
public void OnCmdPing(byte[] reqData) public void OnCmdPing(Protobuf_Ping msg)
{ {
//App.log.Debug($"OnCmdPing"); //App.log.Debug($"OnCmdPing");
Protobuf_Ping msg = ProtoBufHelper.DeSerizlize<Protobuf_Ping>(reqData);
Protobuf_Pong resp = new Protobuf_Pong() Protobuf_Pong resp = new Protobuf_Pong()
{ {
Seed = msg.Seed, Seed = msg.Seed,
@ -108,10 +107,9 @@ namespace AxibugEmuOnline.Client
App.network.SendToServer((int)CommandID.CmdPong, ProtoBufHelper.Serizlize(resp)); App.network.SendToServer((int)CommandID.CmdPong, ProtoBufHelper.Serizlize(resp));
} }
public void OnCmdPong(byte[] reqData) public void OnCmdPong(Protobuf_Pong msg)
{ {
//App.log.Debug($"OnCmdPong"); //App.log.Debug($"OnCmdPong");
Protobuf_Pong msg = ProtoBufHelper.DeSerizlize<Protobuf_Pong>(reqData);
if (LastPingSeed == msg.Seed) if (LastPingSeed == msg.Seed)
{ {

View File

@ -1,9 +1,10 @@
using AxibugEmuOnline.Client.ClientCore; using AxibugEmuOnline.Client.ClientCore;
using AxibugEmuOnline.Client.Event;
using AxibugProtobuf; using AxibugProtobuf;
using Google.Protobuf;
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using UnityEngine; using System.Linq;
using AxibugEmuOnline.Client.Common;
namespace AxibugEmuOnline.Client.Network namespace AxibugEmuOnline.Client.Network
{ {
@ -24,11 +25,28 @@ namespace AxibugEmuOnline.Client.Network
private NetMsg() { } private NetMsg() { }
private static Dictionary<int, Type> cmd2MsgTypeDict = new Dictionary<int, Type>();
private static Type GetTypeByCmd(int cmd, List<Delegate> delegates)
{
if (cmd2MsgTypeDict.TryGetValue(cmd, out var type)) return type;
var paramters = delegates.First().Method.GetParameters();
if (paramters.Length != 0)
{
var protoType = paramters[0].ParameterType;
if (!protoType.IsInterface && !protoType.IsAbstract)
{
cmd2MsgTypeDict[cmd] = protoType;
return protoType;
}
}
return null;
}
#region RegisterMsgEvent #region RegisterMsgEvent
public void RegNetMsgEvent(int cmd, Action<byte[]> callback) public void RegNetMsgEvent<T>(int cmd, Action<T> callback) where T : IMessage
{ {
InterRegNetMsgEvent(cmd, callback); InterRegNetMsgEvent(cmd, callback);
} }
@ -102,7 +120,7 @@ namespace AxibugEmuOnline.Client.Network
{ {
act?.Invoke(); act?.Invoke();
} }
catch(Exception ex) catch (Exception ex)
{ {
App.log.Error(ex.ToString()); App.log.Error(ex.ToString());
} }
@ -171,7 +189,7 @@ namespace AxibugEmuOnline.Client.Network
default: default:
break; break;
} }
OverlayManager.PopTip("错误:"+ errMsg); OverlayManager.PopTip("错误:" + errMsg);
App.log.Error("错误:" + errMsg); App.log.Error("错误:" + errMsg);
} }
@ -182,11 +200,16 @@ namespace AxibugEmuOnline.Client.Network
List<Delegate> eventList = GetNetEventDicList(cmd); List<Delegate> eventList = GetNetEventDicList(cmd);
if (eventList != null) if (eventList != null)
{ {
Type protoType = GetTypeByCmd(cmd, eventList);
foreach (Delegate callback in eventList) foreach (Delegate callback in eventList)
{ {
try try
{ {
((Action<byte[]>)callback)(arg); IMessage protobufMsg = ProtoBufHelper.DeSerizlizeFromPool(arg, protoType);
//((Action<IMessage>)callback)(protobufMsg);
callback.DynamicInvoke(protobufMsg);
ProtoBufHelper.ReleaseToPool(protobufMsg);
//((Action<byte[]>)callback)(arg);
} }
catch (Exception e) catch (Exception e)
{ {

View File

@ -0,0 +1,58 @@
using AxibugEmuOnline.Client.ClientCore;
using Google.Protobuf;
using System;
using System.Collections.Generic;
namespace AxibugEmuOnline.Client.Network
{
public class ProtobufferMsgPool
{
Dictionary<Type, Queue<IResetable>> _pool = new Dictionary<Type, Queue<IResetable>>();
public IMessage Get(Type msgType)
{
if (!_pool.TryGetValue(msgType, out var queue))
{
queue = new Queue<IResetable>();
_pool[msgType] = queue;
}
if (queue.Count == 0)
{
var msgIns = Activator.CreateInstance(msgType) as IMessage;
return msgIns;
}
else
{
var msgIns = queue.Dequeue();
msgIns.Reset();
return msgIns as IMessage;
}
}
public void Release(IMessage msg)
{
if (msg is IResetable resetableMsg)
{
var msgType = msg.GetType();
if (!_pool.TryGetValue(msgType, out var queue))
{
queue = new Queue<IResetable>();
_pool[msgType] = queue;
}
queue.Enqueue(resetableMsg);
}
else
{
App.log.Error("[NET]" + msg.GetType() + "}未生成Resetable代码");
}
}
}
public interface IResetable
{
void Reset();
}
}

View File

@ -0,0 +1,2 @@
fileFormatVersion: 2
guid: 5d5918c81333c984c8912ed3212e960e

View File

@ -0,0 +1,746 @@
using AxibugEmuOnline.Client.Network;
namespace AxibugProtobuf
{
public sealed partial class Protobuf_ChatMsg : IResetable
{
public void Reset()
{
ChatMsg = string.Empty;
}
}
}
namespace AxibugProtobuf
{
public sealed partial class Protobuf_ChatMsg_RESP : IResetable
{
public void Reset()
{
NickName = string.Empty;
ChatMsg = string.Empty;
Date = default;
}
}
}
namespace AxibugProtobuf
{
public sealed partial class Protobuf_Ping : IResetable
{
public void Reset()
{
Seed = default;
}
}
}
namespace AxibugProtobuf
{
public sealed partial class Protobuf_Pong : IResetable
{
public void Reset()
{
Seed = default;
}
}
}
namespace AxibugProtobuf
{
public sealed partial class Protobuf_Login : IResetable
{
public void Reset()
{
LoginType = default;
DeviceType = default;
DeviceStr = string.Empty;
Account = string.Empty;
Password = string.Empty;
}
}
}
namespace AxibugProtobuf
{
public sealed partial class Protobuf_Login_RESP : IResetable
{
public void Reset()
{
NickName = string.Empty;
Token = string.Empty;
LastLoginDate = string.Empty;
RegDate = string.Empty;
Status = default;
UID = default;
}
}
}
namespace AxibugProtobuf
{
public sealed partial class Protobuf_Token_Struct : IResetable
{
public void Reset()
{
UID = default;
TokenGenDate = default;
Seed = default;
}
}
}
namespace AxibugProtobuf
{
public sealed partial class Protobuf_UserList : IResetable
{
public void Reset()
{
}
}
}
namespace AxibugProtobuf
{
public sealed partial class Protobuf_UserList_RESP : IResetable
{
public void Reset()
{
UserCount = default;
UserList?.Clear();
}
}
}
namespace AxibugProtobuf
{
public sealed partial class Protobuf_UserJoin_RESP : IResetable
{
public void Reset()
{
UserInfo?.Reset();
}
}
}
namespace AxibugProtobuf
{
public sealed partial class Protobuf_UserLeave_RESP : IResetable
{
public void Reset()
{
UID = default;
}
}
}
namespace AxibugProtobuf
{
public sealed partial class Protobuf_UserState_RESP : IResetable
{
public void Reset()
{
UID = default;
State = default;
}
}
}
namespace AxibugProtobuf
{
public sealed partial class UserMiniInfo : IResetable
{
public void Reset()
{
UID = default;
NickName = string.Empty;
DeviceType = default;
}
}
}
namespace AxibugProtobuf
{
public sealed partial class Protobuf_Modify_NickName : IResetable
{
public void Reset()
{
NickName = string.Empty;
}
}
}
namespace AxibugProtobuf
{
public sealed partial class Protobuf_Modify_NickName_RESP : IResetable
{
public void Reset()
{
}
}
}
namespace AxibugProtobuf
{
public sealed partial class Protobuf_Update_UserInfo_RESP : IResetable
{
public void Reset()
{
UserInfo?.Reset();
}
}
}
namespace AxibugProtobuf
{
public sealed partial class Protobuf_Update_OtherUserInfo_RESP : IResetable
{
public void Reset()
{
UID = default;
UserInfo?.Reset();
}
}
}
namespace AxibugProtobuf
{
public sealed partial class Protobuf_Room_List : IResetable
{
public void Reset()
{
}
}
}
namespace AxibugProtobuf
{
public sealed partial class Protobuf_Room_List_RESP : IResetable
{
public void Reset()
{
RoomMiniInfoList?.Clear();
}
}
}
namespace AxibugProtobuf
{
public sealed partial class Protobuf_Room_MiniInfo : IResetable
{
public void Reset()
{
RoomID = default;
GameRomID = default;
GameRomHash = string.Empty;
GamePlatformType = default;
HostPlayerUID = default;
GameState = default;
ObsUserCount = default;
ScreenProviderUID = default;
GamePlaySlotList?.Clear();
}
}
}
namespace AxibugProtobuf
{
public sealed partial class Protobuf_Room_GamePlaySlot : IResetable
{
public void Reset()
{
PlayerUID = default;
PlayerNickName = string.Empty;
DeviceType = default;
PlayerLocalJoyIdx = default;
PlayerLocalGamePadType = default;
}
}
}
namespace AxibugProtobuf
{
public sealed partial class Protobuf_Room_Update_RESP : IResetable
{
public void Reset()
{
UpdateType = default;
RoomMiniInfo?.Reset();
}
}
}
namespace AxibugProtobuf
{
public sealed partial class Protobuf_Screnn_Frame : IResetable
{
public void Reset()
{
RoomID = default;
FrameID = default;
RawBitmap = Google.Protobuf.ByteString.Empty;
}
}
}
namespace AxibugProtobuf
{
public sealed partial class Protobuf_Room_SinglePlayerInputData : IResetable
{
public void Reset()
{
FrameID = default;
InputData = default;
}
}
}
namespace AxibugProtobuf
{
public sealed partial class Protobuf_Room_Syn_RoomFrameAllInputData : IResetable
{
public void Reset()
{
FrameID = default;
InputData = default;
ServerFrameID = default;
ServerForwardCount = default;
}
}
}
namespace AxibugProtobuf
{
public sealed partial class Protobuf_Room_Create : IResetable
{
public void Reset()
{
GameRomID = default;
GameRomHash = string.Empty;
}
}
}
namespace AxibugProtobuf
{
public sealed partial class Protobuf_Room_Create_RESP : IResetable
{
public void Reset()
{
RoomMiniInfo?.Reset();
}
}
}
namespace AxibugProtobuf
{
public sealed partial class Protobuf_Room_Join : IResetable
{
public void Reset()
{
RoomID = default;
}
}
}
namespace AxibugProtobuf
{
public sealed partial class Protobuf_Room_Join_RESP : IResetable
{
public void Reset()
{
RoomMiniInfo?.Reset();
}
}
}
namespace AxibugProtobuf
{
public sealed partial class Protobuf_Room_Leave : IResetable
{
public void Reset()
{
RoomID = default;
}
}
}
namespace AxibugProtobuf
{
public sealed partial class Protobuf_Room_Leave_RESP : IResetable
{
public void Reset()
{
RoomID = default;
}
}
}
namespace AxibugProtobuf
{
public sealed partial class Protobuf_Room_MyRoom_State_Change : IResetable
{
public void Reset()
{
RoomMiniInfo?.Reset();
}
}
}
namespace AxibugProtobuf
{
public sealed partial class Protobuf_Room_Change_PlaySlotWithJoy : IResetable
{
public void Reset()
{
SlotWithJoy?.Clear();
}
}
}
namespace AxibugProtobuf
{
public sealed partial class Protobuf_PlaySlotIdxWithJoyIdx : IResetable
{
public void Reset()
{
PlayerSlotIdx = default;
PlayerLocalJoyIdx = default;
PlayerLocalGamePadType = default;
}
}
}
namespace AxibugProtobuf
{
public sealed partial class Protobuf_Room_Change_PlaySlotWithJoy_RESP : IResetable
{
public void Reset()
{
}
}
}
namespace AxibugProtobuf
{
public sealed partial class Protobuf_Room_WaitStep_RESP : IResetable
{
public void Reset()
{
WaitStep = default;
LoadStateRaw = Google.Protobuf.ByteString.Empty;
}
}
}
namespace AxibugProtobuf
{
public sealed partial class Protobuf_Room_HostPlayer_UpdateStateRaw : IResetable
{
public void Reset()
{
LoadStateRaw = Google.Protobuf.ByteString.Empty;
}
}
}
namespace AxibugProtobuf
{
public sealed partial class Protobuf_Room_HostPlayer_UpdateStateRaw_RESP : IResetable
{
public void Reset()
{
}
}
}
namespace AxibugProtobuf
{
public sealed partial class Protobuf_Room_Player_Ready : IResetable
{
public void Reset()
{
PushFrameNeedTimeUs = default;
LoadStateNeedTimeUs = default;
VideoFrameShowNeedTimeUs = default;
AudioFramePlayNeedTimeUs = default;
}
}
}
namespace AxibugProtobuf
{
public sealed partial class Protobuf_Room_Get_Screen : IResetable
{
public void Reset()
{
RoomID = default;
}
}
}
namespace AxibugProtobuf
{
public sealed partial class Protobuf_Room_Get_Screen_RESP : IResetable
{
public void Reset()
{
RoomID = default;
FrameID = default;
RawBitmap = Google.Protobuf.ByteString.Empty;
}
}
}
namespace AxibugProtobuf
{
public sealed partial class Protobuf_Game_Mark : IResetable
{
public void Reset()
{
RomID = default;
Motion = default;
}
}
}
namespace AxibugProtobuf
{
public sealed partial class Protobuf_Game_Mark_RESP : IResetable
{
public void Reset()
{
RomID = default;
IsStar = default;
Stars = default;
}
}
}
namespace AxibugProtobuf
{
public sealed partial class Protobuf_Mine_GetGameSavList : IResetable
{
public void Reset()
{
RomID = default;
}
}
}
namespace AxibugProtobuf
{
public sealed partial class Protobuf_Mine_GetGameSavList_RESP : IResetable
{
public void Reset()
{
RomID = default;
SavDataList?.Clear();
}
}
}
namespace AxibugProtobuf
{
public sealed partial class Protobuf_Mine_GameSavInfo : IResetable
{
public void Reset()
{
BHadSaveData = default;
SavID = default;
Uid = default;
SavDataIdx = default;
RomID = default;
GamePlatformType = default;
SavDate = string.Empty;
SavName = string.Empty;
Note = string.Empty;
SavImgUrl = string.Empty;
SavUrl = string.Empty;
Sequence = default;
}
}
}
namespace AxibugProtobuf
{
public sealed partial class Protobuf_Mine_DelGameSav : IResetable
{
public void Reset()
{
RomID = default;
SavDataIdx = default;
}
}
}
namespace AxibugProtobuf
{
public sealed partial class Protobuf_Mine_DelGameSav_RESP : IResetable
{
public void Reset()
{
RomID = default;
SavDataIdx = default;
}
}
}
namespace AxibugProtobuf
{
public sealed partial class Protobuf_Mine_UpLoadGameSav : IResetable
{
public void Reset()
{
RomID = default;
SavDataIdx = default;
Name = string.Empty;
Note = string.Empty;
SavImg = Google.Protobuf.ByteString.Empty;
StateRaw = Google.Protobuf.ByteString.Empty;
Sequence = default;
}
}
}
namespace AxibugProtobuf
{
public sealed partial class Protobuf_Mine_UpLoadGameSav_RESP : IResetable
{
public void Reset()
{
RomID = default;
SavDataIdx = default;
UploadSevInfo?.Reset();
}
}
}
namespace AxibugProtobuf
{
public sealed partial class Protobuf_GameScreen_Img_Upload : IResetable
{
public void Reset()
{
RomID = default;
SavImg = Google.Protobuf.ByteString.Empty;
}
}
}
namespace AxibugProtobuf
{
public sealed partial class Protobuf_GameScreen_Img_Upload_RESP : IResetable
{
public void Reset()
{
}
}
}
namespace AxibugProtobuf
{
public sealed partial class pb_AxiEssgssStatusData : IResetable
{
public void Reset()
{
MemberData?.Clear();
Array2DMemberData?.Clear();
ClassData?.Clear();
}
}
}
namespace AxibugProtobuf
{
public sealed partial class pb_AxiEssgssStatusData_ByteData : IResetable
{
public void Reset()
{
KeyName = string.Empty;
Raw = Google.Protobuf.ByteString.Empty;
}
}
}
namespace AxibugProtobuf
{
public sealed partial class pb_AxiEssgssStatusData_2DArray : IResetable
{
public void Reset()
{
KeyName = string.Empty;
Rows = default;
Cols = default;
Raw = Google.Protobuf.ByteString.Empty;
}
}
}
namespace AxibugProtobuf
{
public sealed partial class pb_AxiEssgssStatusData_ClassData : IResetable
{
public void Reset()
{
KeyName = string.Empty;
ClassData?.Reset();
}
}
}

View File

@ -0,0 +1,2 @@
fileFormatVersion: 2
guid: 0416c776519c0aa4db70cc28e0ef9945