Exemplo n.º 1
0
 public void Read(BinaryReaderBE Reader)
 {
     Magic    = Reader.ReadBytes(16);
     ServerId = Reader.ReadBytes(8);
     Security = Reader.ReadByte();
     MTU      = Reader.ReadUInt16BE();
 }
Exemplo n.º 2
0
 public void Read(BinaryReaderBE Reader)
 {
     Magic = Reader.ReadBytes(16);
     Address.Read(Reader);
     MTU      = Reader.ReadUInt16BE();
     ClientId = Reader.ReadBytes(8);
 }
Exemplo n.º 3
0
        public void Parse()
        {
            FileStream Stream = File.OpenRead(Path);

            using (BinaryReaderBE Reader = new BinaryReaderBE(Stream))
            {
                bool IsCorrectEndian = Reader.ReadUInt32() == 0x80371240;

                if (!IsCorrectEndian)
                {
                    Reader.Dispose();
                    Stream.Dispose();
                    return;
                }

                Stream.Position       = 0x08;
                Header.ProgramCounter = BitConverter.ToUInt32(Reader.ReadBytes(8), 0);

                Stream.Position = 0x20;
                Header.Name     = System.Text.Encoding.Default.GetString(Reader.ReadBytes(20));

                Stream.Position = 0x0;
                using (MemoryStream ms = new MemoryStream())
                {
                    Stream.CopyTo(ms);
                    AllData = ms.ToArray();
                }

                HasBeenParsed = true;
            }

            Stream.Dispose();
        }
Exemplo n.º 4
0
        public virtual void Load(string filename)
        {
            BinaryReaderBE reader = new BinaryReaderBE(File.Open(filename, FileMode.Open));

            try
            {
                // is it MacBinary?
                int fork_start = 0;
                if (MacBinaryHeader(reader.ReadBytes(128)))
                {
                    fork_start = 128;
                }
                reader.BaseStream.Seek(fork_start, SeekOrigin.Begin);

                // read the header
                version         = reader.ReadInt16();
                DataVersion     = reader.ReadInt16();
                Filename        = reader.ReadMacString(maxFilename);
                checksum        = reader.ReadUInt32();
                directoryOffset = reader.ReadInt32();
                short wadCount = reader.ReadInt16();
                applicationSpecificDirectoryDataSize = reader.ReadInt16();
                entryHeaderSize = reader.ReadInt16();

                directoryEntryBaseSize = reader.ReadInt16();

                // sanity check the map
                if (Version < 2 || entryHeaderSize != 16 || directoryEntryBaseSize != 10)
                {
                    throw new BadMapException("Only Marathon 2 and higher maps are supported");
                }

                ParentChecksum = reader.ReadUInt32();
                reader.ReadBytes(2 * 20); // unused

                // load the directory
                reader.BaseStream.Seek(directoryOffset + fork_start, SeekOrigin.Begin);
                for (int i = 0; i < wadCount; ++i)
                {
                    DirectoryEntry entry = new DirectoryEntry();
                    entry.LoadEntry(reader);
                    Directory[entry.Index] = entry;

                    LoadApplicationSpecificDirectoryData(reader, entry.Index);
                }

                // load all the wads(!)
                foreach (KeyValuePair <int, DirectoryEntry> kvp in Directory)
                {
                    reader.BaseStream.Seek(kvp.Value.Offset + fork_start, SeekOrigin.Begin);
                    kvp.Value.LoadChunks(reader);
                }
            }
            finally
            {
                reader.Close();
            }
        }
Exemplo n.º 5
0
        /// <summary>
        /// Gets the list of Weather UI elements
        /// </summary>
        /// <returns>A list containing XivUi data</returns>
        public async Task <List <XivUi> > GetWeatherList()
        {
            var weatherLock = new object();
            var weatherList = new List <XivUi>();

            // These are the offsets to relevant data
            // These will need to be changed if data gets added or removed with a patch
            const int nameLengthOffset = 6;
            const int iconNumberOffset = 26;

            var weatherExData = await _ex.ReadExData(XivEx.weather);

            var weatherNames = new List <string>();

            await Task.Run(() => Parallel.ForEach(weatherExData.Values, (weather) =>
            {
                var xivUi = new XivUi()
                {
                    PrimaryCategory   = "UI",
                    SecondaryCategory = XivStrings.Weather
                };

                // Big Endian Byte Order
                using (var br = new BinaryReaderBE(new MemoryStream(weather)))
                {
                    br.BaseStream.Seek(nameLengthOffset, SeekOrigin.Begin);

                    var nameLength = br.ReadInt16();

                    br.BaseStream.Seek(iconNumberOffset, SeekOrigin.Begin);

                    var iconNumber = br.ReadUInt16();

                    if (iconNumber == 0)
                    {
                        return;
                    }

                    var name = Encoding.UTF8.GetString(br.ReadBytes(nameLength)).Replace("\0", "");

                    xivUi.IconNumber = iconNumber;
                    xivUi.Name       = name;
                }

                if (weatherNames.Contains(xivUi.Name))
                {
                    return;
                }

                lock (weatherLock)
                {
                    weatherNames.Add(xivUi.Name);
                    weatherList.Add(xivUi);
                }
            }));

            weatherList.Sort();

            return(weatherList);
        }
Exemplo n.º 6
0
 public void Read(BinaryReaderBE Reader)
 {
     ClientId = Reader.ReadBytes(8);
     Reader.ReadUInt32(); // Unknown
     Time     = Reader.ReadUInt32BE();
     Security = Reader.ReadByte();
 }
Exemplo n.º 7
0
        /// <summary>
        /// Reads and parses the ExHeader file
        /// </summary>
        /// <param name="exFile">The Ex file to use.</param>
        private void ReadExHeader(XivEx exFile)
        {
            OffsetTypeDict = new Dictionary <int, int>();
            PageList       = new List <int>();
            LanguageList   = new List <int>();

            var exdFolderHash = HashGenerator.GetHash("exd");
            var exdFileHash   = HashGenerator.GetHash(exFile + ExhExtension);

            var index = new Index(_gameDirectory);
            var dat   = new Dat(_gameDirectory);

            var offset = index.GetDataOffset(exdFolderHash, exdFileHash, XivDataFile._0A_Exd);

            if (offset == 0)
            {
                throw new Exception($"Could not find offest for exd/{exFile}{ExhExtension}");
            }

            var exhData = dat.GetType2Data(offset, XivDataFile._0A_Exd);

            // Big Endian Byte Order
            using (var br = new BinaryReaderBE(new MemoryStream(exhData)))
            {
                var signature      = br.ReadInt32();
                var version        = br.ReadInt16();
                var dataSetChunk   = br.ReadInt16();
                var dataSetCount   = br.ReadInt16();
                var pageTableCount = br.ReadInt16();
                var langTableCount = br.ReadInt16();
                var unknown        = br.ReadInt16();
                var unknown1       = br.ReadInt32();
                var entryCount     = br.ReadInt32();
                br.ReadBytes(8);

                for (var i = 0; i < dataSetCount; i++)
                {
                    var dataType   = br.ReadInt16();
                    var dataOffset = br.ReadInt16();

                    if (!OffsetTypeDict.ContainsKey(dataOffset))
                    {
                        OffsetTypeDict.Add(dataOffset, dataType);
                    }
                }

                for (var i = 0; i < pageTableCount; i++)
                {
                    var pageNumber = br.ReadInt32();
                    var pageSize   = br.ReadInt32();
                    PageList.Add(pageNumber);
                }

                for (var i = 0; i < langTableCount; i++)
                {
                    var langCode = br.ReadInt16();
                    LanguageList.Add(langCode);
                }
            }
        }
