public XivTex GetTexData(TexTypePath ttp) { var folder = Path.GetDirectoryName(ttp.Path); folder = folder.Replace("\\", "/"); var file = Path.GetFileName(ttp.Path); var index = new Index(_gameDirectory); var dat = new Dat(_gameDirectory); var offset = index.GetDataOffset(HashGenerator.GetHash(folder), HashGenerator.GetHash(file), ttp.DataFile); if (offset == 0) { throw new Exception($"Could not find offest for {ttp.Path}"); } XivTex xivTex; if (ttp.Path.Contains(".atex")) { var atex = new ATex(_gameDirectory, ttp.DataFile); xivTex = atex.GetATexData(offset); } else { xivTex = dat.GetType4Data(offset, ttp.DataFile); } xivTex.TextureTypeAndPath = ttp; return(xivTex); }
public async Task <XivTex> GetTexData(TexTypePath ttp) { var xivTex = await GetTexData(ttp.Path); xivTex.TextureTypeAndPath = ttp; return(xivTex); }
public async Task <XivTex> GetTexDataPreFetchedIndex(TexTypePath ttp) { var offset = await _index.GetDataOffset(ttp.Path); if (offset == 0) { throw new Exception($"Could not find offset for {ttp.Path}"); } XivTex xivTex; try { if (ttp.Path.Contains(".atex")) { var atex = new ATex(_gameDirectory, ttp.DataFile); xivTex = await atex.GetATexData(offset); } else { xivTex = await _dat.GetType4Data(offset, ttp.DataFile); } } catch (Exception ex) { throw new Exception($"There was an error reading texture data at offset {offset}"); } xivTex.TextureTypeAndPath = ttp; return(xivTex); }
public XivTex GetTexData(TexTypePath ttp) { var xivTex = new XivTex { TextureTypeAndPath = ttp }; var folder = Path.GetDirectoryName(ttp.Path); folder = folder.Replace("\\", "/"); var file = Path.GetFileName(ttp.Path); var index = new Index(_gameDirectory); var dat = new Dat(_gameDirectory); var offset = index.GetDataOffset(HashGenerator.GetHash(folder), HashGenerator.GetHash(file), ttp.DataFile); if (offset == 0) { throw new Exception($"Could not find offest for {ttp.Path}"); } dat.GetType4Data(offset, ttp.DataFile, xivTex); return(xivTex); }
/// <summary> /// Gets the atex paths for a given item /// </summary> /// <param name="itemModel">The item to get the atex paths for</param> /// <returns>A list of TexTypePath containing the atex info</returns> public List <TexTypePath> GetAtexPaths(IItemModel itemModel) { var atexTexTypePathList = new List <TexTypePath>(); var index = new Index(_gameDirectory); var avfx = new Avfx(_gameDirectory, _dataFile); var itemType = ItemType.GetItemType(itemModel); var vfxPath = GetVfxPath(itemModel, itemType); var vfxOffset = index.GetDataOffset(HashGenerator.GetHash(vfxPath.Folder), HashGenerator.GetHash(vfxPath.File), _dataFile); if (vfxOffset == 0) { throw new Exception($"Could not find offset for vfx path {vfxPath.Folder}/{vfxPath.File}"); } var aTexPaths = avfx.GetATexPaths(vfxOffset); foreach (var atexPath in aTexPaths) { var ttp = new TexTypePath { DataFile = _dataFile, Name = Path.GetFileNameWithoutExtension(atexPath), Path = atexPath }; atexTexTypePathList.Add(ttp); } return(atexTexTypePathList); }
public async Task <XivTex> GetTexData(MapInfo map) { var dataFile = IOUtil.GetDataFileFromPath(map.Path); var ttp = new TexTypePath() { DataFile = dataFile, Path = map.Path, Type = map.Usage }; return(await GetTexData(ttp)); }
public async Task <XivTex> GetTexData(string path) { var folder = Path.GetDirectoryName(path); folder = folder.Replace("\\", "/"); var file = Path.GetFileName(path); long offset = 0; var hashedfolder = 0; var hashedfile = 0; hashedfolder = HashGenerator.GetHash(folder); hashedfile = HashGenerator.GetHash(file); var df = IOUtil.GetDataFileFromPath(path); offset = await _index.GetDataOffset(hashedfolder, hashedfile, df); if (offset == 0) { throw new Exception($"Could not find offset for {path}"); } XivTex xivTex; try { if (path.Contains(".atex")) { var atex = new ATex(_gameDirectory, df); xivTex = await atex.GetATexData(offset); } else { xivTex = await _dat.GetType4Data(offset, df); } } catch (Exception ex) { throw new Exception($"There was an error reading texture data at offset {offset}"); } var ttp = new TexTypePath(); ttp.DataFile = df; ttp.Name = Path.GetFileName(path); ttp.Type = XivTexType.Other; ttp.Path = path; xivTex.TextureTypeAndPath = ttp; return(xivTex); }
public async Task <XivTex> GetTexData(TexTypePath ttp) { var folder = Path.GetDirectoryName(ttp.Path); folder = folder.Replace("\\", "/"); var file = Path.GetFileName(ttp.Path); var offset = 0; var hashedfolder = 0; var hashedfile = 0; lock (texLock) { hashedfolder = HashGenerator.GetHash(folder); hashedfile = HashGenerator.GetHash(file); } offset = await _index.GetDataOffset(hashedfolder, hashedfile, ttp.DataFile); if (offset == 0) { throw new Exception($"Could not find offset for {ttp.Path}"); } XivTex xivTex; try { if (ttp.Path.Contains(".atex")) { var atex = new ATex(_gameDirectory, ttp.DataFile); xivTex = await atex.GetATexData(offset); } else { xivTex = await _dat.GetType4Data(offset, ttp.DataFile); } } catch (Exception ex) { throw new Exception($"There was an error reading texture data at offset {offset}"); } xivTex.TextureTypeAndPath = ttp; return(xivTex); }
/// <summary> /// Gets the atex paths for a given item /// </summary> /// <param name="itemModel">The item to get the atex paths for</param> /// <returns>A list of TexTypePath containing the atex info</returns> public async Task <List <TexTypePath> > GetAtexPaths(IItemModel itemModel) { var atexTexTypePathList = new List <TexTypePath>(); var index = new Index(_gameDirectory); var avfx = new Avfx(_gameDirectory, _dataFile); var itemType = ItemType.GetPrimaryItemType(itemModel); var vfxPath = await GetVfxPath(itemModel, itemType); var vfxOffset = await index.GetDataOffset(HashGenerator.GetHash(vfxPath.Folder), HashGenerator.GetHash(vfxPath.File), _dataFile); if (vfxOffset == 0) { throw new Exception($"Could not find offset for vfx path {vfxPath.Folder}/{vfxPath.File}"); } var aTexPaths = new List <string>(); try { aTexPaths = await avfx.GetATexPaths(vfxOffset); } catch (Exception e) { throw new Exception(e.Message); } foreach (var atexPath in aTexPaths) { var ttp = new TexTypePath { DataFile = _dataFile, Name = "VFX: " + Path.GetFileNameWithoutExtension(atexPath), Path = atexPath }; atexTexTypePathList.Add(ttp); } return(atexTexTypePathList); }
/// <summary> /// Gets the names of the textures based on file name /// </summary> /// <remarks> /// The name of the texture is obtained from the file name ending /// </remarks> /// <param name="texPathList">The list of texture paths</param> /// <returns>A list of TexTypePath</returns> private List <TexTypePath> GetTexNames(IEnumerable <string> texPathList, XivDataFile dataFile) { var index = new Index(_gameDirectory); var texTypePathList = new List <TexTypePath>(); foreach (var path in texPathList) { if (!index.FileExists(HashGenerator.GetHash(Path.GetFileName(path)), HashGenerator.GetHash(Path.GetDirectoryName(path).Replace("\\", "/")), dataFile)) { continue; } var ttp = new TexTypePath { Path = path, DataFile = dataFile }; if (path.Contains("dummy") || path.Equals(string.Empty)) { continue; } if (path.Contains("_s.tex")) { ttp.Type = XivTexType.Specular; } else if (path.Contains("_d.tex")) { ttp.Type = XivTexType.Diffuse; } else if (path.Contains("_n.tex")) { ttp.Type = XivTexType.Normal; } else if (path.Contains("_m.tex")) { ttp.Type = path.Contains("skin") ? XivTexType.Skin : XivTexType.Multi; } texTypePathList.Add(ttp); } return(texTypePathList); }
public async Task <XivTex> GetTexDataPreFetchedIndex(TexTypePath ttp) { var folder = Path.GetDirectoryName(ttp.Path); folder = folder.Replace("\\", "/"); var file = Path.GetFileName(ttp.Path); var offset = 0; lock (texLock) { offset = _indexFileDictionary[$"{HashGenerator.GetHash(file)}{HashGenerator.GetHash(folder)}"]; } if (offset == 0) { throw new Exception($"Could not find offest for {ttp.Path}"); } XivTex xivTex; try { if (ttp.Path.Contains(".atex")) { var atex = new ATex(_modding, ttp.DataFile); xivTex = await atex.GetATexData(offset); } else { xivTex = await _modding.Dat.GetType4Data(offset, ttp.DataFile); } } catch (Exception ex) { throw new Exception($"There was an error reading texture data at offset {offset}"); } xivTex.TextureTypeAndPath = ttp; return(xivTex); }
public async Task <List <TexTypePath> > GetAtexPaths(string vfxPath) { var index = new Index(_gameDirectory); var avfx = new Avfx(_gameDirectory, _dataFile); var folder = vfxPath.Substring(0, vfxPath.LastIndexOf("/")); var file = Path.GetFileName(vfxPath); var vfxOffset = await index.GetDataOffset(HashGenerator.GetHash(folder), HashGenerator.GetHash(file), _dataFile); var atexTexTypePathList = new List <TexTypePath>(); if (vfxOffset <= 0) { return(new List <TexTypePath>()); } var aTexPaths = new List <string>(); try { aTexPaths = await avfx.GetATexPaths(vfxOffset); } catch (Exception e) { throw new Exception(e.Message); } foreach (var atexPath in aTexPaths) { var ttp = new TexTypePath { DataFile = _dataFile, Name = "VFX: " + Path.GetFileNameWithoutExtension(atexPath), Path = atexPath }; atexTexTypePathList.Add(ttp); } return(atexTexTypePathList); }
/// <summary> /// Gets the names of the textures based on file name /// </summary> /// <remarks> /// The name of the texture is obtained from the file name ending /// </remarks> /// <param name="texPathList">The list of texture paths</param> /// <returns>A list of TexTypePath</returns> private static List <TexTypePath> GetTexNames(IEnumerable <string> texPathList, XivDataFile dataFile) { var texTypePathList = new List <TexTypePath>(); foreach (var path in texPathList) { var ttp = new TexTypePath { Path = path, DataFile = dataFile }; if (path.Contains("dummy") || path.Equals(string.Empty)) { continue; } if (path.Contains("_s.tex")) { ttp.Type = XivTexType.Specular; } else if (path.Contains("_d.tex")) { ttp.Type = XivTexType.Diffuse; } else if (path.Contains("_n.tex")) { ttp.Type = XivTexType.Normal; } else if (path.Contains("_m.tex")) { ttp.Type = path.Contains("skin") ? XivTexType.Skin : XivTexType.Multi; } texTypePathList.Add(ttp); } return(texTypePathList); }
/// <summary> /// The event handler for the tree view item selection changed /// </summary> private void TreeView_SelectedItemChanged(object sender, RoutedPropertyChangedEventArgs <object> e) { TextureMapComboBox.Items.Clear(); ModelTypeComboBox.Items.Clear(); MaterialComboBox.Items.Clear(); CustomTextureTextBox.Text = string.Empty; CustomModelTextBox.Text = string.Empty; var selectedItem = e.NewValue as Category; var modList = JsonConvert.DeserializeObject <ModList>(File.ReadAllText(_modListDirectory.FullName)); var modItems = from mod in modList.Mods where mod.name.Equals(selectedItem.Name) select mod; foreach (var modItem in modItems) { var itemPath = modItem.fullPath; var modCB = new ModComboBox(); var ttp = new TexTypePath { Path = itemPath, DataFile = XivDataFiles.GetXivDataFile(modItem.datFile) }; // Textures if (itemPath.Contains("_d.")) { modCB.Name = $"{XivTexType.Diffuse} ({Path.GetFileNameWithoutExtension(itemPath)})"; modCB.SelectedMod = modItem; ttp.Type = XivTexType.Diffuse; } else if (itemPath.Contains("_n.")) { modCB.Name = $"{XivTexType.Normal} ({Path.GetFileNameWithoutExtension(itemPath)})"; modCB.SelectedMod = modItem; ttp.Type = XivTexType.Normal; } else if (itemPath.Contains("_s.")) { modCB.Name = $"{XivTexType.Specular} ({Path.GetFileNameWithoutExtension(itemPath)})"; modCB.SelectedMod = modItem; ttp.Type = XivTexType.Specular; } else if (itemPath.Contains("_m.")) { modCB.Name = $"{XivTexType.Multi} ({Path.GetFileNameWithoutExtension(itemPath)})"; modCB.SelectedMod = modItem; ttp.Type = XivTexType.Multi; } else if (itemPath.Contains("material")) { modCB.Name = $"{XivTexType.ColorSet} ({Path.GetFileNameWithoutExtension(itemPath)})"; modCB.SelectedMod = modItem; ttp.Type = XivTexType.ColorSet; } else if (itemPath.Contains("decal")) { modCB.Name = $"{XivTexType.Mask} ({Path.GetFileNameWithoutExtension(itemPath)})"; modCB.SelectedMod = modItem; ttp.Type = XivTexType.Mask; } else if (itemPath.Contains("vfx")) { modCB.Name = $"{XivTexType.Vfx} ({Path.GetFileNameWithoutExtension(itemPath)})"; modCB.SelectedMod = modItem; ttp.Type = XivTexType.Vfx; } else if (itemPath.Contains("ui/")) { if (itemPath.Contains("icon")) { modCB.Name = $"{XivTexType.Icon} ({Path.GetFileNameWithoutExtension(itemPath)})"; modCB.SelectedMod = modItem; ttp.Type = XivTexType.Icon; } else if (itemPath.Contains("map")) { modCB.Name = $"{XivTexType.Map} ({Path.GetFileNameWithoutExtension(itemPath)})"; modCB.SelectedMod = modItem; ttp.Type = XivTexType.Map; } else { modCB.Name = $"UI ({Path.GetFileNameWithoutExtension(itemPath)})"; modCB.SelectedMod = modItem; ttp.Type = XivTexType.Other; } } if (modCB.Name != null) { modCB.TexTypePath = ttp; TextureMapComboBox.Items.Add(modCB); } // Models if (itemPath.Contains(".mdl")) { modCB.Name = $"{((IItemModel)selectedItem.Item).ModelInfo.ModelID} ({Path.GetFileNameWithoutExtension(itemPath)})"; modCB.SelectedMod = modItem; modCB.TexTypePath = null; ModelTypeComboBox.Items.Add(modCB); } // Material if (itemPath.Contains(".mtrl")) { modCB.Name = $"Material ({Path.GetFileNameWithoutExtension(itemPath)})"; modCB.SelectedMod = modItem; modCB.TexTypePath = null; MaterialComboBox.Items.Add(modCB); MaterialTabItem.IsEnabled = true; } } if (TextureMapComboBox.Items.Count > 0) { AddCurrentTextureButton.IsEnabled = true; GetCustomTextureButton.IsEnabled = true; CustomTextureTextBox.IsEnabled = true; AddCustomTextureButton.IsEnabled = false; TextureMapComboBox.SelectedIndex = 0; NoTextureModsLabel.Content = string.Empty; } else { AddCurrentTextureButton.IsEnabled = false; GetCustomTextureButton.IsEnabled = false; CustomTextureTextBox.IsEnabled = false; AddCustomTextureButton.IsEnabled = false; NoTextureModsLabel.Content = "There are no Texture mods present.\n\nIf you would like to enable this, first import a texture for the selected item."; } if (ModelTypeComboBox.Items.Count > 0) { AddCurrentModelButton.IsEnabled = true; GetCustomModelButton.IsEnabled = true; CustomModelTextBox.IsEnabled = true; AdvOptionsButton.IsEnabled = true; AddCustomModelButton.IsEnabled = false; ModelTypeComboBox.SelectedIndex = 0; NoModelModsLabel.Content = string.Empty; } else { AddCurrentModelButton.IsEnabled = false; GetCustomModelButton.IsEnabled = false; CustomModelTextBox.IsEnabled = false; AdvOptionsButton.IsEnabled = false; AddCustomModelButton.IsEnabled = false; NoModelModsLabel.Content = "There are no 3D Model mods present.\n\nIf you would like to enable this, first import a model for the selected item."; } if (MaterialComboBox.Items.Count > 0) { AddCurrentMaterialButton.IsEnabled = true; MaterialComboBox.SelectedIndex = 0; NoMaterialsModsLabel.Content = string.Empty; } else { AddCurrentMaterialButton.IsEnabled = false; NoMaterialsModsLabel.Content = "There are no Material mods present.\n\nIf you would like to enable this, first import a Material for the selected item."; } SelectModGroup.IsEnabled = true; }
/// <summary> /// Gets the MTRL data for the given item /// </summary> /// <remarks> /// It requires a race (The default is usually <see cref="XivRace.Hyur_Midlander_Male"/>) /// It also requires an mtrl part <see cref="GearInfo.GetPartList(IItemModel, XivRace)"/> (default is 'a') /// </remarks> /// <param name="itemModel">Item that contains model data</param> /// <param name="race">The race for the requested data</param> /// <param name="part">The Mtrl part </param> /// <returns></returns> public XivMtrl GetMtrlData(IItemModel itemModel, XivRace race, char part) { var index = new Index(_gameDirectory); var dat = new Dat(_gameDirectory); var itemType = ItemType.GetItemType(itemModel); // Get mtrl path var mtrlPath = GetMtrlPath(itemModel, race, part, itemType); // Get mtrl offset var mtrlOffset = index.GetDataOffset(HashGenerator.GetHash(mtrlPath.Folder), HashGenerator.GetHash(mtrlPath.File), _dataFile); if (mtrlOffset == 0) { throw new Exception($"Could not find offest for {mtrlPath.Folder}/{mtrlPath.File}"); } // Get uncompressed mtrl data var mtrlData = dat.GetType2Data(mtrlOffset, _dataFile); XivMtrl xivMtrl; using (var br = new BinaryReader(new MemoryStream(mtrlData))) { xivMtrl = new XivMtrl { Signature = br.ReadInt32(), FileSize = br.ReadInt16(), ColorSetDataSize = br.ReadInt16(), MaterialDataSize = br.ReadInt16(), TexturePathsDataSize = br.ReadByte(), Unknown = br.ReadByte(), TextureCount = br.ReadByte(), MapCount = br.ReadByte(), ColorSetCount = br.ReadByte(), Unknown1 = br.ReadByte(), TextureTypePathList = new List <TexTypePath>(), MTRLPath = $"{mtrlPath.Folder}/{mtrlPath.File}" }; var pathSizeList = new List <int>(); // get the texture path offsets xivMtrl.TexturePathOffsetList = new List <int>(xivMtrl.TextureCount); for (var i = 0; i < xivMtrl.TextureCount; i++) { xivMtrl.TexturePathOffsetList.Add(br.ReadInt16()); br.ReadBytes(2); // add the size of the paths if (i > 0) { pathSizeList.Add(xivMtrl.TexturePathOffsetList[i] - xivMtrl.TexturePathOffsetList[i - 1]); } } // get the map path offsets xivMtrl.MapPathOffsetList = new List <int>(xivMtrl.MapCount); for (var i = 0; i < xivMtrl.MapCount; i++) { xivMtrl.MapPathOffsetList.Add(br.ReadInt16()); br.ReadBytes(2); // add the size of the paths if (i > 0) { pathSizeList.Add(xivMtrl.MapPathOffsetList[i] - xivMtrl.MapPathOffsetList[i - 1]); } else { pathSizeList.Add(xivMtrl.MapPathOffsetList[i] - xivMtrl.TexturePathOffsetList[xivMtrl.TextureCount - 1]); } } // get the color set offsets xivMtrl.ColorSetPathOffsetList = new List <int>(xivMtrl.ColorSetCount); for (var i = 0; i < xivMtrl.ColorSetCount; i++) { xivMtrl.ColorSetPathOffsetList.Add(br.ReadInt16()); br.ReadBytes(2); // add the size of the paths if (i > 0) { pathSizeList.Add(xivMtrl.ColorSetPathOffsetList[i] - xivMtrl.ColorSetPathOffsetList[i - 1]); } else { pathSizeList.Add(xivMtrl.ColorSetPathOffsetList[i] - xivMtrl.MapPathOffsetList[xivMtrl.MapCount - 1]); } } pathSizeList.Add(xivMtrl.TexturePathsDataSize - xivMtrl.ColorSetPathOffsetList[xivMtrl.ColorSetCount - 1]); var count = 0; // get the texture path strings xivMtrl.TexturePathList = new List <string>(xivMtrl.TextureCount); for (var i = 0; i < xivMtrl.TextureCount; i++) { xivMtrl.TexturePathList.Add(Encoding.UTF8.GetString(br.ReadBytes(pathSizeList[count])).Replace("\0", "")); count++; } // add the textures to the TextureTypePathList xivMtrl.TextureTypePathList.AddRange(GetTexNames(xivMtrl.TexturePathList, _dataFile)); // get the map path strings xivMtrl.MapPathList = new List <string>(xivMtrl.MapCount); for (var i = 0; i < xivMtrl.MapCount; i++) { xivMtrl.MapPathList.Add(Encoding.UTF8.GetString(br.ReadBytes(pathSizeList[count])).Replace("\0", "")); count++; } // get the color set path strings xivMtrl.ColorSetPathList = new List <string>(xivMtrl.ColorSetCount); for (var i = 0; i < xivMtrl.ColorSetCount; i++) { xivMtrl.ColorSetPathList.Add(Encoding.UTF8.GetString(br.ReadBytes(pathSizeList[count])).Replace("\0", "")); count++; } // If the mtrl file contains a color set, add it to the TextureTypePathList if (xivMtrl.ColorSetDataSize > 0) { var ttp = new TexTypePath { Path = mtrlPath.Folder + "/" + mtrlPath.File, Type = XivTexType.ColorSet, DataFile = _dataFile }; xivMtrl.TextureTypePathList.Add(ttp); } var shaderPathSize = xivMtrl.MaterialDataSize - xivMtrl.TexturePathsDataSize; xivMtrl.Shader = Encoding.UTF8.GetString(br.ReadBytes(shaderPathSize)).Replace("\0", ""); xivMtrl.Unknown2 = br.ReadInt32(); xivMtrl.ColorSetData = new List <Half>(); for (var i = 0; i < xivMtrl.ColorSetDataSize / 2; i++) { xivMtrl.ColorSetData.Add(new Half(br.ReadUInt16())); } xivMtrl.AdditionalDataSize = br.ReadInt16(); xivMtrl.DataStruct1Count = br.ReadInt16(); xivMtrl.DataStruct2Count = br.ReadInt16(); xivMtrl.ParameterStructCount = br.ReadInt16(); xivMtrl.ShaderNumber = br.ReadInt16(); xivMtrl.Unknown3 = br.ReadInt16(); xivMtrl.DataStruct1List = new List <DataStruct1>(xivMtrl.DataStruct1Count); for (var i = 0; i < xivMtrl.DataStruct1Count; i++) { xivMtrl.DataStruct1List.Add(new DataStruct1 { ID = br.ReadUInt32(), Unknown1 = br.ReadUInt32() }); } xivMtrl.DataStruct2List = new List <DataStruct2>(xivMtrl.DataStruct2Count); for (var i = 0; i < xivMtrl.DataStruct2Count; i++) { xivMtrl.DataStruct2List.Add(new DataStruct2 { ID = br.ReadUInt32(), Offset = br.ReadInt16(), Size = br.ReadInt16() }); } xivMtrl.ParameterStructList = new List <ParameterStruct>(xivMtrl.ParameterStructCount); for (var i = 0; i < xivMtrl.ParameterStructCount; i++) { xivMtrl.ParameterStructList.Add(new ParameterStruct { ID = br.ReadUInt32(), Unknown1 = br.ReadInt16(), Unknown2 = br.ReadInt16(), TextureIndex = br.ReadUInt32() }); } xivMtrl.AdditionalData = br.ReadBytes(xivMtrl.AdditionalDataSize); } return(xivMtrl); }
/// <summary> /// Gets the MTRL data for the given offset and path /// </summary> /// <param name="mtrlOffset">The offset to the mtrl in the dat file</param> /// <param name="mtrlPath">The full internal game path for the mtrl</param> /// <returns>XivMtrl containing all the mtrl data</returns> public XivMtrl GetMtrlData(int mtrlOffset, string mtrlPath, int dxVersion) { var dat = new Dat(_gameDirectory); var index = new Index(_gameDirectory); // Get uncompressed mtrl data var mtrlData = dat.GetType2Data(mtrlOffset, _dataFile); XivMtrl xivMtrl; using (var br = new BinaryReader(new MemoryStream(mtrlData))) { xivMtrl = new XivMtrl { Signature = br.ReadInt32(), FileSize = br.ReadInt16(), ColorSetDataSize = br.ReadUInt16(), MaterialDataSize = br.ReadUInt16(), TexturePathsDataSize = br.ReadUInt16(), TextureCount = br.ReadByte(), MapCount = br.ReadByte(), ColorSetCount = br.ReadByte(), UnknownDataSize = br.ReadByte(), TextureTypePathList = new List <TexTypePath>(), MTRLPath = mtrlPath }; var pathSizeList = new List <int>(); // get the texture path offsets xivMtrl.TexturePathOffsetList = new List <int>(xivMtrl.TextureCount); xivMtrl.TexturePathUnknownList = new List <short>(xivMtrl.TextureCount); for (var i = 0; i < xivMtrl.TextureCount; i++) { xivMtrl.TexturePathOffsetList.Add(br.ReadInt16()); xivMtrl.TexturePathUnknownList.Add(br.ReadInt16()); // add the size of the paths if (i > 0) { pathSizeList.Add(xivMtrl.TexturePathOffsetList[i] - xivMtrl.TexturePathOffsetList[i - 1]); } } // get the map path offsets xivMtrl.MapPathOffsetList = new List <int>(xivMtrl.MapCount); xivMtrl.MapPathUnknownList = new List <short>(xivMtrl.MapCount); for (var i = 0; i < xivMtrl.MapCount; i++) { xivMtrl.MapPathOffsetList.Add(br.ReadInt16()); xivMtrl.MapPathUnknownList.Add(br.ReadInt16()); // add the size of the paths if (i > 0) { pathSizeList.Add(xivMtrl.MapPathOffsetList[i] - xivMtrl.MapPathOffsetList[i - 1]); } else { pathSizeList.Add(xivMtrl.MapPathOffsetList[i] - xivMtrl.TexturePathOffsetList[xivMtrl.TextureCount - 1]); } } // get the color set offsets xivMtrl.ColorSetPathOffsetList = new List <int>(xivMtrl.ColorSetCount); xivMtrl.ColorSetPathUnknownList = new List <short>(xivMtrl.ColorSetCount); for (var i = 0; i < xivMtrl.ColorSetCount; i++) { xivMtrl.ColorSetPathOffsetList.Add(br.ReadInt16()); xivMtrl.ColorSetPathUnknownList.Add(br.ReadInt16()); // add the size of the paths if (i > 0) { pathSizeList.Add(xivMtrl.ColorSetPathOffsetList[i] - xivMtrl.ColorSetPathOffsetList[i - 1]); } else { pathSizeList.Add(xivMtrl.ColorSetPathOffsetList[i] - xivMtrl.MapPathOffsetList[xivMtrl.MapCount - 1]); } } pathSizeList.Add(xivMtrl.TexturePathsDataSize - xivMtrl.ColorSetPathOffsetList[xivMtrl.ColorSetCount - 1]); var count = 0; // get the texture path strings xivMtrl.TexturePathList = new List <string>(xivMtrl.TextureCount); for (var i = 0; i < xivMtrl.TextureCount; i++) { var texturePath = Encoding.UTF8.GetString(br.ReadBytes(pathSizeList[count])).Replace("\0", ""); var dx11FileName = Path.GetFileName(texturePath).Insert(0, "--"); if (index.FileExists(HashGenerator.GetHash(dx11FileName), HashGenerator.GetHash(Path.GetDirectoryName(texturePath).Replace("\\", "/")), _dataFile)) { texturePath = texturePath.Insert(texturePath.LastIndexOf("/") + 1, "--"); } xivMtrl.TexturePathList.Add(texturePath); count++; } // add the textures to the TextureTypePathList xivMtrl.TextureTypePathList.AddRange(GetTexNames(xivMtrl.TexturePathList, _dataFile)); // get the map path strings xivMtrl.MapPathList = new List <string>(xivMtrl.MapCount); for (var i = 0; i < xivMtrl.MapCount; i++) { xivMtrl.MapPathList.Add(Encoding.UTF8.GetString(br.ReadBytes(pathSizeList[count])).Replace("\0", "")); count++; } // get the color set path strings xivMtrl.ColorSetPathList = new List <string>(xivMtrl.ColorSetCount); for (var i = 0; i < xivMtrl.ColorSetCount; i++) { xivMtrl.ColorSetPathList.Add(Encoding.UTF8.GetString(br.ReadBytes(pathSizeList[count])).Replace("\0", "")); count++; } // If the mtrl file contains a color set, add it to the TextureTypePathList if (xivMtrl.ColorSetDataSize > 0) { var ttp = new TexTypePath { Path = mtrlPath, Type = XivTexType.ColorSet, DataFile = _dataFile }; xivMtrl.TextureTypePathList.Add(ttp); } var shaderPathSize = xivMtrl.MaterialDataSize - xivMtrl.TexturePathsDataSize; xivMtrl.Shader = Encoding.UTF8.GetString(br.ReadBytes(shaderPathSize)).Replace("\0", ""); xivMtrl.Unknown2 = br.ReadBytes(xivMtrl.UnknownDataSize); if (xivMtrl.ColorSetDataSize > 0) { // Color Data is always 512 (6 x 14 = 64 x 8bpp = 512) var colorDataSize = 512; xivMtrl.ColorSetData = new List <Half>(); for (var i = 0; i < colorDataSize / 2; i++) { xivMtrl.ColorSetData.Add(new Half(br.ReadUInt16())); } // If the color set is 544 in length, it has an extra 32 bytes at the end if (xivMtrl.ColorSetDataSize == 544) { xivMtrl.ColorSetExtraData = br.ReadBytes(32); } } xivMtrl.AdditionalDataSize = br.ReadUInt16(); xivMtrl.DataStruct1Count = br.ReadUInt16(); xivMtrl.DataStruct2Count = br.ReadUInt16(); xivMtrl.ParameterStructCount = br.ReadUInt16(); xivMtrl.ShaderNumber = br.ReadUInt16(); xivMtrl.Unknown3 = br.ReadUInt16(); xivMtrl.DataStruct1List = new List <DataStruct1>(xivMtrl.DataStruct1Count); for (var i = 0; i < xivMtrl.DataStruct1Count; i++) { xivMtrl.DataStruct1List.Add(new DataStruct1 { ID = br.ReadUInt32(), Unknown1 = br.ReadUInt32() }); } xivMtrl.DataStruct2List = new List <DataStruct2>(xivMtrl.DataStruct2Count); for (var i = 0; i < xivMtrl.DataStruct2Count; i++) { xivMtrl.DataStruct2List.Add(new DataStruct2 { ID = br.ReadUInt32(), Offset = br.ReadInt16(), Size = br.ReadInt16() }); } xivMtrl.ParameterStructList = new List <ParameterStruct>(xivMtrl.ParameterStructCount); for (var i = 0; i < xivMtrl.ParameterStructCount; i++) { xivMtrl.ParameterStructList.Add(new ParameterStruct { ID = br.ReadUInt32(), Unknown1 = br.ReadInt16(), Unknown2 = br.ReadInt16(), TextureIndex = br.ReadUInt32() }); } xivMtrl.AdditionalData = br.ReadBytes(xivMtrl.AdditionalDataSize); } return(xivMtrl); }
/// <summary> /// The event handler for the tree view item selection changed /// </summary> private void TreeView_SelectedItemChanged(object sender, RoutedPropertyChangedEventArgs <object> e) { var selectedItem = e.NewValue as Category; if (selectedItem == null || selectedItem.Item == null) { return; } TextureMapComboBox.Items.Clear(); ModelTypeComboBox.Items.Clear(); MaterialComboBox.Items.Clear(); CustomTextureTextBox.Text = string.Empty; var modding = new Modding(_gameDirectory); var modList = modding.GetModList(); var modItems = from mod in modList.Mods where mod.name.Equals(selectedItem.Name) select mod; foreach (var modItem in modItems) { var itemPath = modItem.fullPath; var modCB = new ModComboBox(); var ttp = new TexTypePath { Path = itemPath, DataFile = XivDataFiles.GetXivDataFile(modItem.datFile) }; // Textures if (itemPath.Contains("_d.")) { modCB.Name = $"{XivTexType.Diffuse} ({Path.GetFileNameWithoutExtension(itemPath)})"; modCB.SelectedMod = modItem; ttp.Type = XivTexType.Diffuse; } else if (itemPath.Contains("_n.")) { modCB.Name = $"{XivTexType.Normal} ({Path.GetFileNameWithoutExtension(itemPath)})"; modCB.SelectedMod = modItem; ttp.Type = XivTexType.Normal; } else if (itemPath.Contains("_s.")) { modCB.Name = $"{XivTexType.Specular} ({Path.GetFileNameWithoutExtension(itemPath)})"; modCB.SelectedMod = modItem; ttp.Type = XivTexType.Specular; } else if (itemPath.Contains("_m.")) { modCB.Name = $"{XivTexType.Multi} ({Path.GetFileNameWithoutExtension(itemPath)})"; modCB.SelectedMod = modItem; ttp.Type = XivTexType.Multi; } else if (itemPath.Contains("material")) { modCB.Name = $"{XivTexType.ColorSet} ({Path.GetFileNameWithoutExtension(itemPath)})"; modCB.SelectedMod = modItem; ttp.Type = XivTexType.ColorSet; } else if (itemPath.Contains("decal")) { modCB.Name = $"{XivTexType.Mask} ({Path.GetFileNameWithoutExtension(itemPath)})"; modCB.SelectedMod = modItem; ttp.Type = XivTexType.Mask; } else if (itemPath.Contains("vfx")) { modCB.Name = $"{XivTexType.Vfx} ({Path.GetFileNameWithoutExtension(itemPath)})"; modCB.SelectedMod = modItem; ttp.Type = XivTexType.Vfx; } else if (itemPath.Contains("ui/")) { if (itemPath.Contains("icon")) { modCB.Name = $"{XivTexType.Icon} ({Path.GetFileNameWithoutExtension(itemPath)})"; modCB.SelectedMod = modItem; ttp.Type = XivTexType.Icon; } else if (itemPath.Contains("map")) { modCB.Name = $"{XivTexType.Map} ({Path.GetFileNameWithoutExtension(itemPath)})"; modCB.SelectedMod = modItem; ttp.Type = XivTexType.Map; } else { modCB.Name = $"UI ({Path.GetFileNameWithoutExtension(itemPath)})"; modCB.SelectedMod = modItem; ttp.Type = XivTexType.Other; } } else if (itemPath.Contains(".tex")) { modCB.Name = $"{XivTexType.Other} ({Path.GetFileNameWithoutExtension(itemPath)})"; modCB.SelectedMod = modItem; ttp.Type = XivTexType.Other; } if (modCB.Name != null) { modCB.TexTypePath = ttp; TextureMapComboBox.Items.Add(modCB); } // Models if (itemPath.Contains(".mdl")) { //esrinzou for Repair program crash when selecting [character/Body] item //modCB.Name = $"{((IItemModel)selectedItem.Item).ModelInfo.ModelID} ({Path.GetFileNameWithoutExtension(itemPath)})"; //esrinzou begin if (((IItemModel)selectedItem.Item).ModelInfo == null) { modCB.Name = $"{((IItemModel)selectedItem.Item).Name} ({Path.GetFileNameWithoutExtension(itemPath)})"; } else { var modelId = ((IItemModel)selectedItem.Item).ModelInfo.PrimaryID; if (selectedItem.Item.PrimaryCategory.Equals(XivStrings.Character)) { var item = selectedItem.Item; if (item.Name.Equals(XivStrings.Body)) { modelId = int.Parse( itemPath.Substring(itemPath.IndexOf("/body", StringComparison.Ordinal) + 7, 4)); } else if (item.Name.Equals(XivStrings.Hair)) { modelId = int.Parse( itemPath.Substring(itemPath.IndexOf("/hair", StringComparison.Ordinal) + 7, 4)); } else if (item.Name.Equals(XivStrings.Face)) { modelId = int.Parse( itemPath.Substring(itemPath.IndexOf("/face", StringComparison.Ordinal) + 7, 4)); } else if (item.Name.Equals(XivStrings.Tail)) { modelId = int.Parse( itemPath.Substring(itemPath.IndexOf("/tail", StringComparison.Ordinal) + 7, 4)); } } modCB.Name = $"{modelId} ({Path.GetFileNameWithoutExtension(itemPath)})"; } //esrinzou end modCB.SelectedMod = modItem; modCB.TexTypePath = null; ModelTypeComboBox.Items.Add(modCB); } // Material if (itemPath.Contains(".mtrl")) { var materialModCB = new ModComboBox { Name = $"Material ({Path.GetFileNameWithoutExtension(itemPath)})", SelectedMod = modItem, TexTypePath = null }; MaterialComboBox.Items.Add(materialModCB); MaterialTabItem.IsEnabled = true; } } if (TextureMapComboBox.Items.Count > 0) { AddCurrentTextureButton.IsEnabled = true; GetCustomTextureButton.IsEnabled = true; CustomTextureTextBox.IsEnabled = true; AddCustomTextureButton.IsEnabled = false; TextureMapComboBox.SelectedIndex = 0; NoTextureModsLabel.Content = string.Empty; } else { AddCurrentTextureButton.IsEnabled = false; GetCustomTextureButton.IsEnabled = false; CustomTextureTextBox.IsEnabled = false; AddCustomTextureButton.IsEnabled = false; NoTextureModsLabel.Content = UIStrings.No_Texture_Mods; } if (ModelTypeComboBox.Items.Count > 0) { AddCurrentModelButton.IsEnabled = true; AdvOptionsButton.IsEnabled = true; ModelTypeComboBox.SelectedIndex = 0; NoModelModsLabel.Content = string.Empty; } else { AddCurrentModelButton.IsEnabled = false; AdvOptionsButton.IsEnabled = false; NoModelModsLabel.Content = UIStrings.No_3D_Mods; } if (MaterialComboBox.Items.Count > 0) { AddCurrentMaterialButton.IsEnabled = true; MaterialComboBox.SelectedIndex = 0; NoMaterialsModsLabel.Content = string.Empty; } else { AddCurrentMaterialButton.IsEnabled = false; NoMaterialsModsLabel.Content = UIStrings.No_Material_Mods; } SelectModGroup.IsEnabled = true; }