internal static DataCenterAddress ReadAddress(GameBinaryReader reader) { var segment = reader.ReadUInt16(); var element = reader.ReadUInt16(); return(new DataCenterAddress(segment, element)); }
internal static PacketHeader ReadHeader(byte[] buffer) { using var reader = new GameBinaryReader(buffer); var length = (ushort)(reader.ReadUInt16() - PacketHeader.HeaderSize); var code = reader.ReadUInt16(); return(new PacketHeader(length, code)); }
static PacketHeader ReadHeader(GameBinaryReader reader) { reader.Position = 0; var length = (ushort)(reader.ReadUInt16() - PacketHeader.HeaderSize); var code = reader.ReadUInt16(); return(new PacketHeader(length, code)); }
public PacketLogEntry Read() { if (_disposed) { throw new ObjectDisposedException(GetType().FullName); } try { var time = _reader.ReadInt64(); DateTime stamp; try { stamp = DateTimeOffset.FromUnixTimeMilliseconds(time).LocalDateTime; } catch (ArgumentOutOfRangeException) { throw new InvalidDataException($"Invalid timestamp value {time}."); } var id = _reader.ReadInt32(); if (!Servers.ContainsKey(id)) { throw new InvalidDataException($"Invalid server ID {id}."); } var direction = (Direction)_reader.ReadByte(); if (!Enum.IsDefined(typeof(Direction), direction)) { throw new InvalidDataException($"Unknown direction value {direction}."); } var code = _reader.ReadUInt16(); if (!GameMessages.CodeToName.ContainsKey(code)) { throw new InvalidDataException($"Unknown message code {code}."); } var length = _reader.ReadUInt16(); var payload = _reader.ReadBytes(length); return(new PacketLogEntry(stamp, id, direction, code, payload)); } catch (EndOfStreamException) { return(null); } }
public PacketLogReader(string fileName) { Stream stream = File.OpenRead(fileName); using var reader = new GameBinaryReader(stream, true); if (!reader.ReadBytes(PacketLogEntry.Magic.Count).SequenceEqual(PacketLogEntry.Magic)) { throw new InvalidDataException("Invalid magic number."); } Version = reader.ReadUInt32(); if (Version != PacketLogEntry.Version) { throw new InvalidDataException($"Unknown format version {Version}."); } Region = (Region)reader.ReadByte(); if (!Enum.IsDefined(typeof(Region), Region)) { throw new InvalidDataException($"Unknown region value {Region}."); } var clientVersion = reader.ReadUInt32(); if (!DataCenter.ClientVersions.Values.Contains(clientVersion)) { throw new InvalidDataException($"Unknown client version {clientVersion}."); } GameMessages = new GameMessageTable(clientVersion); SystemMessages = new SystemMessageTable(clientVersion); var serverCount = (int)reader.ReadUInt32(); var servers = new Dictionary <int, ServerInfo>(serverCount); for (var i = 0; i < serverCount; i++) { var id = reader.ReadInt32(); if (servers.ContainsKey(id)) { throw new InvalidDataException($"Duplicate server ID {id}."); } var name = reader.ReadString(); var size = reader.ReadBoolean() ? 16 : 4; var realIPBytes = reader.ReadBytes(size); var realPort = reader.ReadUInt16(); var proxyIPBytes = reader.ReadBytes(size); var proxyPort = reader.ReadUInt16(); IPEndPoint realEP; try { realEP = new IPEndPoint(new IPAddress(realIPBytes), realPort); } catch (ArgumentOutOfRangeException) { throw new InvalidDataException($"Invalid real port {realPort}."); } catch (ArgumentException) { throw new InvalidDataException("Invalid real IP address."); } IPEndPoint proxyEP; try { proxyEP = new IPEndPoint(new IPAddress(proxyIPBytes), proxyPort); } catch (ArgumentOutOfRangeException) { throw new InvalidDataException($"Invalid proxy port {proxyPort}."); } catch (ArgumentException) { throw new InvalidDataException("Invalid proxy IP address."); } servers.Add(id, new ServerInfo(id, name, realEP, proxyEP)); } Servers = servers; CompressionLevel = reader.ReadByte(); _reader = new GameBinaryReader(CompressionLevel != 0 ? new FastDeflateStream(stream, CompressionMode.Decompress) : stream); }
void DeserializeObject(GameBinaryReader reader, object target) { foreach (var info in GetPacketInfo(target.GetType()).Fields.Cast <ReflectionPacketFieldInfo>()) { if (info.IsByteArray) { var offset = reader.ReadOffset(); var count = reader.ReadUInt16(); var list = (List <byte>)info.Property.GetValue(target); list.Clear(); if (count == 0) { continue; } reader.Seek(offset, (r, op) => list.AddRange(r.ReadBytes(count))); } else if (info.IsArray) { var count = reader.ReadUInt16(); var offset = reader.ReadOffset(); var list = (IList)info.Property.GetValue(target); list.Clear(); if (count == 0) { continue; } var next = offset; for (var i = 0; i < count; i++) { reader.Seek(next, (r, op) => { r.ReadOffset(); next = r.ReadOffset(); var elem = info.ElementConstructor(); DeserializeObject(r, elem); list.Add(elem); }); } } else if (info.IsString) { var offset = reader.ReadOffset(); info.Property.SetValue(target, reader.Seek(offset, (r, op) => r.ReadString())); } else { var val = info.PrimitiveDeserializer(reader); info.EnumValidator?.Invoke(val); info.Property.SetValue(target, val); } } }
public static IEnumerable <PotentialArray> FindArrays(ReadOnlyMemory <byte> payload) { using var reader = new GameBinaryReader(payload.GetArray()); for (var i = 0; i < reader.Length; i++) { reader.Position = i; if (!reader.CanRead(sizeof(ushort) * 2)) { break; } var countPos = reader.Position; var count = reader.ReadUInt16(); var offsetPos = reader.Position; var offset = reader.ReadOffset(); if (count == 0 || (count * (sizeof(ushort) * 2 + sizeof(byte)) + sizeof(ushort) * 2) > reader.Length) { continue; } var positions = new HashSet <int> { countPos, countPos + sizeof(byte), offsetPos, offsetPos + sizeof(byte), }; var elems = new List <PotentialArrayElement>(); var good = true; var last = offsetPos; var next = offset; while (next != -PacketHeader.HeaderSize) { if (!(good = next >= 0 && next > last && next <= reader.Length - sizeof(ushort) * 2 - sizeof(byte))) { break; } last = next + sizeof(ushort) * 2; reader.Position = next; var herePos = reader.Position; var here = reader.ReadOffset(); if (!(good = here == herePos && here == next && positions.Add(herePos) && positions.Add(herePos + sizeof(byte)))) { break; } var nextPos = reader.Position; next = reader.ReadOffset(); if (!(good = positions.Add(nextPos) && positions.Add(nextPos + sizeof(byte)))) { break; } elems.Add(new PotentialArrayElement(here, nextPos, next == -PacketHeader.HeaderSize ? 0 : next)); } if (good && elems.Count == count) { yield return(new PotentialArray(countPos, count, offsetPos, offset, elems)); } } }
public PacketLogReader(string fileName) { Stream stream = File.OpenRead(fileName); var magic = new byte[PacketLogEntry.Magic.Count]; if (stream.Read(magic, 0, magic.Length) != magic.Length) { throw new EndOfStreamException(); } if (!magic.SequenceEqual(PacketLogEntry.Magic)) { throw new InvalidDataException(); } var level = stream.ReadByte(); if (level == -1) { throw new EndOfStreamException(); } if ((CompressionLevel = (byte)level) != 0) { stream = new DeflateStream(stream, CompressionMode.Decompress); } _reader = new GameBinaryReader(stream); Version = _reader.ReadUInt32(); if (Version != PacketLogEntry.Version) { throw new InvalidDataException(); } Region = (Region)_reader.ReadByte(); if (!Enum.IsDefined(typeof(Region), Region)) { throw new InvalidDataException(); } var clientVersion = _reader.ReadUInt32(); if (!DataCenter.Versions.Values.Contains(clientVersion)) { throw new InvalidDataException(); } GameMessages = new GameMessageTable(clientVersion); SystemMessages = new SystemMessageTable(clientVersion); var serverCount = (int)_reader.ReadUInt32(); if (serverCount < 0) { throw new InvalidDataException(); } var servers = new Dictionary <int, ServerInfo>(serverCount); for (var i = 0; i < serverCount; i++) { var id = _reader.ReadInt32(); if (servers.ContainsKey(id)) { throw new InvalidDataException(); } var name = _reader.ReadString(); var size = _reader.ReadBoolean() ? 16 : 4; var realIPBytes = _reader.ReadBytes(size); var realPort = _reader.ReadUInt16(); var proxyIPBytes = _reader.ReadBytes(size); var proxyPort = _reader.ReadUInt16(); IPEndPoint realEP; IPEndPoint proxyEP; try { realEP = new IPEndPoint(new IPAddress(realIPBytes), realPort); proxyEP = new IPEndPoint(new IPAddress(proxyIPBytes), proxyPort); } catch (ArgumentException) { throw new InvalidDataException(); } servers.Add(id, new ServerInfo(id, name, realEP, proxyEP)); } Servers = servers; }