Compare commits

...

61 Commits

Author SHA1 Message Date
ALEXTANG
abd152b072 [+] SubAssetsOperationHandle LoadSubAssetsSync(string location)
[+] SubAssetsOperationHandle LoadSubAssetsSync(string location)
2023-06-06 19:28:44 +08:00
ALEXTANG
470e62d9c4 Update ResourceModule.cs 2023-06-06 15:19:28 +08:00
ALEXTANG
481b5911ab Update ResourceManager.cs 2023-06-06 15:19:24 +08:00
ALEXTANG
05d3aff05e Update IResourceManager.cs 2023-06-06 15:19:20 +08:00
ALEXTANG
86bb6353dc Update ResourceManager.Services.cs
同步修复IOS平台流解密失败的问题。
2023-06-06 09:55:01 +08:00
ALEXTANG
334698b6e6 Update RootModule.cs 2023-06-05 19:31:32 +08:00
ALEXTANG
2684bd29f5 Update GameClient.cs 2023-06-05 14:49:26 +08:00
ALEXTANG
c568c62404 [+] Update HybridCLR v2.4.2
[+] Update HybridCLR v2.4.2
2023-06-05 12:34:27 +08:00
ALEXTANG
699ccb3b09 [+] Update YooAssets v1.4.14
[+] Update YooAssets v1.4.14
2023-06-05 12:19:24 +08:00
ALEXTANG
f92bf5c602 Update GameClient.cs 2023-05-20 12:23:45 +08:00
ALEXTANG
cd87c71281 Update MsgDispatcher.cs 2023-05-20 12:23:41 +08:00
ALEXTANG
94c137b3c6 Update ILogicSys.cs 2023-05-20 11:27:11 +08:00
ALEXTANG
120a86b396 Create Redux.cs 2023-05-20 11:25:49 +08:00
ALEXTANG
383dc50fe3 Create Redux.cs.meta 2023-05-20 11:25:46 +08:00
ALEXTANG
2369e8723c Update TSingleton.cs 2023-05-20 11:25:44 +08:00
ALEXTANG
344f3293ad Update ILogicSys.cs 2023-05-20 11:25:37 +08:00
ALEXTANG
5d361dd188 Update BehaviourSingleton.cs 2023-05-20 11:25:09 +08:00
ALEXTANG
a2f7fe907a Update BaseLogicSys.cs 2023-05-20 11:25:02 +08:00
ALEXTANG
5b3f64689f Create Attribute.cs.meta 2023-05-20 11:24:58 +08:00
ALEXTANG
2258c13892 Create Attribute.cs 2023-05-20 11:24:55 +08:00
ALEXTANG
a70d2e7d17 Update main.unity 2023-05-20 11:11:14 +08:00
ALEXTANG
b15f51631a Update Network.cs 2023-05-20 11:10:46 +08:00
ALEXTANG
da12bd7cab Update GameClient.cs 2023-05-20 11:10:41 +08:00
ALEXTANG
98bcaef6b7 Update UnitySingleton.cs 2023-05-20 11:10:39 +08:00
ALEXTANG
71d1286144 Update TSingleton.cs 2023-05-20 11:10:34 +08:00
ALEXTANG
9359a81a96 Update ProtobufUtility.cs 2023-05-20 11:01:38 +08:00
ALEXTANG
a9542646c1 Update NetworkChannelHelper.cs 2023-05-20 11:01:33 +08:00
ALEXTANG
0890ca9bdb [+] Network
[+] Network
2023-05-19 19:40:05 +08:00
ALEXTANG
ec409c7e15 Update Network
Update Network
2023-05-19 17:01:04 +08:00
ALEXTANG
4bc63fafc8 Update gen_pb_code.bat 2023-05-19 00:43:28 +08:00
ALEXTANG
fe0f9afd6d Update gen_pb_code.bat 2023-05-19 00:42:38 +08:00
ALEXTANG
4632a0c099 [+] UpdateNetwork Module
[+] UpdateNetwork Module
2023-05-19 00:31:15 +08:00
ALEXTANG
60e57bb80b Update ProtoUtil.cs 2023-05-19 00:08:23 +08:00
ALEXTANG
b7c79d0438 [+] ProtoCs
[+] ProtoCs
2023-05-19 00:08:11 +08:00
ALEXTANG
62b7c9e4d6 [+] Protobuf.dll
[+] Protobuf.dll
2023-05-19 00:07:24 +08:00
ALEXTANG
75a6977afb [+] ProtobufUtility
[+] ProtobufUtility
2023-05-19 00:06:43 +08:00
ALEXTANG
659da836ac Update GameLogic.asmdef 2023-05-19 00:05:52 +08:00
ALEXTANG
07c459051f [+] Proto
[+] Proto
2023-05-19 00:03:18 +08:00
ALEXTANG
4253a81e78 Update
Update
2023-05-19 00:02:43 +08:00
ALEXTANG
e498abacd1 Update ICSharpCode.SharpZipLib.dll.meta 2023-05-19 00:02:17 +08:00
ALEXTANG
f16759483f [+] NetProto
[+] NetProto
2023-05-17 23:07:17 +08:00
ALEXTANG
899472a5db [+] Network
[+] Network
2023-05-17 23:06:29 +08:00
ALEXTANG
e65245371a Update TEngineLogHelper.cs 2023-05-17 23:05:58 +08:00
ALEXTANG
b04fff4ec9 [+] proto 2023-05-17 21:38:44 +08:00
ALEXTANG
d8f8fd01d9 [+] proto 2023-05-17 21:38:24 +08:00
ALEXTANG
9b1c5e6f0a [+] proto
[+] proto
2023-05-17 21:38:14 +08:00
ALEXTANG
b2b5c9274c Update RuleConfig.asset 2023-05-15 14:09:38 +08:00
ALEXTANG
b814d689d8 [-] AnimationHierarchyEditorTool
[-] AnimationHierarchyEditorTool
2023-05-14 10:31:33 +08:00
ALEXTANG
ca6de42d67 Update main.unity 2023-05-13 14:56:47 +08:00
ALEXTANG
c3e9b76fd6 Update main.unity 2023-05-13 14:56:02 +08:00
ALEXTANG
dca7b71457 [+] DisStripCode 防裁剪
[+] DisStripCode 防裁剪
2023-05-13 14:55:55 +08:00
ALEXTANG
7106454dfb Update ProjectSettings.asset 2023-05-13 22:22:01 +08:00
ALEXTANG
b97e24aa6d Create BurstAotSettings_iOS.json 2023-05-13 22:21:49 +08:00
ALEXTANG
bec4cba501 Update .gitignore 2023-05-13 22:13:50 +08:00
ALEXTANG
0568d5f8b2 Update ProcedureLaunch.cs 2023-05-13 21:21:03 +08:00
ALEXTANG
49db48e7fc Update GameModule.cs 2023-05-13 21:20:42 +08:00
ALEXTANG
92fc5e0bcd Update ProcedureLaunch.cs 2023-05-13 21:12:41 +08:00
ALEXTANG
11391e597e Update AudioModule.cs 2023-05-13 21:12:36 +08:00
ALEXTANG
6b64f3b261 Update Constant.cs 2023-05-13 21:12:29 +08:00
ALEXTANG
dff6ba4e6d Update GameApp_RegisterSystem.cs 2023-05-13 20:35:36 +08:00
ALEXTANG
036c89a6d1 Update BehaviourSingleton.cs 2023-05-13 20:35:34 +08:00
219 changed files with 8415 additions and 1784 deletions

