Sending NetEntityEvents from client to server, ItemComponent class doesn't implement the INetSerializable interfaces (only the derived classes do), reactor syncing

This commit is contained in:
Regalis
2016-11-13 19:34:23 +02:00
parent 724172fe7c
commit 3d234aef73
16 changed files with 146 additions and 59 deletions

View File

@@ -777,7 +777,7 @@ namespace Barotrauma.Networking
outmsg.Write(GameMain.NetLobbyScreen.LastUpdateID);
outmsg.Write(ChatMessage.LastID);
outmsg.Write(Entity.Spawner.NetStateID);
outmsg.Write(entityEventManager.LastReceivedEntityEventID);
outmsg.Write(entityEventManager.LastReceivedID);
ChatMessage removeMsg;
while ((removeMsg = chatMsgQueue.Find(cMsg => cMsg.NetStateID <= lastSentChatMsgID)) != null)
@@ -795,6 +795,8 @@ namespace Barotrauma.Networking
Character.Controlled.ClientWrite(outmsg);
}
entityEventManager.Write(outmsg, client.ServerConnection);
outmsg.Write((byte)ClientNetObject.END_OF_MESSAGE);
client.SendMessage(outmsg, NetDeliveryMethod.Unreliable);
}
@@ -814,6 +816,11 @@ namespace Barotrauma.Networking
chatMsgQueue.Add(chatMessage);
}
public void CreateEntityEvent(IClientSerializable entity, object[] extraData)
{
entityEventManager.CreateEvent(entity, extraData);
}
public bool HasPermission(ClientPermissions permission)
{

View File

@@ -623,6 +623,9 @@ namespace Barotrauma.Networking
c.Character.ServerRead(inc, c);
}
break;
case ClientNetObject.ENTITY_STATE:
entityEventManager.Read(inc, c);
break;
default:
return;
//break;
@@ -1027,6 +1030,10 @@ namespace Barotrauma.Networking
Item.Spawner.Clear();
entityEventManager.Clear();
foreach (Client c in connectedClients)
{
c.entityEventLastSent.Clear();
}
#if DEBUG
messageCount.Clear();
@@ -1418,7 +1425,6 @@ namespace Barotrauma.Networking
}
UpdateNetLobby(null);
}
private Client FindClientWithJobPreference(List<Client> clients, JobPrefab job, bool forceAssign = false)

View File

@@ -15,12 +15,26 @@ namespace Barotrauma.Networking
private GameClient thisClient;
//when was a specific entity event last sent to the client
// key = event id, value = NetTime.Now when sending
public Dictionary<UInt32, float> eventLastSent;
public UInt32 LastReceivedID
{
get { return lastReceivedID; }
}
private UInt32 lastReceivedID;
public ClientEntityEventManager(GameClient client)
{
events = new List<ClientEntityEvent>();
eventLastSent = new Dictionary<uint, float>();
thisClient = client;
}
public void CreateEvent(IClientSerializable entity)
public void CreateEvent(IClientSerializable entity, object[] extraData = null)
{
if (!(entity is Entity))
{
@@ -29,23 +43,45 @@ namespace Barotrauma.Networking
}
ID++;
events.Add(new ClientEntityEvent(entity, ID));
var newEvent = new ClientEntityEvent(entity, ID);
if (extraData != null) newEvent.SetData(extraData);
events.Add(newEvent);
}
public void Write(NetOutgoingMessage msg)
public void Write(NetOutgoingMessage msg, NetConnection serverConnection)
{
if (events.Count == 0) return;
List<NetEntityEvent> eventsToSync = new List<NetEntityEvent>();
for (int i = events.Count - 1; i >= 0 && events[i].ID > thisClient.LastSentEntityEventID; i--)
{
float lastSent = 0;
eventLastSent.TryGetValue(events[i].ID, out lastSent);
if (lastSent > NetTime.Now - serverConnection.AverageRoundtripTime)
{
break;
}
eventsToSync.Add(events[i]);
}
if (eventsToSync.Count == 0) return;
foreach (NetEntityEvent entityEvent in eventsToSync)
{
eventLastSent[entityEvent.ID] = (float)NetTime.Now;
}
msg.Write((byte)ClientNetObject.ENTITY_STATE);
Write(msg, eventsToSync);
}
public void Read(NetIncomingMessage msg, float sendingTime)
{
base.Read(msg, sendingTime, ref lastReceivedID);
}
protected override void WriteEvent(NetBuffer buffer, NetEntityEvent entityEvent, Client recipient = null)
{
var clientEvent = entityEvent as ClientEntityEvent;
@@ -65,6 +101,7 @@ namespace Barotrauma.Networking
public void Clear()
{
events.Clear();
eventLastSent.Clear();
}
}
}

