diff --git a/Subsurface/Barotrauma.csproj b/Subsurface/Barotrauma.csproj index 1d4fa3d64..3bd07bd27 100644 --- a/Subsurface/Barotrauma.csproj +++ b/Subsurface/Barotrauma.csproj @@ -157,10 +157,11 @@ + + - diff --git a/Subsurface/Source/Characters/Character.cs b/Subsurface/Source/Characters/Character.cs index 55e535e02..a5a164129 100644 --- a/Subsurface/Source/Characters/Character.cs +++ b/Subsurface/Source/Characters/Character.cs @@ -1911,7 +1911,7 @@ namespace Barotrauma if (AnimController != null) AnimController.Remove(); } - public virtual void ClientWrite(NetBuffer msg) + public virtual void ClientWrite(NetBuffer msg, object[] extraData = null) { if (GameMain.Server != null) return; @@ -1972,7 +1972,7 @@ namespace Barotrauma } } - public virtual void ServerWrite(NetBuffer msg, Client c) + public virtual void ServerWrite(NetBuffer msg, Client c, object[] extraData = null) { if (GameMain.Server == null) return; diff --git a/Subsurface/Source/Items/Components/DockingPort.cs b/Subsurface/Source/Items/Components/DockingPort.cs index f1acb40ed..c48ad1fd1 100644 --- a/Subsurface/Source/Items/Components/DockingPort.cs +++ b/Subsurface/Source/Items/Components/DockingPort.cs @@ -648,7 +648,7 @@ namespace Barotrauma.Items.Components } } - public override void ServerWrite(Lidgren.Network.NetBuffer msg, Barotrauma.Networking.Client c) + public override void ServerWrite(Lidgren.Network.NetBuffer msg, Barotrauma.Networking.Client c, object[] extraData = null) { msg.Write(docked); diff --git a/Subsurface/Source/Items/Components/Door.cs b/Subsurface/Source/Items/Components/Door.cs index a3fe6d03a..f265e108a 100644 --- a/Subsurface/Source/Items/Components/Door.cs +++ b/Subsurface/Source/Items/Components/Door.cs @@ -489,11 +489,11 @@ namespace Barotrauma.Items.Components if (sendNetworkMessage) { - item.NewComponentEvent(this, false, true); + item.CreateServerEvent(this); } } - public override void ServerWrite(Lidgren.Network.NetBuffer msg, Barotrauma.Networking.Client c) + public override void ServerWrite(Lidgren.Network.NetBuffer msg, Barotrauma.Networking.Client c, object[] extraData = null) { msg.Write(isOpen); msg.WriteRangedSingle(stuck, 0.0f, 100.0f, 8); diff --git a/Subsurface/Source/Items/Components/ItemComponent.cs b/Subsurface/Source/Items/Components/ItemComponent.cs index dd6c9c652..4be776e8a 100644 --- a/Subsurface/Source/Items/Components/ItemComponent.cs +++ b/Subsurface/Source/Items/Components/ItemComponent.cs @@ -662,10 +662,10 @@ namespace Barotrauma.Items.Components } } - public virtual void ClientWrite(NetBuffer msg) { } + public virtual void ClientWrite(NetBuffer msg, object[] extraData = null) { } public virtual void ServerRead(NetIncomingMessage msg, Client c) { } - public virtual void ServerWrite(NetBuffer msg, Client c) { } + public virtual void ServerWrite(NetBuffer msg, Client c, object[] extraData = null) { } public virtual void ClientRead(NetIncomingMessage msg, float sendingTime) { } public virtual XElement Save(XElement parentElement) diff --git a/Subsurface/Source/Items/Components/Machines/Pump.cs b/Subsurface/Source/Items/Components/Machines/Pump.cs index 2ea3985f9..2cfe5819d 100644 --- a/Subsurface/Source/Items/Components/Machines/Pump.cs +++ b/Subsurface/Source/Items/Components/Machines/Pump.cs @@ -196,7 +196,7 @@ namespace Barotrauma.Items.Components if (!IsActive) currPowerConsumption = 0.0f; } - public override void ClientWrite(Lidgren.Network.NetBuffer msg) + public override void ClientWrite(Lidgren.Network.NetBuffer msg, object[] extraData = null) { //flowpercentage can only be adjusted at 10% intervals -> no need for more accuracy than this msg.WriteRangedInteger(-10, 10, (int)(flowPercentage / 10.0f)); @@ -209,7 +209,7 @@ namespace Barotrauma.Items.Components IsActive = msg.ReadBoolean(); } - public override void ServerWrite(Lidgren.Network.NetBuffer msg, Barotrauma.Networking.Client c) + public override void ServerWrite(Lidgren.Network.NetBuffer msg, Barotrauma.Networking.Client c, object[] extraData = null) { //flowpercentage can only be adjusted at 10% intervals -> no need for more accuracy than this msg.WriteRangedInteger(-10, 10, (int)(flowPercentage / 10.0f)); diff --git a/Subsurface/Source/Items/Components/Machines/Radar.cs b/Subsurface/Source/Items/Components/Machines/Radar.cs index 97e5a136e..a24373c50 100644 --- a/Subsurface/Source/Items/Components/Machines/Radar.cs +++ b/Subsurface/Source/Items/Components/Machines/Radar.cs @@ -411,7 +411,7 @@ namespace Barotrauma.Items.Components if (screenOverlay != null) screenOverlay.Remove(); } - public override void ClientWrite(Lidgren.Network.NetBuffer msg) + public override void ClientWrite(Lidgren.Network.NetBuffer msg, object[] extraData = null) { msg.Write(IsActive); } @@ -422,7 +422,7 @@ namespace Barotrauma.Items.Components isActiveTickBox.Selected = IsActive; } - public override void ServerWrite(Lidgren.Network.NetBuffer msg, Barotrauma.Networking.Client c) + public override void ServerWrite(Lidgren.Network.NetBuffer msg, Barotrauma.Networking.Client c, object[] extraData = null) { msg.Write(IsActive); } diff --git a/Subsurface/Source/Items/Components/Machines/Reactor.cs b/Subsurface/Source/Items/Components/Machines/Reactor.cs index 6915abf0b..e17284ff6 100644 --- a/Subsurface/Source/Items/Components/Machines/Reactor.cs +++ b/Subsurface/Source/Items/Components/Machines/Reactor.cs @@ -538,7 +538,7 @@ namespace Barotrauma.Items.Components } } - public override void ClientWrite(NetBuffer msg) + public override void ClientWrite(NetBuffer msg, object[] extraData = null) { msg.Write(autoTemp); msg.WriteRangedSingle(shutDownTemp, 0.0f, 10000.0f, 8); @@ -556,7 +556,7 @@ namespace Barotrauma.Items.Components FissionRate = msg.ReadRangedSingle(0.0f, 100.0f, 8); } - public override void ServerWrite(NetBuffer msg, Client c) + public override void ServerWrite(NetBuffer msg, Client c, object[] extraData = null) { msg.WriteRangedSingle(temperature, 0.0f, 10000.0f, 16); diff --git a/Subsurface/Source/Items/Components/Machines/Steering.cs b/Subsurface/Source/Items/Components/Machines/Steering.cs index 417d14718..e6757707e 100644 --- a/Subsurface/Source/Items/Components/Machines/Steering.cs +++ b/Subsurface/Source/Items/Components/Machines/Steering.cs @@ -443,7 +443,7 @@ namespace Barotrauma.Items.Components } } - public override void ClientWrite(Lidgren.Network.NetBuffer msg) + public override void ClientWrite(Lidgren.Network.NetBuffer msg, object[] extraData = null) { msg.Write(autoPilot); @@ -503,7 +503,7 @@ namespace Barotrauma.Items.Components } } - public override void ServerWrite(Lidgren.Network.NetBuffer msg, Barotrauma.Networking.Client c) + public override void ServerWrite(Lidgren.Network.NetBuffer msg, Barotrauma.Networking.Client c, object[] extraData = null) { msg.Write(autoPilot); diff --git a/Subsurface/Source/Items/Components/Power/PowerContainer.cs b/Subsurface/Source/Items/Components/Power/PowerContainer.cs index 1d10c4ca1..379761ab8 100644 --- a/Subsurface/Source/Items/Components/Power/PowerContainer.cs +++ b/Subsurface/Source/Items/Components/Power/PowerContainer.cs @@ -249,7 +249,7 @@ namespace Barotrauma.Items.Components GuiFrame.Update(1.0f / 60.0f); } - public override void ClientWrite(Lidgren.Network.NetBuffer msg) + public override void ClientWrite(Lidgren.Network.NetBuffer msg, object[] extraData = null) { float chargeSpeed = MathHelper.Clamp(rechargeSpeed / MaxRechargeSpeed, 0.0f, 1.0f); msg.WriteRangedSingle(chargeSpeed, 0.0f, 1.0f, 8); @@ -260,7 +260,7 @@ namespace Barotrauma.Items.Components RechargeSpeed = msg.ReadRangedSingle(0.0f, 1.0f, 8) * maxRechargeSpeed; } - public override void ServerWrite(Lidgren.Network.NetBuffer msg, Barotrauma.Networking.Client c) + public override void ServerWrite(Lidgren.Network.NetBuffer msg, Barotrauma.Networking.Client c, object[] extraData = null) { float chargeSpeed = MathHelper.Clamp(rechargeSpeed / MaxRechargeSpeed, 0.0f, 1.0f); msg.WriteRangedSingle(chargeSpeed, 0.0f, 1.0f, 8); diff --git a/Subsurface/Source/Items/Components/Signal/Connection.cs b/Subsurface/Source/Items/Components/Signal/Connection.cs index 213bfe0bc..bd31e328a 100644 --- a/Subsurface/Source/Items/Components/Signal/Connection.cs +++ b/Subsurface/Source/Items/Components/Signal/Connection.cs @@ -286,7 +286,7 @@ namespace Barotrauma.Items.Components if (!PlayerInput.LeftButtonHeld()) { - panel.Item.NewComponentEvent(panel, true, true); + //panel.Item.CreateServerEvent(panel, true, true); //draggingConnected.Drop(Character); draggingConnected = null; } diff --git a/Subsurface/Source/Items/Components/Signal/Wire.cs b/Subsurface/Source/Items/Components/Signal/Wire.cs index c511abcde..7fe79d295 100644 --- a/Subsurface/Source/Items/Components/Signal/Wire.cs +++ b/Subsurface/Source/Items/Components/Signal/Wire.cs @@ -532,7 +532,7 @@ namespace Barotrauma.Items.Components base.RemoveComponentSpecific(); } - public override void ClientWrite(Lidgren.Network.NetBuffer msg) + public override void ClientWrite(Lidgren.Network.NetBuffer msg, object[] extraData = null) { msg.Write((byte)Math.Min(Nodes.Count, 255)); for (int i = 0; i < Math.Min(Nodes.Count, 255); i++) diff --git a/Subsurface/Source/Items/Item.cs b/Subsurface/Source/Items/Item.cs index b1d66f3bf..6072992e6 100644 --- a/Subsurface/Source/Items/Item.cs +++ b/Subsurface/Source/Items/Item.cs @@ -1580,8 +1580,22 @@ namespace Barotrauma return element; } - public void ServerWrite(NetBuffer msg, Client c) { } - public void ClientRead(NetIncomingMessage msg, float sendingTime) { } + public void ServerWrite(NetBuffer msg, Client c, object[] extraData = null) + { + if (extraData == null) return; + + int componentIndex = (int)extraData[0]; + //component index + msg.Write((byte)componentIndex); + + components[componentIndex].ServerWrite(msg, c); + } + public void ClientRead(NetIncomingMessage msg, float sendingTime) + { + int componentIndex = msg.ReadByte(); + + components[componentIndex].ClientRead(msg, sendingTime); + } public void WriteSpawnData(NetBuffer msg) { @@ -1804,9 +1818,12 @@ namespace Barotrauma } - public void NewComponentEvent(ItemComponent ic, bool isClient, bool isImportant) + public void CreateServerEvent(ItemComponent ic) { + if (GameMain.Server == null) return; + int index = components.IndexOf(ic); + GameMain.Server.CreateEntityEvent(this, new object[] { index }); } public override void Remove() diff --git a/Subsurface/Source/Map/Structure.cs b/Subsurface/Source/Map/Structure.cs index a33b131e8..785d34fcb 100644 --- a/Subsurface/Source/Map/Structure.cs +++ b/Subsurface/Source/Map/Structure.cs @@ -845,7 +845,7 @@ namespace Barotrauma return newBody; } - public void ServerWrite(NetBuffer msg, Client c) + public void ServerWrite(NetBuffer msg, Client c, object[] extraData = null) { for (int i = 0; i < sections.Length; i++) { diff --git a/Subsurface/Source/Map/Submarine.cs b/Subsurface/Source/Map/Submarine.cs index a5e1e56d9..10d3ed934 100644 --- a/Subsurface/Source/Map/Submarine.cs +++ b/Subsurface/Source/Map/Submarine.cs @@ -1163,7 +1163,7 @@ namespace Barotrauma DockedTo.Clear(); } - public void ServerWrite(NetBuffer msg, Client c) + public void ServerWrite(NetBuffer msg, Client c, object[] extraData = null) { msg.Write(ID); //length in bytes diff --git a/Subsurface/Source/Networking/Client.cs b/Subsurface/Source/Networking/Client.cs index 6f7e75df3..b25d056c6 100644 --- a/Subsurface/Source/Networking/Client.cs +++ b/Subsurface/Source/Networking/Client.cs @@ -35,6 +35,8 @@ namespace Barotrauma.Networking public bool hasLobbyData = false; public UInt32 lastSentChatMsgID = 0; //last msg this client said public UInt32 lastRecvChatMsgID = 0; //last msg this client knows about + + public UInt32 lastSentEntityEventID = 0; public UInt32 lastRecvEntityEventID = 0; public UInt32 lastRecvEntitySpawnID = 0; diff --git a/Subsurface/Source/Networking/EntitySpawner.cs b/Subsurface/Source/Networking/EntitySpawner.cs index f7224bd76..2e0baeca6 100644 --- a/Subsurface/Source/Networking/EntitySpawner.cs +++ b/Subsurface/Source/Networking/EntitySpawner.cs @@ -152,7 +152,7 @@ namespace Barotrauma NetStateID = (UInt32)spawnHistory.Count; } - public void ServerWrite(Lidgren.Network.NetBuffer message, Client client) + public void ServerWrite(Lidgren.Network.NetBuffer message, Client client, object[] extraData = null) { if (GameMain.Server == null) return; diff --git a/Subsurface/Source/Networking/GameClient.cs b/Subsurface/Source/Networking/GameClient.cs index 764f66131..0966d4cd6 100644 --- a/Subsurface/Source/Networking/GameClient.cs +++ b/Subsurface/Source/Networking/GameClient.cs @@ -41,6 +41,8 @@ namespace Barotrauma.Networking public UInt32 LastSentEntityEventID; + private ClientEntityEventManager entityEventManager; + public byte ID { get { return myID; } @@ -86,6 +88,8 @@ namespace Barotrauma.Networking Hull.EditWater = false; name = newName; + + entityEventManager = new ClientEntityEventManager(this); characterInfo = new CharacterInfo(Character.HumanConfigFile, name); characterInfo.Job = null; @@ -706,6 +710,7 @@ namespace Barotrauma.Networking { case ServerNetObject.SYNC_IDS: lastSentChatMsgID = inc.ReadUInt32(); + LastSentEntityEventID = inc.ReadUInt32(); break; case ServerNetObject.ENTITY_POSITION: UInt16 id = inc.ReadUInt16(); @@ -724,6 +729,9 @@ namespace Barotrauma.Networking inc.ReadPadBits(); break; + case ServerNetObject.ENTITY_STATE: + entityEventManager.Read(inc, sendingTime); + break; case ServerNetObject.CHAT_MESSAGE: ChatMessage.ClientRead(inc); break; @@ -769,6 +777,7 @@ namespace Barotrauma.Networking outmsg.Write(GameMain.NetLobbyScreen.LastUpdateID); outmsg.Write(ChatMessage.LastID); outmsg.Write(Entity.Spawner.NetStateID); + outmsg.Write(entityEventManager.LastReceivedEntityEventID); ChatMessage removeMsg; while ((removeMsg = chatMsgQueue.Find(cMsg => cMsg.NetStateID <= lastSentChatMsgID)) != null) diff --git a/Subsurface/Source/Networking/GameServer.cs b/Subsurface/Source/Networking/GameServer.cs index b6bbc6998..6e210061c 100644 --- a/Subsurface/Source/Networking/GameServer.cs +++ b/Subsurface/Source/Networking/GameServer.cs @@ -43,6 +43,8 @@ namespace Barotrauma.Networking public TraitorManager TraitorManager; + private ServerEntityEventManager entityEventManager; + public override List ConnectedClients { get @@ -116,6 +118,8 @@ namespace Barotrauma.Networking settingsButton.OnClicked = ToggleSettingsFrame; settingsButton.UserData = "settingsButton"; + entityEventManager = new ServerEntityEventManager(this); + whitelist = new WhiteList(); banList = new BanList(); @@ -542,6 +546,11 @@ namespace Barotrauma.Networking sparseUpdateTimer = DateTime.Now + sparseUpdateInterval; } + public void CreateEntityEvent(IServerSerializable entity, object[] extraData) + { + entityEventManager.CreateEvent(entity, extraData); + } + private byte GetNewClientID() { byte userID = 1; @@ -602,6 +611,7 @@ namespace Barotrauma.Networking c.lastRecvGeneralUpdate = Math.Max(c.lastRecvGeneralUpdate, inc.ReadUInt32()); c.lastRecvChatMsgID = Math.Max(c.lastRecvChatMsgID, inc.ReadUInt32()); c.lastRecvEntitySpawnID = Math.Max(c.lastRecvEntitySpawnID, inc.ReadUInt32()); + c.lastRecvEntityEventID = Math.Max(c.lastRecvEntityEventID, inc.ReadUInt32()); break; case ClientNetObject.CHAT_MESSAGE: @@ -629,6 +639,7 @@ namespace Barotrauma.Networking outmsg.Write((byte)ServerNetObject.SYNC_IDS); 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) { @@ -672,6 +683,8 @@ namespace Barotrauma.Networking outmsg.WritePadBits(); } + entityEventManager.Write(c, outmsg); + outmsg.Write((byte)ServerNetObject.END_OF_MESSAGE); server.SendMessage(outmsg, c.Connection, NetDeliveryMethod.Unreliable); } diff --git a/Subsurface/Source/Networking/INetSerializable.cs b/Subsurface/Source/Networking/INetSerializable.cs index 75db0fc8a..a43001ce5 100644 --- a/Subsurface/Source/Networking/INetSerializable.cs +++ b/Subsurface/Source/Networking/INetSerializable.cs @@ -12,7 +12,7 @@ namespace Barotrauma.Networking { UInt32 NetStateID { get; } - void ClientWrite(NetBuffer msg); + void ClientWrite(NetBuffer msg, object[] extraData = null); void ServerRead(NetIncomingMessage msg, Client c); } @@ -23,7 +23,7 @@ namespace Barotrauma.Networking { UInt32 NetStateID { get; } - void ServerWrite(NetBuffer msg, Client c); + void ServerWrite(NetBuffer msg, Client c, object[] extraData = null); void ClientRead(NetIncomingMessage msg, float sendingTime); } } diff --git a/Subsurface/Source/Networking/NetEntityEvent/ClientEntityEventManager.cs b/Subsurface/Source/Networking/NetEntityEvent/ClientEntityEventManager.cs index c7dcfddf1..cfc9876ad 100644 --- a/Subsurface/Source/Networking/NetEntityEvent/ClientEntityEventManager.cs +++ b/Subsurface/Source/Networking/NetEntityEvent/ClientEntityEventManager.cs @@ -15,7 +15,10 @@ namespace Barotrauma.Networking private GameClient thisClient; - public ClientEntityEventManager(GameClient client) { } + public ClientEntityEventManager(GameClient client) + { + events = new List(); + } public void CreateEvent(IClientSerializable entity) { @@ -31,10 +34,16 @@ namespace Barotrauma.Networking public void Write(NetOutgoingMessage msg) { - var eventsToSync = events.SkipWhile(e => e.ID >= thisClient.LastSentEntityEventID).ToList(); + if (events.Count == 0) return; + + List eventsToSync = new List(); + for (int i = events.Count - 1; i >= 0 && events[i].ID > thisClient.LastSentEntityEventID; i--) + { + eventsToSync.Add(events[i]); + } if (eventsToSync.Count == 0) return; - Write(msg, eventsToSync.Cast().ToList()); + Write(msg, eventsToSync); } protected override void WriteEvent(NetBuffer buffer, NetEntityEvent entityEvent, Client recipient = null) @@ -47,10 +56,15 @@ namespace Barotrauma.Networking protected override void ReadEvent(NetIncomingMessage buffer, INetSerializable entity, float sendingTime, Client sender = null) { - var clientEntity = entity as IClientSerializable; - if (clientEntity == null) return; + var serverEntity = entity as IServerSerializable; + if (serverEntity == null) return; - clientEntity.ServerRead(buffer, sender); + serverEntity.ClientRead(buffer, sendingTime); + } + + public void Clear() + { + events.Clear(); } } } diff --git a/Subsurface/Source/Networking/NetEntityEvent/NetEntityEvent.cs b/Subsurface/Source/Networking/NetEntityEvent/NetEntityEvent.cs index 3d0626a8b..12cc6219a 100644 --- a/Subsurface/Source/Networking/NetEntityEvent/NetEntityEvent.cs +++ b/Subsurface/Source/Networking/NetEntityEvent/NetEntityEvent.cs @@ -12,11 +12,20 @@ namespace Barotrauma.Networking public readonly Entity Entity; public readonly UInt32 ID; + //arbitrary extra data that will be passed to the Write method of the serializable entity + //(the index of an itemcomponent for example) + protected object[] Data; + protected NetEntityEvent(INetSerializable entity, UInt32 id) { this.ID = id; this.Entity = entity as Entity; } + + public void SetData(object[] data) + { + this.Data = data; + } } class ServerEntityEvent : NetEntityEvent @@ -31,7 +40,7 @@ namespace Barotrauma.Networking public void Write(NetBuffer msg, Client recipient) { - serializable.ServerWrite(msg, recipient); + serializable.ServerWrite(msg, recipient, Data); } } @@ -47,7 +56,7 @@ namespace Barotrauma.Networking public void Write(NetBuffer msg) { - serializable.ClientWrite(msg); + serializable.ClientWrite(msg, Data); } } diff --git a/Subsurface/Source/Networking/NetEntityEvent/NetEntityEventManager.cs b/Subsurface/Source/Networking/NetEntityEvent/NetEntityEventManager.cs index 761cf8349..2c2448bc6 100644 --- a/Subsurface/Source/Networking/NetEntityEvent/NetEntityEventManager.cs +++ b/Subsurface/Source/Networking/NetEntityEvent/NetEntityEventManager.cs @@ -12,6 +12,11 @@ namespace Barotrauma.Networking { const int MaxEventsPerWrite = 255; + public UInt32 LastReceivedEntityEventID + { + get { return lastReceivedEntityEventID; } + } + private UInt32 lastReceivedEntityEventID; /// @@ -62,17 +67,20 @@ namespace Barotrauma.Networking byte msgLength = msg.ReadByte(); INetSerializable entity = Entity.FindEntityByID(entityID) as INetSerializable; - + //skip the event if we've already received it or if the entity isn't found - if (thisEventID <= lastReceivedEntityEventID || entity == null) + if (thisEventID != lastReceivedEntityEventID+1 || entity == null) { + DebugConsole.NewMessage("received msg "+thisEventID, Microsoft.Xna.Framework.Color.Red); msg.Position += msgLength * 8; } else { + DebugConsole.NewMessage("received msg "+thisEventID, Microsoft.Xna.Framework.Color.Green); ReadEvent(msg, entity, sendingTime); lastReceivedEntityEventID = thisEventID; } + msg.ReadPadBits(); } } diff --git a/Subsurface/Source/Networking/NetEntityEvent/ServerEntityEventManager.cs b/Subsurface/Source/Networking/NetEntityEvent/ServerEntityEventManager.cs index cb3fda394..de61f5639 100644 --- a/Subsurface/Source/Networking/NetEntityEvent/ServerEntityEventManager.cs +++ b/Subsurface/Source/Networking/NetEntityEvent/ServerEntityEventManager.cs @@ -13,9 +13,12 @@ namespace Barotrauma.Networking private UInt32 ID; - public ServerEntityEventManager(GameServer server) { } + public ServerEntityEventManager(GameServer server) + { + events = new List(); + } - public void CreateEvent(IServerSerializable entity) + public void CreateEvent(IServerSerializable entity, object[] extraData = null) { if (!(entity is Entity)) { @@ -24,7 +27,10 @@ namespace Barotrauma.Networking } ID++; - events.Add(new ServerEntityEvent(entity, ID)); + + var newEvent = new ServerEntityEvent(entity, ID); + if (extraData != null) newEvent.SetData(extraData); + events.Add(newEvent); } /// @@ -32,10 +38,16 @@ namespace Barotrauma.Networking /// public void Write(Client client, NetOutgoingMessage msg) { - var eventsToSync = events.SkipWhile(e => e.ID >= client.lastRecvEntityEventID).ToList(); + if (events.Count == 0) return; + + List eventsToSync = new List(); + for (int i = events.Count - 1; i >= 0 && events[i].ID > client.lastRecvEntityEventID; i--) + { + eventsToSync.Insert(0, events[i]); + } if (eventsToSync.Count == 0) return; - Write(msg, eventsToSync.Cast().ToList(), client); + Write(msg, eventsToSync, client); } protected override void WriteEvent(NetBuffer buffer, NetEntityEvent entityEvent, Client recipient = null) @@ -53,5 +65,10 @@ namespace Barotrauma.Networking clientEntity.ServerRead(buffer, sender); } + + public void Clear() + { + events.Clear(); + } } }