public IEnumerable <IPacket> UpdateBuffer(bool shouldCopy) { if (shouldCopy) { PacketBuffer.AddRange(NetworkBuffer); } Queue <byte[]> toProcess = new Queue <byte[]>(); toProcess.Enqueue(PacketBuffer.ToArray()); while (toProcess.Count > 0) { byte[] arr = toProcess.Dequeue(); using (StarboundStream s = new StarboundStream(arr)) { if (WorkingLength == long.MaxValue && s.Length > 1) { _packetId = s.ReadUInt8(); try { WorkingLength = s.ReadSignedVLQ(); } catch { WorkingLength = long.MaxValue; yield break; } DataIndex = (int)s.Position; Compressed = WorkingLength < 0; if (Compressed) { WorkingLength = -WorkingLength; } } if (WorkingLength != long.MaxValue) { if (s.Length >= WorkingLength + DataIndex) { if (s.Position != DataIndex) { s.Seek(DataIndex, SeekOrigin.Begin); } byte[] data = s.ReadUInt8Array((int)WorkingLength); if (Compressed) { data = ZlibStream.UncompressBuffer(data); } //todo Omit this after testing //SharpStarLogger.DefaultLogger.Info(string.Format("{0}{1}","ID : ",_packetId)); IPacket packet = Decode(_packetId, data); WorkingLength = long.MaxValue; byte[] rest = s.ReadToEnd(); PacketBuffer = rest.ToList(); if (rest.Length > 0) { toProcess.Enqueue(rest); } yield return(packet); } } } } }
public IStarboundPacket[] UpdateBuffer(int length) { if (length == 0) { throw new IOException("Client sent no data, connection is likely terminated."); } int index = PacketBuffer.Length; if (WorkingLength == long.MaxValue) { // We don't know the length of the packet yet, so keep going if (PacketBuffer.Length < index + length) { Array.Resize(ref PacketBuffer, index + length); } Array.Copy(NetworkBuffer, 0, PacketBuffer, index, length); if (PacketBuffer.Length > 1) { // Check to see if we have the entire length yet int i; for (i = 1; i < 5 && i < PacketBuffer.Length; i++) { if ((PacketBuffer[i] & 0x80) == 0) { WorkingLength = StarboundStream.ReadSignedVLQ(PacketBuffer, 1, out DataIndex); DataIndex++; Compressed = WorkingLength < 0; if (Compressed) { WorkingLength = -WorkingLength; } if (WorkingLength > MaxPacketLength) { throw new IOException("Packet exceeded maximum permissible length."); } break; } } if (i == 5) { throw new IOException("Packet exceeded maximum permissible length."); } } } if (WorkingLength != long.MaxValue) // This could be an else, but the earlier block can change the state and this needs to happen if it does { if (PacketBuffer.Length < index + length) { Array.Resize(ref PacketBuffer, index + length); } Array.Copy(NetworkBuffer, 0, PacketBuffer, index, length); if (PacketBuffer.Length >= WorkingLength + DataIndex) { // Ready to decode packet var data = new byte[WorkingLength]; Array.Copy(PacketBuffer, DataIndex, data, 0, WorkingLength); if (Compressed) { data = ZlibStream.UncompressBuffer(data); // TODO: Prevent compressed packets from exceeding MaxInflatedPacketLength } var packets = Decode(PacketBuffer[0], data); Array.Copy(PacketBuffer, DataIndex + WorkingLength, PacketBuffer, 0, PacketBuffer.Length - (DataIndex + WorkingLength)); Array.Resize(ref PacketBuffer, (int)(PacketBuffer.Length - (DataIndex + WorkingLength))); WorkingLength = long.MaxValue; return(packets); } } return(null); }
public static Entity FromStream(IStarboundStream stream) { EntityType et = (EntityType)stream.ReadUInt8(); byte[] storeData = stream.ReadUInt8Array(); Entity ent; if (et == EntityType.Projectile) { ProjectileEntity pent = new ProjectileEntity(); using (StarboundStream s = new StarboundStream(storeData)) { pent.Projectile = s.ReadString(); pent.Information = s.ReadVariant().Value as VariantDict; pent.Unknown1 = s.ReadUInt8Array(17); pent.ThrowerEntityId = s.ReadSignedVLQ(); pent.Unknown2 = s.ReadUInt8Array((int)(s.Length - s.Position)); } ent = pent; } else if (et == EntityType.Player) { PlayerEntity pent = new PlayerEntity(); using (StarboundStream s = new StarboundStream(storeData)) { /* * bool uuid = s.ReadBoolean(); * * if (uuid) * { */ byte[] uuidDat = s.ReadUInt8Array(16); pent.UUID = BitConverter.ToString(uuidDat, 0).Replace("-", "").ToLower(); //} } ent = pent; } else if (et == EntityType.Object) { ObjectEntity oent = new ObjectEntity(); using (StarboundStream s = new StarboundStream(storeData)) { oent.Object = s.ReadString(); oent.Information = s.ReadVariant(); oent.Unknown = s.ReadUInt8Array((int)(s.Length - s.Position)); } ent = oent; } else { ent = new Entity(); } ent.EntityType = et; ent.StoreData = storeData; ent.EntityId = stream.ReadSignedVLQ(); return(ent); }