1
.gitignore vendored
View File

@@ -116,3 +116,4 @@ UserSettings/Layouts/default-2021.dwlt
Assets/UnityOnlineServiceData.meta
Assets/UnityOnlineServiceData
.DS_Store

View File

@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 22d1bcdd317c6f64daeb9bf9742495f2
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 4944189ec9c939b45a65d93c704a22ec
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,33 @@
using System;
namespace TEngine
{
#region Attribute
[AttributeUsage(AttributeTargets.Class)]
public class UpdateAttribute : Attribute
{
}
[AttributeUsage(AttributeTargets.Class)]
public class FixedUpdateAttribute : Attribute
{
}
[AttributeUsage(AttributeTargets.Class)]
public class LateUpdateAttribute : Attribute
{
}
[AttributeUsage(AttributeTargets.Class)]
public class RoleLoginAttribute : Attribute
{
}
[AttributeUsage(AttributeTargets.Class)]
public class RoleLogoutAttribute : Attribute
{
}
#endregion
}

View File

@@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: 80791cccf63d44faa348884ea0c506a2
timeCreated: 1684553027

View File

@@ -51,6 +51,10 @@
{
}
public virtual void OnRoleLogin()
{
}
public virtual void OnRoleLogout()
{
}

View File

@@ -1,9 +1,10 @@
using System.Collections.Generic;
using System;
using System.Collections.Generic;
namespace TEngine
{
/// <summary>
/// 通过LogicSys来驱动且具备Unity完整生命周期的单例不继承MonoBehaviour
/// 通过LogicSys来驱动且具备Unity完整生命周期的单例不继承MonoBehaviour
/// </summary>
/// <typeparam name="T"></typeparam>
public abstract class BehaviourSingleton<T> : BaseBehaviourSingleton where T : BaseBehaviourSingleton, new()
@@ -53,14 +54,30 @@ namespace TEngine
{
}
/// <summary>
/// 帧更新。
/// <remarks>需要UpdateAttribute。</remarks>
/// </summary>
public virtual void Update()
{
}
/// <summary>
/// 后帧更新。
/// <remarks>需要LateUpdateAttribute。</remarks>
/// </summary>
public virtual void LateUpdate()
{
}
/// <summary>
/// 物理帧更新。
/// <remarks>需要FixedUpdateAttribute。</remarks>
/// </summary>
public virtual void FixedUpdate()
{
}
public virtual void Destroy()
{
}
@@ -84,12 +101,25 @@ namespace TEngine
private readonly List<BaseBehaviourSingleton> _listStart = new List<BaseBehaviourSingleton>();
private readonly List<BaseBehaviourSingleton> _listUpdate = new List<BaseBehaviourSingleton>();
private readonly List<BaseBehaviourSingleton> _listLateUpdate = new List<BaseBehaviourSingleton>();
private readonly List<BaseBehaviourSingleton> _listFixedUpdate = new List<BaseBehaviourSingleton>();
public void RegSingleton(BaseBehaviourSingleton inst)
{
Log.Assert(!_listInst.Contains(inst));
_listInst.Add(inst);
_listStart.Add(inst);
if (HadAttribute<UpdateAttribute>(inst.GetType()))
{
_listUpdate.Add(inst);
}
if (HadAttribute<LateUpdateAttribute>(inst.GetType()))
{
_listLateUpdate.Add(inst);
}
if (HadAttribute<FixedUpdateAttribute>(inst.GetType()))
{
_listFixedUpdate.Add(inst);
}
}
public void UnRegSingleton(BaseBehaviourSingleton inst)
@@ -175,6 +205,20 @@ namespace TEngine
}
}
public override void OnFixedUpdate()
{
var listFixedUpdate = _listFixedUpdate;
var listFixedUpdateCnt = listFixedUpdate.Count;
for (int i = 0; i < listFixedUpdateCnt; i++)
{
var inst = listFixedUpdate[i];
TProfiler.BeginFirstSample(inst.GetType().FullName);
inst.FixedUpdate();
TProfiler.EndFirstSample();
}
}
public override void OnDestroy()
{
for (int i = 0; i < _listInst.Count; i++)
@@ -208,5 +252,12 @@ namespace TEngine
inst.OnDrawGizmos();
}
}
private bool HadAttribute<T>(Type type) where T:Attribute
{
T attribute = Attribute.GetCustomAttribute(type, typeof(T)) as T;
return attribute != null;
}
}
}

View File

@@ -35,15 +35,21 @@ public interface ILogicSys
/// </summary>
void OnFixedUpdate();
/// <summary>
/// 登录账号/角色时调用
/// </summary>
void OnRoleLogin();
/// <summary>
/// 清理数据接口,切换账号/角色时调用
/// </summary>
void OnRoleLogout();
/// <summary>
/// OnDrawGizmos
/// 绘制调试接口
/// </summary>
void OnDrawGizmos();
/// <summary>
/// 暂停游戏
/// </summary>

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: 464445719fff48a78021df4a4a6b05a5
timeCreated: 1684552621

View File

@@ -30,11 +30,11 @@ namespace GameBase
{
if (_root == null)
{
_root = GameObject.Find("[SingletonMgr]");
_root = GameObject.Find("[GameModule]");
if (_root == null)
{
_root = new GameObject("[SingletonMgr]")
_root = new GameObject("[GameModule]")
{
transform =
{
@@ -42,7 +42,7 @@ namespace GameBase
}
};
}
UnityEngine.Object.DontDestroyOnLoad(_root);
Object.DontDestroyOnLoad(_root);
}
return _root;
}
@@ -70,7 +70,7 @@ namespace GameBase
_gameObjects.Add(go.name, go);
if (Application.isPlaying)
{
UnityEngine.Object.DontDestroyOnLoad(go);
Object.DontDestroyOnLoad(go);
}
}
}
@@ -80,7 +80,7 @@ namespace GameBase
if (_gameObjects != null && _gameObjects.ContainsKey(go.name))
{
_gameObjects.Remove(go.name);
UnityEngine.Object.Destroy(go);
Object.Destroy(go);
}
}

View File

@@ -17,7 +17,7 @@ namespace GameBase
{
if (_instance == null)
{
var ins = UnityEngine.Object.FindObjectOfType<T>();
var ins = FindObjectOfType<T>();
if (ins != null)
{
var obj = ins.gameObject;
@@ -32,11 +32,16 @@ namespace GameBase
GameObject go = SingletonMgr.GetGameObject(instName);
if (go == null)
{
go = GameObject.Find($"{instName}");
go = GameObject.Find($"[{instName}]");
if (go == null)
{
go = new GameObject(instName);
go.transform.position = Vector3.zero;
go = new GameObject($"[{instName}]")
{
transform =
{
position = Vector3.zero
}
};
}
}
@@ -101,11 +106,9 @@ namespace GameBase
public static void Release()
{
if (_instance != null)
{
if (_instance == null) return;
SingletonMgr.Release(_instance.gameObject);
_instance = null;
}
}
}
}

View File

@@ -25,7 +25,8 @@ public partial class GameApp
/// </summary>
private void RegisterAllSystem()
{
//带生命周期的单例系统。
AddLogicSys(BehaviourSingleSystem.Instance);
}
/// <summary>

View File

@@ -11,7 +11,7 @@
],
"includePlatforms": [],
"excludePlatforms": [],
"allowUnsafeCode": false,
"allowUnsafeCode": true,
"overrideReferences": false,
"precompiledReferences": [],
"autoReferenced": true,

