Esempio n. 1
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;
            const int typeDataOffset       = 13;
            const int dataLength           = 24;

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

            await Task.Run(() => Parallel.ForEach(statusExData.Values, (status) =>
            {
                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)
                    {
                        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.ItemSubCategory = XivStrings.Beneficial;
                    }
                    else if (type == 2)
                    {
                        xivUi.ItemSubCategory = XivStrings.Detrimental;
                    }
                    else
                    {
                        xivUi.ItemSubCategory = XivStrings.None;
                        xivUi.Name            = xivUi.Name + " " + type;
                    }
                }

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

            statusList.Sort();

            return(statusList);
        }
Esempio n. 2
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 async Task <List <XivUi> > GetMapList()
        {
            var mapLock = 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 regionMapDataOffset = 12;
            const int dataLength          = 32;

            var mapList = new List <XivUi>();

            var placeNameData = await _ex.ReadExData(XivEx.placename);

            var mapData = await _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)
            await Task.Run(() => Parallel.ForEach(mapData.Values, (map) =>
            {
                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)
                    {
                        return;
                    }

                    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)
                    {
                        return;
                    }

                    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))
                {
                    return;
                }

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

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

                lock (mapLock)
                {
                    mapNameList.Add(mapName);
                    mapList.Add(xivUi);
                }
            }));

            mapList.Sort();

            return(mapList);
        }
Esempio n. 3
0
        public void Load(BinaryReaderBE reader)
        {
            long origin = reader.BaseStream.Position;

            Version                         = reader.ReadInt16();
            Type                            = (CollectionType)reader.ReadInt16();
            Flags                           = reader.ReadUInt16();
            colorCount                      = reader.ReadInt16();
            colorTableCount                 = reader.ReadInt16();
            colorTableOffset                = reader.ReadInt32();
            highLevelShapeCount             = reader.ReadInt16();
            highLevelShapeOffsetTableOffset = reader.ReadInt32();
            lowLevelShapeCount              = reader.ReadInt16();
            lowLevelShapeOffsetTableOffset  = reader.ReadInt32();
            bitmapCount                     = reader.ReadInt16();
            bitmapOffsetTableOffset         = reader.ReadInt32();
            pixelsToWorld                   = reader.ReadInt16();
            size                            = reader.ReadInt32();
            reader.BaseStream.Seek(253 * 2, SeekOrigin.Current);

            colorTables.Clear();
            reader.BaseStream.Seek(origin + colorTableOffset, SeekOrigin.Begin);
            for (int i = 0; i < colorTableCount; ++i)
            {
                ColorValue[] table = new ColorValue[colorCount];
                for (int j = 0; j < colorCount; ++j)
                {
                    table[j].Load(reader);
                }
                colorTables.Add(table);
            }

            bitmaps.Clear();
            reader.BaseStream.Seek(origin + bitmapOffsetTableOffset, SeekOrigin.Begin);
            for (int i = 0; i < bitmapCount; ++i)
            {
                int  bitmapPosition            = reader.ReadInt32();
                long nextPositionInOffsetTable = reader.BaseStream.Position;

                reader.BaseStream.Seek(origin + bitmapPosition, SeekOrigin.Begin);

                Bitmap bitmap = new Bitmap();
                bitmap.Load(reader);
                bitmaps.Add(bitmap);

                reader.BaseStream.Seek(nextPositionInOffsetTable, SeekOrigin.Begin);
            }

            lowLevelShapes.Clear();
            reader.BaseStream.Seek(origin + lowLevelShapeOffsetTableOffset, SeekOrigin.Begin);
            for (int i = 0; i < lowLevelShapeCount; i++)
            {
                long shapeDefinitionPosition   = origin + reader.ReadInt32();
                long nextPositionInOffsetTable = reader.BaseStream.Position;

                reader.BaseStream.Seek(shapeDefinitionPosition, SeekOrigin.Begin);

                LowLevelShapeDefinition lowLevelShapeDefinition = new LowLevelShapeDefinition();
                lowLevelShapeDefinition.Load(reader);
                lowLevelShapes.Add(lowLevelShapeDefinition);

                reader.BaseStream.Seek(nextPositionInOffsetTable, SeekOrigin.Begin);
            }
        }
