示例#1
0
        /// <summary>
        /// Remove an entity from being controlled by this peer.
        /// </summary>
        public virtual void RevokeControl(RailEntity entity)
        {
            RailDebug.Assert(entity.Controller == this);
            this.controlledEntities.Remove(entity);

            entity.AssignController(null);
        }
示例#2
0
        public static bool operator !=(SequenceId a, SequenceId b)
        {
            RailDebug.Assert(a.IsValid);
            RailDebug.Assert(b.IsValid);

            return(a.rawValue != b.rawValue);
        }
示例#3
0
 public static void Assert(bool condition, object message)
 {
     if (condition == false)
     {
         RailDebug.LogError("Assert Failed: " + message);
     }
 }
示例#4
0
 public static void Assert(bool condition)
 {
     if (condition == false)
     {
         RailDebug.LogError("Assert Failed!");
     }
 }
示例#5
0
        public static int operator -(Tick a, Tick b)
        {
            RailDebug.Assert(a.IsValid && b.IsValid);
            long difference = (long)a.tickValue - (long)b.tickValue;

            return((int)difference);
        }
示例#6
0
 public void SetPeer(IRailNetPeer netPeer)
 {
     RailDebug.Assert(this.serverPeer == null, "Overwriting peer");
     this.serverPeer = new RailClientPeer(netPeer, this.Interpreter);
     this.serverPeer.PacketReceived += this.OnPacketReceived;
     this.serverPeer.EventReceived  += base.OnEventReceived;
 }
示例#7
0
        public void Deallocate(T obj)
        {
            RailDebug.Assert(obj.Pool == this);

            obj.Reset();
            obj.Pool = null; // Prevent multiple frees
            this.freeList.Push(obj);
        }
示例#8
0
        internal void SendPacket(IRailNetPeer peer, IRailPacket packet)
        {
            this.bitBuffer.Clear();
            packet.Encode(this.bitBuffer);
            int length = this.bitBuffer.Store(this.bytes);

            RailDebug.Assert(length <= RailConfig.PACKCAP_MESSAGE_TOTAL);
            peer.SendPayload(this.bytes, length);
        }
示例#9
0
        /// <summary>
        /// Packs all elements of an enumerable up to a given size.
        /// Max 255 elements.
        /// </summary>
        public byte PackToSize <T>(
            int maxTotalBytes,
            int maxIndividualBytes,
            IEnumerable <T> elements,
            Action <T> encode,
            Action <T> packed = null)
        {
            const int MAX_SIZE  = 255;
            const int SIZE_BITS = 8;

            maxTotalBytes -= 1; // Sentinel bit can blow this up
            byte count = 0;

            // Reserve: [Count]
            int countWritePos = this.writePos;

            this.Write(SIZE_BITS, 0);

            // Write: [Elements]
            foreach (T val in elements)
            {
                if (count == MAX_SIZE)
                {
                    break;
                }
                int rollback      = this.writePos;
                int startByteSize = this.ByteSize;

                encode.Invoke(val);

                int endByteSize   = this.ByteSize;
                int writeByteSize = (endByteSize - startByteSize);
                if (writeByteSize > maxIndividualBytes)
                {
                    this.writePos = rollback;
                    RailDebug.LogWarning(
                        "Skipping " + val + " (" + writeByteSize + "B)");
                }
                else if (endByteSize > maxTotalBytes)
                {
                    this.writePos = rollback;
                    break;
                }
                else
                {
                    if (packed != null)
                    {
                        packed.Invoke(val);
                    }
                    count++;
                }
            }

            // Deferred Write: [Count]
            this.Insert(countWritePos, SIZE_BITS, count);
            return(count);
        }
示例#10
0
        private static int GetDifference(SequenceId a, SequenceId b)
        {
            RailDebug.Assert(a.IsValid);
            RailDebug.Assert(b.IsValid);

            int difference =
                (int)((a.rawValue << SequenceId.BIT_SHIFT) -
                      (b.rawValue << SequenceId.BIT_SHIFT));

            return(difference);
        }
示例#11
0
        /// <summary>
        /// Adds an entity to be controlled by this peer.
        /// </summary>
        public virtual void GrantControl(RailEntity entity)
        {
            if (entity.Controller == this)
            {
                return;
            }

            RailDebug.Assert(entity.Controller == null);
            this.controlledEntities.Add(entity);

            entity.AssignController(this);
        }
