예제 #1
0
        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;
        }
예제 #2
0
        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);
        }
예제 #3
0
        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
        }
예제 #4
0
        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);
        }
예제 #5
0
        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);
        }