Exemplo n.º 8
0
        private static String ReadString(BinaryReaderBE Reader)
        {
            var length   = Reader.ReadInt32();
            var strBytes = Reader.ReadBytes(length);

            return(Encoding.UTF8.GetString(strBytes));
        }
Exemplo n.º 9
0
        public QHFReader(string path)
        {
            fs = new FileStream(path, FileMode.Open);
            br = new BinaryReaderBE(fs, encoding);

            fs.Position = 4;
            Size        = br.ReadInt32();
            fs.Position = 34;
            MsgCount    = br.ReadInt32();
            fs.Position = 44;
            Int16 uinLength = br.ReadInt16();

            Uin = encoding.GetString(br.ReadBytes(uinLength));
            Int16 nickLength = br.ReadInt16();

            Nick = encoding.GetString(br.ReadBytes(nickLength));
        }
Exemplo n.º 10
0
        static void Main(string[] args)
        {
            City city = new City();

            string filename = args.Length > 0 ? args[0] : "test.sc2";

#if DEBUG
            // dumb and bad.
            filename = string.Concat("../../../cities/", filename);
#endif

            var rawStream = new MemoryStream();
            using (var fs = File.OpenRead(filename))
            {
                fs.CopyTo(rawStream);
                rawStream.Position = 0;
            }

            var reader = new BinaryReaderBE(rawStream);

            var iffType = Encoding.ASCII.GetString(reader.ReadBytes(4));
            if (iffType != "FORM")
            {
                throw new InvalidDataException(string.Format("Incorrect IFF type: {0}, expected FORM", iffType));
            }

            var filesize = reader.ReadInt32();
            if (filesize + 8 != reader.BaseStream.Length)
            {
                throw new InvalidDataException(string.Format("Incorrect filesize: {0}, expected {1}", filesize, reader.BaseStream.Length - 8));
            }

            var container = Encoding.ASCII.GetString(reader.ReadBytes(4));
            if (container != "SCDH")
            {
                throw new InvalidDataException(string.Format("Incorrect container: {0}, expected SCDH", container));
            }

            while (reader.BaseStream.Position < reader.BaseStream.Length)
            {
                ParseChunk(city, reader);
            }

            Console.WriteLine("City name: {0}", city.name);
            Console.WriteLine("Building count: {0}", buildingCount);
        }
Exemplo n.º 11
0
        /// <summary>
        /// Gets the list of Weather UI elements
        /// </summary>
        /// <returns>A list containing XivUi data</returns>
        public List <XivUi> GetWeatherList()
        {
            var weatherList = new List <XivUi>();

            // These are the offsets to relevant data
            // These will need to be changed if data gets added or removed with a patch
            const int nameLengthOffset = 6;
            const int iconNumberOffest = 26;

            var ex            = new Ex(_gameDirectory, _xivLanguage);
            var weatherExData = ex.ReadExData(XivEx.weather);

            var weatherNames = new List <string>();

            foreach (var weather in weatherExData.Values)
            {
                var xivUi = new XivUi()
                {
                    Category     = "UI",
                    ItemCategory = XivStrings.Weather
                };

                // Big Endian Byte Order
                using (var br = new BinaryReaderBE(new MemoryStream(weather)))
                {
                    br.BaseStream.Seek(nameLengthOffset, SeekOrigin.Begin);

                    var nameLength = br.ReadInt16();

                    br.BaseStream.Seek(iconNumberOffest, SeekOrigin.Begin);

                    var iconNumber = br.ReadUInt16();

                    if (iconNumber == 0)
                    {
                        continue;
                    }

                    var name = Encoding.UTF8.GetString(br.ReadBytes(nameLength)).Replace("\0", "");

                    xivUi.IconNumber = iconNumber;
                    xivUi.Name       = name;
                }

                if (weatherNames.Contains(xivUi.Name))
                {
                    continue;
                }
                weatherNames.Add(xivUi.Name);

                weatherList.Add(xivUi);
            }

            weatherList.Sort();

            return(weatherList);
        }
Exemplo n.º 12
0
        public void Load(BinaryReaderBE reader)
        {
            long start = (int)reader.BaseStream.Position;

            TotalLength     = reader.ReadInt16();
            Flags           = reader.ReadInt16();
            LinesPerPage    = reader.ReadInt16();
            GroupingCount   = reader.ReadInt16();
            FontChangeCount = reader.ReadInt16();

            Groupings   = new List <Grouping>();
            FontChanges = new List <FontChange>();


            for (int i = 0; i < GroupingCount; ++i)
            {
                Grouping grouping = new Grouping();
                grouping.Load(reader);
                Groupings.Add(grouping);
            }

            for (int i = 0; i < FontChangeCount; ++i)
            {
                FontChange fontChange = new FontChange();
                fontChange.Load(reader);
                FontChanges.Add(fontChange);
            }


            int textLength = TotalLength - (int)(reader.BaseStream.Position - start);

            textBytes = reader.ReadBytes(textLength);

            if (Flags == 1)
            {
                //decode text
                for (int i = 0; i < textBytes.Length; ++i)
                {
                    i++;
                    if (textBytes.Length > ++i)
                    {
                        textBytes[i] ^= 0xfe;
                    }
                    if (textBytes.Length > ++i)
                    {
                        textBytes[i] ^= 0xed;
                    }
                }
            }



            Encoding macRoman = Encoding.GetEncoding(10000);

            Texts = macRoman.GetString(textBytes).Split('\0');
        }
Exemplo n.º 13
0
            public void Load(BinaryReaderBE reader)
            {
                Flags  = reader.ReadInt32();
                Name   = reader.ReadMacString(ScriptNameLength);
                Length = reader.ReadInt32();

                byte[] textBytes = reader.ReadBytes(Length);

                Text = Encoding.UTF8.GetString(textBytes);
            }