示例#12
0
        private void UpdateControlled(Tick localTick)
        {
            RailDebug.Assert(this.Controller != null);
            if (this.outgoingCommands.Count < RailConfig.COMMAND_BUFFER_COUNT)
            {
                RailCommand command = RailCommand.Create();

                command.ClientTick   = localTick;
                command.IsNewCommand = true;

                this.UpdateControlGeneric(command);
                this.outgoingCommands.Enqueue(command);
            }
        }
示例#13
0
        /// <summary>
        /// Selects outgoing events to send.
        /// </summary>
        private IEnumerable <RailEvent> FilterOutgoingEvents()
        {
            // The receiving client can only store SequenceWindow.HISTORY_LENGTH
            // events in its received buffer, and will skip any events older than
            // its latest received minus that history length, including reliable
            // events. In order to make sure we don't force the client to skip a
            // reliable event, we will throttle the outgoing events if we've been
            // sending them too fast. For example, if we have a reliable event
            // with ID 3 pending, the highest ID we can send would be ID 67. If we
            // send an event with ID 68, then the client may ignore ID 3 when it
            // comes in for being too old, even though it's reliable.
            //
            // In practice this shouldn't be a problem unless we're sending way
            // more events than is reasonable(/possible) in a single packet, or
            // something is wrong with reliable event acking.

            SequenceId firstReliable = SequenceId.INVALID;

            foreach (RailEvent evnt in this.outgoingEvents)
            {
                if (evnt.IsReliable)
                {
                    if (firstReliable.IsValid == false)
                    {
                        firstReliable = evnt.EventId;
                    }
                    RailDebug.Assert(firstReliable <= evnt.EventId);
                }

                if (firstReliable.IsValid)
                {
                    if (SequenceWindow.AreInRange(firstReliable, evnt.EventId) == false)
                    {
                        string current = "Throttling events due to unacked reliable\n";
                        foreach (RailEvent evnt2 in this.outgoingEvents)
                        {
                            current += evnt2.EventId + " ";
                        }
                        RailDebug.LogWarning(current);
                        break;
                    }
                }

                if (evnt.CanSend)
                {
                    yield return(evnt);
                }
            }
        }
示例#14
0
        internal static Tick Subtract(Tick a, int b, bool warnClamp = false)
        {
            RailDebug.Assert(b >= 0);
            long result = (long)a.tickValue - b;

            if (result < 1)
            {
                if (warnClamp)
                {
                    RailDebug.LogWarning("Clamping tick subtraction");
                }
                result = 1;
            }
            return(new Tick((uint)result));
        }
示例#15
0
        protected void OnPayloadReceived(IRailNetPeer peer, byte[] buffer, int length)
        {
            RailBitBuffer bitBuffer = this.interpreter.LoadData(buffer, length);

            this.reusableIncoming.Decode(bitBuffer);
            if (bitBuffer.IsFinished)
            {
                this.ProcessPacket(this.reusableIncoming);
            }
            else
            {
                RailDebug.LogError("Bad packet read, discarding...");
            }
            this.reusableIncoming.Reset();
        }
示例#16
0
        /// <summary>
        /// Copies the buffer to a byte buffer.
        /// </summary>
        public int Store(byte[] data)
        {
            // Write a sentinel bit to find our position and flash out bad data
            this.Write(1, 1);

            int numChunks = (this.writePos >> 5) + 1;

            RailDebug.Assert(data.Length >= numChunks * 4, "Buffer too small");

            for (int i = 0; i < numChunks; i++)
            {
                int  dataIdx = i * 4;
                uint chunk   = this.chunks[i];
                data[dataIdx]     = (byte)(chunk);
                data[dataIdx + 1] = (byte)(chunk >> 8);
                data[dataIdx + 2] = (byte)(chunk >> 16);
                data[dataIdx + 3] = (byte)(chunk >> 24);
            }

            return(this.ByteSize);
        }
示例#17
0
        public void WriteString(string value)
        {
            if (value == null)
            {
                throw new ArgumentNullException("value");
            }

            uint length = (uint)value.Length;

            RailDebug.Assert(length <= RailConfig.STRING_LENGTH_MAX, value);
            if (value.Length > RailConfig.STRING_LENGTH_MAX)
            {
                length = RailConfig.STRING_LENGTH_MAX;
            }

            this.Write(RailBitBuffer.STRING_LENGTH_BITS, length);
            for (int i = 0; i < length; i++)
            {
                this.Write(RailBitBuffer.ASCII_BITS, RailBitBuffer.ToASCII(value[i]));
            }
        }
