public EntityManager(RailServer server) { m_Server = server ?? throw new ArgumentNullException(nameof(server)); m_Room = m_Server.StartRoom(); InitRoom(m_Room); // Setup callbacks m_Server.ClientAdded += OnClientAdded; m_Server.ClientRemoved += OnClientRemoved; }
private void InitRoom(RailServerRoom room) { room.AddNewEntity <WorldEntityServer>(); foreach (MobileParty party in Campaign.Current.MobileParties) { MobilePartyEntityServer entity = room.AddNewEntity <MobilePartyEntityServer>( e => e.State.PartyId = party.Party.Index); m_Parties.Add(party, entity); } CampaignEvents.OnPartyDisbandedEvent.AddNonSerializedListener(this, OnPartyRemoved); CampaignEvents.OnLordPartySpawnedEvent.AddNonSerializedListener(this, OnPartyAdded); }
private void InitRoom(RailServerRoom room) { room.AddNewEntity <WorldEntityServer>(); // Parties foreach (MobileParty party in Campaign.Current.MobileParties) { if (party.Party.Index == MobilePartyState.InvalidPartyId) { throw new Exception("Invalid party id!"); } MobilePartyEntityServer entity = room.AddNewEntity <MobilePartyEntityServer>( e => e.State.PartyId = party.Party.Index); m_Parties.Add(party, entity); } CampaignEvents.OnPartyDisbandedEvent.AddNonSerializedListener(this, OnPartyRemoved); CampaignEvents.OnLordPartySpawnedEvent.AddNonSerializedListener(this, OnPartyAdded); // Settlements }
private void ClientServerCommunication() { // Initialization CampaignTimeControlMode expectedTimeControl = CampaignTimeControlMode.StoppablePlay; RailClientRoom clientRoom = m_Client.StartRoom(); RailServerRoom serverRoom = m_Server.StartRoom(); RailEntityServer <SomeState> entityServerSide = serverRoom.AddNewEntity <RailEntityServer <SomeState> >(); entityServerSide.State.Mode = expectedTimeControl; m_Server.AddClient(m_PeerServerSide.Object, ""); m_Client.SetPeer(m_PeerClientSide.Object); Assert.Empty(clientRoom.Entities); Assert.Single(serverRoom.Entities); // Sync entity from server to client for (int i = 0; i < RailConfig.SERVER_SEND_RATE + RailConfig.CLIENT_SEND_RATE + 1; ++i) { m_ConClientSide.ExecuteSends(); m_Server.Update(); m_ConServerSide.ExecuteSends(); m_Client.Update(); } // The client has received the entity. Assert.Single(clientRoom.Entities); Assert.Single(serverRoom.Entities); // Clients representation of the entity is identical to the server RailEntityBase entityProxy = clientRoom.Entities.First(); Assert.IsType <RailEntityClient <SomeState> >(entityProxy); RailEntityClient <SomeState> entityClientSide = entityProxy as RailEntityClient <SomeState>; Assert.NotNull(entityClientSide); Assert.Equal(entityServerSide.Id, entityProxy.Id); Assert.Equal(expectedTimeControl, entityServerSide.State.Mode); Assert.Equal(expectedTimeControl, entityClientSide.State.Mode); // Change the entity on server side and sync to the client expectedTimeControl = CampaignTimeControlMode.Stop; entityServerSide.State.Mode = expectedTimeControl; // Let the server detect the change and send the packet bool bWasSendTick = false; while (!bWasSendTick) { m_Server.Update(); bWasSendTick = serverRoom.Tick.IsSendTick(RailConfig.SERVER_SEND_RATE); } // Let the client receive & process the packet. We need to bring the client up to the same tick as the server to see the result. while (clientRoom.Tick < serverRoom.Tick) { m_ConServerSide.ExecuteSends(); m_Client.Update(); } Assert.Equal(expectedTimeControl, entityServerSide.State.Mode); Assert.Equal(expectedTimeControl, entityClientSide.State.Mode); }
private void EntitiesAreSynchronized() { // Initialization RailClientRoom clientRoom = client.StartRoom(); RailServerRoom serverRoom = server.StartRoom(); EntityServer entityServerSide = serverRoom.AddNewEntity <EntityServer>(); server.AddClient(peerServerSide.Object, ""); client.SetPeer(peerClientSide.Object); // Nothing has been sent or received yet peerClientSide.Verify( c => c.SendPayload(It.IsAny <ArraySegment <byte> >()), Times.Never()); peerServerSide.Verify( c => c.SendPayload(It.IsAny <ArraySegment <byte> >()), Times.Never()); Assert.Empty(clientRoom.Entities); Assert.Single(serverRoom.Entities); // Let the server send its update to the client for (int i = 0; i < RailConfig.SERVER_SEND_RATE + RailConfig.CLIENT_SEND_RATE + 1; ++i) { peerServerSide.Object.PollEvents(); server.Update(); peerClientSide.Object.PollEvents(); client.Update(); } // The client has received the server entity. Assert.Single(clientRoom.Entities); Assert.Single(serverRoom.Entities); // Clients representation of the entity is identical to the server RailEntityBase entityProxy = clientRoom.Entities.First(); Assert.IsType <EntityClient>(entityProxy); EntityClient entityClientSide = entityProxy as EntityClient; Assert.NotNull(entityClientSide); Assert.Equal(entityServerSide.Id, entityProxy.Id); Assert.Equal(entityClientSide.State.PosX, entityServerSide.State.PosX); Assert.Equal(entityClientSide.State.PosY, entityServerSide.State.PosY); // Change the entity on the server side and sync it to the client float fExpectedPosX = 42; float fExpectedPosY = 106; entityServerSide.State.PosX = fExpectedPosX; entityServerSide.State.PosY = fExpectedPosY; // Let the server detect the change and send the packet server.Update(); bool bWasSendTick = serverRoom.Tick.IsSendTick(RailConfig.SERVER_SEND_RATE); while (!bWasSendTick) { server.Update(); bWasSendTick = serverRoom.Tick.IsSendTick(RailConfig.SERVER_SEND_RATE); } // Let the client receive & process the packet. We need to bring the client up to the same tick as the server to see the result. while (clientRoom.Tick < serverRoom.Tick) { peerClientSide.Object.PollEvents(); client.Update(); } Assert.Equal(fExpectedPosX, entityClientSide.State.PosX); Assert.Equal(fExpectedPosY, entityClientSide.State.PosY); Assert.Equal(fExpectedPosX, entityServerSide.State.PosX); Assert.Equal(fExpectedPosY, entityServerSide.State.PosY); }