View File

@@ -0,0 +1,166 @@
using TEngine;
namespace GameLogic
{
public enum ClientConnectWatcherStatus
{
StatusInit,
StatusReconnectAuto,
StatusReconnectConfirm,
StatusWaitExit
}
public class ClientConnectWatcher
{
private readonly GameClient _client;
private ClientConnectWatcherStatus _status;
private float _statusTime;
private int _reconnectCnt = 0;
private int _disconnectReason = 0;
private bool _enable = false;
public bool Enable
{
get => _enable;
set
{
if (_enable != value)
{
_enable = value;
if (_enable)
{
OnEnable();
}
else
{
OnDisable();
}
}
}
}
private ClientConnectWatcherStatus Status
{
get => _status;
set
{
if (_status == value) return;
_status = value;
_statusTime = NowTime;
}
}
private float NowTime => GameTime.unscaledTime;
public ClientConnectWatcher(GameClient client)
{
_client = client;
_statusTime = NowTime;
_status = ClientConnectWatcherStatus.StatusInit;
}
public void Update()
{
if (!_enable)
{
return;
}
if (_client.IsEntered)
{
return;
}
switch (_status)
{
case ClientConnectWatcherStatus.StatusInit:
UpdateOnInitStatus();
break;
case ClientConnectWatcherStatus.StatusReconnectAuto:
UpdateOnReconnectAuto();
break;
case ClientConnectWatcherStatus.StatusReconnectConfirm:
UpdateOnReconnectConfirm();
break;
case ClientConnectWatcherStatus.StatusWaitExit:
UpdateOnWaitExit();
break;
}
}
public void OnReConnect()
{
if (_status == ClientConnectWatcherStatus.StatusReconnectConfirm)
{
Status = ClientConnectWatcherStatus.StatusReconnectAuto;
}
}
void UpdateOnInitStatus()
{
int autoReconnectMaxCount = 4;
if (_reconnectCnt <= autoReconnectMaxCount)
{
if (_reconnectCnt == 0)
{
_disconnectReason = _client.LastNetErrCode;
}
Status = ClientConnectWatcherStatus.StatusReconnectAuto;
_reconnectCnt++;
//重连
_client.Reconnect();
}
else
{
Status = ClientConnectWatcherStatus.StatusReconnectConfirm;
_reconnectCnt++;
// UISys.Mgr.ShowUI(GAME_UI_TYPE.Tip_NetDisconn, UISys.Mgr.GetUIWindowParam().SetParam("errCode", m_disconnectReason));
}
}
void UpdateOnReconnectAuto()
{
if (_client.IsEntered)
{
Status = ClientConnectWatcherStatus.StatusInit;
_reconnectCnt = 0;
return;
}
float nowTime = NowTime;
var timeoutTime = 10f;
if (_statusTime + timeoutTime < nowTime)
{
Log.Error("UpdateOnReconnectAuto timeout: {0}", timeoutTime);
//切换到默认的,下一帧继续判断是否需要自动还是手动
Status = ClientConnectWatcherStatus.StatusInit;
}
}
void UpdateOnReconnectConfirm()
{
}
void UpdateOnWaitExit()
{
}
private void OnDisable()
{
Status = ClientConnectWatcherStatus.StatusInit;
_reconnectCnt = 0;
}
private void OnEnable()
{
Status = ClientConnectWatcherStatus.StatusInit;
_reconnectCnt = 0;
}
}
}

View File

@@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: 3e4e637f3da340dd9512150c3e2ff087
timeCreated: 1684334948

View File