示例#18
0
        private void ProcessDelta(RailStateDelta delta)
        {
            RailEntity entity;

            if (this.knownEntities.TryGetValue(delta.EntityId, out entity) == false)
            {
                RailDebug.Assert(delta.IsFrozen == false, "Frozen unknown entity");
                if (delta.IsFrozen)
                {
                    return;
                }

                entity = delta.ProduceEntity();
                entity.AssignId(delta.EntityId);
                this.pendingEntities.Add(entity.Id, entity);
                this.knownEntities.Add(entity.Id, entity);
            }

            entity.ReceiveDelta(delta);
            this.UpdateControlStatus(entity, delta);
        }
示例#19
0
        private static byte ToASCII(char character)
        {
            byte value = 0;

            try
            {
                value = Convert.ToByte(character);
            }
            catch (OverflowException)
            {
                RailDebug.LogMessage("Cannot convert to simple ASCII: " + character);
                return(0);
            }

            if (value > 127)
            {
                RailDebug.LogMessage("Cannot convert to simple ASCII: " + character);
                return(0);
            }

            return(value);
        }
示例#20
0
        private void UpdateAuthState()
        {
            // Apply all un-applied deltas to the auth state
            RailStateDelta next;
            IEnumerable <RailStateDelta> toApply =
                this.incomingStates.GetRangeAndNext(
                    this.authTick,
                    this.Room.Tick,
                    out next);

            foreach (RailStateDelta delta in toApply)
            {
                if (this.authTick == Tick.START)
                {
                    RailDebug.Assert(delta.HasImmutableData);
                }
                if (delta.IsFrozen == false)
                {
                    this.AuthStateBase.ApplyDelta(delta);
                }
                this.shouldBeFrozen = delta.IsFrozen;
                this.authTick       = delta.Tick;
            }

            // If there was a next state, update the next state
            bool canGetNext = (this.shouldBeFrozen == false);

            if (canGetNext && (next != null) && (next.IsFrozen == false))
            {
                this.NextStateBase.OverwriteFrom(this.AuthStateBase);
                this.NextStateBase.ApplyDelta(next);
                this.nextTick = next.Tick;
            }
            else
            {
                this.nextTick = Tick.INVALID;
            }
        }
示例#21
0
 public static Tick operator +(Tick a, uint b)
 {
     RailDebug.Assert(a.IsValid);
     return(new Tick(a.tickValue + b));
 }
示例#22
0
 public float ToTime(float tickDeltaTime)
 {
     RailDebug.Assert(this.IsValid);
     return((float)(this.tickValue - 1) * tickDeltaTime);
 }
示例#23
0
 public Tick GetNext()
 {
     RailDebug.Assert(this.IsValid);
     return(new Tick(this.tickValue + 1));
 }
示例#24
0
 public BitArray8 Store(int value)
 {
     RailDebug.Assert(value < LENGTH);
     return(new BitArray8((byte)(this.bitField | (1U << value))));
 }
示例#25
0
 public override int Compare(Tick x, Tick y)
 {
     RailDebug.Assert(x.IsValid);
     RailDebug.Assert(y.IsValid);
     return(TickComparer.Comparer.Compare(x.tickValue, y.tickValue));
 }
示例#26
0
 public BitArray64 Remove(int value)
 {
     RailDebug.Assert(value < LENGTH);
     return(new BitArray64((ulong)(this.bitField & ~(1UL << value))));
 }
示例#27
0
 public bool Equals(Tick x, Tick y)
 {
     RailDebug.Assert(x.IsValid);
     RailDebug.Assert(y.IsValid);
     return(x == y);
 }
示例#28
0
 public BitArray32 Remove(int value)
 {
     RailDebug.Assert(value < LENGTH);
     return(new BitArray32((uint)(this.bitField & ~(1U << value))));
 }
示例#29
0
 public int GetHashCode(Tick x)
 {
     RailDebug.Assert(x.IsValid);
     return(x.GetHashCode());
 }
示例#30
0
 public static bool operator >=(Tick a, Tick b)
 {
     RailDebug.Assert(a.IsValid && b.IsValid);
     return(a.tickValue >= b.tickValue);
 }