예제 #1
0
 static NetObject()
 {
     RPCSourceConnection = null;
     RPCDestConnection   = null;
     PIsInitialUpdate    = false;
     _dirtyList          = null;
 }
예제 #2
0
        public static void CollapseDirtyList()
        {
            for (var obj = _dirtyList; obj != null;)
            {
                var next   = obj._nextDirtyList;
                var orMask = obj._dirtyMaskBits;

                obj._nextDirtyList = null;
                obj._prevDirtyList = null;
                obj._dirtyMaskBits = 0UL;

                if (orMask > 0)
                {
                    for (var walk = obj._firstObjectRef; walk != null; walk = walk.NextObjectRef)
                    {
                        if (walk.UpdateMask == 0)
                        {
                            walk.UpdateMask = orMask;
                            walk.Connection.GhostPushNonZero(walk);
                        }
                        else
                        {
                            walk.UpdateMask |= orMask;
                        }
                    }
                }

                obj = next;
            }

            _dirtyList = null;
        }
예제 #3
0
 public NetObject()
 {
     _netIndex       = 0xFFFFFFFFU;
     _firstObjectRef = null;
     _prevDirtyList  = null;
     _nextDirtyList  = null;
     _dirtyMaskBits  = 0UL;
 }
예제 #4
0
        public void SetScopeObject(NetObject obj)
        {
            if (ScopeObject == obj)
            {
                return;
            }

            obj.SetOwningConnection(this);
            ScopeObject = obj;
        }
예제 #5
0
 public GhostConnection()
 {
     ScopeObject          = null;
     GhostingSequence     = 0U;
     Ghosting             = false;
     Scoping              = false;
     GhostArray           = null;
     GhostRefs            = null;
     LocalGhosts          = null;
     GhostZeroUpdateIndex = 0;
 }
예제 #6
0
        public void SetMaskBits(ulong orMask)
        {
            if (_dirtyMaskBits == 0UL)
            {
                if (_dirtyList != null)
                {
                    _nextDirtyList            = _dirtyList;
                    _dirtyList._prevDirtyList = this;
                }

                _dirtyList = this;
            }

            _dirtyMaskBits |= orMask;
        }
예제 #7
0
        public void ObjectLocalClearAlways(NetObject obj)
        {
            if (!DoesGhostFrom())
            {
                return;
            }

            for (var i = 0; i < MaxGhostCount; ++i)
            {
                if (GhostArray[i] != null && GhostArray[i].Obj == obj)
                {
                    GhostArray[i].Flags &= ~(uint)GhostInfoFlags.ScopeLocalAlways;
                    return;
                }
            }
        }
예제 #8
0
        public void ObjectInScope(NetObject obj)
        {
            if (!Scoping || !DoesGhostFrom())
            {
                return;
            }

            if (!obj.IsGhostable() || (obj.IsScopeLocal() && !IsLocalConnection()))
            {
                return;
            }

            for (var i = 0; i < MaxGhostCount; ++i)
            {
                if (GhostArray[i] != null && GhostArray[i].Obj == obj)
                {
                    GhostArray[i].Flags |= (uint)GhostInfoFlags.InScope;
                    return;
                }
            }

            if (GhostFreeIndex == MaxGhostCount)
            {
                return;
            }

            var gi = GhostArray[GhostFreeIndex];

            GhostPushFreeToZero(gi);
            gi.UpdateMask = 0xFFFFFFFFFFFFFFFFUL;
            GhostPushNonZero(gi);

            gi.Flags           = (uint)(GhostInfoFlags.NotYetGhosted | GhostInfoFlags.InScope);
            gi.Obj             = obj;
            gi.LastUpdateChain = null;
            gi.UpdateSkipCount = 0U;
            gi.Connection      = this;
            gi.NextObjectRef   = obj.GetFirstObjectRef();

            if (obj.GetFirstObjectRef() != null)
            {
                obj.GetFirstObjectRef().PrevObjectRef = gi;
            }

            gi.PrevObjectRef = null;
            obj.SetFirstObjectRef(gi);
        }
예제 #9
0
        public override void Process(EventConnection ps)
        {
            if (DestObject == null)
            {
                return;
            }

            if (!CheckClassType(DestObject))
            {
                return;
            }

            NetObject.SetRPCSourceConnection(ps as GhostConnection);

            Functor.Dispatch(DestObject);

            NetObject.SetRPCSourceConnection(null);
        }
예제 #10
0
        public int GetGhostIndex(NetObject obj)
        {
            if (obj == null)
            {
                return(-1);
            }

            if (!DoesGhostFrom())
            {
                return((int)obj.GetNetIndex());
            }

            for (var i = 0; i < MaxGhostCount; ++i)
            {
                if (GhostArray[i] != null && GhostArray[i].Obj == obj && (GhostArray[i].Flags & (uint)(GhostInfoFlags.KillingGhost | GhostInfoFlags.Ghosting | GhostInfoFlags.NotYetGhosted | GhostInfoFlags.KillGhost)) == 0U)
                {
                    return((int)GhostArray[i].Index);
                }
            }

            return(-1);
        }