Esempio n. 4
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 async Task <List <XivUi> > GetActionList()
        {
            var actionLock = new object();

            // Data from the action_0 exd
            var actionExData = await _ex.ReadExData(XivEx.action);

            var actionCategoryExData = await _ex.ReadExData(XivEx.actioncategory);

            var actionList = new List <XivUi>();

            var actionNames = new List <string>();

            await Task.Run(() => Parallel.ForEach(actionExData.Values, (action) =>
            {
                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)
                    {
                        return;
                    }

                    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 (xivUi.Name.Equals(string.Empty))
                {
                    return;
                }
                if (actionNames.Contains(xivUi.Name))
                {
                    return;
                }

                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;
                    }
                }

                lock (actionLock)
                {
                    actionNames.Add(xivUi.Name);
                    actionList.Add(xivUi);
                }
            }));

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

            await Task.Run(() => Parallel.ForEach(generalActionExData.Values, (action) =>
            {
                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(6, SeekOrigin.Begin);

                    var nameLength = br.ReadInt16();

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

                    var iconNumber = br.ReadUInt16();

                    if (iconNumber == 0)
                    {
                        return;
                    }

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

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

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

                lock (actionLock)
                {
                    actionNames.Add(xivUi.Name);
                    actionList.Add(xivUi);
                }
            }));

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

            await Task.Run(() => Parallel.ForEach(buddyActionExData.Values, (action) =>
            {
                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)
                    {
                        return;
                    }

                    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))
                {
                    return;
                }

                lock (actionLock)
                {
                    actionNames.Add(xivUi.Name);
                    actionList.Add(xivUi);
                }
            }));

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

            await Task.Run(() => Parallel.ForEach(companyActionExData.Values, (action) =>
            {
                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)
                    {
                        return;
                    }

                    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))
                {
                    return;
                }

                lock (actionLock)
                {
                    actionNames.Add(xivUi.Name);
                    actionList.Add(xivUi);
                }
            }));

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

            await Task.Run(() => Parallel.ForEach(craftActionExData.Values, (action) =>
            {
                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)
                    {
                        return;
                    }

                    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))
                {
                    return;
                }

                lock (actionLock)
                {
                    actionNames.Add(xivUi.Name);
                    actionList.Add(xivUi);
                }
            }));

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

            await Task.Run(() => Parallel.ForEach(eventActionExData.Values, (action) =>
            {
                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)
                    {
                        return;
                    }

                    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))
                {
                    return;
                }

                lock (actionLock)
                {
                    actionNames.Add(xivUi.Name);
                    actionList.Add(xivUi);
                }
            }));

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

            await Task.Run(() => Parallel.ForEach(emoteExData.Values, (action) =>
            {
                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(28, SeekOrigin.Begin);

                    var iconNumber = br.ReadUInt16();

                    if (iconNumber == 0)
                    {
                        return;
                    }

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

                    var nameLength = action.Length - 40;

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


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

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

                lock (actionLock)
                {
                    actionNames.Add(xivUi.Name);
                    actionList.Add(xivUi);
                }
            }));

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

            await Task.Run(() => Parallel.ForEach(markerExData.Values, (action) =>
            {
                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)
                    {
                        return;
                    }

                    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))
                {
                    return;
                }

                lock (actionLock)
                {
                    actionNames.Add(xivUi.Name);
                    actionList.Add(xivUi);
                }
            }));

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

            await Task.Run(() => Parallel.ForEach(fieldMarkerExData.Values, (action) =>
            {
                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)
                    {
                        return;
                    }

                    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))
                {
                    return;
                }

                lock (actionLock)
                {
                    actionNames.Add(xivUi.Name);
                    actionList.Add(xivUi);
                }
            }));

            actionList.Sort();

            return(actionList);
        }
Esempio n. 5
0
 internal void LoadEntry(BinaryReaderBE reader)
 {
     Offset = reader.ReadInt32();
     reader.ReadInt32(); // size
     Index = reader.ReadInt16();
 }
