diff options
Diffstat (limited to 'Client/Assembly-CSharp/InnerNet/InnerNetClient.cs')
-rw-r--r-- | Client/Assembly-CSharp/InnerNet/InnerNetClient.cs | 114 |
1 files changed, 86 insertions, 28 deletions
diff --git a/Client/Assembly-CSharp/InnerNet/InnerNetClient.cs b/Client/Assembly-CSharp/InnerNet/InnerNetClient.cs index b88dda4..3336804 100644 --- a/Client/Assembly-CSharp/InnerNet/InnerNetClient.cs +++ b/Client/Assembly-CSharp/InnerNet/InnerNetClient.cs @@ -14,6 +14,7 @@ namespace InnerNet { public abstract class InnerNetClient : MonoBehaviour { + // 是否连接成功 private bool AmConnected { get @@ -22,6 +23,7 @@ namespace InnerNet } } + // ping public int Ping { get @@ -88,6 +90,7 @@ namespace InnerNet private int networkPort; + // Udp连接 private UdpClientConnection connection; public MatchMakerModes mode; @@ -98,6 +101,7 @@ namespace InnerNet public int ClientId = -1; + // 本局内的所有玩家的数据,包括cliendId,playercontrol public List<ClientData> allClients = new List<ClientData>(); public DisconnectReasons LastDisconnectReason; @@ -155,18 +159,20 @@ namespace InnerNet public enum GameStates { - NotJoined, - Joined, - Started, - Ended + NotJoined, // + Joined, // + Started, // + Ended // } + // 每次开局的时候设置remote endpoint public void SetEndpoint(string addr, ushort port) { this.networkAddress = addr; this.networkPort = (int)port; } + // 初始化 public virtual void Start() { SceneManager.activeSceneChanged += delegate(Scene oldScene, Scene scene) @@ -190,6 +196,7 @@ namespace InnerNet } } + // 找到作为host的主机数据 public ClientData GetHost() { List<ClientData> obj = this.allClients; @@ -207,7 +214,8 @@ namespace InnerNet return null; } - public int GetClientIdFromCharacter(InnerNetObject character) + // 根据playerControl找到对应的clientId + public int GetClientIdFromCharacter(InnerNetObject /*PlayerControl*/ character) { if (!character) { @@ -228,6 +236,7 @@ namespace InnerNet return -1; } + // 销毁的时候断开连接 public virtual void OnDestroy() { if (this.AmConnected) @@ -236,6 +245,7 @@ namespace InnerNet } } + // 只建立“udp连接”,不建房间 public IEnumerator CoConnect() { if (this.AmConnected) @@ -266,6 +276,11 @@ namespace InnerNet messageWriter.Write(this.GameId); } + // 建立连接 + // 因为是Udp所以实际上socket没有调用connect函数,ConnectAsync的第二个参数timeout只是在第一次建立连接的时候向服务器发送一个 + // hello消息,确保连接成功 + // Hazel-Networking的Udp连接风格实现了和Tcp一样的方式,这样容易被客户端使用,将游戏过程中共用的数据比如Ip,端口,封装为一个 + // Udp连接,方便统一管理 IPEndPoint remoteEndPoint = new IPEndPoint(IPAddress.Parse(this.networkAddress), this.networkPort); this.connection = new UdpClientConnection(remoteEndPoint, IPMode.IPv4); this.connection.KeepAliveInterval = 1500; @@ -273,23 +288,25 @@ namespace InnerNet this.connection.ResendPingMultiplier = 2f; this.connection.DataReceived += this.OnMessageReceived; // 注册到网络线程的消息处理函数 this.connection.Disconnected += this.OnDisconnect; // 连接断开时的回调函数 + + // “建立连接”并尝试向服务器发送一个hello消息,保证连接是通的 this.connection.ConnectAsync(this.GetConnectionData(), 5000); - yield return this.WaitWithTimeout(() => this.connection == null || this.connection.State == ConnectionState.Connected); + yield return this.WaitWithTimeout( + () => this.connection == null || this.connection.State == ConnectionState.Connected + ); yield break; } private void Connection_DataReceivedRaw(byte[] data) { - Debug.Log("Client Got: " + string.Join(" ", from b in data - select b.ToString())); + Debug.Log("Client Got: " + string.Join(" ", from b in data select b.ToString())); } private void Connection_DataSentRaw(byte[] data, int length) { - Debug.Log("Client Sent: " + string.Join(" ", (from b in data - select b.ToString()).ToArray<string>(), 0, length)); + Debug.Log("Client Sent: " + string.Join(" ", (from b in data select b.ToString()).ToArray<string>(), 0, length)); } public void Connect(MatchMakerModes mode) @@ -297,6 +314,7 @@ namespace InnerNet base.StartCoroutine(this.CoConnect(mode)); } + // 这个协程包括了建立udp连接和建立host服务器(如果是MatchMakerModes.HostAndClient的话)或加入游戏(如果是MatchMakerModes.Client) private IEnumerator CoConnect(MatchMakerModes mode) { if (this.mode != MatchMakerModes.None) @@ -304,38 +322,57 @@ namespace InnerNet this.DisconnectInternal(DisconnectReasons.NewConnection, null); } this.mode = mode; + + // “udp连接” yield return this.CoConnect(); - if (!this.AmConnected) + + if (!this.AmConnected) // 连接失败 { yield break; } + // 连接成功 + MatchMakerModes matchMakerModes = this.mode; - if (matchMakerModes == MatchMakerModes.Client) + if (matchMakerModes == MatchMakerModes.Client) // 如果在本局只作为client,加入游戏 { - this.JoinGame(); - yield return this.WaitWithTimeout(() => this.ClientId >= 0); + this.JoinGame(); // 加入游戏 + yield return this.WaitWithTimeout( + () => this.ClientId >= 0 // clientId大于0代表加入游戏成功 + ); bool amConnected = this.AmConnected; yield break; } - if (matchMakerModes != MatchMakerModes.HostAndClient) + // 下面是作为host建立房间 + + if (matchMakerModes != MatchMakerModes.HostAndClient) { yield break; } this.GameId = 0; - // 单局游戏配置 + + // 单局游戏的配置,本玩家作为host建立游戏 PlayerControl.GameOptions = SaveManager.GameHostOptions; - this.HostGame(PlayerControl.GameOptions); // 作为host - yield return this.WaitWithTimeout(() => this.GameId != 0); - if (!this.AmConnected) + // 作为host创建游戏 + this.HostGame(PlayerControl.GameOptions); + yield return this.WaitWithTimeout( + () => this.GameId != 0 // gameId不为0代表建立游戏成功,对应InnerNetServer.cs中的HandleMessage + ); + + if (!this.AmConnected) // 连接失败 { yield break; } - this.JoinGame(); - yield return this.WaitWithTimeout(() => this.ClientId >= 0); + + this.JoinGame(); // 加入游戏 + + yield return this.WaitWithTimeout( + () => this.ClientId >= 0 // clientId大于0代表加入游戏成功 + ); bool amConnected2 = this.AmConnected; yield break; } + // 等待连接建立 public IEnumerator WaitForConnectionOrFail() { while (this.AmConnected) @@ -367,6 +404,7 @@ namespace InnerNet yield break; } + // 每帧检查一下success是否达成,并检查timeout,超过timeout限制后fail private IEnumerator WaitWithTimeout(Func<bool> success) { bool failed = true; @@ -383,6 +421,7 @@ namespace InnerNet } yield return null; } + // 超时,断开连接 if (failed) { this.DisconnectInternal(DisconnectReasons.Error, null); @@ -440,6 +479,7 @@ namespace InnerNet } } + // 断开连接的回调,在网络线程调用 private void OnDisconnect(object sender, DisconnectedEventArgs e) { if (!e.Reason.Contains("The remote sent a")) @@ -459,6 +499,7 @@ namespace InnerNet this.OnDisconnected(); } + // 将主动断开连接的任务加到dispatcher,待主线程执行 protected void EnqueueDisconnect(DisconnectReasons reason, string stringReason = null) { UdpClientConnection udpClientConnection = this.connection; @@ -472,6 +513,7 @@ namespace InnerNet } } + // 主动断开连接 protected void DisconnectInternal(DisconnectReasons reason, string stringReason = null) { if (reason != DisconnectReasons.NewConnection && reason != DisconnectReasons.FocusLostBackground) @@ -536,13 +578,14 @@ namespace InnerNet this.IsGamePublic = false; MessageWriter messageWriter = MessageWriter.Get(SendOption.Reliable); messageWriter.StartMessage(0); - messageWriter.WriteBytesAndSize(settings.ToBytes()); + messageWriter.WriteBytesAndSize(settings.ToBytes()); // 这里当作为InnerNetServer启动时没有用到,中心服务器需要这个字段是因为要显示房间列表 messageWriter.EndMessage(); this.SendOrDisconnect(messageWriter); messageWriter.Recycle(); Debug.Log("Client requesting new game."); } + // 加入游戏 public void JoinGame() { this.ClientId = -1; @@ -560,16 +603,19 @@ namespace InnerNet messageWriter.Recycle(); } + // 是否可以ban其他玩家(只有房主可以) public bool CanBan() { return this.AmHost && !this.IsGameStarted; } + // 是否可以踢其他玩家 public bool CanKick() { return this.IsGameStarted || this.AmHost; } + // 踢玩家 public void KickPlayer(int clientId, bool ban) { if (!this.AmHost) @@ -586,6 +632,7 @@ namespace InnerNet messageWriter.Recycle(); } + // 结束游戏 public MessageWriter StartEndGame() { MessageWriter messageWriter = MessageWriter.Get(SendOption.Reliable); @@ -1043,6 +1090,7 @@ namespace InnerNet }); } + // 根据clientID返回对应的client结构,如果没有的话新建一个并保存 private ClientData GetOrCreateClient(int clientId) { List<ClientData> obj = this.allClients; @@ -1059,6 +1107,7 @@ namespace InnerNet return clientData; } + //在网络线程调用,删除某个角色gameobject private void RemovePlayer(int playerIdThatLeft, DisconnectReasons reason) { ClientData client = null; @@ -1083,12 +1132,14 @@ namespace InnerNet { this.Dispatcher.Add(delegate { + // 在主线程调用 this.OnPlayerLeft(client, reason); }); } } } + // protected virtual void OnApplicationPause(bool pause) { this.appPaused = pause; @@ -1123,6 +1174,7 @@ namespace InnerNet } } + // protected void SendInitialData(int clientId) { MessageWriter messageWriter = MessageWriter.Get(SendOption.Reliable); @@ -1171,6 +1223,7 @@ namespace InnerNet protected abstract byte[] GetConnectionData(); + // 根据clientId返回对应的client结构 protected ClientData FindClientById(int id) { if (id < 0) @@ -1265,7 +1318,7 @@ namespace InnerNet for (int j = 0; j < this.Streams.Length; j++) { MessageWriter messageWriter2 = this.Streams[j]; - /* + /* public void StartMessage(byte typeFlag) { messageStarts.Push(this.Position); @@ -1280,11 +1333,11 @@ namespace InnerNet this.Buffer[lastMessageStart + 1] = (byte)(length >> 8); } */ - if (messageWriter2.HasBytes(7)) // 里面是否有数据,有的话发送。7=length(2B) + DataFlag(1B) + netId(4B) - { + // 里面是否有数据,有的话发送。 + if (messageWriter2.HasBytes(7)) // 7=length(2B) + DataFlag(1B) + netId(4B) + { messageWriter2.EndMessage(); this.SendOrDisconnect(messageWriter2); - messageWriter2.Clear((SendOption)j); messageWriter2.StartMessage(5); // 初始化 messageWriter2.Write(this.GameId); @@ -1292,6 +1345,7 @@ namespace InnerNet } } + // 根据netId返回对应的同步对象 public T FindObjectByNetId<T>(uint netId) where T : InnerNetObject { InnerNetObject innerNetObject; @@ -1317,6 +1371,7 @@ namespace InnerNet messageWriter.Recycle(); } + // 封装一个Rpc,配合FinishRpcImmediately public MessageWriter StartRpcImmediately(uint targetNetId, byte callId, SendOption option, int targetClientId = -1) { MessageWriter messageWriter = MessageWriter.Get(option); @@ -1345,10 +1400,11 @@ namespace InnerNet msg.Recycle(); } - // + // 向公用的stream写入Rpc public void SendRpc(uint targetNetId, byte callId, SendOption option = SendOption.Reliable) { - this.StartRpc(targetNetId, callId, option).EndMessage(); + this.StartRpc(targetNetId, callId, option) + .EndMessage(); } public MessageWriter StartRpc(uint targetNetId, byte callId, SendOption option = SendOption.Reliable) @@ -1360,6 +1416,7 @@ namespace InnerNet return messageWriter; } + // 发送切换场景消息 private void SendSceneChange(string sceneName) { this.InOnlineScene = string.Equals(sceneName, "OnlineGame"); @@ -1746,6 +1803,7 @@ namespace InnerNet }) + string.Join<byte>(" ", reader.Buffer)); } + // 延迟发送消息 private void DeferMessage(int cnt, MessageReader reader, string logMsg) { if (cnt > 10) |