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); }
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); } } } }
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); }
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); }
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; } }