diff --git a/Subsurface/Source/Networking/GameClient.cs b/Subsurface/Source/Networking/GameClient.cs index 7c74fe45f..e8fbf1237 100644 --- a/Subsurface/Source/Networking/GameClient.cs +++ b/Subsurface/Source/Networking/GameClient.cs @@ -697,7 +697,7 @@ namespace Barotrauma.Networking Item.Spawner.ReadNetworkData(inc); break; case (byte)PacketTypes.NewCharacter: - ReadCharacterSpawnMessage(inc); + ReadCharacterData(inc); break; case (byte)PacketTypes.RemoveItem: Item.Remover.ReadNetworkData(inc); @@ -764,43 +764,7 @@ namespace Barotrauma.Networking byte characterCount = inc.ReadByte(); for (int i = 0; i < characterCount; i++) { - bool isAiCharacter = inc.ReadBoolean(); - ushort id = inc.ReadUInt16(); - - if (isAiCharacter) - { - string configPath = inc.ReadString(); - - Vector2 position = new Vector2(inc.ReadFloat(), inc.ReadFloat()); - - var existingEntity = Entity.FindEntityByID(id); - if (existingEntity is AICharacter && existingEntity.ID == id) - { - continue; - } - - var character = Character.Create(configPath, position, null, true); - if (character != null) character.ID = id; - } - else - { - bool hasOwner = inc.ReadBoolean(); - int ownerId = -1; - if (hasOwner) - { - ownerId = inc.ReadByte(); - } - - Character newCharacter = ReadCharacterData(inc, ownerId == myID); - - if (ownerId != myID) - { - var characterOwner = otherClients.Find(c => c.ID == ownerId); - if (characterOwner != null) characterOwner.Character = newCharacter; - } - - crew.Add(newCharacter); - } + ReadCharacterData(inc); } gameStarted = true; @@ -903,15 +867,23 @@ namespace Barotrauma.Networking GUI.DrawRectangle(spriteBatch, new Rectangle(x, y, width, height), Color.Black * 0.7f, true); spriteBatch.DrawString(GUI.Font, "Network statistics:", new Vector2(x + 10, y + 10), Color.White); - spriteBatch.DrawString(GUI.Font, "Ping: " + (int)(client.ServerConnection.AverageRoundtripTime * 1000.0f) + " ms", new Vector2(x + 10, y + 25), Color.White); + if (client.ServerConnection != null) + { + spriteBatch.DrawString(GUI.Font, "Ping: " + (int)(client.ServerConnection.AverageRoundtripTime * 1000.0f) + " ms", new Vector2(x + 10, y + 25), Color.White); - y += 15; + y += 15; - spriteBatch.DrawString(GUI.SmallFont, "Received bytes: " + client.Statistics.ReceivedBytes, new Vector2(x + 10, y + 45), Color.White); - spriteBatch.DrawString(GUI.SmallFont, "Received packets: " + client.Statistics.ReceivedPackets, new Vector2(x + 10, y + 60), Color.White); + spriteBatch.DrawString(GUI.SmallFont, "Received bytes: " + client.Statistics.ReceivedBytes, new Vector2(x + 10, y + 45), Color.White); + spriteBatch.DrawString(GUI.SmallFont, "Received packets: " + client.Statistics.ReceivedPackets, new Vector2(x + 10, y + 60), Color.White); + + spriteBatch.DrawString(GUI.SmallFont, "Sent bytes: " + client.Statistics.SentBytes, new Vector2(x + 10, y + 75), Color.White); + spriteBatch.DrawString(GUI.SmallFont, "Sent packets: " + client.Statistics.SentPackets, new Vector2(x + 10, y + 90), Color.White); + } + else + { + spriteBatch.DrawString(GUI.Font, "Disconnected", new Vector2(x + 10, y + 25), Color.White); + } - spriteBatch.DrawString(GUI.SmallFont, "Sent bytes: " + client.Statistics.SentBytes, new Vector2(x + 10, y + 75), Color.White); - spriteBatch.DrawString(GUI.SmallFont, "Sent packets: " + client.Statistics.SentPackets, new Vector2(x + 10, y + 90), Color.White); } @@ -968,25 +940,6 @@ namespace Barotrauma.Networking return true; } - public void ReadCharacterSpawnMessage(NetIncomingMessage message) - { - string configPath = message.ReadString(); - - if (configPath != Character.HumanConfigFile) - { - ushort id = message.ReadUInt16(); - - Vector2 position = new Vector2(message.ReadFloat(), message.ReadFloat()); - - var character = Character.Create(configPath, position, null, true); - if (character != null) character.ID = id; - } - else - { - ReadCharacterData(message, false, true); - } - } - public void RequestFile(string file, FileTransferMessageType fileType) { if (fileStreamReceiver!=null) @@ -1171,37 +1124,77 @@ namespace Barotrauma.Networking client.SendMessage(msg, NetDeliveryMethod.ReliableUnordered); } - public Character ReadCharacterData(NetIncomingMessage inc, bool isMyCharacter, bool hasAi = false) + public Character ReadCharacterData(NetIncomingMessage inc) { - string newName = inc.ReadString(); - ushort ID = inc.ReadUInt16(); - bool isFemale = inc.ReadBoolean(); + bool noInfo = inc.ReadBoolean(); + ushort id = inc.ReadUInt16(); + string configPath = inc.ReadString(); - int headSpriteID = inc.ReadByte(); - Vector2 position = new Vector2(inc.ReadFloat(), inc.ReadFloat()); + + bool enabled = inc.ReadBoolean(); - string jobName = inc.ReadString(); - JobPrefab jobPrefab = JobPrefab.List.Find(jp => jp.Name == jobName); + Character character = null; - CharacterInfo ch = new CharacterInfo(Character.HumanConfigFile, newName, isFemale ? Gender.Female : Gender.Male, jobPrefab); - ch.HeadSpriteId = headSpriteID; - - Character character = Character.Create(ch, position, !isMyCharacter, hasAi); - GameMain.GameSession.CrewManager.characters.Add(character); - - character.ID = ID; - - Item.Spawner.ReadNetworkData(inc); - - if (isMyCharacter) + if (noInfo) { - myCharacter = character; - Character.Controlled = character; - GameMain.LightManager.LosEnabled = true; + var existingEntity = Entity.FindEntityByID(id); + if (existingEntity is AICharacter && existingEntity.ID == id) + { + return (Character)existingEntity; + } - if (endVoteTickBox != null) endVoteTickBox.Visible = Voting.AllowEndVoting; + character = Character.Create(configPath, position, null, true); + character.ID = id; } + else + { + bool hasOwner = inc.ReadBoolean(); + int ownerId = -1; + if (hasOwner) + { + ownerId = inc.ReadByte(); + } + + string newName = inc.ReadString(); + + bool hasAi = inc.ReadBoolean(); + bool isFemale = inc.ReadBoolean(); + int headSpriteID = inc.ReadByte(); + string jobName = inc.ReadString(); + + JobPrefab jobPrefab = JobPrefab.List.Find(jp => jp.Name == jobName); + + CharacterInfo ch = new CharacterInfo(configPath, newName, isFemale ? Gender.Female : Gender.Male, jobPrefab); + ch.HeadSpriteId = headSpriteID; + + character = Character.Create(configPath, position, ch, ownerId != myID, hasAi); + character.ID = id; + + if (configPath == Character.HumanConfigFile) + { + GameMain.GameSession.CrewManager.characters.Add(character); + } + + Item.Spawner.ReadNetworkData(inc); + + if (ownerId == myID) + { + myCharacter = character; + Character.Controlled = character; + GameMain.LightManager.LosEnabled = true; + + if (endVoteTickBox != null) endVoteTickBox.Visible = Voting.AllowEndVoting; + } + else + { + var characterOwner = otherClients.Find(c => c.ID == ownerId); + if (characterOwner != null) characterOwner.Character = character; + + } + } + + character.Enabled = enabled; return character; } diff --git a/Subsurface/Source/Networking/GameServer.cs b/Subsurface/Source/Networking/GameServer.cs index 56f0ebe79..873cf8d62 100644 --- a/Subsurface/Source/Networking/GameServer.cs +++ b/Subsurface/Source/Networking/GameServer.cs @@ -995,35 +995,7 @@ namespace Barotrauma.Networking msg.Write((byte)characters.Count); foreach (Character c in characters) { - msg.Write(c is AICharacter); - msg.Write(c.ID); - - if (c is AICharacter) - { - msg.Write(c.ConfigPath); - - msg.Write(c.Position.X); - msg.Write(c.Position.Y); - } - else - { - Client client = connectedClients.Find(cl => cl.Character == c); - if (client != null) - { - msg.Write(true); - msg.Write(client.ID); - } - else if (myCharacter == c) - { - msg.Write(true); - msg.Write((byte)0); - } - else - { - msg.Write(false); - } - WriteCharacterData(msg, c.Name, c); - } + WriteCharacterData(msg, c.Name, c); } return msg; @@ -1609,41 +1581,55 @@ namespace Barotrauma.Networking } } - public void WriteCharacterData(NetOutgoingMessage message, string name, Character character) + public void WriteCharacterData(NetOutgoingMessage msg, string name, Character c) { - message.Write(name); - message.Write(character.ID); - message.Write(character.Info.Gender == Gender.Female); + msg.Write(c.Info == null); + msg.Write(c.ID); + msg.Write(c.ConfigPath); - message.Write((byte)character.Info.HeadSpriteId); + msg.Write(c.WorldPosition.X); + msg.Write(c.WorldPosition.Y); - message.Write(character.WorldPosition.X); - message.Write(character.WorldPosition.Y); + msg.Write(c.Enabled); + + if (c.Info != null) + { + Client client = connectedClients.Find(cl => cl.Character == c); + if (client != null) + { + msg.Write(true); + msg.Write(client.ID); + } + else if (myCharacter == c) + { + msg.Write(true); + msg.Write((byte)0); + } + else + { + msg.Write(false); + } + + msg.Write(name); + + msg.Write(c is AICharacter); + msg.Write(c.Info.Gender == Gender.Female); + msg.Write((byte)c.Info.HeadSpriteId); + msg.Write(c.Info.Job == null ? "" : c.Info.Job.Name); - message.Write(character.Info.Job.Name); - - Item.Spawner.FillNetworkData(message, character.SpawnItems); + Item.Spawner.FillNetworkData(msg, c.SpawnItems); + } } public void SendCharacterSpawnMessage(Character character, List recipients = null) { + if (recipients == null || !recipients.Any()) return; + NetOutgoingMessage message = server.CreateMessage(); message.Write((byte)PacketTypes.NewCharacter); - message.Write(character.ConfigPath); - - if (character.ConfigPath == Character.HumanConfigFile) - { - WriteCharacterData(message, character.Name, character); - } - else - { - message.Write(character.ID); - - message.Write(character.Position.X); - message.Write(character.Position.Y); - } - + WriteCharacterData(message, character.Name, character); + SendMessage(message, NetDeliveryMethod.ReliableUnordered, recipients); } diff --git a/Subsurface/Source/Networking/RespawnManager.cs b/Subsurface/Source/Networking/RespawnManager.cs index df89056fb..3940e64a3 100644 --- a/Subsurface/Source/Networking/RespawnManager.cs +++ b/Subsurface/Source/Networking/RespawnManager.cs @@ -532,7 +532,7 @@ namespace Barotrauma.Networking { byte clientId = inc.ReadByte(); - var character = client.ReadCharacterData(inc, clientId == client.ID); + var character = client.ReadCharacterData(inc); } if (state != newState)