Exemplo n.º 14
0
        /// <summary>
        /// Gets the list of online status UI elements
        /// </summary>
        /// <returns>A list containing XivUi data</returns>
        public async Task <List <XivUi> > GetOnlineStatusList()
        {
            var onlineStatusLock = new object();
            var onlineStatusList = new List <XivUi>();

            // These are the offsets to relevant data
            // These will need to be changed if data gets added or removed with a patch
            const int iconNumberOffset = 6;
            const int dataSize         = 12;

            var onlineStatusExData = await _ex.ReadExData(XivEx.onlinestatus);

            await Task.Run(() => Parallel.ForEach(onlineStatusExData.Values, (onlineStatus) =>
            {
                var xivUi = new XivUi()
                {
                    PrimaryCategory   = "UI",
                    SecondaryCategory = XivStrings.OnlineStatus
                };

                // Big Endian Byte Order
                using (var br = new BinaryReaderBE(new MemoryStream(onlineStatus)))
                {
                    br.BaseStream.Seek(iconNumberOffset, SeekOrigin.Begin);

                    var iconNumber = br.ReadUInt16();

                    if (iconNumber == 0)
                    {
                        return;
                    }

                    br.BaseStream.Seek(dataSize, SeekOrigin.Begin);

                    // The size of the online status name string
                    // Size of the entire data chunk - size of the data portion
                    var nameLength = onlineStatus.Length - dataSize;

                    var name = Encoding.UTF8.GetString(br.ReadBytes(nameLength)).Replace("\0", "");

                    xivUi.IconNumber = iconNumber;
                    xivUi.Name       = name;
                }

                lock (onlineStatusLock)
                {
                    onlineStatusList.Add(xivUi);
                }
            }));

            onlineStatusList.Sort();

            return(onlineStatusList);
        }
Exemplo n.º 15
0
            // private short nameLen;
            public void Load(BinaryReaderBE reader)
            {
                reader.ReadBytes(1);
                // reader.ReadBytes(1);
                Type = reader.ReadInt16();
                // reader.ReadBytes(1);
                Flags = reader.ReadUInt16();

                // long position = reader.BaseStream.Position;
                // position += 1;//???
                // reader.BaseStream.Seek(position, SeekOrigin.Begin);

                // reader.ReadBytes(1);
                Name               = reader.ReadMacString(33);
                NoOfViews          = reader.ReadInt16();
                FramesPerView      = reader.ReadInt16();
                TickePerFrame      = reader.ReadInt16();
                KeyFrame           = reader.ReadInt16();
                TrasferMode        = reader.ReadInt16();
                TransferModePeriod = reader.ReadInt16();
                FirstFrameSound    = reader.ReadInt16();
                KeyFrameSound      = reader.ReadInt16();
                LastFrameSound     = reader.ReadInt16();
                PixelsToWorld      = reader.ReadInt16();
                LoopFrame          = reader.ReadInt16();

                // long position = reader.BaseStream.Position;
                // position += 28;//???
                // reader.BaseStream.Seek(position, SeekOrigin.Begin);
                reader.ReadBytes(28);
                short nov      = NoOfViews;
                int   idxCount = getRealViewCount(nov) * FramesPerView;

                FrameIndexes = new List <int>();
                for (int i = 0; i < idxCount; i++)
                {
                    short frameIndex = reader.ReadInt16();
                    FrameIndexes.Add(frameIndex);
                }
            }
Exemplo n.º 16
0
        /// <summary>
        /// Gets the list of online status UI elements
        /// </summary>
        /// <returns>A list containing XivUi data</returns>
        public List <XivUi> GetOnlineStatusList()
        {
            var onlineStatusList = new List <XivUi>();

            // These are the offsets to relevant data
            // These will need to be changed if data gets added or removed with a patch
            const int iconNumberOffset = 6;
            const int dataSize         = 12;

            var ex = new Ex(_gameDirectory, _xivLanguage);
            var onlineStatusExData = ex.ReadExData(XivEx.onlinestatus);

            foreach (var onlineStatus in onlineStatusExData.Values)
            {
                var xivUi = new XivUi()
                {
                    Category     = "UI",
                    ItemCategory = XivStrings.OnlineStatus
                };

                // Big Endian Byte Order
                using (var br = new BinaryReaderBE(new MemoryStream(onlineStatus)))
                {
                    br.BaseStream.Seek(iconNumberOffset, SeekOrigin.Begin);

                    var iconNumber = br.ReadUInt16();

                    if (iconNumber == 0)
                    {
                        continue;
                    }

                    br.BaseStream.Seek(dataSize, SeekOrigin.Begin);

                    // The size of the online status name string
                    // Size of the entire data chunk - size of the data portion
                    var nameLength = onlineStatus.Length - dataSize;

                    var name = Encoding.UTF8.GetString(br.ReadBytes(nameLength)).Replace("\0", "");

                    xivUi.IconNumber = iconNumber;
                    xivUi.Name       = name;
                }

                onlineStatusList.Add(xivUi);
            }

            onlineStatusList.Sort();

            return(onlineStatusList);
        }
Exemplo n.º 17
0
        /// <summary>
        /// Gets the list of available loading screen images
        /// </summary>
        /// <returns>A list containing XivUi data</returns>
        public async Task <List <XivUi> > GetLoadingImageList()
        {
            var loadingImageLock = new object();
            var loadingImageList = new List <XivUi>();

            // These are the offsets to relevant data
            // These will need to be changed if data gets added or removed with a patch
            const int dataLength = 4;

            var loadingImageExData = await _ex.ReadExData(XivEx.loadingimage);

            await Task.Run(() => Parallel.ForEach(loadingImageExData.Values, (loadingImage) =>
            {
                var xivUi = new XivUi()
                {
                    PrimaryCategory   = "UI",
                    SecondaryCategory = XivStrings.LoadingScreen,
                    UiPath            = "ui/loadingimage"
                };

                // Big Endian Byte Order
                using (var br = new BinaryReaderBE(new MemoryStream(loadingImage)))
                {
                    br.BaseStream.Seek(dataLength, SeekOrigin.Begin);

                    // The length of the loading image name string
                    // Size of the entire data chunk - size of the data portion
                    var nameLength = loadingImage.Length - dataLength;

                    var name = Encoding.UTF8.GetString(br.ReadBytes(nameLength)).Replace("\0", "");

                    if (name.Equals(""))
                    {
                        return;
                    }

                    xivUi.Name = name;
                }

                lock (loadingImageLock)
                {
                    loadingImageList.Add(xivUi);
                }
            }));

            loadingImageList.Sort();

            return(loadingImageList);
        }
Exemplo n.º 18
0
        public void Read(BinaryReaderBE Reader)
        {
            var lines = Reader.ReadUInt32();

            Lines = new ConsoleLine[lines];
            for (var i = 0; i < lines; i++)
            {
                var consoleLine = new ConsoleLine();
                var length      = Reader.ReadUInt32();
                var unknown     = Reader.ReadByte();
                var length2     = Reader.ReadUInt32();
                var line        = Reader.ReadBytes((int)length);
                consoleLine.Level = Reader.ReadUInt32();
                consoleLine.Line  = Encoding.UTF8.GetString(line);
                Lines[i]          = consoleLine;
            }
        }