Esempio n. 6
0
        public void Load(BinaryReaderBE reader)
        {
            long origin = reader.BaseStream.Position;

            Version                         = reader.ReadInt16();
            Type                            = (CollectionType)reader.ReadInt16();
            Flags                           = reader.ReadUInt16();
            colorCount                      = reader.ReadInt16();
            colorTableCount                 = reader.ReadInt16();
            colorTableOffset                = reader.ReadInt32();
            highLevelShapeCount             = reader.ReadInt16();
            highLevelShapeOffsetTableOffset = reader.ReadInt32();
            lowLevelShapeCount              = reader.ReadInt16();
            lowLevelShapeOffsetTableOffset  = reader.ReadInt32();
            bitmapCount                     = reader.ReadInt16();
            bitmapOffsetTableOffset         = reader.ReadInt32();
            pixelsToWorld                   = reader.ReadInt16();
            size                            = reader.ReadInt32();
            reader.BaseStream.Seek(253 * 2, SeekOrigin.Current);

            colorTables.Clear();
            reader.BaseStream.Seek(origin + colorTableOffset, SeekOrigin.Begin);
            for (int i = 0; i < colorTableCount; ++i)
            {
                ColorValue[] table = new ColorValue[colorCount];
                for (int j = 0; j < colorCount; ++j)
                {
                    table[j].Load(reader);
                }
                colorTables.Add(table);
            }

            reader.BaseStream.Seek(origin + bitmapOffsetTableOffset, SeekOrigin.Begin);
            bitmaps.Clear();
            for (int i = 0; i < bitmapCount; ++i)
            {
                int  offset   = reader.ReadInt32();
                long position = reader.BaseStream.Position;
                reader.BaseStream.Seek(origin + offset, SeekOrigin.Begin);
                Bitmap bitmap = new Bitmap();
                bitmap.Load(reader);
                bitmaps.Add(bitmap);
                reader.BaseStream.Seek(position, SeekOrigin.Begin);
            }

            reader.BaseStream.Seek(origin + lowLevelShapeOffsetTableOffset, SeekOrigin.Begin);
            frames.Clear();
            for (int i = 0; i < lowLevelShapeCount; ++i)
            {
                int  offset   = reader.ReadInt32();
                long position = reader.BaseStream.Position;
                reader.BaseStream.Seek(origin + offset, SeekOrigin.Begin);
                ShapeFrame frame = new ShapeFrame();
                frame.Load(reader);
                frames.Add(frame);
                reader.BaseStream.Seek(position, SeekOrigin.Begin);
            }

            reader.BaseStream.Seek(origin + highLevelShapeOffsetTableOffset, SeekOrigin.Begin);
            sequences.Clear();
            for (int i = 0; i < highLevelShapeCount; ++i)
            {
                int  offset   = reader.ReadInt32();
                long position = reader.BaseStream.Position;
                reader.BaseStream.Seek(origin + offset, SeekOrigin.Begin);
                ShapeSequence sequence = new ShapeSequence();
                sequence.Load(reader);
                sequences.Add(sequence);
                reader.BaseStream.Seek(position, SeekOrigin.Begin);
            }
        }
Esempio n. 7
0
 public void Load(BinaryReaderBE reader)
 {
     X       = reader.ReadInt16();
     Y       = reader.ReadInt16();
     Texture = (ShapeDescriptor)reader.ReadUInt16();
 }
Esempio n. 8
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 List <XivFurniture> GetIndoorFurniture()
        {
            // 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;
            const int itemDataLength     = 160;
            const int itemIconDataOffset = 136;

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

            var furnitureList = new List <XivFurniture>();

            foreach (var housingItem in housingDictionary.Values)
            {
                var item = new XivFurniture
                {
                    Category     = XivStrings.Housing,
                    ItemCategory = XivStrings.Furniture_Indoor,
                    ModelInfo    = new XivModelInfo()
                };

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

                    br.BaseStream.Seek(modelNumberOffset, SeekOrigin.Begin);
                    item.ModelInfo.ModelID = 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))
                {
                    furnitureList.Add(item);
                }
            }

            furnitureList.Sort();

            return(furnitureList);
        }
Esempio n. 9
0
        /// <summary>
        /// Gets the list to be displayed in the Minion category
        /// </summary>
        /// <remarks>
        /// The model data for the minion is held separately in modelchara_0.exd
        /// The data within companion_0 exd contains a reference to the index for lookup in modelchara
        /// </remarks>
        /// <returns>A list containing XivMinion data</returns>
        public async Task <List <XivMinion> > GetUncachedMinionList()
        {
            var minionLock = new object();
            var minionList = new List <XivMinion>();

            // 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            = 48;
            const int nameDataOffset        = 6;
            const int modelCharaIndexOffset = 16;

            var minionEx = await _ex.ReadExData(XivEx.companion);

            var modelCharaEx = await XivModelChara.GetModelCharaData(_gameDirectory);

            // Loops through all available minions in the companion exd files
            // At present only one file exists (companion_0)
            await Task.Run(() => Parallel.ForEach(minionEx.Values, (minion) =>
            {
                var xivMinion = new XivMinion
                {
                    PrimaryCategory   = XivStrings.Companions,
                    SecondaryCategory = XivStrings.Minions
                };

                int modelCharaIndex;

                // Big Endian Byte Order
                using (var br = new BinaryReaderBE(new MemoryStream(minion)))
                {
                    br.BaseStream.Seek(nameDataOffset, SeekOrigin.Begin);
                    var nameOffset = br.ReadInt16();

                    br.BaseStream.Seek(modelCharaIndexOffset, SeekOrigin.Begin);
                    modelCharaIndex = br.ReadInt16();

                    br.BaseStream.Seek(dataLength, SeekOrigin.Begin);
                    var nameString =
                        CultureInfo.CurrentCulture.TextInfo.ToTitleCase(Encoding.UTF8
                                                                        .GetString(br.ReadBytes(nameOffset)).Replace("\0", ""));
                    xivMinion.Name = new string(nameString.Where(c => !char.IsControl(c)).ToArray());
                }

                if (modelCharaIndex == 0)
                {
                    return;
                }

                // This will get the model data using the index obtained for the current minion
                xivMinion.ModelInfo = XivModelChara.GetModelInfo(modelCharaEx, modelCharaIndex);

                lock (minionLock)
                {
                    minionList.Add(xivMinion);
                }
            }));

            minionList.Sort();

            return(minionList);
        }