@@ -0,0 +1,428 @@
using System.Net.Sockets;
using GameBase;
using GameProto;
using TEngine;
using CSPkg = GameProto.CSPkg;
namespace GameLogic
{
public enum GameClientStatus
{
StatusInit, //初始化
StatusReconnect, //重新连接
StatusClose, //断开连接
StatusLogin, //登录中
StatusEnter, //AccountLogin成功进入服务器了
}
public enum CsMsgResult
{
NoError = 0,
NetworkError = 1,
InternalError = 2,
MsgTimeOut = 3,
PingTimeOut = 4,
}
//定义消息回报的回调接口
public delegate void CsMsgDelegate(CsMsgResult result, CSPkg msg);
/// <summary>
/// 统计网络协议的接口
/// </summary>
public delegate void CsMsgStatDelegate(int cmdID, int pkgSize);
public class GameClient : Singleton<GameClient>
{
private readonly INetworkChannel _channel;
private GameClientStatus _status = GameClientStatus.StatusInit;
private readonly MsgDispatcher _dispatcher;
private readonly ClientConnectWatcher _connectWatcher;
private float _lastLogDisconnectErrTime = 0f;
private int _lastNetErrCode = 0;
public int LastNetErrCode => _lastNetErrCode;
public GameClientStatus Status
{
get => _status;
set => _status = value;
}
public bool IsEntered => _status == GameClientStatus.StatusEnter;
/// <summary>
/// 连续心跳超时
/// </summary>
private int _heatBeatTimeoutNum = 0;
private int _ping = -1;
private float NowTime => GameTime.unscaledTime;
private string _lastHost = null;
private int _lastPort = 0;
public GameClient()
{
_connectWatcher = new ClientConnectWatcher(this);
_dispatcher = new MsgDispatcher();
_dispatcher.SetTimeout(5f);
GameEvent.AddEventListener<INetworkChannel,object>(NetworkEvent.NetworkConnectedEvent,OnNetworkConnected);
GameEvent.AddEventListener<INetworkChannel>(NetworkEvent.NetworkClosedEvent,OnNetworkClosed);
GameEvent.AddEventListener<INetworkChannel,NetworkErrorCode,SocketError,string>(NetworkEvent.NetworkErrorEvent,OnNetworkError);
GameEvent.AddEventListener<INetworkChannel,object>(NetworkEvent.NetworkCustomErrorEvent,OnNetworkCustomError);
_channel = Network.Instance.CreateNetworkChannel("GameClient", ServiceType.Tcp, new NetworkChannelHelper());
}
private void OnNetworkConnected(INetworkChannel channel, object userdata)
{
bool isReconnect = (_status == GameClientStatus.StatusReconnect);
//准备登录
Status = GameClientStatus.StatusLogin;
OnServerConnected(isReconnect);
}
private void OnNetworkClosed(INetworkChannel channel)
{
}
private void OnNetworkError(INetworkChannel channel, NetworkErrorCode networkErrorCode, SocketError socketError, string errorMessage)
{
}
private void OnNetworkCustomError(INetworkChannel channel, object userData)
{
}
public void Connect(string host, int port, bool reconnect = false)
{
ResetParam();
if (!reconnect)
{
SetWatchReconnect(false);
}
if (reconnect)
{
// GameEvent.Get<ICommUI>().ShowWaitUITip(WaitUISeq.LOGINWORLD_SEQID, G.R(TextDefine.ID_TIPS_RECONNECTING));
}
else
{
// GameEvent.Get<ICommUI>().ShowWaitUI(WaitUISeq.LOGINWORLD_SEQID);
}
_lastHost = host;
_lastPort = port;
Status = reconnect ? GameClientStatus.StatusReconnect : GameClientStatus.StatusInit;
_channel.Connect(host, port);
}
public void Reconnect()
{
if (string.IsNullOrEmpty(_lastHost) || _lastPort <= 0)
{
// GameModule.UI.ShowTipMsg("Invalid reconnect param");
return;
}
_connectWatcher.OnReConnect();
Connect(_lastHost, _lastPort, true);
}
public void Shutdown()
{
_channel.Close();
_status = GameClientStatus.StatusInit;
}
public void OnServerConnected(bool isReconnect)
{
}
public bool SendCsMsg(CSPkg reqPkg)
{
if (!IsStatusCanSendMsg(reqPkg.Head.MsgId))
{
return false;
}
return DoSendData(reqPkg);
}
public bool IsStatusCanSendMsg(uint msgId)
{
bool canSend = false;
if (_status == GameClientStatus.StatusLogin)
{
canSend = (msgId == (uint)CSMsgID.CsCmdActLoginReq);
}
if (_status == GameClientStatus.StatusEnter)
{
canSend = true;
}
if (!canSend)
{
float nowTime = NowTime;
if (_lastLogDisconnectErrTime + 5 < nowTime)
{
Log.Error("GameClient not connected, send msg failed, msgId[{0}]", msgId);
_lastLogDisconnectErrTime = nowTime;
}
//UISys.Mgr.ShowTipMsg(TextDefine.ID_ERR_NETWORKD_DISCONNECT);
}
return canSend;
}
public bool SendCsMsg(CSPkg reqPkg, uint resCmd, CsMsgDelegate resHandler = null, bool needShowWaitUI = true)
{
if (!IsStatusCanSendMsg(reqPkg.Head.MsgId))
{
return false;
}
var ret = DoSendData(reqPkg);
if (!ret)
{
if (resHandler != null)
{
resHandler(CsMsgResult.InternalError, null);
}
_dispatcher.NotifyCmdError(resCmd, CsMsgResult.InternalError);
}
else
{
//注册消息
if (resHandler != null)
{
_dispatcher.RegSeqHandle(reqPkg.Head.Echo, resCmd, resHandler);
if (reqPkg.Head.Echo > 0 && IsWaitingCmd(resCmd) && needShowWaitUI)
{
// TODO
// GameEvent.Get<ICommUI>().ShowWaitUI(reqPkg.Head.Echo);
}
}
}
return ret;
}
private bool DoSendData(CSPkg reqPkg)
{
if (!IsIgnoreLog(reqPkg.Head.MsgId))
{
Log.Debug("[c-s] CmdId[{0}]\n{1}", reqPkg.Head.MsgId, reqPkg.Body.ToString());
}
var sendRet = _channel.Send(reqPkg);
return sendRet;
}
private bool IsIgnoreLog(uint msgId)
{
bool ignoreLog = false;
switch (msgId)
{
case (uint)CSMsgID.CsCmdHeatbeatReq:
case (uint)CSMsgID.CsCmdHeatbeatRes:
ignoreLog = true;
break;
}
return ignoreLog;
}
public static bool IsWaitingCmd(uint msgId)
{
//心跳包不需要读条等待
if (msgId == (uint)CSMsgID.CsCmdHeatbeatRes)
{
return false;
}
return true;
}
private void ResetParam()
{
_lastLogDisconnectErrTime = 0f;
_heatBeatTimeoutNum = 0;
_lastHbTime = 0f;
_ping = -1;
_lastNetErrCode = 0;
}
public void OnUpdate()
{
_dispatcher.Update();
TickHeartBeat();
CheckHeatBeatTimeout();
_connectWatcher.Update();
}
/// <summary>
/// 注册静态消息
/// </summary>
/// <param name="iCmdID"></param>
/// <param name="msgDelegate"></param>
public void RegCmdHandle(int iCmdID, CsMsgDelegate msgDelegate)
{
_dispatcher.RegCmdHandle((uint)iCmdID, msgDelegate);
}
/// <summary>
/// 移除消息处理函数
/// </summary>
/// <param name="cmdId"></param>
/// <param name="msgDelegate"></param>
public void RmvCmdHandle(int cmdId, CsMsgDelegate msgDelegate)
{
_dispatcher.RmvCmdHandle((uint)cmdId, msgDelegate);
}
/// <summary>
/// 设置加密密钥
/// </summary>
/// <param name="key"></param>
public void SetEncryptKey(string key)
{
}
/// <summary>
/// 设置是否需要监控网络重连。
/// 登录成功后,开启监控,可以自动重连或者提示玩家重连。
/// </summary>
/// <param name="needWatch"></param>
public void SetWatchReconnect(bool needWatch)
{
_connectWatcher.Enable = needWatch;
}
public bool IsNetworkOkAndLogin()
{
return _status == GameClientStatus.StatusEnter;
}
#region
/// <summary>
/// 最近一次心跳的时间
/// </summary>
private float _lastHbTime = 0f;
/// <summary>
/// 心跳间隔
/// </summary>
private readonly float _heartBeatDurTime = 5;
/// <summary>
/// 心跳超时的最大次数
/// </summary>
private const int HeatBeatTimeoutMaxCount = 2;
private bool CheckHeatBeatTimeout()
{
if (_heatBeatTimeoutNum >= HeatBeatTimeoutMaxCount)
{
//断开连接
Shutdown();
//准备重连
_heatBeatTimeoutNum = 0;
Status = GameClientStatus.StatusClose;
Log.Error("heat beat detect timeout");
return false;
}
return true;
}
void TickHeartBeat()
{
if (Status != GameClientStatus.StatusEnter)
{
return;
}
var nowTime = NowTime;
if (_lastHbTime + _heartBeatDurTime < nowTime)
{
_lastHbTime = nowTime;
CSPkg heatPkg = ProtobufUtility.BuildCsMsg((int)CSMsgID.CsCmdHeatbeatReq);
heatPkg.Body.HeatBeatReq = new CSHeatBeatReq { HeatEchoTime = _lastHbTime };
SendCsMsg(heatPkg, (int)CSMsgID.CsCmdHeatbeatRes, HandleHeatBeatRes);
}
}
void HandleHeatBeatRes(CsMsgResult result, CSPkg msg)
{
if (result != CsMsgResult.NoError)
{
//如果是超时了,则标记最近收到包的次数
if (result == CsMsgResult.MsgTimeOut)
{
_heatBeatTimeoutNum++;
Log.Warning("heat beat timeout: {0}", _heatBeatTimeoutNum);
}
}
else
{
var resBody = msg.Body.HeatBeatRes;
float diffTime = NowTime - resBody.HeatEchoTime;
_ping = (int)(diffTime * 1000);
_heatBeatTimeoutNum = 0;
}
}
#endregion
#region Ping值
/// <summary>
/// ping值
/// </summary>
public int Ping
{
get
{
if (IsPingValid())
{
return _ping / 4;
}
else
{
return 0;
}
}
}
public bool IsPingValid()
{
if (IsNetworkOkAndLogin())
{
return _ping >= 0;
}
return false;
}
#endregion
}
}

View File