Exemplo n.º 19
0
        /// <summary>
        /// Gets the list of available loading screen images
        /// </summary>
        /// <returns>A list containing XivUi data</returns>
        public List <XivUi> GetLoadingImageList()
        {
            var loadingImageList = new List <XivUi>();

            // These are the offsets to relevant data
            // These will need to be changed if data gets added or removed with a patch
            const int dataLength = 4;

            var ex = new Ex(_gameDirectory, _xivLanguage);
            var loadingImageExData = ex.ReadExData(XivEx.loadingimage);

            foreach (var loadingImage in loadingImageExData.Values)
            {
                var xivUi = new XivUi()
                {
                    Category     = "UI",
                    ItemCategory = XivStrings.LoadingScreen,
                    UiPath       = "ui/loadingimage"
                };

                // Big Endian Byte Order
                using (var br = new BinaryReaderBE(new MemoryStream(loadingImage)))
                {
                    br.BaseStream.Seek(dataLength, SeekOrigin.Begin);

                    // The length of the loading image name string
                    // Size of the entire data chunk - size of the data portion
                    var nameLength = loadingImage.Length - dataLength;

                    var name = Encoding.UTF8.GetString(br.ReadBytes(nameLength)).Replace("\0", "");

                    if (name.Equals(""))
                    {
                        continue;
                    }

                    xivUi.Name = name;
                }

                loadingImageList.Add(xivUi);
            }

            loadingImageList.Sort();

            return(loadingImageList);
        }
Exemplo n.º 20
0
        /// <summary>
        /// Helper function to obtain the string value from placename_0
        /// </summary>
        /// <param name="data">The uncompressed placename byte data</param>
        /// <returns>A string containing the place name</returns>
        private static string GetPlaceName(byte[] data)
        {
            // These are the offsets to relevant data
            // These will need to be changed if data gets added or removed with a patch
            const int nameLengthOffset = 6;
            const int dataLength       = 24;

            // Big Endian Byte Order
            using (var br = new BinaryReaderBE(new MemoryStream(data)))
            {
                br.BaseStream.Seek(nameLengthOffset, SeekOrigin.Begin);

                var nameLength = br.ReadInt16();

                br.BaseStream.Seek(dataLength, SeekOrigin.Begin);

                return(Encoding.UTF8.GetString(br.ReadBytes(nameLength)).Replace("\0", ""));
            }
        }
Exemplo n.º 21
0
            internal void LoadChunks(BinaryReaderBE reader)
            {
                long position = reader.BaseStream.Position;
                int  nextOffset;

                do
                {
                    uint tag = reader.ReadUInt32();
                    nextOffset = reader.ReadInt32();
                    int length = reader.ReadInt32();
                    reader.ReadInt32(); // offset

                    Chunks[tag] = reader.ReadBytes(length);

                    if (nextOffset > 0)
                    {
                        reader.BaseStream.Seek(position + nextOffset, SeekOrigin.Begin);
                    }
                } while (nextOffset > 0);
            }
Exemplo n.º 22
0
        public bool GetNextMessage(QHFMessage msg)
        {
            if (fs.Position >= fs.Length - 24)
            {
                return(false);
            }

            byte[] msgBytes = null;
            //Trace.WriteLine("Block start: " + fs.Position);
            msg.Signature = br.ReadInt16();
            if (msg.SignatureMismatch)
            {
                if (br.ReadByte() == 1)
                {
                    // В предыдущем сообщении были ошибки и структура съехала.
                    msg.Signature = 1;
                }
                else
                {
                    // Сдвигаем позицию на исходную для достоверности отладки.
                    fs.Position -= 1;
                    Trace.WriteLine($"{Uin} ({Nick}). Signature mismatch. (sign={msg.Signature})");
                    return(true);
                }
            }
            var size       = br.ReadInt32();
            var endOfBlock = size + fs.Position;

            try
            {
                msg.ID   = GetNextBlock();
                msg.Time = UnixTimeStampToDateTime(GetNextBlock());
                msg.IsMy = GetNextBlock() > 0;
                var msgLength = GetNextBlock();
                if (msgLength < 0)
                {
                    fs.Position -= 4;
                    msgBytes     = ReadBytesUntilNextMessage(msg.ID + 1);
                    msgLength    = msgBytes.Length;
                }
                else
                {
                    if (msgLength > size)
                    {
                        fs.Position -= 4;
                        msgLength    = br.ReadInt16();
                        if (msgLength > size)
                        {
                            fs.Position -= 2;
                            msgLength    = br.ReadByte();
                        }
                    }

                    msgBytes = br.ReadBytes(msgLength);
                }

                msg.Text = encoding.GetString(DecodeBytes(msgBytes));

                return(true);
            }
            catch (ArgumentException ex)
            {
                Trace.WriteLine(ex.Message);
                if (fs.Position == fs.Length)
                {
                    msg.Text = "Сообщение потеряно.";
                }
                return(true);
            }
        }
Exemplo n.º 23
0
        /// <summary>
        /// Reads and parses the ExData file
        /// </summary>
        /// <remarks>
        /// This reads the data at each index of the exd file
        /// It then places the data in a dictionary with format [index, raw data]
        /// </remarks>
        /// <param name="exFile"></param>
        /// <returns>A dictionary containing the Index and Raw Data of the ex file</returns>
        public async Task <Dictionary <int, byte[]> > ReadExData(XivEx exFile)
        {
            var exdNameOffsetDictionary = new Dictionary <long, string>();
            var exdDataDictionary       = new Dictionary <int, byte[]>();
            var errorString             = "";

            await ReadExHeader(exFile);

            var language = "_" + _langCode;

            // Some Ex files are universal and do not have a language code
            if (LanguageList.Count == 0)
            {
                language = "";
            }

            // Each page is a new exd file
            // A good example is item_[page]_[language].exd
            // item_0_en.exd, item_500_en.exd, item_1000_en.exd, etc.
            foreach (var page in PageList)
            {
                var exdFile = exFile + "_" + page + language + ExdExtension;

                var exdFolderHash = HashGenerator.GetHash("exd");
                var exdFileHash   = HashGenerator.GetHash(exdFile);
                var offset        = await _index.GetDataOffset(exdFolderHash, exdFileHash, XivDataFile._0A_Exd);

                try
                {
                    exdNameOffsetDictionary.Add(offset, exdFile);
                }
                catch (Exception ex)
                {
                    var zz = "zz";
                    throw ex;
                }
            }

            await Task.Run(async() =>
            {
                foreach (var exdData in exdNameOffsetDictionary)
                {
                    try
                    {
                        var exData = await _dat.GetType2Data(exdData.Key, XivDataFile._0A_Exd);

                        // Big Endian Byte Order
                        using (var br = new BinaryReaderBE(new MemoryStream(exData)))
                        {
                            br.ReadBytes(8);
                            var offsetTableSize = br.ReadInt32();

                            for (var i = 0; i < offsetTableSize; i += 8)
                            {
                                br.BaseStream.Seek(i + 32, SeekOrigin.Begin);

                                var entryNum    = br.ReadInt32();
                                var entryOffset = br.ReadInt32();

                                br.BaseStream.Seek(entryOffset, SeekOrigin.Begin);

                                var entrySize = br.ReadInt32();
                                br.ReadBytes(2);

                                if (!exdDataDictionary.ContainsKey(entryNum))
                                {
                                    exdDataDictionary.Add(entryNum, br.ReadBytes(entrySize));
                                }
                            }
                        }
                    }
                    catch (Exception ex)
                    {
                        errorString += $"File: {exdData.Value}\nError: {ex.Message}\n\n";
                    }
                }
            });


            if (!string.IsNullOrEmpty(errorString))
            {
                throw new Exception($"There was an error reading EX data for the following\n\n{errorString}");
            }

            return(exdDataDictionary);
        }