Esempio n. 10
0
 public void Load(BinaryReaderBE reader)
 {
     Type  = (SideType)reader.ReadInt16();
     Flags = (SideFlags)reader.ReadUInt16();
     Primary.Load(reader);
     Secondary.Load(reader);
     Transparent.Load(reader);
     reader.BaseStream.Seek(16, SeekOrigin.Current); // exclusion zone
     ControlPanelType        = reader.ReadInt16();
     ControlPanelPermutation = reader.ReadInt16();
     PrimaryTransferMode     = reader.ReadInt16();
     SecondaryTransferMode   = reader.ReadInt16();
     TransparentTransferMode = reader.ReadInt16();
     PolygonIndex            = reader.ReadInt16();
     LineIndex = reader.ReadInt16();
     PrimaryLightsourceIndex     = reader.ReadInt16();
     SecondaryLightsourceIndex   = reader.ReadInt16();
     TransparentLightsourceIndex = reader.ReadInt16();
     AmbientDelta = reader.ReadInt32();
     reader.ReadInt16(); // unused
 }
Esempio n. 11
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> > 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
            const int itemIndexOffset  = 0;
            const int iconNumberOffset = 4;

            const int itemNameDataOffset = 14;
            const int itemDataLength     = 160;
            const int itemIconDataOffset = 136;

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

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

            var furnitureList = new List <XivFurniture>();

            await Task.Run(() => Parallel.ForEach(pictureDictionary.Values, (housingItem) =>
            {
                var item = new XivFurniture
                {
                    Category     = XivStrings.Housing,
                    ItemCategory = XivStrings.Paintings,
                    ModelInfo    = new XivModelInfo()
                };

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

                    br.BaseStream.Seek(iconNumberOffset, SeekOrigin.Begin);
                    item.ModelInfo.ModelID = br.ReadInt32();

                    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 (paintingsLock)
                    {
                        furnitureList.Add(item);
                    }
                }
            }));

            furnitureList.Sort();

            return(furnitureList);
        }
Esempio n. 12
0
 public void Load(BinaryReaderBE reader)
 {
     Type             = (MediaType)reader.ReadInt16();
     Flags            = (MediaFlags)reader.ReadUInt16();
     LightIndex       = reader.ReadInt16();
     direction        = reader.ReadInt16();
     CurrentMagnitude = reader.ReadInt16();
     Low  = reader.ReadInt16();
     High = reader.ReadInt16();
     reader.ReadInt16(); // X
     reader.ReadInt16(); // Y
     reader.ReadInt16(); // Height
     MinimumLightIntensity = reader.ReadFixed();
     reader.ReadInt16(); // Texture
     reader.ReadInt16(); // TransferMode
     reader.BaseStream.Seek(2 * 2, SeekOrigin.Current);
 }
Esempio n. 13
0
 public void Load(BinaryReaderBE reader)
 {
     Index  = reader.ReadInt16();
     Face   = reader.ReadInt16();
     Colour = reader.ReadInt16();
 }
Esempio n. 14
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     = 168;
            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 = 160;
            }
            else if (_xivLanguage == XivLanguage.Chinese)
            {
                itemDataLength = 160;
            }


            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);
        }