예제 #11
0
        public void ClearMaskBits(ulong orMask)
        {
            if (_dirtyMaskBits > 0)
            {
                _dirtyMaskBits &= ~orMask;

                if (_dirtyMaskBits == 0)
                {
                    if (_prevDirtyList != null)
                    {
                        _prevDirtyList._nextDirtyList = _nextDirtyList;
                    }
                    else
                    {
                        _prevDirtyList = _nextDirtyList;
                    }

                    if (_nextDirtyList != null)
                    {
                        _nextDirtyList._prevDirtyList = _prevDirtyList;
                    }

                    _nextDirtyList = _prevDirtyList = null;
                }
            }

            for (var walk = _firstObjectRef; walk != null; walk = walk.NextObjectRef)
            {
                if (walk.UpdateMask > 0 && walk.UpdateMask == orMask)
                {
                    walk.UpdateMask = 0;
                    walk.Connection.GhostPushToZero(walk);
                }
                else
                {
                    walk.UpdateMask &= ~orMask;
                }
            }
        }
예제 #12
0
 public bool IsGhostAvailable(NetObject obj)
 {
     return(GetGhostIndex(obj) != -1);
 }
예제 #13
0
        public void ProcessConnections()
        {
            CurrentTime = Environment.TickCount;
            PuzzleManager.Tick(CurrentTime);

            if (SendPacketList.Count > 0)
            {
                foreach (var dsp in SendPacketList.Where(dsp => dsp.SendTime > CurrentTime))
                {
                    Socket.Send(dsp.RemoteAddress, dsp.PacketData, dsp.PacketSize);

                    SendPacketList.Remove(dsp);
                }
            }

            NetObject.CollapseDirtyList();

            lock (_connectionList)
                foreach (var conn in _connectionList)
                {
                    conn.CheckPacketSend(false, CurrentTime);
                }

            if (CurrentTime > LastTimeoutCheckTime + TimeoutCheckInterval)
            {
                var removeList = new List <NetConnection>();

                foreach (var pair in PendingConnections)
                {
                    var pending = pair.Value;

                    if (pending.ConnectionState == NetConnectionState.AwaitingChallengeResponse && CurrentTime > pending.ConnectLastSendTime + ChallengeRetryTime)
                    {
                        if (pending.ConnectSendCount > ChallengeRetryCount)
                        {
                            pending.ConnectionState = NetConnectionState.ConnectTimedOut;
                            pending.OnConnectTerminated(TerminationReason.ReasonTimedOut, "Timeout");

                            removeList.Add(pending);

                            continue;
                        }

                        SendConnectChallengeRequest(pending);
                    }
                    else if (pending.ConnectionState == NetConnectionState.AwaitingConnectResponse && CurrentTime > pending.ConnectLastSendTime + ConnectRetryTime)
                    {
                        if (pending.ConnectSendCount > ConnectRetryCount)
                        {
                            pending.ConnectionState = NetConnectionState.ConnectTimedOut;
                            pending.OnConnectTerminated(TerminationReason.ReasonTimedOut, "Timeout");

                            removeList.Add(pending);

                            continue;
                        }

                        if (pending.GetConnectionParameters().IsArranged)
                        {
                            SendArrangedConnectRequest(pending);
                        }
                        else
                        {
                            SendConnectRequest(pending);
                        }
                    }
                    else if (pending.ConnectionState == NetConnectionState.SendingPunchPackets && CurrentTime > pending.ConnectLastSendTime + PunchRetryTime)
                    {
                        if (pending.ConnectSendCount > PunchRetryCount)
                        {
                            pending.ConnectionState = NetConnectionState.ConnectTimedOut;
                            pending.OnConnectTerminated(TerminationReason.ReasonTimedOut, "Timeout");

                            removeList.Add(pending);

                            continue;
                        }

                        SendPunchPackets(pending);
                    }
                    else if (pending.ConnectionState == NetConnectionState.ComputingPuzzleSolution && CurrentTime > pending.ConnectLastSendTime + PuzzleSolutionTimeout)
                    {
                        pending.ConnectionState = NetConnectionState.ConnectTimedOut;
                        pending.OnConnectTerminated(TerminationReason.ReasonTimedOut, "Timeout");

                        removeList.Add(pending);
                    }
                }

                foreach (var conn in removeList)
                {
                    RemovePendingConnection(conn);
                }

                removeList.Clear();

                LastTimeoutCheckTime = CurrentTime;

                lock (_connectionList)
                {
                    foreach (var conn in _connectionList)
                    {
                        if (conn.CheckTimeout(CurrentTime))
                        {
                            conn.ConnectionState = NetConnectionState.TimedOut;
                            conn.OnConnectTerminated(TerminationReason.ReasonTimedOut, "Timeout");

                            removeList.Add(conn);
                        }
                    }
                }

                foreach (var conn in removeList)
                {
                    RemoveConnection(conn);
                }
            }

            foreach (var pair in PendingConnections.Where(pair => pair.Value.ConnectionState == NetConnectionState.ComputingPuzzleSolution))
            {
                ContinuePuzzleSolution(pair.Value);
                break;
            }
        }
예제 #14
0
 protected NetObjectRPCEvent(NetObject destObject, RPCGuaranteeType gType, NetObjectRPCDirection dir)
     : base(gType, RPCDirection.RPCDirAny)
 {
     DestObject   = destObject;
     RpcDirection = dir;
 }
예제 #15
0
 public void SetServerObject(NetObject o)
 {
     _serverObject = o;
 }
예제 #16
0
 public virtual float GetUpdatePriority(NetObject scopeObject, ulong updateMask, int updateSkips)
 {
     return(updateSkips * 0.1f);
 }