Exemplo n.º 24
0
        /// <summary>
        /// Gets the list of indoor furniture
        /// </summary>
        /// <remarks>
        /// Housing items can be obtained one of two ways
        /// One: checking the housingfurniture exd for the item index, and going to that item to grab the data
        /// Two: iterating through the entire item list seeing if the item contains an index to a housing item (offset 112, 4 bytes)
        /// This method does option one
        /// </remarks>
        /// <returns>A list of XivFurniture objects containing indoor furniture item info</returns>
        private async Task <List <XivFurniture> > GetIndoorFurniture()
        {
            var indoorLock = new object();
            // These are the offsets to relevant data
            // These will need to be changed if data gets added or removed with a patch
            const int itemIndexOffset    = 10;
            const int modelNumberOffset  = 12;
            const int itemCategoryOffset = 14;

            const int itemNameDataOffset = 14;
            int       itemDataLength     = DataLengthByPatch["5.5"];
            const int itemIconDataOffset = 136;

            if (_xivLanguage == XivLanguage.Korean)
            {
                itemDataLength = DataLengthByPatch["5.4"];
            }
            else if (_xivLanguage == XivLanguage.Chinese)
            {
                itemDataLength = DataLengthByPatch["5.4"];
            }

            var ex = new Ex(_gameDirectory, _xivLanguage);
            var housingDictionary = await ex.ReadExData(XivEx.housingfurniture);

            var itemDictionary = await ex.ReadExData(XivEx.item);

            var furnitureList = new List <XivFurniture>();

            await Task.Run(() => Parallel.ForEach(housingDictionary.Values, (housingItem) =>
            {
                try
                {
                    var item = new XivFurniture
                    {
                        PrimaryCategory   = XivStrings.Housing,
                        SecondaryCategory = XivStrings.Furniture_Indoor,
                        ModelInfo         = new XivModelInfo()
                    };

                    using (var br = new BinaryReaderBE(new MemoryStream(housingItem)))
                    {
                        br.BaseStream.Seek(itemIndexOffset, SeekOrigin.Begin);
                        var itemIndex = br.ReadUInt16();

                        br.BaseStream.Seek(modelNumberOffset, SeekOrigin.Begin);
                        item.ModelInfo.PrimaryID = br.ReadInt16();

                        br.BaseStream.Seek(itemCategoryOffset, SeekOrigin.Begin);
                        var housingCategory = br.ReadByte();

                        using (var br1 = new BinaryReaderBE(new MemoryStream(itemDictionary[itemIndex])))
                        {
                            br1.BaseStream.Seek(itemNameDataOffset, SeekOrigin.Begin);
                            var nameOffset = br1.ReadInt16();

                            br1.BaseStream.Seek(itemIconDataOffset, SeekOrigin.Begin);
                            item.IconNumber = br1.ReadUInt16();

                            var gearNameOffset = itemDataLength + nameOffset;
                            var gearNameLength = itemDictionary[itemIndex].Length - gearNameOffset;
                            br1.BaseStream.Seek(gearNameOffset, SeekOrigin.Begin);
                            var nameString = Encoding.UTF8.GetString(br1.ReadBytes(gearNameLength)).Replace("\0", "");
                            item.Name      = new string(nameString.Where(c => !char.IsControl(c)).ToArray());
                        }
                    }

                    if (!item.Name.Equals(string.Empty))
                    {
                        lock (indoorLock)
                        {
                            furnitureList.Add(item);
                        }
                    }
                } catch (Exception ex)
                {
                    throw;
                }
            }));

            furnitureList.Sort();

            return(furnitureList);
        }
Exemplo n.º 25
0
        /// <summary>
        /// Gets the list of indoor furniture
        /// </summary>
        /// <remarks>
        /// Housing items can be obtained one of two ways
        /// One: checking the housingfurniture exd for the item index, and going to that item to grab the data
        /// Two: iterating through the entire item list seeing if the item contains an index to a housing item (offset 112, 4 bytes)
        /// This method does option two as the item index was removed from the picture exd file in patch 5.2
        /// </remarks>
        /// <returns>A list of XivFurniture objects containing indoor furniture item info</returns>
        private async Task <List <XivFurniture> > GetPaintings()
        {
            var paintingsLock = new object();
            // These are the offsets to relevant data
            // These will need to be changed if data gets added or removed with a patch
            int iconNumberOffset = 0;

            const int itemNameDataOffset = 14;
            const int housingIndexOffset = 112;
            int       itemDataLength     = DataLengthByPatch["5.5"];
            const int itemIconDataOffset = 136;

            var ex = new Ex(_gameDirectory, _xivLanguage);
            var pictureDictionary = await ex.ReadExData(XivEx.picture);

            var itemDictionary = await ex.ReadExData(XivEx.item);


            if (_xivLanguage == XivLanguage.Korean)
            {
                itemDataLength = DataLengthByPatch["5.4"];
            }
            else if (_xivLanguage == XivLanguage.Chinese)
            {
                itemDataLength = DataLengthByPatch["5.4"];
            }


            var furnitureList = new List <XivFurniture>();

            await Task.Run(() => Parallel.ForEach(itemDictionary.Values, (item) =>
            {
                var painting = new XivFurniture
                {
                    PrimaryCategory   = XivStrings.Housing,
                    SecondaryCategory = XivStrings.Paintings,
                    ModelInfo         = new XivModelInfo()
                };

                using (var br = new BinaryReaderBE(new MemoryStream(item)))
                {
                    br.BaseStream.Seek(housingIndexOffset, SeekOrigin.Begin);
                    var pictureIndex = br.ReadInt32();

                    if (pictureIndex == 0 || pictureIndex > (pictureDictionary.Count - 1))
                    {
                        return;
                    }

                    br.BaseStream.Seek(itemNameDataOffset, SeekOrigin.Begin);
                    var nameOffset = br.ReadInt16();

                    br.BaseStream.Seek(itemIconDataOffset, SeekOrigin.Begin);
                    painting.IconNumber = br.ReadUInt16();

                    var gearNameOffset = itemDataLength + nameOffset;
                    var gearNameLength = item.Length - gearNameOffset;
                    br.BaseStream.Seek(gearNameOffset, SeekOrigin.Begin);
                    var nameString = Encoding.UTF8.GetString(br.ReadBytes(gearNameLength)).Replace("\0", "");
                    painting.Name  = new string(nameString.Where(c => !char.IsControl(c)).ToArray());

                    using (var br1 = new BinaryReaderBE(new MemoryStream(pictureDictionary[pictureIndex])))
                    {
                        br1.BaseStream.Seek(iconNumberOffset, SeekOrigin.Begin);
                        painting.ModelInfo.PrimaryID = br1.ReadInt32();
                    }
                }

                if (!painting.Name.Equals(string.Empty) && (painting.Name.IndexOf("painting", System.StringComparison.OrdinalIgnoreCase) >= 0))
                {
                    lock (paintingsLock)
                    {
                        furnitureList.Add(painting);
                    }
                }
            }));

            furnitureList.Sort();

            return(furnitureList);
        }