Esempio n. 15
0
        public 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 || DataVersion < 1 || 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);

                    if (applicationSpecificDirectoryDataSize == DirectoryEntry.DataSize)
                    {
                        entry.LoadData(reader);
                    }
                    else
                    {
                        reader.ReadBytes(applicationSpecificDirectoryDataSize);
                    }
                    Directory[entry.Index] = entry;
                }

                // 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);
                }

                if (applicationSpecificDirectoryDataSize != DirectoryEntry.DataSize)
                {
                    foreach (var kvp in Directory)
                    {
                        if (kvp.Value.Chunks.ContainsKey(MapInfo.Tag))
                        {
                            MapInfo        info        = new MapInfo();
                            BinaryReaderBE chunkReader = new BinaryReaderBE(new MemoryStream(kvp.Value.Chunks[MapInfo.Tag]));
                            info.Load(chunkReader);
                            kvp.Value.MissionFlags     = info.MissionFlags;
                            kvp.Value.EnvironmentFlags = info.EnvironmentFlags;
                            kvp.Value.EntryPointFlags  = info.EntryPointFlags;
                            kvp.Value.LevelName        = info.Name;
                        }
                    }
                }
            } finally {
                reader.Close();
            }
        }
Esempio n. 16
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     = 168;
            const int itemIconDataOffset = 136;

            if (_xivLanguage == XivLanguage.Korean)
            {
                itemDataLength = 160;
            }
            else if (_xivLanguage == XivLanguage.Chinese)
            {
                itemDataLength = 160;
            }

            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);
        }
Esempio n. 17
0
        public void Load(BinaryReaderBE reader)
        {
            ItemType    = reader.ReadInt16();
            PowerupType = reader.ReadInt16();
            WeaponClass = reader.ReadInt16();
            Flags       = reader.ReadInt16();

            FiringLightIntensity      = reader.ReadFixed();
            FiringIntensityDecayTicks = reader.ReadInt16();

            IdleHeight          = reader.ReadFixed();
            BobAmplitude        = reader.ReadFixed();
            KickHeight          = reader.ReadFixed();
            ReloadHeight        = reader.ReadFixed();
            IdleWidth           = reader.ReadFixed();
            HorizontalAmplitude = reader.ReadFixed();

            Collection     = reader.ReadInt16();
            IdleShape      = reader.ReadInt16();
            FiringShape    = reader.ReadInt16();
            ReloadingShape = reader.ReadInt16();
            Unused         = reader.ReadInt16();
            ChargingShape  = reader.ReadInt16();
            ChargedShape   = reader.ReadInt16();

            ReadyTicks         = reader.ReadInt16();
            AwaitReloadTicks   = reader.ReadInt16();
            LoadingTicks       = reader.ReadInt16();
            FinishLoadingTicks = reader.ReadInt16();
            PowerupTicks       = reader.ReadInt16();

            for (int i = 0; i < 2; ++i)
            {
                Triggers[i] = new TriggerDefinition();
                Triggers[i].Load(reader);
            }
        }
Esempio n. 18
0
        /// <summary>
        /// Reads and parses the ExHeader file
        /// </summary>
        /// <param name="exFile">The Ex file to use.</param>
        private async Task 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 offset = await _index.GetDataOffset(exdFolderHash, exdFileHash, XivDataFile._0A_Exd);

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

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

            await Task.Run(() =>
            {
                // 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();
                        if (langCode != 0)
                        {
                            LanguageList.Add(langCode);
                        }
                    }
                }
            });
        }
Esempio n. 19
0
        public void Load(BinaryReaderBE reader)
        {
            Type        = (PolygonType)reader.ReadInt16();
            Flags       = reader.ReadUInt16();
            Permutation = reader.ReadInt16();
            VertexCount = reader.ReadUInt16();
            for (int i = 0; i < MaxVertexCount; ++i)
            {
                EndpointIndexes[i] = reader.ReadInt16();
            }

            for (int i = 0; i < MaxVertexCount; ++i)
            {
                LineIndexes[i] = reader.ReadInt16();
            }

            FloorTexture   = (ShapeDescriptor)reader.ReadUInt16();
            CeilingTexture = (ShapeDescriptor)reader.ReadUInt16();
            FloorHeight    = reader.ReadInt16();
            CeilingHeight  = reader.ReadInt16();
            FloorLight     = reader.ReadInt16();
            CeilingLight   = reader.ReadInt16();

            reader.ReadInt32(); // area
            FirstObjectIndex = reader.ReadInt16();

            reader.ReadInt16(); // first_exclusion_zone_index
            reader.ReadInt16(); // line_exclusion_zone_count
            reader.ReadInt16(); // point_exclusion_zone_count
            FloorTransferMode   = reader.ReadInt16();
            CeilingTransferMode = reader.ReadInt16();

            for (int i = 0; i < MaxVertexCount; ++i)
            {
                AdjacentPolygonIndexes[i] = reader.ReadInt16();
            }

            reader.ReadInt16(); // first_neighbor_index
            reader.ReadInt16(); // neighbor_count

            reader.ReadInt16(); // center.x
            reader.ReadInt16(); // center.y

            for (int i = 0; i < SideIndexes.Length; ++i)
            {
                SideIndexes[i] = reader.ReadInt16();
            }

            FloorOrigin.Load(reader);
            CeilingOrigin.Load(reader);

            MediaIndex = reader.ReadInt16();
            MediaLight = reader.ReadInt16();

            reader.ReadInt16(); // sound_source_indexes

            AmbientSound = reader.ReadInt16();
            RandomSound  = reader.ReadInt16();

            reader.BaseStream.Seek(2, SeekOrigin.Current);
        }
