From 6364915353129fa0bf814d82d7c90288a845064c Mon Sep 17 00:00:00 2001 From: Regalis Date: Sat, 7 Jan 2017 16:11:50 +0200 Subject: [PATCH 1/5] Fixed incorrect msg lengths in CHARACTER_POSITION messages (+ calculating the length automatically) --- Subsurface/Source/Characters/Character.cs | 39 ++++++++++++----------- 1 file changed, 20 insertions(+), 19 deletions(-) diff --git a/Subsurface/Source/Characters/Character.cs b/Subsurface/Source/Characters/Character.cs index ccd94e712..b46c9e094 100644 --- a/Subsurface/Source/Characters/Character.cs +++ b/Subsurface/Source/Characters/Character.cs @@ -2067,18 +2067,16 @@ namespace Barotrauma { msg.Write(ID); + NetBuffer tempBuffer = new NetBuffer(); + if (this == c.Character) { - //length of the message - msg.Write((byte)(4+4+4)); - msg.Write(true); - msg.Write((UInt32)(LastNetworkUpdateID - memInput.Count - 1)); + tempBuffer.Write(true); + tempBuffer.Write((UInt32)(LastNetworkUpdateID - memInput.Count - 1)); } else { - //length of the message - msg.Write((byte)(4+4+1 + 1 + 1)); - msg.Write(false); + tempBuffer.Write(false); bool aiming = false; bool use = false; @@ -2096,33 +2094,36 @@ namespace Barotrauma networkUpdateSent = true; } - msg.Write(aiming); - msg.Write(use); + tempBuffer.Write(aiming); + tempBuffer.Write(use); if (selectedCharacter != null || selectedConstruction != null) { - msg.Write(true); - msg.Write(selectedCharacter != null ? selectedCharacter.ID : selectedConstruction.ID); + tempBuffer.Write(true); + tempBuffer.Write(selectedCharacter != null ? selectedCharacter.ID : selectedConstruction.ID); } else { - msg.Write(false); + tempBuffer.Write(false); } if (aiming) { //TODO: write this with less accuracy? - - msg.Write(cursorPosition.X); - msg.Write(cursorPosition.Y); + + tempBuffer.Write(cursorPosition.X); + tempBuffer.Write(cursorPosition.Y); } - - msg.Write(AnimController.TargetDir == Direction.Right); + + tempBuffer.Write(AnimController.TargetDir == Direction.Right); } - msg.Write(SimPosition.X); - msg.Write(SimPosition.Y); + tempBuffer.Write(SimPosition.X); + tempBuffer.Write(SimPosition.Y); + + msg.Write((byte)tempBuffer.LengthBytes); + msg.Write(tempBuffer); msg.WritePadBits(); } From 44cbd0d9bf23b2ca7e34ab1e5e752e264e47ef1d Mon Sep 17 00:00:00 2001 From: Regalis Date: Sat, 7 Jan 2017 16:51:51 +0200 Subject: [PATCH 2/5] Fixed AI characters constantly flipping over the X-axis when inside, fixed clients not receiving a msg about characters spawned by RespawnManager --- .../Characters/Animation/FishAnimController.cs | 4 ++-- Subsurface/Source/Characters/Character.cs | 9 ++------- Subsurface/Source/Networking/EntitySpawner.cs | 12 ++++++++++++ Subsurface/Source/Networking/GameServer.cs | 3 +-- Subsurface/Source/Networking/RespawnManager.cs | 11 ++++++----- 5 files changed, 23 insertions(+), 16 deletions(-) diff --git a/Subsurface/Source/Characters/Animation/FishAnimController.cs b/Subsurface/Source/Characters/Animation/FishAnimController.cs index 543339e16..05645bac4 100644 --- a/Subsurface/Source/Characters/Animation/FishAnimController.cs +++ b/Subsurface/Source/Characters/Animation/FishAnimController.cs @@ -155,8 +155,8 @@ namespace Barotrauma if (!flip) return; flipTimer += deltaTime; - - if (TargetDir != dir) + + if (TargetDir != Direction.None && TargetDir != dir) { if (flipTimer>1.0f || character.IsRemotePlayer) { diff --git a/Subsurface/Source/Characters/Character.cs b/Subsurface/Source/Characters/Character.cs index b46c9e094..6c22b1d7e 100644 --- a/Subsurface/Source/Characters/Character.cs +++ b/Subsurface/Source/Characters/Character.cs @@ -823,7 +823,7 @@ namespace Barotrauma public void Control(float deltaTime, Camera cam) { - if (isDead || AnimController.StunTimer>0.0f) return; + if (!AllowInput) return; Vector2 targetMovement = GetTargetMovement(); @@ -1461,12 +1461,7 @@ namespace Barotrauma ControlLocalPlayer(deltaTime, cam); } - if (controlled == this || - !(this is AICharacter) || - !((AICharacter)this).AIController.Enabled) - { - Control(deltaTime, cam); - } + Control(deltaTime, cam); if (selectedConstruction != null && !selectedConstruction.IsInPickRange(WorldPosition)) { diff --git a/Subsurface/Source/Networking/EntitySpawner.cs b/Subsurface/Source/Networking/EntitySpawner.cs index 3eb6a8d35..cdb1ff9f9 100644 --- a/Subsurface/Source/Networking/EntitySpawner.cs +++ b/Subsurface/Source/Networking/EntitySpawner.cs @@ -152,6 +152,18 @@ namespace Barotrauma NetStateID = (UInt32)spawnHistory.Count; } + public void AddToSpawnedList(IEnumerable entities) + { + if (GameMain.Server == null) return; + if (entities == null) return; + + foreach (Entity entity in entities) + { + spawnHistory.Add(new SpawnOrRemove(entity, false)); + NetStateID = (UInt32)spawnHistory.Count; + } + } + public void ServerWrite(Lidgren.Network.NetBuffer message, Client client, object[] extraData = null) { if (GameMain.Server == null) return; diff --git a/Subsurface/Source/Networking/GameServer.cs b/Subsurface/Source/Networking/GameServer.cs index 3508a5df5..5ccaaf5cb 100644 --- a/Subsurface/Source/Networking/GameServer.cs +++ b/Subsurface/Source/Networking/GameServer.cs @@ -960,8 +960,7 @@ namespace Barotrauma.Networking foreach (Character c in GameMain.GameSession.CrewManager.characters) { Entity.Spawner.AddToSpawnedList(c); - - c.SpawnItems.ForEach(item => Entity.Spawner.AddToSpawnedList(item)); + Entity.Spawner.AddToSpawnedList(c.SpawnItems); } SendStartMessage(roundStartSeed, Submarine.MainSub, GameMain.GameSession.gameMode.Preset, connectedClients); diff --git a/Subsurface/Source/Networking/RespawnManager.cs b/Subsurface/Source/Networking/RespawnManager.cs index 0d0178024..0ee0fdf61 100644 --- a/Subsurface/Source/Networking/RespawnManager.cs +++ b/Subsurface/Source/Networking/RespawnManager.cs @@ -412,6 +412,8 @@ namespace Barotrauma.Networking bool myCharacter = i >= clients.Count; var character = Character.Create(characterInfos[i], shuttleSpawnPoints[i].WorldPosition, !myCharacter, false); + Entity.Spawner.AddToSpawnedList(character); + character.TeamID = 1; if (myCharacter) @@ -424,9 +426,7 @@ namespace Barotrauma.Networking { clients[i].Character = character; } - - spawnedCharacters.Add(character); - + Vector2 pos = cargoSp == null ? character.Position : cargoSp.Position; if (divingSuitPrefab != null && oxyPrefab != null) @@ -450,10 +450,11 @@ namespace Barotrauma.Networking spawnedItems.Add(scooter); spawnedItems.Add(battery); } - - spawnedItems.ForEach(s => Item.Spawner.AddToSpawnedList(s)); character.GiveJobItems(mainSubSpawnPoints[i]); + Entity.Spawner.AddToSpawnedList(character.SpawnItems); + Entity.Spawner.AddToSpawnedList(spawnedItems); + GameMain.GameSession.CrewManager.characters.Add(character); } From 402c745fc3a52e5e27e07c7d8a23d4c43b84b5c1 Mon Sep 17 00:00:00 2001 From: Regalis Date: Sat, 7 Jan 2017 19:22:48 +0200 Subject: [PATCH 3/5] Reimplemented chat range & radio messages. Each client now has their own chatMsgQueue, so all chat messages don't have to be sent to all clients. --- .../Items/Components/Signal/WifiComponent.cs | 28 ++- Subsurface/Source/Networking/ChatMessage.cs | 14 +- Subsurface/Source/Networking/Client.cs | 2 +- Subsurface/Source/Networking/GameClient.cs | 10 +- Subsurface/Source/Networking/GameServer.cs | 173 ++++++++++++++---- Subsurface/Source/Networking/NetworkMember.cs | 32 +--- 6 files changed, 182 insertions(+), 77 deletions(-) diff --git a/Subsurface/Source/Items/Components/Signal/WifiComponent.cs b/Subsurface/Source/Items/Components/Signal/WifiComponent.cs index 7572e53e4..595d8d24a 100644 --- a/Subsurface/Source/Items/Components/Signal/WifiComponent.cs +++ b/Subsurface/Source/Items/Components/Signal/WifiComponent.cs @@ -45,9 +45,14 @@ namespace Barotrauma.Items.Components list.Add(this); } + public bool CanTransmit() + { + return HasRequiredContainedItems(true); + } + public void Transmit(string signal) { - if (!HasRequiredContainedItems(true)) return; + if (!CanTransmit()) return; var receivers = GetReceiversInRange(); foreach (WifiComponent w in receivers) @@ -60,14 +65,22 @@ namespace Barotrauma.Items.Components private List GetReceiversInRange() { - return list.FindAll(w => - w != this && w.channel == channel && - Vector2.Distance(item.WorldPosition, w.item.WorldPosition) <= Range); + return list.FindAll(w => w != this && w.CanReceive(this)); + } + + public bool CanReceive(WifiComponent sender) + { + if (!HasRequiredContainedItems(false)) return false; + + if (sender == null || sender.channel != channel) return false; + + return Vector2.Distance(item.WorldPosition, sender.item.WorldPosition) <= sender.Range; } public override void ReceiveSignal(int stepsTaken, string signal, Connection connection, Item sender, float power=0.0f) { - if (!HasRequiredContainedItems(false)) return; + var senderComponent = sender.GetComponent(); + if (senderComponent != null && !CanReceive(senderComponent)) return; if (LinkToChat) { @@ -76,7 +89,10 @@ namespace Barotrauma.Items.Components item.ParentInventory.Owner == Character.Controlled && GameMain.NetworkMember != null) { - signal = ChatMessage.ApplyDistanceEffect(item, sender, signal, range); + if (senderComponent != null) + { + signal = ChatMessage.ApplyDistanceEffect(item, sender, signal, senderComponent.range); + } GameMain.NetworkMember.AddChatMessage(signal, ChatMessageType.Radio); } diff --git a/Subsurface/Source/Networking/ChatMessage.cs b/Subsurface/Source/Networking/ChatMessage.cs index e69dfd6e6..1a8c1d39f 100644 --- a/Subsurface/Source/Networking/ChatMessage.cs +++ b/Subsurface/Source/Networking/ChatMessage.cs @@ -40,10 +40,11 @@ namespace Barotrauma.Networking } public static UInt32 LastID = 0; - public UInt32 netStateID = 0; + public UInt32 NetStateID { - get { return netStateID; } + get; + set; } private ChatMessage(string senderName, string text, ChatMessageType type, Character sender) @@ -56,12 +57,6 @@ namespace Barotrauma.Networking SenderName = senderName; TextWithSender = string.IsNullOrWhiteSpace(senderName) ? text : senderName + ": " + text; - - if (GameMain.Server != null) - { - LastID++; - netStateID = LastID; - } } public static ChatMessage Create(string senderName, string text, ChatMessageType type, Character sender) @@ -140,7 +135,8 @@ namespace Barotrauma.Networking if (c.lastSentChatMsgID < ID) { //this chat message is new to the server - GameMain.Server.AddChatMessage(txt, ChatMessageType.Default, c.name); + GameMain.Server.SendChatMessage(txt, null, c); + //GameMain.Server.AddChatMessage(txt, ChatMessageType.Default, c.name); c.lastSentChatMsgID = ID; } } diff --git a/Subsurface/Source/Networking/Client.cs b/Subsurface/Source/Networking/Client.cs index e8b94e8af..41d9039c0 100644 --- a/Subsurface/Source/Networking/Client.cs +++ b/Subsurface/Source/Networking/Client.cs @@ -41,7 +41,7 @@ namespace Barotrauma.Networking public UInt32 lastRecvEntitySpawnID = 0; - public List ChatMessages = new List(); + public List chatMsgQueue = new List(); public float ChatSpamSpeed; public float ChatSpamTimer; public int ChatSpamCount; diff --git a/Subsurface/Source/Networking/GameClient.cs b/Subsurface/Source/Networking/GameClient.cs index 9426bdccd..d786d62ac 100644 --- a/Subsurface/Source/Networking/GameClient.cs +++ b/Subsurface/Source/Networking/GameClient.cs @@ -847,18 +847,18 @@ namespace Barotrauma.Networking client.SendMessage(outmsg, NetDeliveryMethod.Unreliable); } - public override void SendChatMessage(string message, ChatMessageType? type = null) + public void SendChatMessage(string message) { if (client.ServerConnection == null) return; - type = ChatMessageType.Default; - ChatMessage chatMessage = ChatMessage.Create( gameStarted && myCharacter != null ? myCharacter.Name : name, - message, (ChatMessageType)type, gameStarted ? myCharacter : null); + message, + ChatMessageType.Default, + gameStarted ? myCharacter : null); lastQueueChatMsgID++; - chatMessage.netStateID = lastQueueChatMsgID; + chatMessage.NetStateID = lastQueueChatMsgID; chatMsgQueue.Add(chatMessage); } diff --git a/Subsurface/Source/Networking/GameServer.cs b/Subsurface/Source/Networking/GameServer.cs index 5ccaaf5cb..f8bb3c890 100644 --- a/Subsurface/Source/Networking/GameServer.cs +++ b/Subsurface/Source/Networking/GameServer.cs @@ -542,7 +542,7 @@ namespace Barotrauma.Networking // } //} - foreach (Character c in Character.CharacterList) + /*foreach (Character c in Character.CharacterList) { if (c.IsDead) continue; @@ -554,7 +554,7 @@ namespace Barotrauma.Networking //if (FarseerPhysics.ConvertUnits.ToSimUnits(diff.Length()) > NetConfig.CharacterIgnoreDistance) continue; } - } + }*/ sparseUpdateTimer = DateTime.Now + sparseUpdateInterval; } @@ -658,17 +658,11 @@ namespace Barotrauma.Networking outmsg.Write(c.lastSentChatMsgID); //send this to client so they know which chat messages weren't received by the server outmsg.Write(c.lastSentEntityEventID); - foreach (GUIComponent gc in GameMain.NetLobbyScreen.ChatBox.children) + c.chatMsgQueue.RemoveAll(cMsg => cMsg.NetStateID <= c.lastRecvChatMsgID); + foreach (ChatMessage cMsg in c.chatMsgQueue) { - if (gc is GUITextBlock && gc.UserData is ChatMessage) - { - ChatMessage cMsg = (ChatMessage)gc.UserData; - if (cMsg.NetStateID > c.lastRecvChatMsgID) - { - cMsg.ServerWrite(outmsg, c); - } - } - } + cMsg.ServerWrite(outmsg, c); + } if (Item.Spawner.NetStateID > c.lastRecvEntitySpawnID) { @@ -681,7 +675,7 @@ namespace Barotrauma.Networking { if (character is AICharacter) { - //TODO: don't send if the ai character is far from the client + //TODO: don't send if the ai character is far from the client //(some sort of distance-based culling might be a good idea for player-controlled characters as well) outmsg.Write((byte)ServerNetObject.ENTITY_POSITION); character.ServerWrite(outmsg, c); @@ -766,20 +760,12 @@ namespace Barotrauma.Networking outmsg.Write(c.lastSentChatMsgID); //send this to client so they know which chat messages weren't received by the server - foreach (GUIComponent gc in GameMain.NetLobbyScreen.ChatBox.children) + c.chatMsgQueue.RemoveAll(cMsg => cMsg.NetStateID <= c.lastRecvChatMsgID); + foreach (ChatMessage cMsg in c.chatMsgQueue) { - if (gc is GUITextBlock) - { - if (gc.UserData is ChatMessage) - { - ChatMessage cMsg = (ChatMessage)gc.UserData; - if (cMsg.NetStateID > c.lastRecvChatMsgID) - { - cMsg.ServerWrite(outmsg,c); - } - } - } - } + cMsg.ServerWrite(outmsg, c); + } + outmsg.Write((byte)ServerNetObject.END_OF_MESSAGE); server.SendMessage(outmsg, c.Connection, NetDeliveryMethod.Unreliable); } @@ -1214,16 +1200,139 @@ namespace Barotrauma.Networking } } - public override void SendChatMessage(string message, ChatMessageType? type = null) + /// + /// Add the message to the chatbox and pass it to all clients who can receive it + /// + public void SendChatMessage(string message, ChatMessageType? type = null, Client senderClient = null) { - type = ChatMessageType.Default; + Character senderCharacter = null; + string senderName = ""; + + if (type==null) + { + string tempStr; + string command = ChatMessage.GetChatMessageCommand(message, out tempStr); + switch (command) + { + case "r": + case "radio": + type = ChatMessageType.Radio; + break; + case "d": + case "dead": + type = ChatMessageType.Dead; + break; + default: + type = ChatMessageType.Default; + break; + } + } - ChatMessage chatMessage = ChatMessage.Create( - gameStarted && myCharacter != null ? myCharacter.Name : name, - message, (ChatMessageType)type, gameStarted ? myCharacter : null); + if (gameStarted) + { + //msg sent by the server + if (senderClient == null) + { + senderCharacter = myCharacter; + senderName = myCharacter == null ? name : myCharacter.Name; + } + //msg sent by a client + else + { + senderCharacter = senderClient.Character; + senderName = senderCharacter == null ? senderClient.name : senderCharacter.Name; + //sender doesn't have an alive character -> only ChatMessageType.Dead allowed + if (senderCharacter == null || senderCharacter.IsDead) + { + type = ChatMessageType.Dead; + } + } + } + else + { + //game not started -> clients can only send normal chatmessages + if (senderClient != null) + { + type = ChatMessageType.Default; + } + } - AddChatMessage(chatMessage); + //check if the client is allowed to send the message + WifiComponent senderRadio = null; + switch (type) + { + case ChatMessageType.Radio: + if (senderCharacter == null) return; + + //return if senderCharacter doesn't have a working radio + var radio = senderCharacter.Inventory.Items.First(i => i != null && i.GetComponent() != null); + if (radio == null) return; + + senderRadio = radio.GetComponent(); + if (!senderRadio.CanTransmit()) return; + break; + case ChatMessageType.Dead: + //character still alive -> not allowed + if (senderClient != null && senderCharacter != null && !senderCharacter.IsDead) + { + return; + } + break; + } + + //check which clients can receive the message and apply distance effects + foreach (Client client in ConnectedClients) + { + string modifiedMessage = message; + + switch (type) + { + case ChatMessageType.Default: + if (senderCharacter != null && + client.Character != null && !client.Character.IsDead) + { + modifiedMessage = ChatMessage.ApplyDistanceEffect(client.Character, senderCharacter, message, ChatMessage.SpeakRange); + + //too far to hear the msg -> don't send + if (string.IsNullOrWhiteSpace(modifiedMessage)) continue; + } + break; + case ChatMessageType.Radio: + if (client.Character != null && !client.Character.IsDead) + { + var radio = client.Character.Inventory.Items.First(i => i != null && i.GetComponent() != null); + //client doesn't have a radio -> don't send + if (radio == null) return; + + var radioComponent = radio.GetComponent(); + if (!radioComponent.CanReceive(senderRadio)) return; + + modifiedMessage = ChatMessage.ApplyDistanceEffect(radio, senderRadio.Item, message, senderRadio.Range); + + //too far to hear the msg -> don't send + if (string.IsNullOrWhiteSpace(modifiedMessage)) continue; + } + break; + case ChatMessageType.Dead: + if (client.Character != null && !client.Character.IsDead) return; + break; + } + + var chatMsg = ChatMessage.Create( + senderName, + modifiedMessage, + (ChatMessageType)type, + senderCharacter); + + chatMsg.NetStateID = client.chatMsgQueue.Count > 0 ? + client.chatMsgQueue.Last().NetStateID + 1 : + client.lastRecvChatMsgID+1; + + client.chatMsgQueue.Add(chatMsg); + } + + AddChatMessage(message, (ChatMessageType)type, senderName); } public override void Draw(Microsoft.Xna.Framework.Graphics.SpriteBatch spriteBatch) diff --git a/Subsurface/Source/Networking/NetworkMember.cs b/Subsurface/Source/Networking/NetworkMember.cs index c27335465..7131a5df2 100644 --- a/Subsurface/Source/Networking/NetworkMember.cs +++ b/Subsurface/Source/Networking/NetworkMember.cs @@ -195,7 +195,14 @@ namespace Barotrauma.Networking if (string.IsNullOrWhiteSpace(message)) return false; - SendChatMessage(message); + if (this == GameMain.Server) + { + GameMain.Server.SendChatMessage(message, null, null); + } + else if (this == GameMain.Client) + { + GameMain.Client.SendChatMessage(message); + } if (textBox == chatMsgBox) textBox.Deselect(); @@ -209,33 +216,12 @@ namespace Barotrauma.Networking public void AddChatMessage(ChatMessage message) { - - if (message.Type == ChatMessageType.Radio && - Character.Controlled != null && - message.Sender != null && message.Sender != myCharacter) - { - var radio = message.Sender.Inventory.Items.First(i => i != null && i.GetComponent() != null); - if (radio == null) return; - - message.Sender.ShowSpeechBubble(2.0f, ChatMessage.MessageColor[(int)ChatMessageType.Radio]); - - var radioComponent = radio.GetComponent(); - radioComponent.Transmit(message.TextWithSender); - return; - } - GameServer.Log(message.TextWithSender, message.Color); string displayedText = message.Text; if (message.Sender != null) { - if (message.Type == ChatMessageType.Default && Character.Controlled != null) - { - displayedText = message.ApplyDistanceEffect(Character.Controlled); - if (string.IsNullOrWhiteSpace(displayedText)) return; - } - message.Sender.ShowSpeechBubble(2.0f, ChatMessage.MessageColor[(int)ChatMessageType.Default]); } @@ -279,8 +265,6 @@ namespace Barotrauma.Networking GUI.PlayUISound(soundType); } - public virtual void SendChatMessage(string message, ChatMessageType? type = null) { } - public virtual void KickPlayer(string kickedName, bool ban, bool range = false) { } public virtual void AddToGUIUpdateList() From 6747faae3d9d7a65a572371b8cd1bd405e30acd3 Mon Sep 17 00:00:00 2001 From: Regalis Date: Sat, 7 Jan 2017 19:25:22 +0200 Subject: [PATCH 4/5] Clients can't make their character immortal by not sending inputs, clients don't implode their characters unless the server says so --- Subsurface/Source/Characters/Character.cs | 47 ++++++++++++----------- 1 file changed, 24 insertions(+), 23 deletions(-) diff --git a/Subsurface/Source/Characters/Character.cs b/Subsurface/Source/Characters/Character.cs index 6c22b1d7e..09abd6e6c 100644 --- a/Subsurface/Source/Characters/Character.cs +++ b/Subsurface/Source/Characters/Character.cs @@ -1342,30 +1342,31 @@ namespace Barotrauma if (GameMain.Server != null && !(this is AICharacter) && AllowInput) { if (memInput.Count == 0) - { - if (AllowInput) AnimController.Frozen = true; - return; - } - - AnimController.Frozen = false; - prevDequeuedInput = dequeuedInput; - - dequeuedInput = memInput[memInput.Count - 1]; - memInput.RemoveAt(memInput.Count - 1); - - cursorPosition = memMousePos[memMousePos.Count - 1]; - memMousePos.RemoveAt(memMousePos.Count - 1); - - TransformCursorPos(); - - if (dequeuedInput == InputNetFlags.None && Math.Abs(AnimController.Collider.LinearVelocity.X) < 0.005f && Math.Abs(AnimController.Collider.LinearVelocity.Y) < 0.005f) { - while (memInput.Count > 5 && memInput[memInput.Count - 1] == 0) + AnimController.Frozen = true; + } + else + { + AnimController.Frozen = false; + prevDequeuedInput = dequeuedInput; + + dequeuedInput = memInput[memInput.Count - 1]; + memInput.RemoveAt(memInput.Count - 1); + + cursorPosition = memMousePos[memMousePos.Count - 1]; + memMousePos.RemoveAt(memMousePos.Count - 1); + + TransformCursorPos(); + + if (dequeuedInput == InputNetFlags.None && Math.Abs(AnimController.Collider.LinearVelocity.X) < 0.005f && Math.Abs(AnimController.Collider.LinearVelocity.Y) < 0.005f) { - //remove inputs where the player is not moving at all - //helps the server catch up, shouldn't affect final position - memInput.RemoveAt(memInput.Count - 1); - memMousePos.RemoveAt(memMousePos.Count - 1); + while (memInput.Count > 5 && memInput[memInput.Count - 1] == 0) + { + //remove inputs where the player is not moving at all + //helps the server catch up, shouldn't affect final position + memInput.RemoveAt(memInput.Count - 1); + memMousePos.RemoveAt(memMousePos.Count - 1); + } } } } @@ -1813,7 +1814,7 @@ namespace Barotrauma { if (!isNetworkMessage) { - if (GameMain.NetworkMember != null && controlled != this) return; + if (GameMain.Client != null) return; } Health = minHealth; From 05cb5989dc90ba749f3b3e1675ee724e07bf07ec Mon Sep 17 00:00:00 2001 From: Regalis Date: Sat, 7 Jan 2017 20:24:01 +0200 Subject: [PATCH 5/5] Chat range also affects the server host if they're controlling a character, fixed missing sender names in the server lobby --- Subsurface/Source/Networking/GameServer.cs | 83 +++++++++++++++------- 1 file changed, 59 insertions(+), 24 deletions(-) diff --git a/Subsurface/Source/Networking/GameServer.cs b/Subsurface/Source/Networking/GameServer.cs index f8bb3c890..fb919d7c9 100644 --- a/Subsurface/Source/Networking/GameServer.cs +++ b/Subsurface/Source/Networking/GameServer.cs @@ -1235,9 +1235,8 @@ namespace Barotrauma.Networking { senderCharacter = myCharacter; senderName = myCharacter == null ? name : myCharacter.Name; - } - //msg sent by a client - else + } + else //msg sent by a client { senderCharacter = senderClient.Character; senderName = senderCharacter == null ? senderClient.name : senderCharacter.Name; @@ -1251,10 +1250,16 @@ namespace Barotrauma.Networking } else { - //game not started -> clients can only send normal chatmessages - if (senderClient != null) + //msg sent by the server + if (senderClient == null) { + senderName = name; + } + else //msg sent by a client + { + //game not started -> clients can only send normal chatmessages type = ChatMessageType.Default; + senderName = senderClient.name; } } @@ -1289,33 +1294,18 @@ namespace Barotrauma.Networking switch (type) { case ChatMessageType.Default: + case ChatMessageType.Radio: if (senderCharacter != null && client.Character != null && !client.Character.IsDead) { - modifiedMessage = ChatMessage.ApplyDistanceEffect(client.Character, senderCharacter, message, ChatMessage.SpeakRange); - - //too far to hear the msg -> don't send - if (string.IsNullOrWhiteSpace(modifiedMessage)) continue; - } - break; - case ChatMessageType.Radio: - if (client.Character != null && !client.Character.IsDead) - { - var radio = client.Character.Inventory.Items.First(i => i != null && i.GetComponent() != null); - //client doesn't have a radio -> don't send - if (radio == null) return; - - var radioComponent = radio.GetComponent(); - if (!radioComponent.CanReceive(senderRadio)) return; - - modifiedMessage = ChatMessage.ApplyDistanceEffect(radio, senderRadio.Item, message, senderRadio.Range); + modifiedMessage = ApplyChatMsgDistanceEffects(message, (ChatMessageType)type, senderCharacter, client.Character); //too far to hear the msg -> don't send if (string.IsNullOrWhiteSpace(modifiedMessage)) continue; } break; case ChatMessageType.Dead: - if (client.Character != null && !client.Character.IsDead) return; + if (client.Character != null && !client.Character.IsDead) continue; break; } @@ -1332,7 +1322,52 @@ namespace Barotrauma.Networking client.chatMsgQueue.Add(chatMsg); } - AddChatMessage(message, (ChatMessageType)type, senderName); + string myReceivedMessage = message; + + if (gameStarted && myCharacter != null) + { + myReceivedMessage = ApplyChatMsgDistanceEffects(message, (ChatMessageType)type, senderCharacter, myCharacter); + } + + if (!string.IsNullOrWhiteSpace(myReceivedMessage)) + { + AddChatMessage(myReceivedMessage, (ChatMessageType)type, senderName); + } + } + + private string ApplyChatMsgDistanceEffects(string message, ChatMessageType type, Character sender, Character receiver) + { + if (sender == null) return ""; + + switch (type) + { + case ChatMessageType.Default: + if (!receiver.IsDead) + { + return ChatMessage.ApplyDistanceEffect(receiver, sender, message, ChatMessage.SpeakRange); + } + break; + case ChatMessageType.Radio: + if (!receiver.IsDead) + { + var receiverItem = receiver.Inventory.Items.First(i => i != null && i.GetComponent() != null); + //client doesn't have a radio -> don't send + if (receiverItem == null) return ""; + + var senderItem = sender.Inventory.Items.First(i => i != null && i.GetComponent() != null); + if (senderItem == null) return ""; + + var receiverRadio = receiverItem.GetComponent(); + var senderRadio = senderItem.GetComponent(); + + if (!receiverRadio.CanReceive(senderRadio)) return ""; + + return ChatMessage.ApplyDistanceEffect(receiverItem, senderItem, message, senderRadio.Range); + } + break; + } + + return message; } public override void Draw(Microsoft.Xna.Framework.Graphics.SpriteBatch spriteBatch)