public bool TryGet(NetworkId id, out AscensionEntity entity) { EntityProxy proxy; if (dict.TryGetValue(id, out proxy) && proxy.Entity != null && proxy.Entity.UnityObject != null) { entity = proxy.Entity.UnityObject; return(true); } entity = null; return(false); }
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; } } }
/// <summary> /// Find an entity based on unique id /// </summary> public static AscensionEntity FindEntity(NetworkId id) { VerifyIsRunning(); if (id.Packed == 0) { return(null); } foreach (var itval in Core.entities) { if (itval.IsAttached && itval.UnityObject && itval.NetworkId.Packed == id.Packed) { return(itval.UnityObject); } } NetLog.Warn("Could not find entity with {0}", id); return(null); }
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(); } } } }
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 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; } }
public static bool Diff(NetworkId a, NetworkId b) { return(a != b); }
public static void WriteNetworkId(this BasePacket packet, NetworkId id) { NetAssert.True(id.Connection != uint.MaxValue); packet.WriteUIntVB(id.Connection); packet.WriteUIntVB(id.Entity); }