Esempio n. 20
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);
                }
            }
Esempio n. 21
0
        /// <summary>
        /// A getter for available gear in the Item exd files
        /// </summary>
        /// <returns>A list containing XivGear data</returns>
        public async Task <List <XivGear> > GetGearList()
        {
            // These are the offsets to relevant data
            // These will need to be changed if data gets added or removed with a patch
            const int modelDataCheckOffset = 30;
            const int dataLength           = 160;
            const int nameDataOffset       = 14;
            const int modelDataOffset      = 24;
            const int iconDataOffset       = 136;
            const int slotDataOffset       = 154;

            var xivGearList = new List <XivGear>();

            xivGearList.AddRange(GetMissingGear());

            var ex             = new Ex(_gameDirectory, _xivLanguage);
            var itemDictionary = await ex.ReadExData(XivEx.item);

            // Loops through all the items in the item exd files
            // Item files start at 0 and increment by 500 for each new file
            // Item_0, Item_500, Item_1000, etc.
            await Task.Run(() => Parallel.ForEach(itemDictionary, (item) =>
            {
                // This checks whether there is any model data present in the current item
                if (item.Value[modelDataCheckOffset] <= 0 && item.Value[modelDataCheckOffset + 1] <= 0)
                {
                    return;
                }

                // Gear can have 2 separate models (MNK weapons for example)
                var primaryMi   = new XivModelInfo();
                var secondaryMi = new XivModelInfo();

                var xivGear = new XivGear
                {
                    Category           = XivStrings.Gear,
                    ModelInfo          = primaryMi,
                    SecondaryModelInfo = secondaryMi
                };

                /* Used to determine if the given model is a weapon
                 * This is important because the data is formatted differently
                 * The model data is a 16 byte section separated into two 8 byte parts (primary model, secondary model)
                 * Format is 8 bytes in length with 2 bytes per data point [short, short, short, short]
                 * Gear: primary model [blank, blank, variant, ID] nothing in secondary model
                 * Weapon: primary model [blank, variant, body, ID] secondary model [blank, variant, body, ID]
                 */
                var isWeapon = false;

                // Big Endian Byte Order
                using (var br = new BinaryReaderBE(new MemoryStream(item.Value)))
                {
                    br.BaseStream.Seek(nameDataOffset, SeekOrigin.Begin);
                    var nameOffset = br.ReadInt16();

                    // Model Data
                    br.BaseStream.Seek(modelDataOffset, SeekOrigin.Begin);

                    // Primary Model Key
                    primaryMi.ModelKey = Quad.Read(br.ReadBytes(8), 0);
                    br.BaseStream.Seek(-8, SeekOrigin.Current);

                    // Primary Blank
                    primaryMi.Unused = br.ReadInt16();

                    // Primary Variant for weapon, blank otherwise
                    var weaponVariant = br.ReadInt16();

                    if (weaponVariant != 0)
                    {
                        primaryMi.Variant = weaponVariant;
                        isWeapon          = true;
                    }

                    // Primary Body if weapon, Variant otherwise
                    if (isWeapon)
                    {
                        primaryMi.Body = br.ReadInt16();
                    }
                    else
                    {
                        primaryMi.Variant = br.ReadInt16();
                    }

                    // Primary Model ID
                    primaryMi.ModelID = br.ReadInt16();

                    // Secondary Model Key
                    isWeapon             = false;
                    secondaryMi.ModelKey = Quad.Read(br.ReadBytes(8), 0);
                    br.BaseStream.Seek(-8, SeekOrigin.Current);

                    // Secondary Blank
                    secondaryMi.Unused = br.ReadInt16();

                    // Secondary Variant for weapon, blank otherwise
                    weaponVariant = br.ReadInt16();

                    if (weaponVariant != 0)
                    {
                        secondaryMi.Variant = weaponVariant;
                        isWeapon            = true;
                    }

                    // Secondary Body if weapon, Variant otherwise
                    if (isWeapon)
                    {
                        secondaryMi.Body = br.ReadInt16();
                    }
                    else
                    {
                        secondaryMi.Variant = br.ReadInt16();
                    }

                    // Secondary Model ID
                    secondaryMi.ModelID = br.ReadInt16();

                    // Icon
                    br.BaseStream.Seek(iconDataOffset, SeekOrigin.Begin);
                    xivGear.IconNumber = br.ReadUInt16();

                    // Gear Slot/Category
                    br.BaseStream.Seek(slotDataOffset, SeekOrigin.Begin);
                    int slotNum = br.ReadByte();

                    // Waist items do not have texture or model data
                    if (slotNum == 6)
                    {
                        return;
                    }

                    xivGear.EquipSlotCategory = slotNum;
                    xivGear.ItemCategory      = _slotNameDictionary.ContainsKey(slotNum) ? _slotNameDictionary[slotNum] : "Unknown";

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

                    lock (_gearLock)
                    {
                        xivGearList.Add(xivGear);
                    }
                }
            }));

            xivGearList.Sort();

            return(xivGearList);
        }
