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
            });
        }
Exemple #4
0
        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);
        }
Exemple #5
0
        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);
        }
Exemple #9
0
        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));
        }
Exemple #10
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);
        }
Exemple #11
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;
            }
        }
Exemple #12
0
 public static void Reset(uint connectionId)
 {
     NetLog.Debug("Id allocator reset with id {0}", connectionId);
     EntityId     = 0u;
     ConnectionId = connectionId;
 }