@@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: 8c5441725c9f4d98a7790dc76a6a0c48
timeCreated: 1684331687

View File

@@ -1,19 +0,0 @@
using System;
using ProtoBuf;
namespace GameLogic
{
[Serializable, ProtoContract(Name = @"HeartBeat")]
public class HeartBeat : PacketBase
{
public HeartBeat()
{
}
public override int Id => 1;
public override void Clear()
{
}
}
}

View File

@@ -1,3 +0,0 @@
fileFormatVersion: 2
guid: d8b9b60d2abf409ca9dd2ce00506ac79
timeCreated: 1682046644

View File

@@ -0,0 +1,265 @@
using System;
using System.Collections.Generic;
using GameProto;
using TEngine;
using CSPkg = GameProto.CSPkg;
namespace GameLogic
{
internal class MsgHandleDataToRmv
{
public uint MsgId;
public CsMsgDelegate Handle;
};
class MsgDispatcher
{
const int CheckTimeoutPerframe = 10;
const int MaxMsgHandle = 256;
private readonly CsMsgDelegate[] _aMsgHandles = new CsMsgDelegate[MaxMsgHandle];
private readonly float[] _fMsgRegTime = new float[MaxMsgHandle];
private readonly UInt32[] _adwMsgRegSeq = new UInt32[MaxMsgHandle]; //因为_aiMsgRegResCmdID存储的是hash不能保证一定seqid一样所以这儿存储下用来校验
private readonly uint[] _aiMsgRegResCmdID = new uint[MaxMsgHandle];
UInt32 _dwLastCheckIndex = 0;
private readonly Dictionary<uint, List<CsMsgDelegate>> _mapCmdHandle = new Dictionary<uint, List<CsMsgDelegate>>();
private readonly List<CsMsgStatDelegate> _listStatHandle = new List<CsMsgStatDelegate>();
//防止在处理消息的时候又删除了消息映射,所以这儿加了个队列来做个保护
private readonly List<MsgHandleDataToRmv> _rmvList = new List<MsgHandleDataToRmv>();
private bool _isInHandleLoop = false;
private float _timeout = 5;
// 清理所有的网络消息
public void CleanAllNetMsg()
{
_mapCmdHandle.Clear();
}
public void SetTimeout(float timeout)
{
_timeout = timeout;
}
public void RegSeqHandle(UInt32 dwMsgSeqID, uint iResCmdID, CsMsgDelegate msgDelegate)
{
UInt32 hashIndex = dwMsgSeqID % MaxMsgHandle;
if (_aMsgHandles[hashIndex] != null)
{
OnCallSeqHandle(_adwMsgRegSeq[hashIndex], _aiMsgRegResCmdID[hashIndex]);
NotifyTimeout(_aMsgHandles[hashIndex]);
RmvReg((int)hashIndex);
}
_aMsgHandles[hashIndex] = msgDelegate;
_fMsgRegTime[hashIndex] = NowTime;
_adwMsgRegSeq[hashIndex] = dwMsgSeqID;
_aiMsgRegResCmdID[hashIndex] = iResCmdID;
}
public void RegCmdHandle(uint iCmdID, CsMsgDelegate msgDelegate)
{
if (!_mapCmdHandle.TryGetValue(iCmdID, out var listHandle))
{
listHandle = new List<CsMsgDelegate>();
_mapCmdHandle[iCmdID] = listHandle;
}
if (listHandle != null)
{
if (listHandle.Contains(msgDelegate))
{
Log.Error("-------------repeat RegCmdHandle:{0}-----------", iCmdID);
}
listHandle.Add(msgDelegate);
}
}
/// <summary>
/// 注册统计处理接口
/// </summary>
/// <param name="handler"></param>
public void RegCmdStatHandle(CsMsgStatDelegate handler)
{
_listStatHandle.Add(handler);
}
public void DispatchCmdStat(int cmdID, int pkgSize)
{
foreach (CsMsgStatDelegate handle in _listStatHandle)
{
handle(cmdID, pkgSize);
}
}
public void RmvCmdHandle(uint iCmdID, CsMsgDelegate msgDelegate)
{
if (_isInHandleLoop)
{
MsgHandleDataToRmv toRmvData = new MsgHandleDataToRmv();
toRmvData.MsgId = iCmdID;
toRmvData.Handle = msgDelegate;
_rmvList.Add(toRmvData);
return;
}
if (!_mapCmdHandle.TryGetValue(iCmdID, out var listHandle))
{
return;
}
if (listHandle != null)
{
listHandle.Remove(msgDelegate);
}
}
public void NotifyCmdError(uint iCmdID, CsMsgResult result)
{
NotifyCmdHandle(iCmdID, result, default(CSPkg));
}
protected bool NotifyCmdHandle(uint cmdID, CsMsgResult result, CSPkg pkg)
{
bool ret = false;
if (_mapCmdHandle.TryGetValue(cmdID, out var listHandle))
{
_isInHandleLoop = true;
var rmvList = _rmvList;
rmvList.Clear();
foreach (CsMsgDelegate handle in listHandle)
{
ret = true;
TProfiler.BeginSample("handle");
handle(result, pkg);
TProfiler.EndSample();
}
_isInHandleLoop = false;
//再统一删除掉
int rmvCnt = rmvList.Count;
for (int i = 0; i < rmvCnt; i++)
{
var rmvItem = rmvList[i];
Log.Error("-------------remove cmd handle on loop:{0}-----------", rmvItem.MsgId);
RmvCmdHandle(rmvItem.MsgId, rmvItem.Handle);
}
}
return ret;
}
protected void OnCallSeqHandle(UInt32 echoSeq, uint resCmdID)
{
if (echoSeq > 0)
{
// TODO
// GameEvent.Get<ICommUI>().FinWaitUI(echoSeq);
}
}
protected void NotifyTimeout(CsMsgDelegate msgHandler)
{
msgHandler(CsMsgResult.MsgTimeOut, default(CSPkg));
}
public void NotifySeqError(UInt32 dwSeqID, CsMsgResult result)
{
UInt32 hashIndex = dwSeqID % MaxMsgHandle;
//先判断是否有注册的指定消息
if (_aMsgHandles[hashIndex] != null &&
_adwMsgRegSeq[hashIndex] == dwSeqID)
{
OnCallSeqHandle(dwSeqID, _aiMsgRegResCmdID[hashIndex]);
_aMsgHandles[hashIndex](result, null);
RmvReg((int)hashIndex);
}
}
public bool IsCmdFilterNoLog(int cmdID)
{
switch (cmdID)
{
case (int)CSMsgID.CsCmdHeatbeatRes:
return true;
default:
break;
}
return false;
}
public void NotifyMsg(CSPkg msg)
{
UInt32 dwSeq = msg.Head.Echo;
UInt32 hashIndex = dwSeq % MaxMsgHandle;
//判断是否有固定的消息处理流程
bool bHaveHandle = NotifyCmdHandle(msg.Head.MsgId, CsMsgResult.NoError, msg);
//再判断是否有注册的指定消息
if (_aMsgHandles[hashIndex] != null &&
_adwMsgRegSeq[hashIndex] == dwSeq &&
_aiMsgRegResCmdID[hashIndex] == (int)msg.Head.MsgId)
{
OnCallSeqHandle(_adwMsgRegSeq[hashIndex], _aiMsgRegResCmdID[hashIndex]);
_aMsgHandles[hashIndex](CsMsgResult.NoError, msg);
RmvReg((int)hashIndex);
bHaveHandle = true;
}
if (!bHaveHandle)
{
Log.Debug("there is no handle for Msg[{0}]", msg.Head.MsgId);
}
}
private float NowTime => GameTime.unscaledTime;
public void Update()
{
CheckTimeOut();
}
/// <summary>
/// 定时检查是否请求超时。
/// </summary>
private void CheckTimeOut()
{
float timeout = _timeout;
float nowTime = NowTime;
for (int i = 0; i < CheckTimeoutPerframe; i++)
{
_dwLastCheckIndex = (_dwLastCheckIndex + 1) % MaxMsgHandle;
if (_aMsgHandles[_dwLastCheckIndex] != null)
{
if (_fMsgRegTime[_dwLastCheckIndex] + timeout < nowTime)
{
Log.Error("msg timeout, resCmdID[{0}], reqSeq[{1}]", _aiMsgRegResCmdID[_dwLastCheckIndex],
_adwMsgRegSeq[_dwLastCheckIndex]);
OnCallSeqHandle(_adwMsgRegSeq[_dwLastCheckIndex], _aiMsgRegResCmdID[_dwLastCheckIndex]);
NotifyTimeout(_aMsgHandles[_dwLastCheckIndex]);
RmvReg((int)_dwLastCheckIndex);
}
}
}
}
public void RmvReg(int index)
{
_aMsgHandles[index] = null;
_adwMsgRegSeq[index] = 0;
_aiMsgRegResCmdID[index] = 0;
_fMsgRegTime[index] = 0;
}
}
}

