示例#1
0
 public void ForceSync(Entity en, out EntityProxy proxy)
 {
     if (_outgoingDict.TryGetValue(en.NetworkId, out proxy))
     {
         proxy.Flags |= ProxyFlags.FORCE_SYNC;
         proxy.Flags &= ~ProxyFlags.IDLE;
     }
 }
示例#2
0
        void IEntitySerializer.InitProxy(EntityProxy p)
        {
            p.PropertyPriority = new Priority[Meta.CountProperties];

            for (int i = 0; i < p.PropertyPriority.Length; ++i)
            {
                p.PropertyPriority[i].PropertyIndex = i;
            }
        }
示例#3
0
        BitSet IEntitySerializer.GetFilter(Connection connection, EntityProxy proxy)
        {
            if (Entity.IsController(connection))
            {
                return(Meta.Filters[31]);
            }

            return(Meta.Filters[30]);
        }
        public void Dispose()
        {
            Proxy = null;
            Flags = ProxyFlags.ZERO;

            Written.Clear();

            EntityProxyEnvelopePool.Release(this);
        }
示例#5
0
        private void DestroyIncommingProxy(EntityProxy proxy, IMessageRider token)
        {
            // remove incomming proxy
            _incommingDict.Remove(proxy.NetworkId);

            // destroy entity
            proxy.Entity.DetachToken = token;

            // destroy entity
            Core.DestroyForce(proxy.Entity);
        }
示例#6
0
        private void ReadInput(Packet packet)
        {
            int maxFrame = Core.Frame;
            int minFrame = maxFrame - (Core.Config.commandDelayAllowed + PingFrames);

            while (packet.ReadStopMarker())
            {
                NetworkId   netId = packet.ReadNetworkId();
                EntityProxy proxy = null;

                if (OutgoingProxiesByNetworkId.ContainsKey(netId))
                {
                    proxy = OutgoingProxiesByNetworkId[netId];
                }

                while (packet.ReadStopMarker())
                {
                    Command cmd = Factory.NewCommand(packet.ReadTypeId());
                    cmd.Sequence          = packet.ReadUShort(Command.SEQ_BITS);
                    cmd.ServerFrame       = packet.ReadIntVB();
                    cmd.InputObject.Token = packet.ReadToken();
                    cmd.ReadInput(connection, packet);

                    // no proxy or entity
                    if (!proxy || !proxy.Entity)
                    {
                        continue;
                    }

                    Entity entity = proxy.Entity;

                    // remote is not controller
                    if (ReferenceEquals(entity.Controller, connection) == false)
                    {
                        continue;
                    }

                    // sequence is old
                    if (NetMath.SeqDistance(cmd.Sequence, entity.CommandSequence, Command.SEQ_SHIFT) <= 0)
                    {
                        continue;
                    }

                    // put on command queue
                    entity.CommandQueue.AddLast(cmd);
                    entity.CommandSequence = cmd.Sequence;
                }
            }
        }
示例#7
0
        private void DestroyOutgoingProxy(EntityProxy proxy)
        {
            // remove outgoing proxy index
            _outgoingDict.Remove(proxy.NetworkId);

            // remove proxy from entity
            if (proxy.Entity && proxy.Entity.IsAttached)
            {
                proxy.Entity.Proxies.Remove(proxy);
            }

            if (proxy.Flags & ProxyFlags.DESTROY_IGNORE)
            {
                CreateOnRemote(proxy.Entity);
            }
        }
示例#8
0
        public EntityProxy CreateProxy()
        {
            EntityProxy p;

            p        = new EntityProxy();
            p.Entity = this;
            p.Combine(Serializer.GetDefaultMask());

            // add to list
            Proxies.AddLast(p);

            // let serializer init
            Serializer.InitProxy(p);

            return(p);
        }
示例#9
0
        public void CreateOnRemote(Entity entity, out EntityProxy proxy)
        {
            if (_incommingDict.TryGetValue(entity.NetworkId, out proxy))
            {
                return;
            }
            if (_outgoingDict.TryGetValue(entity.NetworkId, out proxy))
            {
                return;
            }

            proxy            = entity.CreateProxy();
            proxy.NetworkId  = entity.NetworkId;
            proxy.Flags      = ProxyFlags.CREATE_REQUESTED;
            proxy.Connection = connection;

            _outgoingDict.Add(proxy.NetworkId, proxy);

            NetLog.Debug("Created {0} on {1}", entity, connection);
        }