Exemplo n.º 26
0
        /// <summary>
        /// Gets the list of available map data
        /// </summary>
        /// <remarks>
        /// The map data is obtained from the map exd files
        /// There may be unlisted maps which this does not check for
        /// </remarks>
        /// <returns>A list containing XivUi data</returns>
        public List <XivUi> GetMapList()
        {
            // These are the offsets to relevant data
            // These will need to be changed if data gets added or removed with a patch
            const int regionMapDataOffset = 12;
            const int dataLength          = 32;

            var mapList = new List <XivUi>();

            var ex            = new Ex(_gameDirectory, _xivLanguage);
            var placeNameData = ex.ReadExData(XivEx.placename);
            var mapData       = ex.ReadExData(XivEx.map);

            var mapNameList = new List <string>();

            // Loops through all available maps in the map exd files
            // At present only one file exists (map_0)
            foreach (var map in mapData.Values)
            {
                int regionIndex;
                int mapIndex;

                var xivUi = new XivUi()
                {
                    Category     = "UI",
                    ItemCategory = XivStrings.Maps
                };

                // Big Endian Byte Order
                using (var br = new BinaryReaderBE(new MemoryStream(map)))
                {
                    br.BaseStream.Seek(regionMapDataOffset, SeekOrigin.Begin);

                    regionIndex = br.ReadInt16();
                    mapIndex    = br.ReadInt16();

                    if (mapIndex == 0)
                    {
                        continue;
                    }

                    br.BaseStream.Seek(dataLength, SeekOrigin.Begin);

                    // The size of the map path string
                    // Size of the entire data chunk - size of the data portion
                    var mapPathLength = map.Length - dataLength;

                    if (mapPathLength < 4)
                    {
                        continue;
                    }

                    xivUi.UiPath = Encoding.UTF8.GetString(br.ReadBytes(mapPathLength)).Replace("\0", "");
                }

                // Gets the name from the placename exd file
                var regionName = GetPlaceName(placeNameData[regionIndex]);
                var mapName    = GetPlaceName(placeNameData[mapIndex]);

                if (mapName.Equals(string.Empty))
                {
                    continue;
                }

                xivUi.Name            = mapName;
                xivUi.ItemSubCategory = regionName;

                if (mapNameList.Contains(mapName))
                {
                    xivUi.Name = mapName + " " + xivUi.UiPath.Substring(xivUi.UiPath.Length - 2);
                }

                mapNameList.Add(mapName);

                mapList.Add(xivUi);
            }

            mapList.Sort();

            return(mapList);
        }
Exemplo n.º 27
0
        /// <summary>
        /// Gets the list of status effect UI elements
        /// </summary>
        /// <returns>A list containing XivUi data</returns>
        public async Task <List <XivUi> > GetStatusList()
        {
            var statusLock = new object();
            var statusList = new List <XivUi>();

            // These are the offsets to relevant data
            // These will need to be changed if data gets added or removed with a patch
            const int nameLengthDataOffset = 6;
            var       typeDataOffset       = 13;
            var       dataLength           = 24;

            if (_xivLanguage != XivLanguage.Korean)
            {
                typeDataOffset = 16;
                dataLength     = 28;
            }

            var statusExData = await _ex.ReadExData(XivEx.status);

            await Task.Run(() => Parallel.ForEach(statusExData.Values, (status) =>
            {
                var xivUi = new XivUi()
                {
                    PrimaryCategory   = "UI",
                    SecondaryCategory = XivStrings.Status
                };

                // Big Endian Byte Order
                using (var br = new BinaryReaderBE(new MemoryStream(status)))
                {
                    br.BaseStream.Seek(nameLengthDataOffset, SeekOrigin.Begin);

                    var nameLength = br.ReadInt16();

                    var iconNumber = br.ReadUInt16();

                    if (iconNumber == 0)
                    {
                        return;
                    }

                    br.BaseStream.Seek(typeDataOffset, SeekOrigin.Begin);

                    var type = br.ReadByte();

                    br.BaseStream.Seek(dataLength, SeekOrigin.Begin);

                    var name = Encoding.UTF8.GetString(br.ReadBytes(nameLength)).Replace("\0", "");

                    xivUi.IconNumber = iconNumber;
                    xivUi.Name       = name;

                    if (name.Equals(string.Empty))
                    {
                        return;
                    }

                    //Status effects have a byte that determines whether the effect is detrimental or beneficial
                    if (type == 1)
                    {
                        xivUi.TertiaryCategory = XivStrings.Beneficial;
                    }
                    else if (type == 2)
                    {
                        xivUi.TertiaryCategory = XivStrings.Detrimental;
                    }
                    else
                    {
                        xivUi.TertiaryCategory = XivStrings.None;
                        xivUi.Name             = xivUi.Name + " " + type;
                    }
                }

                lock (statusLock)
                {
                    statusList.Add(xivUi);
                }
            }));

            statusList.Sort();

            return(statusList);
        }
Exemplo n.º 28
0
        /// <summary>
        /// Gets the list of status effect UI elements
        /// </summary>
        /// <returns>A list containing XivUi data</returns>
        public List <XivUi> GetStatusList()
        {
            var statusList = new List <XivUi>();

            // These are the offsets to relevant data
            // These will need to be changed if data gets added or removed with a patch
            const int nameLengthDataOffset = 6;
            const int typeDataOffset       = 13;
            const int dataLength           = 24;

            var ex           = new Ex(_gameDirectory, _xivLanguage);
            var statusExData = ex.ReadExData(XivEx.status);

            foreach (var status in statusExData.Values)
            {
                var xivUi = new XivUi()
                {
                    Category     = "UI",
                    ItemCategory = XivStrings.Status
                };

                // Big Endian Byte Order
                using (var br = new BinaryReaderBE(new MemoryStream(status)))
                {
                    br.BaseStream.Seek(nameLengthDataOffset, SeekOrigin.Begin);

                    var nameLength = br.ReadInt16();

                    var iconNumber = br.ReadUInt16();

                    if (iconNumber == 0)
                    {
                        continue;
                    }

                    br.BaseStream.Seek(typeDataOffset, SeekOrigin.Begin);

                    var type = br.ReadByte();

                    br.BaseStream.Seek(dataLength, SeekOrigin.Begin);

                    var name = Encoding.UTF8.GetString(br.ReadBytes(nameLength)).Replace("\0", "");

                    xivUi.IconNumber = iconNumber;
                    xivUi.Name       = name;

                    if (name.Equals(string.Empty))
                    {
                        continue;
                    }

                    //Status effects have a byte that determines whether the effect is detrimental or beneficial
                    if (type == 1)
                    {
                        xivUi.ItemSubCategory = XivStrings.Beneficial;
                    }
                    else if (type == 2)
                    {
                        xivUi.ItemSubCategory = XivStrings.Detrimental;
                    }
                    else
                    {
                        xivUi.ItemSubCategory = XivStrings.None;
                        xivUi.Name            = xivUi.Name + " " + type;
                    }
                }

                statusList.Add(xivUi);
            }

            statusList.Sort();

            return(statusList);
        }
