/// <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); }
public static bool operator !=(SequenceId a, SequenceId b) { RailDebug.Assert(a.IsValid); RailDebug.Assert(b.IsValid); return(a.rawValue != b.rawValue); }
public static void Assert(bool condition, object message) { if (condition == false) { RailDebug.LogError("Assert Failed: " + message); } }
public static void Assert(bool condition) { if (condition == false) { RailDebug.LogError("Assert Failed!"); } }
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); }
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; }
public void Deallocate(T obj) { RailDebug.Assert(obj.Pool == this); obj.Reset(); obj.Pool = null; // Prevent multiple frees this.freeList.Push(obj); }
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); }
/// <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); }
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); }
/// <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); }
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); } }
/// <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); } } }
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)); }
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(); }
/// <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); }
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])); } }
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); }
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); }
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; } }
public static Tick operator +(Tick a, uint b) { RailDebug.Assert(a.IsValid); return(new Tick(a.tickValue + b)); }
public float ToTime(float tickDeltaTime) { RailDebug.Assert(this.IsValid); return((float)(this.tickValue - 1) * tickDeltaTime); }
public Tick GetNext() { RailDebug.Assert(this.IsValid); return(new Tick(this.tickValue + 1)); }
public BitArray8 Store(int value) { RailDebug.Assert(value < LENGTH); return(new BitArray8((byte)(this.bitField | (1U << value)))); }
public override int Compare(Tick x, Tick y) { RailDebug.Assert(x.IsValid); RailDebug.Assert(y.IsValid); return(TickComparer.Comparer.Compare(x.tickValue, y.tickValue)); }
public BitArray64 Remove(int value) { RailDebug.Assert(value < LENGTH); return(new BitArray64((ulong)(this.bitField & ~(1UL << value)))); }
public bool Equals(Tick x, Tick y) { RailDebug.Assert(x.IsValid); RailDebug.Assert(y.IsValid); return(x == y); }
public BitArray32 Remove(int value) { RailDebug.Assert(value < LENGTH); return(new BitArray32((uint)(this.bitField & ~(1U << value)))); }
public int GetHashCode(Tick x) { RailDebug.Assert(x.IsValid); return(x.GetHashCode()); }
public static bool operator >=(Tick a, Tick b) { RailDebug.Assert(a.IsValid && b.IsValid); return(a.tickValue >= b.tickValue); }