示例#10
0
        private void ReadResult(Packet packet)
        {
            while (packet.CanRead())
            {
                if (packet.ReadBool() == false)
                {
                    break;
                }

                NetworkId   netId  = packet.ReadNetworkId();
                EntityProxy proxy  = IncommingProxiesByNetworkId[netId];
                Entity      entity = proxy.Entity;

                while (packet.CanRead())
                {
                    if (packet.ReadBool() == false)
                    {
                        break;
                    }

                    TypeId        typeId      = packet.ReadTypeId();
                    ushort        sequence    = packet.ReadUShort(Command.SEQ_BITS);
                    IMessageRider resultToken = packet.ReadToken();

                    Command cmd = null;

                    if (entity != null)
                    {
                        var it = entity.CommandQueue.GetIterator();

                        while (it.Next())
                        {
                            int dist = NetMath.SeqDistance(it.val.Sequence, sequence, Command.SEQ_SHIFT);
                            if (dist > 0)
                            {
                                break;
                            }
                            if (dist < 0)
                            {
                                it.val.Flags |= CommandFlags.DISPOSE;
                            }
                            if (dist == 0)
                            {
                                cmd = it.val;
                                break;
                            }
                        }
                    }

                    if (cmd)
                    {
                        cmd.ResultObject.Token = resultToken;
                        cmd.Flags |= CommandFlags.CORRECTION_RECEIVED;

                        if (cmd.Meta.SmoothFrames > 0)
                        {
                            cmd.BeginSmoothing();
                        }

                        cmd.ReadResult(connection, packet);
                    }
                    else
                    {
                        cmd = Factory.NewCommand(typeId);
                        cmd.ReadResult(connection, packet);
                        cmd.Free();
                    }
                }
                // remove all disposable commands
                if (entity != null)
                {
                    while ((entity.CommandQueue.Count > 1) && (entity.CommandQueue.First.Flags & CommandFlags.DISPOSE))
                    {
                        entity.CommandQueue.RemoveFirst().Free();
                    }
                }
            }
        }
示例#11
0
        private bool ReadUpdate(Packet packet)
        {
            if (packet.ReadBool() == false)
            {
                return(false);
            }
            // grab networkid
            NetworkId     networkId        = packet.ReadNetworkId();
            bool          isController     = packet.ReadBool();
            IMessageRider controlToken     = packet.ReadToken();
            bool          destroyRequested = packet.ReadBool();

            // we're destroying this proxy
            if (destroyRequested)
            {
                EntityProxy   proxy;
                IMessageRider detachToken = packet.ReadToken();

                if (_incommingDict.TryGetValue(networkId, out proxy))
                {
                    if (proxy.Entity.HasControl)
                    {
                        proxy.Entity.ReleaseControlInternal(controlToken);
                    }

                    DestroyIncommingProxy(proxy, detachToken);
                }
                else
                {
                    NetLog.Warn("Received destroy of {0} but no such proxy was found", networkId);
                }
            }
            else
            {
                IMessageRider attachToken = null;

                bool isSceneObject   = false;
                bool createRequested = packet.ReadBool();

                UniqueId   sceneId       = UniqueId.None;
                PrefabId   prefabId      = new PrefabId();
                TypeId     serializerId  = new TypeId();
                Vector3    spawnPosition = new Vector3();
                Quaternion spawnRotation = new Quaternion();

                if (createRequested)
                {
                    attachToken = packet.ReadToken();

                    prefabId      = packet.ReadPrefabId();
                    serializerId  = packet.ReadTypeId();
                    spawnPosition = packet.ReadVector3();
                    spawnRotation = packet.ReadQuaternion();
                    isSceneObject = packet.ReadBool();

                    if (isSceneObject)
                    {
                        sceneId = packet.ReadUniqueId();
                    }
                }

                Entity      entity = null;
                EntityProxy proxy  = null;

                if (createRequested && (_incommingDict.ContainsKey(networkId) == false))
                {
                    // create entity
                    if (isSceneObject)
                    {
                        GameObject go = Core.FindSceneObject(sceneId);

                        if (!go)
                        {
                            NetLog.Warn("Could not find scene object with {0}", sceneId);
                            go = Core.PrefabPool.Instantiate(prefabId, spawnPosition, spawnRotation);
                        }

                        entity = Entity.CreateFor(go, prefabId, serializerId, EntityFlags.SCENE_OBJECT);
                    }
                    else
                    {
                        GameObject go = Core.PrefabPool.LoadPrefab(prefabId);

                        // prefab checks (if applicable)
                        if (go)
                        {
                            if (Core.IsServer && !go.GetComponent <AscensionEntity>().allowInstantiateOnClient)
                            {
                                throw new AscensionException(
                                          "Received entity of prefab {0} from client at {1}, but this entity is not allowed to be instantiated from clients",
                                          go.name, connection.RemoteEndPoint);
                            }
                        }

                        NetLog.Warn("Creating instance of {0}", prefabId);
                        entity = Entity.CreateFor(prefabId, serializerId, spawnPosition, spawnRotation);
                    }

                    entity.Source    = connection;
                    entity.SceneId   = sceneId;
                    entity.NetworkId = networkId;

                    // handle case where we are given control (it needs to be true during the initialize, read and attached callbacks)
                    if (isController)
                    {
                        entity.Flags |= EntityFlags.HAS_CONTROL;
                    }

                    // initialize entity
                    entity.Initialize();

                    // create proxy
                    proxy            = entity.CreateProxy();
                    proxy.NetworkId  = networkId;
                    proxy.Connection = connection;

                    // register proxy
                    _incommingDict.Add(proxy.NetworkId, proxy);

                    // read packet
                    entity.Serializer.Read(connection, packet, packet.Frame);

                    // attach entity
                    proxy.Entity.AttachToken = attachToken;
                    proxy.Entity.Attach();

                    // assign control properly
                    if (isController)
                    {
                        proxy.Entity.Flags &= ~EntityFlags.HAS_CONTROL;
                        proxy.Entity.TakeControlInternal(controlToken);
                    }

                    // log debug info
                    NetLog.Debug("Received {0} from {1}", entity, connection);

                    // update last received frame
                    proxy.Entity.LastFrameReceived = AscensionNetwork.Frame;
                    proxy.Entity.Freeze(false);

                    // notify user
                    GlobalEventListenerBase.EntityReceivedInvoke(proxy.Entity.UnityObject);
                }
                else
                {
                    // find proxy
                    proxy = _incommingDict[networkId];

                    if (proxy == null)
                    {
                        throw new AscensionException("Couldn't find entity for {0}", networkId);
                    }

                    // update control state yes/no
                    if (proxy.Entity.HasControl ^ isController)
                    {
                        if (isController)
                        {
                            proxy.Entity.TakeControlInternal(controlToken);
                        }
                        else
                        {
                            proxy.Entity.ReleaseControlInternal(controlToken);
                        }
                    }

                    // read update
                    proxy.Entity.Serializer.Read(connection, packet, packet.Frame);
                    proxy.Entity.LastFrameReceived = AscensionNetwork.Frame;
                    proxy.Entity.Freeze(false);
                }
            }

            return(true);
        }
