Client LuaCsForBarotrauma
NetEntityEventManager.cs
1 using System;
2 using System.Collections.Generic;
3 using System.Linq;
4 
5 namespace Barotrauma.Networking
6 {
7  abstract class NetEntityEventManager
8  {
9  public const int MaxEventBufferLength = 1024;
10 
14  protected void Write(IWriteMessage msg, List<NetEntityEvent> eventsToSync, out List<NetEntityEvent> sentEvents, Client recipient = null)
15  {
16  //write into a temporary buffer so we can write the number of events before the actual data
17  IWriteMessage tempBuffer = new WriteOnlyMessage();
18 
19  sentEvents = new List<NetEntityEvent>();
20 
21  int eventCount = 0;
22  foreach (NetEntityEvent e in eventsToSync)
23  {
24  //write into a temporary buffer so we can write the length before the actual data
25  IWriteMessage tempEventBuffer = new WriteOnlyMessage();
26  try
27  {
28  WriteEvent(tempEventBuffer, e, recipient);
29  }
30  catch (Exception exception)
31  {
32  DebugConsole.ThrowError("Failed to write an event for the entity \"" + e.Entity + "\"", exception);
33  GameAnalyticsManager.AddErrorEventOnce("NetEntityEventManager.Write:WriteFailed" + e.Entity.ToString(),
34  GameAnalyticsManager.ErrorSeverity.Error,
35  "Failed to write an event for the entity \"" + e.Entity + "\"\n" + exception.StackTrace.CleanupStackTrace());
36 
37  //write an empty event to avoid messing up IDs
38  //(otherwise the clients might read the next event in the message and think its ID
39  //is consecutive to the previous one, even though we skipped over this broken event)
40  tempBuffer.WriteUInt16(Entity.NullEntityID);
41  eventCount++;
42  continue;
43  }
44 
45  if (eventCount > 0 &&
46  msg.LengthBytes + tempBuffer.LengthBytes + tempEventBuffer.LengthBytes > MaxEventBufferLength)
47  {
48  //no more room in this packet
49  break;
50  }
51 
52  tempBuffer.WriteUInt16(e.EntityID);
53  tempBuffer.WriteVariableUInt32((uint)tempEventBuffer.LengthBytes);
54  tempBuffer.WriteBytes(tempEventBuffer.Buffer, 0, tempEventBuffer.LengthBytes);
55  sentEvents.Add(e);
56 
57  eventCount++;
58  }
59 
60  if (eventCount > 0)
61  {
62  msg.WritePadBits();
63  msg.WriteUInt16(eventsToSync[0].ID);
64  msg.WriteByte((byte)eventCount);
65  msg.WriteBytes(tempBuffer.Buffer, 0, tempBuffer.LengthBytes);
66  }
67  }
68 
69  protected static bool ValidateEntity(INetSerializable entity)
70  {
71  void error(string reason)
72  => DebugConsole.ThrowError($"Can't create an entity event for {entity} - {reason}.\n{Environment.StackTrace.CleanupStackTrace()}");
73 
74  if (entity is Entity { Removed: var removed, IdFreed: var idFreed })
75  {
76  if (removed)
77  {
78  error("the entity has been removed");
79  return false;
80  }
81  if (idFreed)
82  {
83  error("the ID of the entity has been freed");
84  return false;
85  }
86  }
87  else
88  {
89  error($"input is not of type {nameof(Entity)}");
90  return false;
91  }
92  return true;
93  }
94 
95  protected abstract void WriteEvent(IWriteMessage buffer, NetEntityEvent entityEvent, Client recipient = null);
96  }
97 }
const ushort NullEntityID
Definition: Entity.cs:14
abstract void WriteEvent(IWriteMessage buffer, NetEntityEvent entityEvent, Client recipient=null)
void Write(IWriteMessage msg, List< NetEntityEvent > eventsToSync, out List< NetEntityEvent > sentEvents, Client recipient=null)
Write the events to the outgoing message. The recipient parameter is only needed for ServerEntityEven...
static bool ValidateEntity(INetSerializable entity)