diff --git a/Subsurface/Source/Characters/CharacterNetworking.cs b/Subsurface/Source/Characters/CharacterNetworking.cs index 176666535..dd2e18618 100644 --- a/Subsurface/Source/Characters/CharacterNetworking.cs +++ b/Subsurface/Source/Characters/CharacterNetworking.cs @@ -425,11 +425,9 @@ namespace Barotrauma tempBuffer.Write(aiming); tempBuffer.Write(use); - if (AnimController.Limbs.Any(l => l != null && l.attack != null)) - { - tempBuffer.Write(attack); - } - + bool hasAttackLimb = AnimController.Limbs.Any(l => l != null && l.attack != null); + tempBuffer.Write(hasAttackLimb); + if (hasAttackLimb) tempBuffer.Write(attack); if (aiming) { @@ -491,7 +489,8 @@ namespace Barotrauma keys[(int)InputType.Use].Held = useInput; keys[(int)InputType.Use].SetState(false, useInput); - if (AnimController.Limbs.Any(l => l != null && l.attack != null)) + bool hasAttackLimb = msg.ReadBoolean(); + if (hasAttackLimb) { bool attackInput = msg.ReadBoolean(); keys[(int)InputType.Attack].Held = attackInput; diff --git a/Subsurface/Source/Networking/GameClient.cs b/Subsurface/Source/Networking/GameClient.cs index 63d03c439..e1d015833 100644 --- a/Subsurface/Source/Networking/GameClient.cs +++ b/Subsurface/Source/Networking/GameClient.cs @@ -921,18 +921,17 @@ namespace Barotrauma.Networking UInt16 id = inc.ReadUInt16(); byte msgLength = inc.ReadByte(); + long msgEndPos = inc.Position + msgLength * 8; + var entity = Entity.FindEntityByID(id) as IServerSerializable; - if (entity == null) - { - //skip through the rest of the message - inc.Position += msgLength * 8; - } - else + if (entity != null) { entity.ClientRead(objHeader, inc, sendingTime); } - inc.ReadPadBits(); + //force to the correct position in case the entity doesn't exist + //or the message wasn't read correctly for whatever reason + inc.Position = msgEndPos; break; case ServerNetObject.ENTITY_EVENT: case ServerNetObject.ENTITY_EVENT_INITIAL: diff --git a/Subsurface/Source/Networking/GameServer.cs b/Subsurface/Source/Networking/GameServer.cs index 7f8569503..554ada652 100644 --- a/Subsurface/Source/Networking/GameServer.cs +++ b/Subsurface/Source/Networking/GameServer.cs @@ -703,12 +703,12 @@ namespace Barotrauma.Networking #if DEBUG //client thinks they've received a msg we haven't sent yet (corrupted packet, msg read/written incorrectly?) if (NetIdUtils.IdMoreRecent(lastRecvChatMsgID, c.lastChatMsgQueueID)) - DebugConsole.ThrowError("client.lastRecvChatMsgID > lastChatMsgQueueID"); - + DebugConsole.ThrowError("client.lastRecvChatMsgID > lastChatMsgQueueID (" + c.lastRecvChatMsgID + " > " + c.lastChatMsgQueueID + ")"); + if (lastRecvEntityEventID > lastEntityEventID) - DebugConsole.ThrowError("client.lastRecvEntityEventID > lastEntityEventID"); + DebugConsole.ThrowError("client.lastRecvEntityEventID > lastEntityEventID (" + c.lastRecvEntityEventID + " > " + lastEntityEventID + ")"); #endif - + if (NetIdUtils.IdMoreRecent(lastRecvChatMsgID, c.lastRecvChatMsgID)) c.lastRecvChatMsgID = lastRecvChatMsgID; if (NetIdUtils.IdMoreRecent(c.lastRecvChatMsgID, c.lastChatMsgQueueID)) c.lastRecvChatMsgID = c.lastChatMsgQueueID; @@ -833,40 +833,45 @@ namespace Barotrauma.Networking cMsg.ServerWrite(outmsg, c); } - foreach (Character character in Character.CharacterList) + //don't send position updates to characters who are still midround syncing + //characters or items spawned mid-round don't necessarily exist at the client's end yet + if (!c.NeedsMidRoundSync) { - if (!character.Enabled) continue; - - if (c.Character != null && - Vector2.DistanceSquared(character.WorldPosition, c.Character.WorldPosition) >= - NetConfig.CharacterIgnoreDistance * NetConfig.CharacterIgnoreDistance) + foreach (Character character in Character.CharacterList) { - continue; + if (!character.Enabled) continue; + + if (c.Character != null && + Vector2.DistanceSquared(character.WorldPosition, c.Character.WorldPosition) >= + NetConfig.CharacterIgnoreDistance * NetConfig.CharacterIgnoreDistance) + { + continue; + } + + outmsg.Write((byte)ServerNetObject.ENTITY_POSITION); + character.ServerWrite(outmsg, c); + outmsg.WritePadBits(); } - outmsg.Write((byte)ServerNetObject.ENTITY_POSITION); - character.ServerWrite(outmsg, c); - outmsg.WritePadBits(); - } + foreach (Submarine sub in Submarine.Loaded) + { + //if docked to a sub with a smaller ID, don't send an update + // (= update is only sent for the docked sub that has the smallest ID, doesn't matter if it's the main sub or a shuttle) + if (sub.DockedTo.Any(s => s.ID < sub.ID)) continue; - foreach (Submarine sub in Submarine.Loaded) - { - //if docked to a sub with a smaller ID, don't send an update - // (= update is only sent for the docked sub that has the smallest ID, doesn't matter if it's the main sub or a shuttle) - if (sub.DockedTo.Any(s => s.ID < sub.ID)) continue; + outmsg.Write((byte)ServerNetObject.ENTITY_POSITION); + sub.ServerWrite(outmsg, c); + outmsg.WritePadBits(); + } - outmsg.Write((byte)ServerNetObject.ENTITY_POSITION); - sub.ServerWrite(outmsg, c); - outmsg.WritePadBits(); - } + foreach (Item item in Item.ItemList) + { + if (!item.NeedsPositionUpdate) continue; - foreach (Item item in Item.ItemList) - { - if (!item.NeedsPositionUpdate) continue; - - outmsg.Write((byte)ServerNetObject.ENTITY_POSITION); - item.ServerWritePosition(outmsg, c); - outmsg.WritePadBits(); + outmsg.Write((byte)ServerNetObject.ENTITY_POSITION); + item.ServerWritePosition(outmsg, c); + outmsg.WritePadBits(); + } } entityEventManager.Write(c, outmsg);