示例#12
0
        private int PackUpdate(Packet packet, EntityProxy proxy)
        {
            int pos       = packet.Position;
            int packCount = 0;

            EntityProxyEnvelope env = proxy.CreateEnvelope();

            packet.WriteBool(true);
            packet.WriteNetworkId(proxy.NetworkId);

            if (packet.WriteBool(proxy.Entity.IsController(connection)))
            {
                packet.WriteToken(proxy.ControlTokenGained);
                proxy.ControlTokenLost = null;
            }
            else
            {
                packet.WriteToken(proxy.ControlTokenLost);
                proxy.ControlTokenGained = null;
            }

            if (packet.WriteBool(proxy.Flags & ProxyFlags.DESTROY_REQUESTED))
            {
                packet.WriteToken(proxy.Entity.DetachToken);
            }
            else
            {
                // data for first packet
                if (packet.WriteBool(proxy.Flags & ProxyFlags.CREATE_REQUESTED))
                {
                    packet.WriteToken(proxy.Entity.AttachToken);

                    packet.WritePrefabId(proxy.Entity.PrefabId);
                    packet.WriteTypeId(proxy.Entity.Serializer.TypeId);

                    packet.WriteVector3(proxy.Entity.UnityObject.transform.position);
                    packet.WriteQuaternion(proxy.Entity.UnityObject.transform.rotation);

                    if (packet.WriteBool(proxy.Entity.IsSceneObject))
                    {
                        NetAssert.False(proxy.Entity.SceneId.IsNone,
                                        string.Format("'{0}' is marked a scene object but has no scene id ",
                                                      proxy.Entity.UnityObject.gameObject));
                        packet.WriteUniqueId(proxy.Entity.SceneId);
                    }
                }

                packCount = proxy.Entity.Serializer.Pack(connection, packet, env);
            }

            if (packet.Overflowing)
            {
                packet.Position = pos;
                return(-1);
            }
            if (packCount == -1)
            {
                packet.Position = pos;
                return(0);
            }
            else
            {
                var isForce   = proxy.Flags & ProxyFlags.FORCE_SYNC;
                var isCreate  = proxy.Flags & ProxyFlags.CREATE_REQUESTED;
                var isDestroy = proxy.Flags & ProxyFlags.DESTROY_REQUESTED;

                // if we didn't pack anything and we are not creating or destroying this, just goto next
                if ((packCount == 0) && !isCreate && !isDestroy && !isForce)
                {
                    packet.Position = pos;
                    return(0);
                }

                // set in progress flags
                if (isDestroy)
                {
                    env.Flags = (proxy.Flags |= ProxyFlags.DESTROY_PENDING);
                }

                // clear force sync flag
                proxy.Flags &= ~ProxyFlags.FORCE_SYNC;

                // clear skipped count
                proxy.Skipped = 0;

                // set packet number
                env.PacketNumber = packet.Number;

                // put on packets list
                packet.EntityUpdates.Enqueue(env);

                // put on proxies pending queue
                // NetLog.Info("adding envelope to {0}, count: {1}", proxy, proxy.Envelopes.Count + 1);
                proxy.Envelopes.Enqueue(env);

                // keep going!
                return(1);
            }
        }
示例#13
0
 public bool TryFindProxy(Entity en, out EntityProxy proxy)
 {
     return(_incommingDict.TryGetValue(en.NetworkId, out proxy) ||
            _outgoingDict.TryGetValue(en.NetworkId, out proxy));
 }