summaryrefslogtreecommitdiff
path: root/Client/Assembly-CSharp/InnerNet
diff options
context:
space:
mode:
Diffstat (limited to 'Client/Assembly-CSharp/InnerNet')
-rw-r--r--Client/Assembly-CSharp/InnerNet/InnerNetClient.cs96
-rw-r--r--Client/Assembly-CSharp/InnerNet/InnerNetObject.cs26
-rw-r--r--Client/Assembly-CSharp/InnerNet/InnerNetServer.cs113
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