Exemplo n.º 29
0
        /// <summary>
        /// Gets the list of action UI elements
        /// </summary>
        /// <remarks>
        /// The actions are obtained from different sources, but is not all inclusive
        /// There may be some actions that are missing
        /// </remarks>
        /// <returns>A list containing XivUi data</returns>
        public List <XivUi> GetActionList()
        {
            var ex = new Ex(_gameDirectory, _xivLanguage);

            // Data from the action_0 exd
            var actionExData         = ex.ReadExData(XivEx.action);
            var actionCategoryExData = ex.ReadExData(XivEx.actioncategory);

            var actionList = new List <XivUi>();

            var actionNames = new List <string>();

            foreach (var action in actionExData.Values)
            {
                var xivUi = new XivUi()
                {
                    Category     = "UI",
                    ItemCategory = XivStrings.Actions
                };

                int actionCategory;

                // Big Endian Byte Order
                using (var br = new BinaryReaderBE(new MemoryStream(action)))
                {
                    br.BaseStream.Seek(8, SeekOrigin.Begin);
                    var iconNumber = br.ReadUInt16();

                    if (iconNumber == 0)
                    {
                        continue;
                    }

                    br.BaseStream.Seek(26, SeekOrigin.Begin);
                    actionCategory = br.ReadByte();

                    br.BaseStream.Seek(56, SeekOrigin.Begin);
                    var nameLength = action.Length - 56;
                    var name       = Encoding.UTF8.GetString(br.ReadBytes(nameLength)).Replace("\0", "");

                    xivUi.Name       = name;
                    xivUi.IconNumber = iconNumber;
                }

                if (actionNames.Contains(xivUi.Name))
                {
                    continue;
                }
                actionNames.Add(xivUi.Name);

                var actionCategoryData = actionCategoryExData[actionCategory];

                // Big Endian Byte Order
                using (var br = new BinaryReaderBE(new MemoryStream(actionCategoryData)))
                {
                    br.BaseStream.Seek(4, SeekOrigin.Begin);

                    var nameLength = actionCategoryData.Length - 4;
                    var name       = Encoding.UTF8.GetString(br.ReadBytes(nameLength)).Replace("\0", "");

                    if (name.Equals(string.Empty))
                    {
                        xivUi.ItemSubCategory = XivStrings.None;
                    }
                    else
                    {
                        xivUi.ItemSubCategory = name;
                    }
                }

                actionList.Add(xivUi);
            }

            // Data from generalaction_0
            var generalActionExData = ex.ReadExData(XivEx.generalaction);

            foreach (var action in generalActionExData.Values)
            {
                var xivUi = new XivUi()
                {
                    Category        = "UI",
                    ItemCategory    = XivStrings.Actions,
                    ItemSubCategory = XivStrings.General
                };

                // Big Endian Byte Order
                using (var br = new BinaryReaderBE(new MemoryStream(action)))
                {
                    br.BaseStream.Seek(8, SeekOrigin.Begin);

                    var nameLength = br.ReadInt16();

                    br.BaseStream.Seek(10, SeekOrigin.Begin);

                    var iconNumber = br.ReadUInt16();

                    if (iconNumber == 0)
                    {
                        continue;
                    }

                    br.BaseStream.Seek(20, SeekOrigin.Begin);

                    var name = Encoding.UTF8.GetString(br.ReadBytes(nameLength)).Replace("\0", "");

                    xivUi.Name       = name;
                    xivUi.IconNumber = iconNumber;
                }

                if (actionNames.Contains(xivUi.Name))
                {
                    continue;
                }
                actionNames.Add(xivUi.Name);

                actionList.Add(xivUi);
            }

            // Data from buddyaction_0
            var buddyActionExData = ex.ReadExData(XivEx.buddyaction);

            foreach (var action in buddyActionExData.Values)
            {
                var xivUi = new XivUi()
                {
                    Category        = "UI",
                    ItemCategory    = XivStrings.Actions,
                    ItemSubCategory = XivStrings.Buddy
                };

                // Big Endian Byte Order
                using (var br = new BinaryReaderBE(new MemoryStream(action)))
                {
                    br.BaseStream.Seek(6, SeekOrigin.Begin);

                    var nameLength = br.ReadInt16();

                    br.BaseStream.Seek(10, SeekOrigin.Begin);

                    var iconNumber = br.ReadUInt16();

                    if (iconNumber == 0)
                    {
                        continue;
                    }

                    br.BaseStream.Seek(20, SeekOrigin.Begin);

                    var name = Encoding.UTF8.GetString(br.ReadBytes(nameLength)).Replace("\0", "");

                    xivUi.Name       = name;
                    xivUi.IconNumber = iconNumber;
                }

                if (actionNames.Contains(xivUi.Name))
                {
                    continue;
                }
                actionNames.Add(xivUi.Name);

                actionList.Add(xivUi);
            }

            // Data from companyaction_0
            var companyActionExData = ex.ReadExData(XivEx.companyaction);

            foreach (var action in companyActionExData.Values)
            {
                var xivUi = new XivUi()
                {
                    Category        = "UI",
                    ItemCategory    = XivStrings.Actions,
                    ItemSubCategory = XivStrings.Company
                };

                // Big Endian Byte Order
                using (var br = new BinaryReaderBE(new MemoryStream(action)))
                {
                    br.BaseStream.Seek(6, SeekOrigin.Begin);

                    var nameLength = br.ReadInt16();

                    br.BaseStream.Seek(14, SeekOrigin.Begin);

                    var iconNumber = br.ReadUInt16();

                    if (iconNumber == 0)
                    {
                        continue;
                    }

                    br.BaseStream.Seek(20, SeekOrigin.Begin);

                    var name = Encoding.UTF8.GetString(br.ReadBytes(nameLength)).Replace("\0", "");

                    xivUi.Name       = name;
                    xivUi.IconNumber = iconNumber;
                }

                if (actionNames.Contains(xivUi.Name))
                {
                    continue;
                }
                actionNames.Add(xivUi.Name);

                actionList.Add(xivUi);
            }

            // Data from craftaction_100000
            var craftActionExData = ex.ReadExData(XivEx.craftaction);

            foreach (var action in craftActionExData.Values)
            {
                var xivUi = new XivUi()
                {
                    Category        = "UI",
                    ItemCategory    = XivStrings.Actions,
                    ItemSubCategory = XivStrings.Craft
                };

                // Big Endian Byte Order
                using (var br = new BinaryReaderBE(new MemoryStream(action)))
                {
                    br.BaseStream.Seek(6, SeekOrigin.Begin);

                    var nameLength = br.ReadInt16();

                    br.BaseStream.Seek(48, SeekOrigin.Begin);

                    var iconNumber = br.ReadUInt16();

                    if (iconNumber == 0)
                    {
                        continue;
                    }

                    br.BaseStream.Seek(60, SeekOrigin.Begin);

                    var name = Encoding.UTF8.GetString(br.ReadBytes(nameLength)).Replace("\0", "");

                    xivUi.Name       = name;
                    xivUi.IconNumber = iconNumber;
                }

                if (actionNames.Contains(xivUi.Name))
                {
                    continue;
                }
                actionNames.Add(xivUi.Name);

                actionList.Add(xivUi);
            }

            // Data from eventaction_0
            var eventActionExData = ex.ReadExData(XivEx.eventaction);

            foreach (var action in eventActionExData.Values)
            {
                var xivUi = new XivUi()
                {
                    Category        = "UI",
                    ItemCategory    = XivStrings.Actions,
                    ItemSubCategory = XivStrings.Event
                };

                // Big Endian Byte Order
                using (var br = new BinaryReaderBE(new MemoryStream(action)))
                {
                    br.BaseStream.Seek(4, SeekOrigin.Begin);

                    var iconNumber = br.ReadUInt16();

                    if (iconNumber == 0)
                    {
                        continue;
                    }

                    br.BaseStream.Seek(16, SeekOrigin.Begin);

                    var nameLength = action.Length - 16;

                    var name = Encoding.UTF8.GetString(br.ReadBytes(nameLength)).Replace("\0", "");

                    xivUi.Name       = name;
                    xivUi.IconNumber = iconNumber;
                }

                if (actionNames.Contains(xivUi.Name))
                {
                    continue;
                }
                actionNames.Add(xivUi.Name);

                actionList.Add(xivUi);
            }

            // Data from emote_0
            var emoteExData = ex.ReadExData(XivEx.emote);

            foreach (var action in emoteExData.Values)
            {
                var xivUi = new XivUi()
                {
                    Category        = "UI",
                    ItemCategory    = XivStrings.Actions,
                    ItemSubCategory = XivStrings.Emote
                };

                // Big Endian Byte Order
                using (var br = new BinaryReaderBE(new MemoryStream(action)))
                {
                    br.BaseStream.Seek(26, SeekOrigin.Begin);

                    var iconNumber = br.ReadUInt16();

                    if (iconNumber == 0)
                    {
                        continue;
                    }

                    br.BaseStream.Seek(36, SeekOrigin.Begin);

                    var nameLength = action.Length - 36;

                    var name = Encoding.UTF8.GetString(br.ReadBytes(nameLength)).Replace("\0", "");

                    xivUi.Name       = name;
                    xivUi.IconNumber = iconNumber;
                }

                if (actionNames.Contains(xivUi.Name))
                {
                    continue;
                }
                actionNames.Add(xivUi.Name);

                actionList.Add(xivUi);
            }

            // Data from marker_0
            var markerExData = ex.ReadExData(XivEx.marker);

            foreach (var action in markerExData.Values)
            {
                var xivUi = new XivUi()
                {
                    Category        = "UI",
                    ItemCategory    = XivStrings.Actions,
                    ItemSubCategory = XivStrings.Marker
                };

                // Big Endian Byte Order
                using (var br = new BinaryReaderBE(new MemoryStream(action)))
                {
                    br.BaseStream.Seek(6, SeekOrigin.Begin);

                    var iconNumber = br.ReadUInt16();

                    if (iconNumber == 0)
                    {
                        continue;
                    }

                    var nameLength = action.Length - 6;

                    var name = Encoding.UTF8.GetString(br.ReadBytes(nameLength)).Replace("\0", "");

                    xivUi.Name       = name;
                    xivUi.IconNumber = iconNumber;
                }

                if (actionNames.Contains(xivUi.Name))
                {
                    continue;
                }
                actionNames.Add(xivUi.Name);

                actionList.Add(xivUi);
            }

            // Data from fieldmarker_0
            var fieldMarkerExData = ex.ReadExData(XivEx.fieldmarker);

            foreach (var action in fieldMarkerExData.Values)
            {
                var xivUi = new XivUi()
                {
                    Category        = "UI",
                    ItemCategory    = XivStrings.Actions,
                    ItemSubCategory = XivStrings.FieldMarker
                };

                // Big Endian Byte Order
                using (var br = new BinaryReaderBE(new MemoryStream(action)))
                {
                    br.BaseStream.Seek(8, SeekOrigin.Begin);

                    var iconNumber = br.ReadUInt16();

                    if (iconNumber == 0)
                    {
                        continue;
                    }

                    br.BaseStream.Seek(12, SeekOrigin.Begin);

                    var nameLength = action.Length - 12;

                    var name = Encoding.UTF8.GetString(br.ReadBytes(nameLength)).Replace("\0", "");

                    xivUi.Name       = name;
                    xivUi.IconNumber = iconNumber;
                }

                if (actionNames.Contains(xivUi.Name))
                {
                    continue;
                }
                actionNames.Add(xivUi.Name);

                actionList.Add(xivUi);
            }

            actionList.Sort();

            return(actionList);
        }
