diff options
Diffstat (limited to 'Client/Assembly-CSharp/InnerNet')
-rw-r--r-- | Client/Assembly-CSharp/InnerNet/InnerNetClient.cs | 96 | ||||
-rw-r--r-- | Client/Assembly-CSharp/InnerNet/InnerNetObject.cs | 26 | ||||
-rw-r--r-- | Client/Assembly-CSharp/InnerNet/InnerNetServer.cs | 113 |
3 files changed, 183 insertions, 52 deletions
diff --git a/Client/Assembly-CSharp/InnerNet/InnerNetClient.cs b/Client/Assembly-CSharp/InnerNet/InnerNetClient.cs index 7cff87c..b88dda4 100644 --- a/Client/Assembly-CSharp/InnerNet/InnerNetClient.cs +++ b/Client/Assembly-CSharp/InnerNet/InnerNetClient.cs @@ -34,6 +34,7 @@ namespace InnerNet } } + // 本机是host public bool AmHost { get @@ -176,6 +177,7 @@ namespace InnerNet this.GameId = 32; } + //c 发送数据,在主线程调用 private void SendOrDisconnect(MessageWriter msg) { try @@ -244,21 +246,26 @@ namespace InnerNet this.LastDisconnectReason = DisconnectReasons.ExitGame; this.NetIdCnt = 1U; this.DestroyedObjects.Clear(); + // 创建发送流 if (this.Streams == null) { - this.Streams = new MessageWriter[2]; - for (int i = 0; i < this.Streams.Length; i++) + this.Streams = new MessageWriter[2]; // 一个是不可靠的,一个是可靠的 + for (int i = 0; i < this.Streams.Length; i++) { this.Streams[i] = MessageWriter.Get((SendOption)i); } } - for (int j = 0; j < this.Streams.Length; j++) + //c 初始化发送流 + // SendRpcImmediately和SendRpc的区别是前者每次会发送一个rpc,后者会把rpc拼起来 + // 所以这里设置了头5 + for (int j = 0; j < this.Streams.Length; j++) { MessageWriter messageWriter = this.Streams[j]; messageWriter.Clear((SendOption)j); - messageWriter.StartMessage(5); + messageWriter.StartMessage(5); // GameData messageWriter.Write(this.GameId); } + IPEndPoint remoteEndPoint = new IPEndPoint(IPAddress.Parse(this.networkAddress), this.networkPort); this.connection = new UdpClientConnection(remoteEndPoint, IPMode.IPv4); this.connection.KeepAliveInterval = 1500; @@ -315,8 +322,9 @@ namespace InnerNet yield break; } this.GameId = 0; + // 单局游戏配置 PlayerControl.GameOptions = SaveManager.GameHostOptions; - this.HostGame(PlayerControl.GameOptions); + this.HostGame(PlayerControl.GameOptions); // 作为host yield return this.WaitWithTimeout(() => this.GameId != 0); if (!this.AmConnected) { @@ -520,7 +528,10 @@ namespace InnerNet this.allObjectsFast.Clear(); } - public void HostGame(IBytesSerializable settings) + // 作为host建立服务器 + // 根据settings配置 + // 服务器会返回GameId(根据settings) + public void HostGame(IBytesSerializable settings) { this.IsGamePublic = false; MessageWriter messageWriter = MessageWriter.Get(SendOption.Reliable); @@ -925,7 +936,7 @@ namespace InnerNet }); return; } - IL_2F5: + IL_2F5: // 同时处理join game和disconnect int num8 = reader.ReadInt32(); DisconnectReasons disconnectReasons = (DisconnectReasons)num8; if (InnerNetClient.disconnectReasons.Contains(disconnectReasons)) @@ -950,6 +961,7 @@ namespace InnerNet { this.Dispatcher.Add(delegate { + // 某个玩家加入了本局 this.OnPlayerJoined(client); }); } @@ -1210,6 +1222,7 @@ namespace InnerNet private void FixedUpdate() { + // 每隔MinSendInterval的时间同步一次标记为脏的数据 if (this.mode == MatchMakerModes.None || this.Streams == null) { this.timer = 0f; @@ -1229,9 +1242,12 @@ namespace InnerNet for (int i = 0; i < this.allObjects.Count; i++) { InnerNetObject innerNetObject = this.allObjects[i]; - if (innerNetObject && innerNetObject.DirtyBits != 0U && (innerNetObject.AmOwner || (innerNetObject.OwnerId == -2 && this.AmHost))) + // 如果这个数据是本玩家控制的,作为同步数据写入 + if (innerNetObject + && innerNetObject.DirtyBits != 0U + && (innerNetObject.AmOwner || (innerNetObject.OwnerId == /*-2*/InvalidClient && this.AmHost))) { - MessageWriter messageWriter = this.Streams[(int)innerNetObject.sendMode]; + MessageWriter messageWriter = this.Streams[(int)innerNetObject.sendMode]; // 根据是否是可靠UDP,选择对应的writer messageWriter.StartMessage(1); messageWriter.WritePacked(innerNetObject.NetId); if (innerNetObject.Serialize(messageWriter, false)) @@ -1245,16 +1261,32 @@ namespace InnerNet } } } - + // 发送数据 for (int j = 0; j < this.Streams.Length; j++) { MessageWriter messageWriter2 = this.Streams[j]; - if (messageWriter2.HasBytes(7)) - { + /* + public void StartMessage(byte typeFlag) + { + messageStarts.Push(this.Position); + this.Position += 2; // Skip for size + this.Write(typeFlag); + } + public void EndMessage() + { + var lastMessageStart = messageStarts.Pop(); + ushort length = (ushort)(this.Position - lastMessageStart - 3); // Minus length and type byte + this.Buffer[lastMessageStart] = (byte)length; + this.Buffer[lastMessageStart + 1] = (byte)(length >> 8); + } + */ + if (messageWriter2.HasBytes(7)) // 里面是否有数据,有的话发送。7=length(2B) + DataFlag(1B) + netId(4B) + { messageWriter2.EndMessage(); this.SendOrDisconnect(messageWriter2); + messageWriter2.Clear((SendOption)j); - messageWriter2.StartMessage(5); + messageWriter2.StartMessage(5); // 初始化 messageWriter2.Write(this.GameId); } } @@ -1270,12 +1302,13 @@ namespace InnerNet return default(T); } + //c 发送RPC public void SendRpcImmediately(uint targetNetId, byte callId, SendOption option) { MessageWriter messageWriter = MessageWriter.Get(option); - messageWriter.StartMessage(5); - messageWriter.Write(this.GameId); - messageWriter.StartMessage(2); + messageWriter.StartMessage(5); // public const byte GameData = 5; + messageWriter.Write(this.GameId); + messageWriter.StartMessage(2); // Rpc messageWriter.WritePacked(targetNetId); messageWriter.Write(callId); messageWriter.EndMessage(); @@ -1312,6 +1345,7 @@ namespace InnerNet msg.Recycle(); } + // public void SendRpc(uint targetNetId, byte callId, SendOption option = SendOption.Reliable) { this.StartRpc(targetNetId, callId, option).EndMessage(); @@ -1319,8 +1353,8 @@ namespace InnerNet public MessageWriter StartRpc(uint targetNetId, byte callId, SendOption option = SendOption.Reliable) { - MessageWriter messageWriter = this.Streams[(int)option]; - messageWriter.StartMessage(2); + MessageWriter messageWriter = this.Streams[(int)option]; // 拿到对应的发送流 + messageWriter.StartMessage(2); // 2 = rpc messageWriter.WritePacked(targetNetId); messageWriter.Write(callId); return messageWriter; @@ -1393,11 +1427,11 @@ namespace InnerNet yield break; } - public void Spawn(InnerNetObject netObjParent, int ownerId = -2, SpawnFlags flags = SpawnFlags.None) + public void Spawn(InnerNetObject netObjParent, int ownerId = /*-2*/InvalidClient, SpawnFlags flags = SpawnFlags.None) { if (this.AmHost) { - ownerId = ((ownerId == -3) ? this.ClientId : ownerId); + ownerId = ((ownerId == /*-3*/CurrentClient) ? this.ClientId : ownerId); MessageWriter msg = this.Streams[1]; this.WriteSpawnMessage(netObjParent, ownerId, flags, msg); return; @@ -1482,7 +1516,7 @@ namespace InnerNet public void RemoveUnownedObjects() { HashSet<int> hashSet = new HashSet<int>(); - hashSet.Add(-2); + hashSet.Add(/*-2*/InvalidClient); List<ClientData> obj = this.allClients; lock (obj) { @@ -1530,6 +1564,15 @@ namespace InnerNet } //c 辅助tag别名 + /* + internal const byte DataFlag = 1; + internal const byte RpcFlag = 2; + internal const byte SpawnFlag = 4; + internal const byte DespawnFlag = 5; + internal const byte SceneChangeFlag = 6; + internal const byte ReadyFlag = 7; + internal const byte ChangeSettingsFlag = 8; + */ private enum SubTagAlias { Normal = 1, // 游戏内的简单数据,比如同步角色位置、动画等 @@ -1565,17 +1608,18 @@ namespace InnerNet case (int)SubTagAlias.Rpc: { // 根据编号找到对应的同步数据 - uint index = reader.ReadPackedUInt32(); + uint netId = reader.ReadPackedUInt32(); InnerNetObject innerNetObject2; - if (this.allObjectsFast.TryGetValue(index, out innerNetObject2)) + if (this.allObjectsFast.TryGetValue(netId, out innerNetObject2)) { byte callId = reader.ReadByte(); + //c 调用Rpc的唯一入口 innerNetObject2.HandleRpc(callId, reader); return; } - if (!this.DestroyedObjects.Contains(index)) + if (!this.DestroyedObjects.Contains(netId)) { - this.DeferMessage(cnt, reader, "Stored RPC for " + index); + this.DeferMessage(cnt, reader, "Stored RPC for " + netId); return; } return; @@ -1623,7 +1667,7 @@ namespace InnerNet for (int i = 0; i < num5; i++) { InnerNetObject innerNetObject4 = componentsInChildren[i]; - innerNetObject4.NetId = reader.ReadPackedUInt32(); + innerNetObject4.NetId = reader.ReadPackedUInt32(); // 设置netid innerNetObject4.OwnerId = num4; if (this.DestroyedObjects.Contains(innerNetObject4.NetId)) { diff --git a/Client/Assembly-CSharp/InnerNet/InnerNetObject.cs b/Client/Assembly-CSharp/InnerNet/InnerNetObject.cs index 0fdcf2d..e589296 100644 --- a/Client/Assembly-CSharp/InnerNet/InnerNetObject.cs +++ b/Client/Assembly-CSharp/InnerNet/InnerNetObject.cs @@ -6,6 +6,7 @@ namespace InnerNet { public abstract class InnerNetObject : MonoBehaviour, IComparable<InnerNetObject> { + // 这个数据是不是我(本玩家) public bool AmOwner { get @@ -14,16 +15,35 @@ namespace InnerNet } } + // 这个字段用处未知,应该是用来标记此类的派生类 public uint SpawnId; + // 每一个此类数据(及派生数据)都会在创建的时候分配一个netId + // 每个这类数据都有一个场景内唯一的netId,会在广播Rpc调用的时候用来找到对应的数据结构 public uint NetId; - public uint DirtyBits; + // 此类数据公用的脏数据标记为,用来决定是否同步这个数据(即用MessageWriter写入) + public uint DirtyBits; - public SpawnFlags SpawnFlags; + /* + public enum SpawnFlags : byte + { + None = 0, + IsClientCharacter = 1 + } + */ + public SpawnFlags SpawnFlags; - public SendOption sendMode = SendOption.Reliable; + /* + public enum SendOption : byte + { + None = 0, + Reliable = 1 + } + */ + public SendOption sendMode = SendOption.Reliable; + // 数据对应的玩家ID,对于本玩家自己的数据会有特殊处理 public int OwnerId; protected bool DespawnOnDestroy = true; diff --git a/Client/Assembly-CSharp/InnerNet/InnerNetServer.cs b/Client/Assembly-CSharp/InnerNet/InnerNetServer.cs index 3705318..3e09a4c 100644 --- a/Client/Assembly-CSharp/InnerNet/InnerNetServer.cs +++ b/Client/Assembly-CSharp/InnerNet/InnerNetServer.cs @@ -11,10 +11,12 @@ namespace InnerNet { public class InnerNetServer : DestroyableSingleton<InnerNetServer> { - public const int MaxPlayers = 10; + // 单局最大玩家数 + public const int MaxPlayers = 10; public bool Running; + // 是本地游戏的话id是这个32 public const int LocalGameId = 32; private const int InvalidHost = -1; @@ -25,13 +27,23 @@ namespace InnerNet public int Port = 22023; - [SerializeField] + /* + public enum GameStates : byte + { + NotStarted, + Started, + Ended, + Destroyed + } + */ + [SerializeField] private GameStates GameState; private NetworkConnectionListener listener; private List<InnerNetServer.Player> Clients = new List<InnerNetServer.Player>(); + // 某个玩家的连接 protected class Player { private static int IdCount = 1; @@ -49,25 +61,32 @@ namespace InnerNet } } + // 销毁这个单例 public override void OnDestroy() { this.StopServer(); base.OnDestroy(); } + // 开启本地服务器,监听端口 + // 在HostGameButton.CoStartGame中调用 public void StartAsServer() { if (this.listener != null) { this.StopServer(); } + this.GameState = GameStates.NotStarted; + this.listener = new UdpConnectionListener(new IPEndPoint(IPAddress.Any, this.Port), IPMode.IPv4, null); this.listener.NewConnection += this.OnServerConnect; this.listener.Start(); + this.Running = true; } + // 停止服务器 public void StopServer() { this.HostId = -1; @@ -91,6 +110,7 @@ namespace InnerNet return Constants.CompatVersions.Contains(version); } + // 收到某个玩家的连接 private void OnServerConnect(NewConnectionEventArgs evt) { MessageReader handshakeData = evt.HandshakeData; @@ -112,7 +132,9 @@ namespace InnerNet handshakeData.Recycle(); } InnerNetServer.Player client = new InnerNetServer.Player(evt.Connection); + Debug.Log(string.Format("Client {0} added: {1}", client.Id, evt.Connection.EndPoint)); + UdpConnection udpConnection = (UdpConnection)evt.Connection; udpConnection.KeepAliveInterval = 1500; udpConnection.DisconnectTimeout = 6000; @@ -169,75 +191,111 @@ namespace InnerNet } } - private void HandleMessage(InnerNetServer.Player client, MessageReader reader, SendOption sendOption) + /* + public static class Tags + { + public const byte HostGame = 0; + + public const byte JoinGame = 1; + + public const byte StartGame = 2; + + public const byte RemoveGame = 3; + + public const byte RemovePlayer = 4; + + public const byte GameData = 5; + + public const byte GameDataTo = 6; + + public const byte JoinedGame = 7; + + public const byte EndGame = 8; + + public const byte GetGameList = 9; + + public const byte AlterGame = 10; + + public const byte KickPlayer = 11; + + public const byte WaitForHost = 12; + + public const byte Redirect = 13; + } + */ + + // 处理收到的消息,在网络线程执行 + // reader是数据 + private void HandleMessage(InnerNetServer.Player client, MessageReader reader, SendOption sendOption) { - switch (reader.Tag) + switch (reader.Tag) { - case 0: + case 0: // HostGame { Debug.Log("Server got host game"); MessageWriter messageWriter = MessageWriter.Get(SendOption.Reliable); - messageWriter.StartMessage(0); - messageWriter.Write(32); + messageWriter.StartMessage(0); // tag + messageWriter.Write(LocalGameId); // gameId messageWriter.EndMessage(); client.Connection.Send(messageWriter); messageWriter.Recycle(); return; } - case 1: + case 1: // JoinGame { Debug.Log("Server got join game"); - if (reader.ReadInt32() == 32) + if (reader.ReadInt32() == LocalGameId) { this.JoinGame(client); return; } MessageWriter messageWriter2 = MessageWriter.Get(SendOption.Reliable); - messageWriter2.StartMessage(1); - messageWriter2.Write(3); + messageWriter2.StartMessage(1); // tag + messageWriter2.Write(3); // messageWriter2.EndMessage(); client.Connection.Send(messageWriter2); messageWriter2.Recycle(); return; } - case 2: + case 2: // StartGame if (reader.ReadInt32() == 32) { this.StartGame(reader, client); return; } break; - case 3: + case 3: // RemoveGame if (reader.ReadInt32() == 32) { this.ClientDisconnect(client); return; } break; - case 4: - case 7: - case 9: - case 10: + case 4: // remove player + case 7: // joined game + case 9: // get game list + case 10: // alter game break; - case 5: + case 5: // Tags.GameData if (this.Clients.Contains(client)) { if (reader.ReadInt32() == 32) { MessageWriter messageWriter3 = MessageWriter.Get(sendOption); messageWriter3.CopyFrom(reader); + // 广播这个消息 this.Broadcast(messageWriter3, client); messageWriter3.Recycle(); return; } } - else if (this.GameState == GameStates.Started) + else if (this.GameState == GameStates.Started) // 没有这个连接就踢掉这个错误的连接 { client.Connection.Dispose(); return; } break; - case 6: + case 6: // GameDataTo 到指定玩家,和Tags.GameData不同,包括Rpc if (this.Clients.Contains(client)) { if (reader.ReadInt32() == 32) @@ -257,14 +315,14 @@ namespace InnerNet return; } break; - case 8: + case 8: // EndGame if (reader.ReadInt32() == 32) { this.EndGame(reader, client); return; } break; - case 11: + case 11: // kick player if (reader.ReadInt32() == 32) { this.KickPlayer(reader.ReadPackedInt32(), reader.ReadBoolean()); @@ -275,12 +333,14 @@ namespace InnerNet } } + // 踢玩家 private void KickPlayer(int targetId, bool ban) { List<InnerNetServer.Player> clients = this.Clients; lock (clients) { InnerNetServer.Player player = null; + // 找到对应的玩家的连接 for (int i = 0; i < this.Clients.Count; i++) { if (this.Clients[i].Id == targetId) @@ -291,7 +351,7 @@ namespace InnerNet } if (player != null) { - if (ban) + if (ban) // 是否ban掉这个ip { HashSet<string> obj = this.ipBans; lock (obj) @@ -318,6 +378,7 @@ namespace InnerNet lock (obj) { IPEndPoint endPoint = client.Connection.EndPoint; + // 如果这个ip被ban掉了,踢掉这个玩家 if (this.ipBans.Contains(endPoint.Address.ToString())) { MessageWriter messageWriter = MessageWriter.Get(SendOption.Reliable); @@ -457,6 +518,7 @@ namespace InnerNet } } + // 游戏结束 private void EndGame(MessageReader message, InnerNetServer.Player source) { if (source.Id == this.HostId) @@ -476,6 +538,7 @@ namespace InnerNet Debug.LogWarning("Reset request rejected from: " + source.Id); } + // 开始游戏,房主点击了开始按钮后,服务器向其他玩家广播开始消息 private void StartGame(MessageReader message, InnerNetServer.Player source) { this.GameState = GameStates.Started; @@ -509,6 +572,7 @@ namespace InnerNet messageWriter.Recycle(); } + // 精确发给某个玩家,而不是广播 protected void SendTo(MessageWriter msg, int targetId) { List<InnerNetServer.Player> clients = this.Clients; @@ -534,11 +598,13 @@ namespace InnerNet } } + // 广播消息 protected void Broadcast(MessageWriter msg, InnerNetServer.Player source) { List<InnerNetServer.Player> clients = this.Clients; lock (clients) { + // 遍历所有的玩家,广播数据 for (int i = 0; i < this.Clients.Count; i++) { InnerNetServer.Player player = this.Clients[i]; @@ -546,6 +612,7 @@ namespace InnerNet { try { + // 发送数据 player.Connection.Send(msg); } catch |