Esempio n. 22
0
        /// <summary>
        /// A getter for available gear in the Item exd files
        /// </summary>
        /// <returns>A list containing XivGear data</returns>
        public async Task <List <XivGear> > GetUnCachedGearList()
        {
            // These are the offsets to relevant data
            // These will need to be changed if data gets added or removed with a patch
            const int modelDataCheckOffset = 30;
            int       dataLength           = DataLengthByPatch["5.5"];
            const int nameDataOffset       = 14;
            const int modelDataOffset      = 24;
            const int iconDataOffset       = 136;
            int       slotDataOffset       = SlotDataOffsetByPatch["5.5"];


            if (_xivLanguage == XivLanguage.Korean)
            {
                dataLength     = DataLengthByPatch["5.5"];
                slotDataOffset = SlotDataOffsetByPatch["5.5"];
            }
            else if (_xivLanguage == XivLanguage.Chinese)
            {
                dataLength     = DataLengthByPatch["5.5"];
                slotDataOffset = SlotDataOffsetByPatch["5.5"];
            }

            var xivGearList = new List <XivGear>();

            xivGearList.AddRange(GetMissingGear());

            var ex             = new Ex(_gameDirectory, _xivLanguage);
            var itemDictionary = await ex.ReadExData(XivEx.item);

            // Loops through all the items in the item exd files
            // Item files start at 0 and increment by 500 for each new file
            // Item_0, Item_500, Item_1000, etc.
            await Task.Run(() => Parallel.ForEach(itemDictionary, (item) =>
            {
                try
                {
                    // This checks whether there is any model data present in the current item
                    if (item.Value[modelDataCheckOffset] <= 0 && item.Value[modelDataCheckOffset + 1] <= 0)
                    {
                        return;
                    }

                    var primaryMi    = new XivGearModelInfo();
                    var secondaryMi  = new XivGearModelInfo();
                    var hasSecondary = false;

                    var xivGear = new XivGear
                    {
                        ExdID           = item.Key,
                        PrimaryCategory = XivStrings.Gear,
                        ModelInfo       = primaryMi,
                    };

                    /* Used to determine if the given model is a weapon
                     * This is important because the data is formatted differently
                     * The model data is a 16 byte section separated into two 8 byte parts (primary model, secondary model)
                     * Format is 8 bytes in length with 2 bytes per data point [short, short, short, short]
                     * Gear: primary model [blank, blank, variant, ID] nothing in secondary model
                     * Weapon: primary model [blank, variant, body, ID] secondary model [blank, variant, body, ID]
                     */
                    var isWeapon = false;

                    // Big Endian Byte Order
                    using (var br = new BinaryReaderBE(new MemoryStream(item.Value)))
                    {
                        br.BaseStream.Seek(nameDataOffset, SeekOrigin.Begin);
                        var nameOffset = br.ReadInt16();

                        // Model Data
                        br.BaseStream.Seek(modelDataOffset, SeekOrigin.Begin);

                        // Primary Model Key
                        primaryMi.ModelKey = Quad.Read(br.ReadBytes(8), 0);
                        br.BaseStream.Seek(-8, SeekOrigin.Current);

                        // Primary Blank
                        var unused = br.ReadInt16();

                        // Primary Variant for weapon, blank otherwise
                        var weaponVariant = br.ReadInt16();

                        if (weaponVariant != 0)
                        {
                            primaryMi.ImcSubsetID = weaponVariant;
                            primaryMi.IsWeapon    = true;
                            isWeapon = true;
                        }

                        // Primary Body if weapon, Variant otherwise
                        if (isWeapon)
                        {
                            primaryMi.SecondaryID = br.ReadInt16();
                        }
                        else
                        {
                            primaryMi.ImcSubsetID = br.ReadInt16();
                        }

                        // Primary Model ID
                        primaryMi.PrimaryID = br.ReadInt16();

                        // Secondary Model Key
                        isWeapon             = false;
                        secondaryMi.ModelKey = Quad.Read(br.ReadBytes(8), 0);
                        br.BaseStream.Seek(-8, SeekOrigin.Current);

                        // Secondary Blank
                        var unused2 = br.ReadInt16();

                        // Secondary Variant for weapon, blank otherwise
                        weaponVariant = br.ReadInt16();

                        if (weaponVariant != 0)
                        {
                            secondaryMi.ImcSubsetID = weaponVariant;
                            secondaryMi.IsWeapon    = true;
                            isWeapon = true;
                        }

                        // Secondary Body if weapon, Variant otherwise
                        if (isWeapon)
                        {
                            secondaryMi.SecondaryID = br.ReadInt16();
                        }
                        else
                        {
                            secondaryMi.ImcSubsetID = br.ReadInt16();
                        }

                        // Secondary Model ID
                        secondaryMi.PrimaryID = br.ReadInt16();

                        // Icon
                        br.BaseStream.Seek(iconDataOffset, SeekOrigin.Begin);
                        xivGear.IconNumber = br.ReadUInt16();

                        // Gear Slot/Category
                        br.BaseStream.Seek(slotDataOffset, SeekOrigin.Begin);
                        int slotNum = br.ReadByte();

                        // Waist items do not have texture or model data
                        if (slotNum == 6)
                        {
                            return;
                        }

                        xivGear.EquipSlotCategory = slotNum;
                        xivGear.SecondaryCategory = _slotNameDictionary.ContainsKey(slotNum) ? _slotNameDictionary[slotNum] : "Unknown";

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

                        // If we have a secondary model

                        XivGear secondaryItem = null;
                        if (secondaryMi.PrimaryID != 0)
                        {
                            // Make a new item for it.
                            secondaryItem                   = (XivGear)xivGear.Clone();
                            secondaryItem.ModelInfo         = secondaryMi;
                            xivGear.Name                   += " - " + XivStrings.Main_Hand;
                            secondaryItem.Name             += " - " + XivStrings.Off_Hand;
                            xivGear.PairedItem              = secondaryItem;
                            secondaryItem.PairedItem        = xivGear;
                            xivGear.SecondaryCategory       = XivStrings.Dual_Wield;
                            secondaryItem.SecondaryCategory = XivStrings.Dual_Wield;
                        }

                        // Rings
                        if (slotNum == 12)
                        {
                            // Make this the Right ring, and create the Left Ring entry.
                            secondaryItem = (XivGear)xivGear.Clone();

                            xivGear.Name       += " - " + XivStrings.Right;
                            secondaryItem.Name += " - " + XivStrings.Left;

                            xivGear.PairedItem       = secondaryItem;
                            secondaryItem.PairedItem = xivGear;
                        }

                        lock (_gearLock)
                        {
                            xivGearList.Add(xivGear);
                            if (secondaryItem != null)
                            {
                                xivGearList.Add(secondaryItem);
                            }
                        }
                    }
                } catch (Exception ex)
                {
                    throw;
                }
            }));

            xivGearList.Sort();

            return(xivGearList);
        }
Esempio n. 23
0
            public void Load(BinaryReaderBE reader)
            {
                Flags = reader.ReadUInt16();
                MinimumLightIntensity = reader.ReadFixed();
                BitmapIndex           = reader.ReadInt16();
                OriginX     = reader.ReadInt16();
                OriginY     = reader.ReadInt16();
                KeyX        = reader.ReadInt16();
                KeyY        = reader.ReadInt16();
                WorldLeft   = reader.ReadInt16();
                WorldRight  = reader.ReadInt16();
                WorldTop    = reader.ReadInt16();
                WorldBottom = reader.ReadInt16();
                WorldX0     = reader.ReadInt16();
                WorldY0     = reader.ReadInt16();

                Unused = new short[4];
                for (int i = 0; i < Unused.Length; i++)
                {
                    Unused[i] = reader.ReadInt16();
                }
            }