(61d00a474) v0.9.7.1
This commit is contained in:
@@ -0,0 +1,83 @@
|
||||
using System;
|
||||
|
||||
namespace Barotrauma.Networking
|
||||
{
|
||||
abstract class NetEntityEvent
|
||||
{
|
||||
public enum Type
|
||||
{
|
||||
Invalid,
|
||||
ComponentState,
|
||||
InventoryState,
|
||||
Status,
|
||||
Treatment,
|
||||
ApplyStatusEffect,
|
||||
ChangeProperty,
|
||||
Control,
|
||||
UpdateSkills,
|
||||
Combine
|
||||
}
|
||||
|
||||
public readonly Entity Entity;
|
||||
public readonly UInt16 ID;
|
||||
|
||||
public UInt16 EntityID
|
||||
{
|
||||
get;
|
||||
private set;
|
||||
}
|
||||
|
||||
//arbitrary extra data that will be passed to the Write method of the serializable entity
|
||||
//(the index of an itemcomponent for example)
|
||||
public object[] Data
|
||||
{
|
||||
get;
|
||||
private set;
|
||||
}
|
||||
|
||||
public bool Sent;
|
||||
|
||||
protected NetEntityEvent(INetSerializable serializableEntity, UInt16 id)
|
||||
{
|
||||
this.ID = id;
|
||||
this.Entity = serializableEntity as Entity;
|
||||
RefreshEntityID();
|
||||
}
|
||||
|
||||
public void RefreshEntityID()
|
||||
{
|
||||
this.EntityID = this.Entity is Entity entity ? entity.ID : Entity.NullEntityID;
|
||||
}
|
||||
|
||||
public void SetData(object[] data)
|
||||
{
|
||||
this.Data = data;
|
||||
}
|
||||
|
||||
public bool IsDuplicate(NetEntityEvent other)
|
||||
{
|
||||
if (other.Entity != this.Entity) return false;
|
||||
|
||||
if (Data != null && other.Data != null)
|
||||
{
|
||||
if (Data.Length != other.Data.Length) return false;
|
||||
|
||||
for (int i = 0; i < Data.Length; i++)
|
||||
{
|
||||
if (Data[i] == null)
|
||||
{
|
||||
if (other.Data[i] != null) return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (other.Data[i] == null) return false;
|
||||
if (!Data[i].Equals(other.Data[i])) return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
return Data == other.Data;
|
||||
}
|
||||
}
|
||||
}
|
||||
+86
@@ -0,0 +1,86 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace Barotrauma.Networking
|
||||
{
|
||||
abstract class NetEntityEventManager
|
||||
{
|
||||
public const int MaxEventBufferLength = 1024;
|
||||
|
||||
/// <summary>
|
||||
/// Write the events to the outgoing message. The recipient parameter is only needed for ServerEntityEventManager
|
||||
/// </summary>
|
||||
protected void Write(IWriteMessage msg, List<NetEntityEvent> eventsToSync, out List<NetEntityEvent> sentEvents, Client recipient = null)
|
||||
{
|
||||
//write into a temporary buffer so we can write the number of events before the actual data
|
||||
IWriteMessage tempBuffer = new WriteOnlyMessage();
|
||||
|
||||
sentEvents = new List<NetEntityEvent>();
|
||||
|
||||
int eventCount = 0;
|
||||
foreach (NetEntityEvent e in eventsToSync)
|
||||
{
|
||||
//write into a temporary buffer so we can write the length before the actual data
|
||||
IWriteMessage tempEventBuffer = new WriteOnlyMessage();
|
||||
try
|
||||
{
|
||||
WriteEvent(tempEventBuffer, e, recipient);
|
||||
}
|
||||
|
||||
catch (Exception exception)
|
||||
{
|
||||
DebugConsole.ThrowError("Failed to write an event for the entity \"" + e.Entity + "\"", exception);
|
||||
GameAnalyticsManager.AddErrorEventOnce("NetEntityEventManager.Write:WriteFailed" + e.Entity.ToString(),
|
||||
GameAnalyticsSDK.Net.EGAErrorSeverity.Error,
|
||||
"Failed to write an event for the entity \"" + e.Entity + "\"\n" + exception.StackTrace);
|
||||
|
||||
//write an empty event to avoid messing up IDs
|
||||
//(otherwise the clients might read the next event in the message and think its ID
|
||||
//is consecutive to the previous one, even though we skipped over this broken event)
|
||||
tempBuffer.Write(Entity.NullEntityID);
|
||||
tempBuffer.WritePadBits();
|
||||
eventCount++;
|
||||
continue;
|
||||
}
|
||||
|
||||
//the length of the data is written as a byte, so the data needs to be less than 255 bytes long
|
||||
if (tempEventBuffer.LengthBytes > 255)
|
||||
{
|
||||
DebugConsole.ThrowError("Too much data in network event for entity \"" + e.Entity.ToString() + "\" (" + tempEventBuffer.LengthBytes + " bytes, event ID " + e.ID + ")");
|
||||
GameAnalyticsManager.AddErrorEventOnce("NetEntityEventManager.Write:TooLong" + e.Entity.ToString(),
|
||||
GameAnalyticsSDK.Net.EGAErrorSeverity.Error,
|
||||
"Too much data in network event for entity \"" + e.Entity.ToString() + "\" (" + tempEventBuffer.LengthBytes + " bytes, event ID " + e.ID + ")");
|
||||
|
||||
//write an empty event to prevent breaking the event syncing
|
||||
tempBuffer.Write(Entity.NullEntityID);
|
||||
tempBuffer.WritePadBits();
|
||||
eventCount++;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (msg.LengthBytes + tempBuffer.LengthBytes + tempEventBuffer.LengthBytes > MaxEventBufferLength)
|
||||
{
|
||||
//no more room in this packet
|
||||
break;
|
||||
}
|
||||
|
||||
tempBuffer.Write(e.EntityID);
|
||||
tempBuffer.Write((byte)tempEventBuffer.LengthBytes);
|
||||
tempBuffer.Write(tempEventBuffer.Buffer, 0, tempEventBuffer.LengthBytes);
|
||||
tempBuffer.WritePadBits();
|
||||
sentEvents.Add(e);
|
||||
|
||||
eventCount++;
|
||||
}
|
||||
|
||||
if (eventCount > 0)
|
||||
{
|
||||
msg.Write(eventsToSync[0].ID);
|
||||
msg.Write((byte)eventCount);
|
||||
msg.Write(tempBuffer.Buffer, 0, tempBuffer.LengthBytes);
|
||||
}
|
||||
}
|
||||
|
||||
protected abstract void WriteEvent(IWriteMessage buffer, NetEntityEvent entityEvent, Client recipient = null);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user