Exemplo n.º 30
0
        public override GameFile[] Unpack()
        {
            this.file.BaseStream.Position = this.file.Position;
            BinaryReaderBE br = new BinaryReaderBE(this.file.BaseStream);

            // Read header
            if (br.ReadUInt32() != MagicStamp)
            {
                throw new InvalidDataException();
            }

            uint numFiles = br.ReadUInt32();

            br.ReadUInt32();    // File size
            br.ReadUInt32();    // Header + FAT size
            uint nameSecOffset = br.ReadUInt32();
            uint fileSecOffset = br.ReadUInt32();

            br.ReadUInt32();    // Unknown, maybe FAT entry or header size?
            br.ReadUInt32();    // Unknown, maybe MD5 size?
            br.ReadUInt32();    // Unknown, padding?

            // Read FAT & name
            GameFile[] files = new GameFile[numFiles];
            for (int i = 0; i < numFiles; i++)
            {
                this.file.BaseStream.Position = this.file.Position + 0x20 + i * 0x20;
                files[i] = new GameFile(this.file.BaseStream);

                byte[] md5 = br.ReadBytes(0x10);
                files[i].Position = this.file.Position + fileSecOffset + br.ReadUInt32();
                files[i].Size     = br.ReadUInt32();

                // Get name
                this.file.BaseStream.Position = this.file.Position + nameSecOffset + br.ReadUInt32();
                string relativePath = br.ReadString();
                //relativePath = relativePath.Replace('/', '\\');
                if (relativePath.Contains("//"))
                {
                    relativePath = relativePath.Replace("//", "");
                }
                if (relativePath.Contains("/"))
                {
                    files[i].FileName = relativePath.Substring(relativePath.LastIndexOf('/') + 1);
                    files[i].FilePath = Path.Combine(
                        this.file.FilePath,
                        relativePath.Substring(0, relativePath.LastIndexOf('/')));
                }
                else
                {
                    files[i].FileName = relativePath;
                    files[i].FilePath = Path.Combine(this.file.FilePath, relativePath);
                }

                files[i].Parent = this.file;
                this.file.AddChild(files[i]);
            }

            br = null;
            return(files);
        }