View File

@@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: 7d667fb84fed4c5f93a06c464585512f
timeCreated: 1684333223

View File

@@ -1,10 +1,10 @@
using ProtoBuf;
using ProtoBuf.Meta;
using System;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Net.Sockets;
using System.Reflection;
using GameProto;
using Google.Protobuf;
using TEngine;
namespace GameLogic
@@ -29,31 +29,6 @@ namespace GameLogic
{
_networkChannel = networkChannel;
// 反射注册包和包处理函数。
Type packetBaseType = typeof(ProtoPacket);
Assembly assembly = Assembly.GetExecutingAssembly();
Type[] types = assembly.GetTypes();
for (int i = 0; i < types.Length; i++)
{
if (!types[i].IsClass || types[i].IsAbstract)
{
continue;
}
if (types[i].BaseType == packetBaseType)
{
PacketBase packetBase = (PacketBase)Activator.CreateInstance(types[i]);
Type packetType = GetServerToClientPacketType(packetBase.Id);
if (packetType != null)
{
Log.Warning("Already exist packet type '{0}', check '{1}' or '{2}'?.", packetBase.Id.ToString(), packetType.Name, packetBase.GetType().Name);
continue;
}
_serverToClientPacketTypes.Add(packetBase.Id, types[i]);
}
}
GameEvent.AddEventListener<INetworkChannel, object>(NetworkEvent.NetworkConnectedEvent, OnNetworkConnected);
GameEvent.AddEventListener<INetworkChannel>(NetworkEvent.NetworkClosedEvent, OnNetworkClosed);
GameEvent.AddEventListener<INetworkChannel, int>(NetworkEvent.NetworkMissHeartBeatEvent, OnNetworkMissHeartBeat);
@@ -84,13 +59,16 @@ namespace GameLogic
_networkChannel.Socket.SendBufferSize = 1024 * 64;
}
public CSPkg HeartBeatPack = new CSPkg { Head = new CSPkgHead(), Body = new CSPkgBody() };
/// <summary>
/// 发送心跳消息包。
/// </summary>
/// <returns>是否发送心跳消息包成功。</returns>
public bool SendHeartBeat()
{
_networkChannel.Send(MemoryPool.Acquire<HeartBeat>());
HeartBeatPack.Head.MsgId = (uint)CSMsgID.CsCmdHeatbeatReq;
_networkChannel.Send(HeartBeatPack);
return true;
}
@@ -101,10 +79,9 @@ namespace GameLogic
/// <param name="packet">要序列化的消息包。</param>
/// <param name="destination">要序列化的目标流。</param>
/// <returns>是否序列化成功。</returns>
public bool Serialize<T>(T packet, Stream destination) where T : Packet
public bool Serialize(CSPkg packet, Stream destination)
{
PacketBase packetImpl = packet as PacketBase;
if (packetImpl == null)
if (packet == null)
{
Log.Warning("Packet is invalid.");
return false;
@@ -112,14 +89,7 @@ namespace GameLogic
_cachedStream.SetLength(_cachedStream.Capacity); // 此行防止 Array.Copy 的数据无法写入
_cachedStream.Position = 0L;
PacketHeader packetHeader = MemoryPool.Acquire<PacketHeader>();
Serializer.Serialize(_cachedStream, packetHeader);
MemoryPool.Release(packetHeader);
Serializer.SerializeWithLengthPrefix(_cachedStream, packet, PrefixStyle.Fixed32);
MemoryPool.Release((IMemory)packet);
global::ProtobufUtility.ToStreamWithHead(packet,_cachedStream);
_cachedStream.WriteTo(destination);
return true;
}
@@ -134,7 +104,9 @@ namespace GameLogic
{
// 注意:此函数并不在主线程调用!
customErrorData = null;
return (IPacketHeader)RuntimeTypeModel.Default.Deserialize(source, MemoryPool.Acquire<PacketHeader>(), typeof(PacketHeader));
PacketHeader packetHeader = MemoryPool.Acquire<PacketHeader>();
packetHeader.PacketLength = ((MemoryStream)source).GetBuffer()[0];
return packetHeader;
}
/// <summary>
@@ -144,7 +116,7 @@ namespace GameLogic
/// <param name="source">要反序列化的来源流。</param>
/// <param name="customErrorData">用户自定义错误数据。</param>
/// <returns>反序列化后的消息包。</returns>
public Packet DeserializePacket(IPacketHeader packetHeader, Stream source, out object customErrorData)
public CSPkg DeserializePacket(IPacketHeader packetHeader, Stream source, out object customErrorData)
{
// 注意:此函数并不在主线程调用!
customErrorData = null;
@@ -156,17 +128,17 @@ namespace GameLogic
return null;
}
Packet packet = null;
CSPkg csPkg = null;
if (scPacketHeader.IsValid)
{
Type packetType = GetServerToClientPacketType(scPacketHeader.Id);
if (packetType != null)
try
{
packet = (Packet)RuntimeTypeModel.Default.DeserializeWithLengthPrefix(source, MemoryPool.Acquire(packetType), packetType, PrefixStyle.Fixed32, 0);
csPkg = global::ProtobufUtility.Deserialize(((MemoryStream)source).GetBuffer(),0,scPacketHeader.PacketLength);
Log.Debug("[s-c] CmdId[{0}]\n{1}", csPkg.Head.MsgId, csPkg.ToString());
}
else
catch (Exception e)
{
Log.Warning("Can not deserialize packet for packet id '{0}'.", scPacketHeader.Id.ToString());
Log.Warning(e);
}
}
else
@@ -175,7 +147,7 @@ namespace GameLogic
}
MemoryPool.Release(scPacketHeader);
return packet;
return csPkg;
}
private Type GetServerToClientPacketType(int id)

