Beispiel #1
0
        private void SendUpdate()
        {
            if (!FullyConnected)
            {
                return;
            }

            // don't actaully want this going out every frame. Should collect input and send at slightly more spread-out intervals.
            OutboundMessage m = OutboundMessage.CreateUnreliable((byte)EngineMessage.ClientUpdate);

            // write the "latest snapshot" info to the message
            m.Write(LatestSnapshotTick);

            WriteUpdate(m);
            SendMessage(m);
        }
Beispiel #2
0
        private void SendSnapshot()
        {
            OutboundMessage m = OutboundMessage.CreateUnreliable((byte)EngineMessage.Snapshot);

            m.Write(GameServer.Instance.CurrentTick);

            // now step through all entities, decide what to send. Will either be:
            // No change (sends nothing)
            // New entity / full update of entity (Full)
            // Partial update of entity (Partial)
            // Forget about this entity (Delete)
            // ID reassigned, full update of new entity (Replace)
            foreach (Entity e in Entity.AllEntities)
            {
                if (!e.IsNetworked)
                {
                    continue;
                }

                NetworkedEntity ne = e as NetworkedEntity;
                if (ne.IsDeleted || !ne.HasChanges(this))
                {
                    continue;
                }

                if (!ne.ShouldSendToClient(this))
                {
                    if (KnownEntities.ContainsKey(ne.EntityID))
                    {
                        DeletedEntities.Add(ne.EntityID, false); // the client shouldn't see this entity any more, so delete it on their end
                    }
                    continue;
                }

                m.Write(ne.EntityID);

                EntitySnapshotType updateType;
                if (KnownEntities.ContainsKey(ne.EntityID))
                {
                    if (DeletedEntities.ContainsKey(ne.EntityID))
                    {
                        // Reusing an entity ID the client is still using for something else. Ensure it knows the old should be deleted.
                        // Also, don't include it on the Delete list - the Replace accounts for that.
                        updateType = EntitySnapshotType.Replace;
                        DeletedEntities.Remove(ne.EntityID);
                    }
                    else
                    {
                        updateType = NeedsFullUpdate ? EntitySnapshotType.Full : EntitySnapshotType.Partial;
                    }
                }
                else
                {
                    updateType = EntitySnapshotType.Full;
                    KnownEntities[ne.EntityID] = true;
                }

                m.Write((byte)updateType);
                ne.WriteSnapshot(m, this, updateType == EntitySnapshotType.Partial);
            }

            foreach (ushort entityID in DeletedEntities.Keys)
            {
                m.Write(entityID);
                m.Write((byte)EntitySnapshotType.Delete);
                KnownEntities.Remove(entityID);
            }
            DeletedEntities.Clear();

            Send(m);
            NeedsFullUpdate = false;
        }