static void RaiseLocal(Event ev) { try { NetLog.Debug("Raising {0}", ev); if (ev.IsEntityEvent) { ev.TargetEntity.EventDispatcher.Raise(ev); } else { Core.GlobalEventDispatcher.Raise(ev); } if (Core.IsClient && ev.FromSelf == false) { ev.FreeStorage(); } } finally { ev.DecrementRefs(); } }
bool PackEvent(Event ev, Packet stream, uint sequence) { NetLog.Debug("sending event {0}", ev); stream.WriteContinueMarker(); // type id of this event stream.WriteTypeId(ev.Meta.TypeId); // targets of this event stream.WriteInt(ev.Targets, 5); if (stream.WriteBool(ev.Reliability == ReliabilityModes.ReliableOrdered)) { // write sequence number for reliable events stream.WriteUInt(sequence, Event.RELIABLE_SEQUENCE_BITS); } else { if (ev.IsEntityEvent) { // write network id for entity events stream.WriteEntity(ev.TargetEntity); } } stream.WriteByteArrayLengthPrefixed(ev.BinaryData, Core.Config.packetSize / 2); return(ev.Pack(connection, stream)); }
public static void Enqueue(SceneLoadState scene) { NetLog.Debug("Loading {0} ({1})", scene, AscensionNetworkInternal.GetSceneName(scene.Scene.Index)); delay = 0; LoadOps.AddLast(new LoadOp { scene = scene }); }
public static void RegisterTokenClass(Type type) { if (_token2id.Count == 255) { throw new ArgumentException("Can only register 255 different token types"); } byte id = (byte)(_token2id.Count + 1); _token2id.Add(type, id); _id2token.Add(id, type); NetLog.Debug("Registered token class {0} as id {1}", type, id); }
public static void Assigned(long connectionId) { //Converts the long connection id to a unsigned integer with data loss, as well as with overflow protection //This is useful if long.MaxValue is passed to the previous System.Convert.ToInt32 uint convertedConnection = unchecked ((uint)connectionId); NetAssert.True(Core.IsClient, "Core.IsClient"); NetAssert.True(convertedConnection > 0U, "connectionId > 0U"); NetAssert.True(convertedConnection != uint.MaxValue, "connectionId != uint.MaxValue"); // verify connection id NetAssert.True(ConnectionId == uint.MaxValue, "ConnectionId == uint.MaxValue"); NetLog.Debug("Assigned id {0} from server", connectionId); ConnectionId = convertedConnection; }
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); }
public override void Read(Packet packet) { int startPtr = packet.Position; while (packet.ReadStopMarker()) { uint sequence = 0; Event ev = ReadEvent(packet, ref sequence); NetLog.Debug("recv event {0}", ev); if (ev.Reliability == ReliabilityModes.Unreliable) { EventDispatcher.Received(ev); } else { switch (reliableOrderedRecv.TryEnqueue(EventReliable.Wrap(ev, sequence))) { case RecvBufferAddResult.Old: case RecvBufferAddResult.OutOfBounds: case RecvBufferAddResult.AlreadyExists: NetLog.Debug("FAILED"); //ev.DecrementRefs(); break; } } } EventReliable reliable; while (reliableOrderedRecv.TryRemove(out reliable)) { EventDispatcher.Received(reliable.NetworkEvent); } packet.Stats.EventBits = packet.Position - startPtr; }
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 AdjustRemoteFrame() { if (packetsReceived == 0) { return; } if (Core.Config.disableDejitterBuffer) { if (remoteFrameAdjust) { framesToStep = Mathf.Max(0, remoteFrameActual - remoteFrameEstimated); remoteFrameEstimated = remoteFrameActual; remoteFrameAdjust = false; } else { framesToStep = 1; } return; } int rate = Core.RemoteSendRate; int delay = Core.LocalInterpolationDelay; int delayMin = Core.LocalInterpolationDelayMin; int delayMax = Core.LocalInterpolationDelayMax; bool useDelay = delay >= 0; if (remoteFrameAdjust) { remoteFrameAdjust = false; // if we apply delay if (useDelay) { // first packet is special! if (packetsReceived == 1) { remoteFrameEstimated = remoteFrameActual - delay; } // calculate frame diff (actual vs. estimated) remoteFrameDiff = remoteFrameActual - remoteFrameEstimated; // if we are *way* off if ((remoteFrameDiff < (delayMin - rate)) || (remoteFrameDiff > (delayMax + rate))) { int oldFrame = remoteFrameEstimated; int newFrame = remoteFrameActual - delay; NetLog.Debug("FRAME RESET: {0}", remoteFrameDiff); remoteFrameEstimated = newFrame; remoteFrameDiff = remoteFrameActual - remoteFrameEstimated; // call into channels to notify that the frame reset //for (int i = 0; i < _channels.Length; ++i) { // _channels[i].RemoteFrameReset(oldFrame, newFrame); //} } } } if (useDelay) { // drifted to far behind, step two frames if (remoteFrameDiff > delayMax) { NetLog.Debug("FRAME FORWARD: {0}", remoteFrameDiff); framesToStep = 2; remoteFrameDiff -= framesToStep; } // drifting to close to 0 delay, stall one frame else if (remoteFrameDiff < delayMin) { NetLog.Debug("FRAME STALL: {0}", remoteFrameDiff); framesToStep = 0; remoteFrameDiff += 1; } // we have not drifted, just step one frame else { framesToStep = 1; } } else { remoteFrameEstimated = remoteFrameActual - (rate - 1); } //Debug.Log(string.Format("{0}, {1}, {2}, {3}", remoteFrameActual, remoteFrameAdjust, remoteFrameDiff, remoteFrameEstimated)); }
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; } }
public static void Reset(uint connectionId) { NetLog.Debug("Id allocator reset with id {0}", connectionId); EntityId = 0u; ConnectionId = connectionId; }