View File

@@ -1,6 +1,8 @@
using System;
using System.Net;
using System.Net.Sockets;
using GameProto;
using Google.Protobuf;
namespace TEngine
{
@@ -163,7 +165,7 @@ namespace TEngine
/// <typeparam name="T">消息包类型。</typeparam>
/// <param name="packet">要发送的消息包。</param>
/// <returns>消息包是否发送成功。</returns>
bool Send<T>(T packet) where T : Packet;
bool Send(CSPkg packet);
/// <summary>
/// 向远程主机发送消息包并注册消息回调。
@@ -173,6 +175,6 @@ namespace TEngine
/// <param name="resHandler">要注册的回调。</param>
/// <param name="needShowWaitUI">是否需要等待UI。</param>
/// <returns>消息包是否发送成功。</returns>
bool Send<T>(T packet, CsMsgDelegate resHandler, bool needShowWaitUI = false) where T : Packet;
bool Send(CSPkg packet, CsMsgDelegate resHandler, bool needShowWaitUI = false);
}
}

View File

@@ -1,4 +1,5 @@
using System.IO;
using GameProto;
namespace TEngine
{
@@ -44,7 +45,7 @@ namespace TEngine
/// <param name="packet">要序列化的消息包。</param>
/// <param name="destination">要序列化的目标流。</param>
/// <returns>是否序列化成功。</returns>
bool Serialize<T>(T packet, Stream destination) where T : Packet;
bool Serialize(CSPkg packet, Stream destination);
/// <summary>
/// 反序列化消息包头。
@@ -61,6 +62,6 @@ namespace TEngine
/// <param name="source">要反序列化的来源流。</param>
/// <param name="customErrorData">用户自定义错误数据。</param>
/// <returns>反序列化后的消息包。</returns>
Packet DeserializePacket(IPacketHeader packetHeader, Stream source, out object customErrorData);
CSPkg DeserializePacket(IPacketHeader packetHeader, Stream source, out object customErrorData);
}
}

View File

