Exemple #1
0
        public static int operator +(Tick a, Tick b)
        {
            RailDebug.Assert(a.IsValid && b.IsValid);
            long sum = a.tickValue + (long)b.tickValue;

            return((int)sum);
        }
Exemple #2
0
        public static int operator -(Tick a, Tick b)
        {
            RailDebug.Assert(a.IsValid && b.IsValid);
            long difference = a.tickValue - (long)b.tickValue;

            return((int)difference);
        }
Exemple #3
0
        public static bool operator !=(SequenceId a, SequenceId b)
        {
            RailDebug.Assert(a.IsValid);
            RailDebug.Assert(b.IsValid);

            return(a.rawValue != b.rawValue);
        }
Exemple #4
0
        /// <summary>
        ///     Returns true iff we stored the delta.
        /// </summary>
        public bool ProcessDelta(RailStateDelta delta)
        {
            if (knownEntities.TryGetValue(delta.EntityId, out RailEntityClient entity) == false)
            {
                RailDebug.Assert(delta.IsFrozen == false, "Frozen unknown entity");
                if (delta.IsFrozen || delta.IsRemoving)
                {
                    return(false);
                }

                entity = delta.ProduceEntity(Resource) as RailEntityClient;
                if (entity == null)
                {
                    throw new TypeAccessException(
                              "Got unexpected instance from RailResource. Internal error in type RailRegistry and/or RailResource.");
                }

                entity.AssignId(delta.EntityId);
                entity.PrimeState(delta);
                pendingEntities.Add(entity.Id, entity);
                knownEntities.Add(entity.Id, entity);
            }

            // If we're already removing the entity, we don't care about other deltas
            bool stored = false;

            if (entity.IsRemoving == false)
            {
                stored = entity.ReceiveDelta(delta);
            }
            return(stored);
        }
Exemple #5
0
        /// <summary>
        ///     Remove an entity from being controlled by this peer.
        /// </summary>
        public void RevokeControlInternal(RailEntityBase entity)
        {
            RailDebug.Assert(entity.Controller == this);

            controlledEntities.Remove(entity);
            entity.AssignController(null);
        }
Exemple #6
0
        public void Deallocate(T instance)
        {
            RailDebug.Assert(instance.Pool == this);

            instance.Reset();
            instance.Pool = null; // Prevent multiple frees
            freeList.Push(instance);
        }
Exemple #7
0
        public void SendPacket(RailResource resource, IRailNetPeer peer, RailPacketOutgoing packet)
        {
            bitBuffer.Clear();
            packet.Encode(resource, bitBuffer);
            int length = bitBuffer.Store(bytes);

            RailDebug.Assert(length <= RailConfig.PACKCAP_MESSAGE_TOTAL);
            peer.SendPayload(new ArraySegment <byte>(bytes, 0, length));
        }
Exemple #8
0
        private static int GetDifference(SequenceId a, SequenceId b)
        {
            RailDebug.Assert(a.IsValid);
            RailDebug.Assert(b.IsValid);

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

            return(difference);
        }
Exemple #9
0
        /// <summary>
        ///     Adds an entity to be controlled by this peer.
        /// </summary>
        public void GrantControlInternal(RailEntityBase entity)
        {
            if (entity.Controller == this)
            {
                return;
            }
            RailDebug.Assert(entity.Controller == null);

            controlledEntities.Add(entity);
            entity.AssignController(this);
        }
Exemple #10
0
 /// <summary>
 ///     Queues an event to broadcast to the server with a number of retries.
 /// </summary>
 public void RaiseEvent <T>(Action <T> initializer, ushort attempts = 3)
     where T : RailEvent
 {
     RailDebug.Assert(client.ServerPeer != null);
     if (client.ServerPeer != null)
     {
         T evnt = eventCreator.CreateEvent <T>();
         initializer(evnt);
         client.ServerPeer.SendEvent(evnt, attempts, false);
     }
 }
Exemple #11
0
        private static void EncodeHeader(RailPacketOutgoing packet, RailBitBuffer buffer)
        {
            RailDebug.Assert(packet.SenderTick.IsValid);

            // Write: [LocalTick]
            buffer.WriteTick(packet.SenderTick);

            // Write: [LastAckTick]
            buffer.WriteTick(packet.LastAckTick);

            // Write: [AckReliableEventId]
            buffer.WriteSequenceId(packet.LastAckEventId);
        }
