/************************************************************************* * ModernUO * * Copyright (C) 2019-2020 - ModernUO Development Team * * Email: hi@modernuo.com * * File: BinaryFileReader.cs * * * * This program is free software: you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation, either version 3 of the License, or * * (at your option) any later version. * * * * You should have received a copy of the GNU General Public License * * along with this program. If not, see . * *************************************************************************/ using System; using System.Collections.Generic; using System.IO; using System.Net; using Server.Guilds; namespace Server { public sealed class BinaryFileReader : IGenericReader { private readonly BinaryReader m_File; public BinaryFileReader(BinaryReader br) => m_File = br; public long Position => m_File.BaseStream.Position; public string ReadString() => ReadByte() != 0 ? m_File.ReadString() : null; public DateTime ReadDeltaTime() { var ticks = m_File.ReadInt64(); var now = DateTime.UtcNow.Ticks; if (ticks > 0 && ticks + now < 0) return DateTime.MaxValue; if (ticks < 0 && ticks + now < 0) return DateTime.MinValue; try { return new DateTime(now + ticks); } catch { return ticks > 0 ? DateTime.MaxValue : DateTime.MinValue; } } public IPAddress ReadIPAddress() => new IPAddress(m_File.ReadInt64()); public int ReadEncodedInt() { int v = 0, shift = 0; byte b; do { b = m_File.ReadByte(); v |= (b & 0x7F) << shift; shift += 7; } while (b >= 0x80); return v; } public DateTime ReadDateTime() => new DateTime(m_File.ReadInt64()); public DateTimeOffset ReadDateTimeOffset() { var ticks = m_File.ReadInt64(); var offset = new TimeSpan(m_File.ReadInt64()); return new DateTimeOffset(ticks, offset); } public TimeSpan ReadTimeSpan() => new TimeSpan(m_File.ReadInt64()); public decimal ReadDecimal() => m_File.ReadDecimal(); public long ReadLong() => m_File.ReadInt64(); public ulong ReadULong() => m_File.ReadUInt64(); public int ReadInt() => m_File.ReadInt32(); public uint ReadUInt() => m_File.ReadUInt32(); public short ReadShort() => m_File.ReadInt16(); public ushort ReadUShort() => m_File.ReadUInt16(); public double ReadDouble() => m_File.ReadDouble(); public float ReadFloat() => m_File.ReadSingle(); public char ReadChar() => m_File.ReadChar(); public byte ReadByte() => m_File.ReadByte(); public sbyte ReadSByte() => m_File.ReadSByte(); public bool ReadBool() => m_File.ReadBoolean(); public Point3D ReadPoint3D() => new Point3D(ReadInt(), ReadInt(), ReadInt()); public Point2D ReadPoint2D() => new Point2D(ReadInt(), ReadInt()); public Rectangle2D ReadRect2D() => new Rectangle2D(ReadPoint2D(), ReadPoint2D()); public Rectangle3D ReadRect3D() => new Rectangle3D(ReadPoint3D(), ReadPoint3D()); public Map ReadMap() => Map.Maps[ReadByte()]; public IEntity ReadEntity() { Serial serial = ReadUInt(); return World.FindEntity(serial) ?? new Entity(serial, new Point3D(0, 0, 0), Map.Internal); } public Item ReadItem() => World.FindItem(ReadUInt()); public Mobile ReadMobile() => World.FindMobile(ReadUInt()); public BaseGuild ReadGuild() => BaseGuild.Find(ReadUInt()); public T ReadItem() where T : Item => ReadItem() as T; public T ReadMobile() where T : Mobile => ReadMobile() as T; public T ReadGuild() where T : BaseGuild => ReadGuild() as T; public List ReadStrongItemList() => ReadStrongItemList(); public List ReadStrongItemList() where T : Item { var count = ReadInt(); if (count > 0) { var list = new List(count); for (var i = 0; i < count; ++i) if (ReadItem() is T item) list.Add(item); return list; } return new List(); } public HashSet ReadItemSet() => ReadItemSet(); public HashSet ReadItemSet() where T : Item { var count = ReadInt(); if (count > 0) { var set = new HashSet(); for (var i = 0; i < count; ++i) if (ReadItem() is T item) set.Add(item); return set; } return new HashSet(); } public List ReadStrongMobileList() => ReadStrongMobileList(); public List ReadStrongMobileList() where T : Mobile { var count = ReadInt(); if (count > 0) { var list = new List(count); for (var i = 0; i < count; ++i) if (ReadMobile() is T m) list.Add(m); return list; } return new List(); } public HashSet ReadMobileSet() => ReadMobileSet(); public HashSet ReadMobileSet() where T : Mobile { var count = ReadInt(); if (count > 0) { var set = new HashSet(); for (var i = 0; i < count; ++i) if (ReadMobile() is T item) set.Add(item); return set; } return new HashSet(); } public List ReadStrongGuildList() => ReadStrongGuildList(); public List ReadStrongGuildList() where T : BaseGuild { var count = ReadInt(); if (count > 0) { var list = new List(count); for (var i = 0; i < count; ++i) if (ReadGuild() is T g) list.Add(g); return list; } return new List(); } public HashSet ReadGuildSet() => ReadGuildSet(); public HashSet ReadGuildSet() where T : BaseGuild { var count = ReadInt(); if (count > 0) { var set = new HashSet(); for (var i = 0; i < count; ++i) if (ReadGuild() is T item) set.Add(item); return set; } return new HashSet(); } public Race ReadRace() => Race.Races[ReadByte()]; public bool End() => m_File.PeekChar() == -1; public void Close() { m_File.Close(); } public long Seek(long offset, SeekOrigin origin) => m_File.BaseStream.Seek(offset, origin); } }