@@ -1,5 +1,6 @@
using System.Collections.Generic;
using System.Net.Sockets;
using GameBase;
using UnityEngine;
namespace TEngine
@@ -8,9 +9,9 @@ namespace TEngine
/// 网络组件。
/// </summary>
[DisallowMultipleComponent]
public sealed class Network : GameFrameworkModuleBase
public sealed class Network : UnitySingleton<Network>
{
private static INetworkManager m_NetworkManager = null;
private NetworkManager m_NetworkManager = null;
/// <summary>
/// 获取网络频道数量。
@@ -20,11 +21,12 @@ namespace TEngine
/// <summary>
/// 游戏框架组件初始化。
/// </summary>
protected override void Awake()
public override void Awake()
{
base.Awake();
m_NetworkManager = GameFrameworkEntry.GetModule<INetworkManager>();
// m_NetworkManager = GameFrameworkEntry.GetModule<INetworkManager>();
m_NetworkManager = new NetworkManager();
if (m_NetworkManager == null)
{
Log.Fatal("Network manager is invalid.");
@@ -38,12 +40,17 @@ namespace TEngine
m_NetworkManager.NetworkCustomError += OnNetworkCustomError;
}
private void Update()
{
m_NetworkManager.Update(GameTime.deltaTime, GameTime.unscaledDeltaTime);
}
/// <summary>
/// 检查是否存在网络频道。
/// </summary>
/// <param name="name">网络频道名称。</param>
/// <returns>是否存在网络频道。</returns>
public static bool HasNetworkChannel(string name)
public bool HasNetworkChannel(string name)
{
return m_NetworkManager.HasNetworkChannel(name);
}
@@ -53,7 +60,7 @@ namespace TEngine
/// </summary>
/// <param name="name">网络频道名称。</param>
/// <returns>要获取的网络频道。</returns>
public static INetworkChannel GetNetworkChannel(string name)
public INetworkChannel GetNetworkChannel(string name)
{
return m_NetworkManager.GetNetworkChannel(name);
}
@@ -62,7 +69,7 @@ namespace TEngine
/// 获取所有网络频道。
/// </summary>
/// <returns>所有网络频道。</returns>
public static INetworkChannel[] StaticGetAllNetworkChannels()
public INetworkChannel[] StaticGetAllNetworkChannels()
{
return m_NetworkManager.GetAllNetworkChannels();
}
@@ -80,7 +87,7 @@ namespace TEngine
/// 获取所有网络频道。
/// </summary>
/// <param name="results">所有网络频道。</param>
public static void GetAllNetworkChannels(List<INetworkChannel> results)
public void GetAllNetworkChannels(List<INetworkChannel> results)
{
m_NetworkManager.GetAllNetworkChannels(results);
}
@@ -92,7 +99,8 @@ namespace TEngine
/// <param name="serviceType">网络服务类型。</param>
/// <param name="networkChannelHelper">网络频道辅助器。</param>
/// <returns>要创建的网络频道。</returns>
public static INetworkChannel CreateNetworkChannel(string name, ServiceType serviceType, INetworkChannelHelper networkChannelHelper)
public INetworkChannel CreateNetworkChannel(string name, ServiceType serviceType,
INetworkChannelHelper networkChannelHelper)
{
return m_NetworkManager.CreateNetworkChannel(name, serviceType, networkChannelHelper);
}
@@ -102,7 +110,7 @@ namespace TEngine
/// </summary>
/// <param name="channelName">网络频道名称。</param>
/// <returns>是否销毁网络频道成功。</returns>
public static bool DestroyNetworkChannel(string channelName)
public bool DestroyNetworkChannel(string channelName)
{
return m_NetworkManager.DestroyNetworkChannel(channelName);
}
@@ -122,7 +130,8 @@ namespace TEngine
GameEvent.Send(NetworkEvent.NetworkMissHeartBeatEvent, channel, missCount);
}
private void OnNetworkError(INetworkChannel channel, NetworkErrorCode networkErrorCode, SocketError socketError, string errorMessage)
private void OnNetworkError(INetworkChannel channel, NetworkErrorCode networkErrorCode, SocketError socketError,
string errorMessage)
{
GameEvent.Send(NetworkEvent.NetworkErrorEvent, channel, networkErrorCode, socketError, errorMessage);
}

View File

@@ -2,6 +2,8 @@
using System.Collections.Generic;
using System.Net;
using System.Net.Sockets;
using GameProto;
using Google.Protobuf;
namespace TEngine
{
@@ -15,7 +17,7 @@ namespace TEngine
private const float DefaultHeartBeatInterval = 30f;
private readonly string _name;
protected readonly Queue<Packet> SendPacketPool;
protected readonly Queue<CSPkg> SendPacketPool;
protected readonly INetworkChannelHelper NetworkChannelHelper;
protected AddressFamily MAddressFamily;
protected bool MResetHeartBeatElapseSecondsWhenReceivePacket;
@@ -48,7 +50,7 @@ namespace TEngine
/// <summary>
/// 消息包缓存堆栈。
/// </summary>
private readonly Queue<Packet> _packsQueue = new Queue<Packet>();
private readonly Queue<CSPkg> _packsQueue = new Queue<CSPkg>();
/// <summary>
/// 初始化网络频道基类的新实例。
@@ -58,7 +60,7 @@ namespace TEngine
public NetworkChannelBase(string name, INetworkChannelHelper networkChannelHelper)
{
_name = name ?? string.Empty;
SendPacketPool = new Queue<Packet>();
SendPacketPool = new Queue<CSPkg>();
NetworkChannelHelper = networkChannelHelper;
MAddressFamily = AddressFamily.Unknown;
MResetHeartBeatElapseSecondsWhenReceivePacket = false;
@@ -411,9 +413,8 @@ namespace TEngine
/// <summary>
/// 向远程主机发送消息包。
/// </summary>
/// <typeparam name="T">消息包类型。</typeparam>
/// <param name="packet">要发送的消息包。</param>
public bool Send<T>(T packet) where T : Packet
public bool Send(CSPkg packet)
{
if (MSocket == null)
{
@@ -461,14 +462,13 @@ namespace TEngine
/// <summary>
/// 向远程主机发送消息包并注册消息回调。
/// </summary>
/// <typeparam name="T">消息包类型。</typeparam>
/// <param name="packet">要发送的消息包。</param>
/// <param name="resHandler">要注册的回调。</param>
/// <param name="needShowWaitUI">是否需要等待UI。</param>
/// <returns>消息包是否发送成功。</returns>
public bool Send<T>(T packet, CsMsgDelegate resHandler, bool needShowWaitUI = false) where T : Packet
public bool Send(CSPkg packet, CsMsgDelegate resHandler, bool needShowWaitUI = false)
{
RegisterMsgHandler(packet.Id,resHandler,false);
RegisterMsgHandler((int)packet.Head.MsgId,resHandler,false);
return Send(packet);
}
@@ -511,16 +511,16 @@ namespace TEngine
while (SendPacketPool.Count > 0)
{
Packet packet = null;
CSPkg csPkg = null;
lock (SendPacketPool)
{
packet = SendPacketPool.Dequeue();
csPkg = SendPacketPool.Dequeue();
}
bool serializeResult = false;
try
{
serializeResult = NetworkChannelHelper.Serialize(packet, MSendState.Stream);
serializeResult = NetworkChannelHelper.Serialize(csPkg, MSendState.Stream);
}
catch (Exception exception)
{
@@ -614,22 +614,22 @@ namespace TEngine
try
{
Packet packet = NetworkChannelHelper.DeserializePacket(MReceiveState.PacketHeader, MReceiveState.Stream, out var customErrorData);
CSPkg csPkg = NetworkChannelHelper.DeserializePacket(MReceiveState.PacketHeader, MReceiveState.Stream, out var customErrorData);
if (customErrorData != null && NetworkChannelCustomError != null)
{
NetworkChannelCustomError(this, customErrorData);
}
if (packet != null)
if (csPkg != null)
{
lock (_cacheHandlerQueue)
{
if (_msgHandlerMap.TryGetValue((int)packet.Id, out var listHandle))
if (_msgHandlerMap.TryGetValue((int)csPkg.Head.MsgId, out var listHandle))
{
_cacheHandlerQueue.Enqueue(listHandle);
_packsQueue.Enqueue(packet);
_packsQueue.Enqueue(csPkg);
}
}
}

View File

@@ -1,18 +1,20 @@
using System;
using System.Collections.Generic;
using System.Net.Sockets;
using GameBase;
using GameProto;
namespace TEngine
{
/// <summary>
/// 网络消息委托。
/// </summary>
public delegate void CsMsgDelegate(Packet packet);
public delegate void CsMsgDelegate(CSPkg csPkg);
/// <summary>
/// 网络管理器。
/// </summary>
internal sealed partial class NetworkManager : GameFrameworkModule, INetworkManager
internal sealed partial class NetworkManager : Singleton<NetworkManager>, INetworkManager
{
private readonly Dictionary<string, NetworkChannelBase> _networkChannels;
@@ -90,7 +92,7 @@ namespace TEngine
/// </summary>
/// <param name="elapseSeconds">逻辑流逝时间,以秒为单位。</param>
/// <param name="realElapseSeconds">真实流逝时间,以秒为单位。</param>
internal override void Update(float elapseSeconds, float realElapseSeconds)
public void Update(float elapseSeconds, float realElapseSeconds)
{
foreach (KeyValuePair<string, NetworkChannelBase> networkChannel in _networkChannels)
{
@@ -101,7 +103,7 @@ namespace TEngine
/// <summary>
/// 关闭并清理网络管理器。
/// </summary>
internal override void Shutdown()
public void Shutdown()
{
foreach (KeyValuePair<string, NetworkChannelBase> networkChannel in _networkChannels)
{
@@ -183,7 +185,8 @@ namespace TEngine
/// <param name="serviceType">网络服务类型。</param>
/// <param name="networkChannelHelper">网络频道辅助器。</param>
/// <returns>要创建的网络频道。</returns>
public INetworkChannel CreateNetworkChannel(string name, ServiceType serviceType, INetworkChannelHelper networkChannelHelper)
public INetworkChannel CreateNetworkChannel(string name, ServiceType serviceType,
INetworkChannelHelper networkChannelHelper)
{
if (networkChannelHelper == null)
{
@@ -197,7 +200,8 @@ namespace TEngine
if (HasNetworkChannel(name))
{
throw new GameFrameworkException(Utility.Text.Format("Already exist network channel '{0}'.", name ?? string.Empty));
throw new GameFrameworkException(Utility.Text.Format("Already exist network channel '{0}'.",
name ?? string.Empty));
}
NetworkChannelBase networkChannel = null;
@@ -220,7 +224,8 @@ namespace TEngine
break;
default:
throw new GameFrameworkException(Utility.Text.Format("Not supported service type '{0}'.", serviceType));
throw new GameFrameworkException(Utility.Text.Format("Not supported service type '{0}'.",
serviceType));
}
networkChannel.NetworkChannelConnected += OnNetworkChannelConnected;
@@ -249,6 +254,7 @@ namespace TEngine
networkChannel.Shutdown();
return name != null && _networkChannels.Remove(name);
}
return false;
}
@@ -285,7 +291,8 @@ namespace TEngine
}
}
private void OnNetworkChannelError(NetworkChannelBase networkChannel, NetworkErrorCode errorCode, SocketError socketErrorCode, string errorMessage)
private void OnNetworkChannelError(NetworkChannelBase networkChannel, NetworkErrorCode errorCode,
SocketError socketErrorCode, string errorMessage)
{
if (_networkErrorEventHandler != null)
{

View File

@@ -1,24 +0,0 @@
using TEngine;
namespace GameLogic
{
/// <summary>
/// 网络消息包基类。
/// </summary>
public abstract class PacketBase : Packet
{
/// <summary>
/// 网络消息包Id。
/// </summary>
public int ProtoId;
/// <summary>
/// 网络消息包包体。
/// </summary>
public byte[] ProtoBody;
public void Close()
{
}
}
}

View File

@@ -1,3 +0,0 @@
fileFormatVersion: 2
guid: acea4283f57644b6b4452354d23f2803
timeCreated: 1682045887

View File

@@ -1,15 +0,0 @@
namespace GameLogic
{
/// <summary>
/// 网络消息包。
/// </summary>
public partial class ProtoPacket : PacketBase
{
public override int Id => 1;
public override void Clear()
{
Close();
}
}
}

Some files were not shown because too many files have changed in this diff Show More