Exemple #12
0
        /// <summary>
        ///     Selects outgoing events to send.
        /// </summary>
        private IEnumerable <RailEvent> FilterOutgoingEvents()
        {
            // The receiving client can only store a limited size sequence history
            // of 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 an
            // event with attempts remaining, we will throttle the outgoing events
            // if we've been sending them too fast. For example, if we have a live
            // event with ID 3 pending, and a maximum history length of 64 (see
            // RailConfig.HISTORY_CHUNKS) then the highest ID we can send would be
            // ID 67. Were we to 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 still live.
            //
            // 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. You can always increase
            // the number of history chunks if this becomes an issue.

            SequenceId firstId = SequenceId.Invalid;

            foreach (RailEvent evnt in outgoingEvents)
            {
                // Ignore dead events, they'll be cleaned up eventually
                if (evnt.Attempts <= 0)
                {
                    continue;
                }

                // Don't send an event if it's out of scope for this peer
                if (Scope != null && Scope.Includes(evnt) == false)
                {
                    // Skipping due to out of scope counts as an attempt
                    evnt.RegisterSkip();
                    continue;
                }

                if (firstId.IsValid == false)
                {
                    firstId = evnt.EventId;
                }
                RailDebug.Assert(firstId <= evnt.EventId);

                if (eventHistory.AreInRange(firstId, evnt.EventId) == false)
                {
                    RailDebug.LogWarning("Throttling events due to lack of ack");
                    break;
                }

                yield return(evnt);
            }
        }
Exemple #13
0
        public void Overwrite(IRailStateConstruction stateCreator, Tick tick, RailState state)
        {
            RailDebug.Assert(tick.IsValid);

            this.tick = tick;
            if (this.state == null)
            {
                this.state = state.Clone(stateCreator);
            }
            else
            {
                this.state.OverwriteFrom(state);
            }
        }
Exemple #14
0
        public void Overwrite(
            Tick tick,
            RailState state)
        {
            RailDebug.Assert(tick.IsValid);

            this.tick = tick;
            if (this.state == null)
            {
                this.state = state.Clone();
            }
            else
            {
                this.state.OverwriteFrom(state);
            }
        }
Exemple #15
0
        public void WriteString(string value)
        {
            if (value == null)
            {
                throw new ArgumentNullException(nameof(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;
            }

            Write(STRING_LENGTH_BITS, length);
            for (int i = 0; i < length; i++)
            {
                Write(ASCII_BITS, ToASCII(value[i]));
            }
        }
Exemple #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
            Write(1, 1);

            int numChunks = (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   = 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(ByteSize);
        }
Exemple #17
0
        /// <summary>
        ///     Sets the current server peer.
        /// </summary>
        public void SetPeer(IRailNetPeer netPeer)
        {
            if (netPeer == null)
            {
                if (ServerPeer != null)
                {
                    ServerPeer.PacketReceived -= OnPacketReceived;
                    ServerPeer.EventReceived  -= OnEventReceived;
                    Disconnected?.Invoke(ServerPeer);
                }

                ServerPeer = null;
            }
            else
            {
                RailDebug.Assert(ServerPeer == null, "Overwriting peer");
                ServerPeer = new RailClientPeer(Resource, netPeer, Interpreter);
                ServerPeer.PacketReceived += OnPacketReceived;
                ServerPeer.EventReceived  += OnEventReceived;
                Connected?.Invoke(ServerPeer);
            }
        }
Exemple #18
0
 public bool Equals(Tick x, Tick y)
 {
     RailDebug.Assert(x.IsValid);
     RailDebug.Assert(y.IsValid);
     return(x == y);
 }
Exemple #19
0
 public Tick GetNext()
 {
     RailDebug.Assert(IsValid);
     return(new Tick(tickValue + 1));
 }
Exemple #20
0
 public float ToTime(float tickDeltaTime)
 {
     RailDebug.Assert(IsValid);
     return((tickValue - 1) * tickDeltaTime);
 }
Exemple #21
0
 public static Tick operator +(Tick a, uint b)
 {
     RailDebug.Assert(a.IsValid);
     return(new Tick(a.tickValue + b));
 }
Exemple #22
0
 public SequenceWindow(SequenceId latest)
 {
     RailDebug.Assert(latest.IsValid);
     this.latest       = latest;
     this.historyArray = new BitArray64();
 }
Exemple #23
0
 public static bool operator >=(Tick a, Tick b)
 {
     RailDebug.Assert(a.IsValid && b.IsValid);
     return(a.tickValue >= b.tickValue);
 }
Exemple #24
0
 public override int Compare(Tick x, Tick y)
 {
     RailDebug.Assert(x.IsValid);
     RailDebug.Assert(y.IsValid);
     return(comparer.Compare(x.tickValue, y.tickValue));
 }
Exemple #25
0
 public int GetHashCode(Tick x)
 {
     RailDebug.Assert(x.IsValid);
     return(x.GetHashCode());
 }
Exemple #26
0
        public static SequenceId operator ++(SequenceId a)
        {
            RailDebug.Assert(a.IsValid);

            return(a.Next);
        }
Exemple #27
0
 public BitArray8 Store(int value)
 {
     RailDebug.Assert(value < LENGTH);
     return(new BitArray8((byte)(bitField | (1U << value))));
 }
Exemple #28
0
 public virtual void Removed()
 {
     RailDebug.Assert(HasStarted);
     OnRemoved();
 }
Exemple #29
0
 public static SequenceId operator -(SequenceId a, int b)
 {
     RailDebug.Assert(a.IsValid);
     return(new SequenceId((uint)WrapValue((int)a.rawValue - b)));
 }
Exemple #30
0
 private SequenceWindow(SequenceId latest, BitArray64 history)
 {
     RailDebug.Assert(latest.IsValid);
     this.latest       = latest;
     this.historyArray = history;
 }