View File

@@ -10,15 +10,14 @@ namespace Barotrauma.Networking
{
abstract class NetEntityEventManager
{
const int MaxEventBufferLength = 1024;
const int MaxEventsPerWrite = 64;
public UInt32 LastReceivedEntityEventID
{
get { return lastReceivedEntityEventID; }
}
//public UInt32 LastReceivedEntityEventID
//{
// get { return lastReceivedEntityEventID; }
//}
private UInt32 lastReceivedEntityEventID;
/// <summary>
/// Write the events to the outgoing message. The recipient parameter is only needed for ServerEntityEventManager
/// </summary>
@@ -30,8 +29,6 @@ namespace Barotrauma.Networking
eventsToSync.RemoveRange(MaxEventsPerWrite, eventsToSync.Count - MaxEventsPerWrite);
}
msg.Write((byte)ServerNetObject.ENTITY_STATE);
msg.Write(eventsToSync[0].ID);
msg.Write((byte)eventsToSync.Count);
@@ -55,7 +52,7 @@ namespace Barotrauma.Networking
/// <summary>
/// Read the events from the message, ignoring ones we've already received
/// </summary>
public void Read(NetIncomingMessage msg, float sendingTime)
protected void Read(NetIncomingMessage msg, float sendingTime, ref UInt32 lastReceivedID)
{
UInt32 firstEventID = msg.ReadUInt32();
int eventCount = msg.ReadByte();
@@ -69,7 +66,7 @@ namespace Barotrauma.Networking
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+1 || entity == null)
if (thisEventID != lastReceivedID + 1 || entity == null)
{
DebugConsole.NewMessage("received msg "+thisEventID, Microsoft.Xna.Framework.Color.Red);
msg.Position += msgLength * 8;
@@ -77,8 +74,8 @@ namespace Barotrauma.Networking
else
{
DebugConsole.NewMessage("received msg "+thisEventID, Microsoft.Xna.Framework.Color.Green);
lastReceivedID++;
ReadEvent(msg, entity, sendingTime);
lastReceivedEntityEventID = thisEventID;
}
msg.ReadPadBits();
}

View File

@@ -61,6 +61,7 @@ namespace Barotrauma.Networking
client.entityEventLastSent[entityEvent.ID] = (float)NetTime.Now;
}
msg.Write((byte)ServerNetObject.ENTITY_STATE);
Write(msg, eventsToSync, client);
}
@@ -80,6 +81,11 @@ namespace Barotrauma.Networking
clientEntity.ServerRead(buffer, sender);
}
public void Read(NetIncomingMessage msg, Client client)
{
base.Read(msg, 0.0f, ref client.lastSentEntityEventID);
}
public void Clear()
{
events.Clear();

View File

@@ -25,7 +25,8 @@ namespace Barotrauma.Networking
CHAT_MESSAGE, //also self-explanatory
VOTE, //you get the idea
CHARACTER_INPUT,
ITEM_INTERACTION
ITEM_INTERACTION,
ENTITY_STATE
}
enum ServerPacketHeader