예제 #1
0
        public void ReleaseControlInternal(IMessageRider token)
        {
            NetAssert.True(Flags & EntityFlags.HAS_CONTROL);

            Flags &= ~EntityFlags.HAS_CONTROL;
            CommandQueue.Clear();
            CommandSequence     = 0;
            CommandLastExecuted = null;

            ControlLostToken   = token;
            ControlGainedToken = null;

            // call to serializer
            Serializer.OnControlLost();

            // call to user behaviours
            foreach (IEntityBehaviour eb in Behaviours)
            {
                if (ReferenceEquals(eb.entity, this.UnityObject))
                {
                    eb.ControlLost();
                }
            }

            // call user event
            GlobalEventListenerBase.ControlOfEntityLostInvoke(UnityObject);

            // de-freeze
            Freeze(false);
        }
예제 #2
0
 public void Freeze(bool freeze)
 {
     if (IsFrozen != freeze)
     {
         if (IsFrozen)
         {
             IsFrozen = false;
             Core.entitiesFrozen.Remove(this);
             Core.entitiesThawed.AddLast(this);
             GlobalEventListenerBase.EntityThawedInvoke(this.UnityObject);
         }
         else
         {
             if (CanFreeze)
             {
                 IsFrozen = true;
                 Core.entitiesThawed.Remove(this);
                 Core.entitiesFrozen.AddLast(this);
                 GlobalEventListenerBase.EntityFrozenInvoke(this.UnityObject);
             }
         }
     }
 }
예제 #3
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);
        }
예제 #4
0
        public void Detach()
        {
            NetAssert.NotNull(UnityObject);
            NetAssert.True(IsAttached);
            NetAssert.True(NetworkId.Packed != 0UL);

            if (AutoRemoveChildEntities)
            {
                foreach (AscensionEntity child in UnityObject.GetComponentsInChildren(typeof(AscensionEntity), true))
                {
                    if (child.IsAttached && (ReferenceEquals(child.entity, this) == false))
                    {
                        child.transform.parent = null;
                    }
                }
            }

            if (Controller)
            {
                RevokeControl(null);
            }

            // destroy on all connections
            var it = Core.connections.GetIterator();

            while (it.Next())
            {
                it.val.entityChannel.DestroyOnRemote(this);
            }

            // call out to behaviours
            foreach (IEntityBehaviour eb in Behaviours)
            {
                try
                {
                    if (eb.Invoke && ReferenceEquals(eb.entity, this.UnityObject))
                    {
                        eb.Detached();
                        eb.entity = null;
                    }
                }
                catch (Exception exn)
                {
                    NetLog.Error("User code threw exception inside Detach callback");
                    NetLog.Exception(exn);
                }
            }

            // call out to user
            try
            {
                GlobalEventListenerBase.EntityDetachedInvoke(this.UnityObject);
            }
            catch (Exception exn)
            {
                NetLog.Error("User code threw exception inside Detach callback");
                NetLog.Exception(exn);
            }

            // clear out attached flag
            Flags &= ~EntityFlags.ATTACHED;

            // remove from entities list
            if (Core.entitiesFrozen.Contains(this))
            {
                Core.entitiesFrozen.Remove(this);
            }

            if (Core.entitiesThawed.Contains(this))
            {
                Core.entitiesThawed.Remove(this);
            }

            // clear from unity object
            UnityObject.entity = null;

            // log
            NetLog.Debug("Detached {0}", this);
        }
예제 #5
0
        public void Attach()
        {
            NetAssert.NotNull(UnityObject);
            NetAssert.False(IsAttached);
            NetAssert.True((NetworkId.Packed == 0UL) || (Source != null));

            try
            {
                AttachIsRunning = true;

                // mark as don't destroy on load
                GameObject.DontDestroyOnLoad(UnityObject.gameObject);

                // assign network id
                if (Source == null)
                {
                    NetworkId = NetworkIdAllocator.Allocate();
                }

                // add to entities list
                Core.entitiesThawed.AddLast(this);

                // mark as attached
                Flags |= EntityFlags.ATTACHED;

                // call out to behaviours
                foreach (IEntityBehaviour eb in Behaviours)
                {
                    try
                    {
                        if (eb.Invoke && ReferenceEquals(eb.entity, this.UnityObject))
                        {
                            eb.Attached();
                        }
                    }
                    catch (Exception exn)
                    {
                        NetLog.Error("User code threw exception inside Attached callback");
                        NetLog.Exception(exn);
                    }
                }

                // call out to user
                try
                {
                    GlobalEventListenerBase.EntityAttachedInvoke(this.UnityObject);
                }
                catch (Exception exn)
                {
                    NetLog.Error("User code threw exception inside Attached callback");
                    NetLog.Exception(exn);
                }

                // log
                NetLog.Debug("Attached {0} (Token: {1})", this, AttachToken);
            }
            finally
            {
                AttachIsRunning = false;
            }
        }