public ModListViewModel() { HashSet <string> categorySet = new HashSet <string>(); try { foreach (string line in File.ReadAllLines(Info.modListDir)) { JsonEntry entry = JsonConvert.DeserializeObject <JsonEntry>(line); categorySet.Add(entry.category); } } catch (Exception e) { MessageBox.Show("[VM] Error Accessing .modlist File \n" + e.Message, "Error", MessageBoxButton.OK, MessageBoxImage.Error); } foreach (string category in categorySet) { _category = new ModListTVViewModel(category); _categories.Add(_category); } }
private void SaveReportJson() { // TODO needs a more restricted output (full internal state contains useless information). var session = m_parser.SessionInfo; var countDrivers = m_parser.CountDrivers; var drivers = m_parser.Drivers; var events = m_parser.EventList.Events; JsonEntry json = new JsonEntry(); json.SessionInfo = session.Session.ToString("g"); json.Track = session.EventTrack.ToString("g"); json.Laps = session.TotalLaps; DriverData[] jsonDrivers = new DriverData[countDrivers]; for (int i = 0; i < countDrivers; ++i) { jsonDrivers[i] = m_parser.Drivers[i]; } json.Drivers = jsonDrivers; string[] jsonDriversTag = new string[countDrivers]; json.DriverTag = jsonDriversTag; string filename = DateTime.Now.ToString("ddMMyy_HHmmss") + "_report.json"; var jsonText = Newtonsoft.Json.JsonConvert.SerializeObject(json, Newtonsoft.Json.Formatting.Indented); File.WriteAllText(filename, jsonText); }
public ModListTVViewModel(string category, ModListTVViewModel parent) { _parent = parent; _category = category; HashSet <string> itemSet = new HashSet <string>(); try { foreach (string line in File.ReadAllLines(Properties.Settings.Default.Modlist_Directory)) { JsonEntry entry = JsonConvert.DeserializeObject <JsonEntry>(line); if (entry.category.Equals(category) && _parent == null) { itemSet.Add(entry.name); } } } catch (Exception e) { FlexibleMessageBox.Show("Error Accessing .modlist File \n" + e.Message, "MLTVVM Error " + Info.appVersion, MessageBoxButtons.OK, MessageBoxIcon.Error); } foreach (string name in itemSet) { _children.Add(new ModListTVViewModel(name, this)); } }
public ModListTVViewModel(string category, ModListTVViewModel parent) { _parent = parent; _category = category; HashSet <string> itemSet = new HashSet <string>(); try { foreach (string line in File.ReadAllLines(Info.modListDir)) { JsonEntry entry = JsonConvert.DeserializeObject <JsonEntry>(line); if (entry.category.Equals(category) && _parent == null) { itemSet.Add(entry.name); } } } catch (Exception e) { MessageBox.Show("[VM] Error Accessing .modlist File \n" + e.Message, "Error", MessageBoxButton.OK, MessageBoxImage.Error); } foreach (string name in itemSet) { _children.Add(new ModListTVViewModel(name, this)); } }
public ModListViewModel() { HashSet <string> categorySet = new HashSet <string>(); try { foreach (string line in File.ReadAllLines(Properties.Settings.Default.Modlist_Directory)) { JsonEntry entry = JsonConvert.DeserializeObject <JsonEntry>(line); if (!entry.category.Equals("")) { categorySet.Add(entry.category); } } } catch (Exception e) { FlexibleMessageBox.Show("Error Accessing .modlist File \n" + e.Message, "ModListViewModel Error " + Info.appVersion, MessageBoxButtons.OK, MessageBoxIcon.Error); } foreach (string category in categorySet) { _category = new ModListTVViewModel(category); _categories.Add(_category); } }
private void Menu_ReapplyAll_Click(object sender, RoutedEventArgs e) { JsonEntry modEntry = null; string line; try { using (StreamReader sr = new StreamReader(Properties.Settings.Default.Modlist_Directory)) { while ((line = sr.ReadLine()) != null) { modEntry = JsonConvert.DeserializeObject <JsonEntry>(line); if (modEntry.originalOffset != 0) { Helper.UpdateIndex(modEntry.modOffset, modEntry.fullPath, modEntry.datFile); Helper.UpdateIndex2(modEntry.modOffset, modEntry.fullPath, modEntry.datFile); } } } } catch (Exception ex) { MessageBox.Show("[Main] Error Accessing .modlist File \n" + ex.Message, "Error", MessageBoxButton.OK, MessageBoxImage.Error); } }
private void RevertAllMods() { if (!Helper.IsIndexLocked(true)) { JsonEntry modEntry = null; string line; try { using (StreamReader sr = new StreamReader(Properties.Settings.Default.Modlist_Directory)) { while ((line = sr.ReadLine()) != null) { modEntry = JsonConvert.DeserializeObject <JsonEntry>(line); Helper.UpdateIndex(modEntry.originalOffset, modEntry.fullPath, modEntry.datFile); Helper.UpdateIndex2(modEntry.originalOffset, modEntry.fullPath, modEntry.datFile); } } } catch (Exception ex) { FlexibleMessageBox.Show("Error Accessing .modlist File \n" + ex.Message, "MainViewModel Error " + Info.appVersion, MessageBoxButtons.OK, MessageBoxIcon.Error); } } }
private void DeleteButton_Click(object sender, RoutedEventArgs e) { var selected = listBox.SelectedItems; List <ModListModel> removeList = new List <ModListModel>(); var mlm = (ObservableCollection <ModListModel>)listBox.ItemsSource; foreach (ModListModel s in selected) { int offset = 0; if (s.Active == Brushes.Transparent) { offset = s.Entry.originalOffset; Helper.UpdateIndex(offset, s.Entry.fullPath, s.Entry.datFile); Helper.UpdateIndex2(offset, s.Entry.fullPath, s.Entry.datFile); } removeList.Add(s); } string[] lines = File.ReadAllLines(Properties.Settings.Default.Modlist_Directory); foreach (var r in removeList) { for (int i = 0; i < lines.Length; i++) { var modEntry = JsonConvert.DeserializeObject <JsonEntry>(lines[i]); if (r.Entry.fullPath.Equals(modEntry.fullPath)) { JsonEntry replaceEntry = new JsonEntry() { category = String.Empty, name = String.Empty, fullPath = String.Empty, originalOffset = 0, modOffset = modEntry.modOffset, modSize = modEntry.modSize, datFile = modEntry.datFile }; lines[i] = JsonConvert.SerializeObject(replaceEntry); } } mlm.Remove(r); } File.WriteAllLines(Properties.Settings.Default.Modlist_Directory, lines); if (mlm.Count < 1) { ModListViewModel vm = new ModListViewModel(); modListTreeView.DataContext = vm; } }
private void RevertAll() { JsonEntry modEntry = null; string line; using (StreamReader sr = new StreamReader(Properties.Settings.Default.Modlist_Directory)) { while ((line = sr.ReadLine()) != null) { modEntry = JsonConvert.DeserializeObject <JsonEntry>(line); if (modEntry.originalOffset != 0) { Helper.UpdateIndex(modEntry.originalOffset, modEntry.fullPath, modEntry.datFile); Helper.UpdateIndex2(modEntry.originalOffset, modEntry.fullPath, modEntry.datFile); } } } }
public ListViewModel(string selectedItem) { try { foreach (string line in File.ReadAllLines(Properties.Settings.Default.Modlist_Directory)) { JsonEntry entry = JsonConvert.DeserializeObject <JsonEntry>(line); if (entry.name.Equals(selectedItem)) { mlmList.Add(ParseEntry(entry)); } } } catch (Exception e) { MessageBox.Show("[VM] Error Accessing .modlist File \n" + e.Message, "Error", MessageBoxButton.OK, MessageBoxImage.Error); } }
public ListViewModel(string selectedItem) { try { foreach (string line in File.ReadAllLines(Properties.Settings.Default.Modlist_Directory)) { JsonEntry entry = JsonConvert.DeserializeObject <JsonEntry>(line); if (entry.name.Equals(selectedItem)) { mlmList.Add(ParseEntry(entry)); } } } catch (Exception e) { FlexibleMessageBox.Show("Error Accessing .modlist File \n" + e.Message, "ListViewModel Error " + Info.appVersion, MessageBoxButtons.OK, MessageBoxIcon.Error); Debug.WriteLine(e.StackTrace); } }
private void RevertAllMods() { JsonEntry modEntry = null; string line; try { using (StreamReader sr = new StreamReader(Info.modListDir)) { while ((line = sr.ReadLine()) != null) { modEntry = JsonConvert.DeserializeObject <JsonEntry>(line); Helper.UpdateIndex(modEntry.originalOffset, modEntry.fullPath); Helper.UpdateIndex2(modEntry.originalOffset, modEntry.fullPath); } } } catch (Exception ex) { MessageBox.Show("[Main] Error Accessing .modlist File \n" + ex.Message, "Error", MessageBoxButton.OK, MessageBoxImage.Error); } }
/// <summary> /// Imports the items texture into a dat file /// </summary> /// <param name="texData">Data for the currently displayed texture</param> /// <param name="category">The items category</param> /// <param name="itemName">The items name</param> /// <param name="internalFilePath">The internal file path of the texture map</param> /// <returns>The offset in which the data was placed</returns> public static int ImportTexture(TEXData texData, string category, string itemName, string internalFilePath) { int textureType, lineNum = 0, offset = 0; bool inModList = false; JsonEntry modEntry = null; string dxPath = Path.GetFileNameWithoutExtension(internalFilePath); var savePath = Properties.Settings.Default.Save_Directory + "/" + category + "/" + itemName + "/" + dxPath + ".dds"; if (File.Exists(savePath)) { if (Properties.Settings.Default.Mod_List == 0) { try { using (StreamReader sr = new StreamReader(Info.modListDir)) { string line; while ((line = sr.ReadLine()) != null) { modEntry = JsonConvert.DeserializeObject <JsonEntry>(line); if (modEntry.fullPath.Equals(internalFilePath)) { inModList = true; break; } lineNum++; } } } catch (Exception ex) { MessageBox.Show("[Main] Error Accessing .modlist File \n" + ex.Message, "Error", MessageBoxButton.OK, MessageBoxImage.Error); } } using (BinaryReader br = new BinaryReader(File.OpenRead(savePath))) { br.BaseStream.Seek(12, SeekOrigin.Begin); var newHeight = br.ReadInt32(); var newWidth = br.ReadInt32(); br.ReadBytes(8); var newMipCount = br.ReadInt32(); br.BaseStream.Seek(84, SeekOrigin.Begin); textureType = Info.DDSType[br.ReadInt32()]; if (textureType == texData.Type) { List <byte> newTEX = new List <byte>(); int uncompressedLength = (int)new FileInfo(savePath).Length - 128; var DDSInfo = ReadDDS(br, texData, newWidth, newHeight, newMipCount); newTEX.AddRange(MakeType4DATHeader(texData, DDSInfo.Item2, DDSInfo.Item3, uncompressedLength, newMipCount, newWidth, newHeight)); newTEX.AddRange(MakeTextureInfoHeader(texData, newWidth, newHeight, newMipCount)); newTEX.AddRange(DDSInfo.Item1); offset = WriteToDat(newTEX, modEntry, inModList, internalFilePath, category, itemName, lineNum); } else { MessageBox.Show("Incorrect file type \nExpected: " + Info.TextureTypes[texData.Type] + " Given: " + Info.TextureTypes[textureType], "Texture format error", MessageBoxButton.OK, MessageBoxImage.Error); } } } else { MessageBox.Show("Could not find file \n" + savePath, "File read Error", MessageBoxButton.OK, MessageBoxImage.Error); } return(offset); }
/// <summary> /// Writes the newly imported data to the .dat for modifications. /// </summary> /// <param name="data">The data to be written.</param> /// <param name="modEntry">The modlist entry (if any) for the given file.</param> /// <param name="inModList">Is the item already contained within the mod list.</param> /// <param name="internalFilePath">The internal file path of the item being modified.</param> /// <param name="category">The category of the item.</param> /// <param name="itemName">The name of the item being modified.</param> /// <param name="lineNum">The line number of the existing mod list entry for the item if it exists.</param> /// <returns>The new offset in which the modified data was placed.</returns> public static int WriteToDat(List <byte> data, JsonEntry modEntry, bool inModList, string internalFilePath, string category, string itemName, int lineNum) { int offset = 0; bool dataOverwritten = false; try { using (BinaryWriter bw = new BinaryWriter(File.OpenWrite(Info.modDatDir))) { /* * If the item has been previously modified and the compressed data being imported is smaller or equal to the exisiting data * replace the existing data with new data. */ if (inModList && data.Count <= modEntry.modSize) { int sizeDiff = modEntry.modSize - data.Count; bw.BaseStream.Seek(modEntry.modOffset - DatOffsetAmount, SeekOrigin.Begin); bw.Write(data.ToArray()); bw.Write(new byte[sizeDiff]); Helper.UpdateIndex(modEntry.modOffset, internalFilePath); Helper.UpdateIndex2(modEntry.modOffset, internalFilePath); offset = modEntry.modOffset; dataOverwritten = true; } else { int emptyLength = 0; int emptyLine = 0; /* * If there is an empty entry in the modlist and the compressed data being imported is smaller or equal to the available space * write the compressed data in the existing space. */ if (Properties.Settings.Default.Mod_List == 0) { try { foreach (string line in File.ReadAllLines(Info.modListDir)) { JsonEntry emptyEntry = JsonConvert.DeserializeObject <JsonEntry>(line); if (emptyEntry.fullPath.Equals("")) { emptyLength = emptyEntry.modSize; if (emptyLength > data.Count) { int sizeDiff = emptyLength - data.Count; bw.BaseStream.Seek(emptyEntry.modOffset - DatOffsetAmount, SeekOrigin.Begin); bw.Write(data.ToArray()); bw.Write(new byte[sizeDiff]); int originalOffset = Helper.UpdateIndex(emptyEntry.modOffset, internalFilePath) * 8; Helper.UpdateIndex2(emptyEntry.modOffset, internalFilePath); JsonEntry replaceEntry = new JsonEntry() { category = category, name = itemName, fullPath = internalFilePath, originalOffset = originalOffset, modOffset = emptyEntry.modOffset, modSize = emptyEntry.modSize }; string[] lines = File.ReadAllLines(Info.modListDir); lines[emptyLine] = JsonConvert.SerializeObject(replaceEntry); File.WriteAllLines(Info.modListDir, lines); offset = emptyEntry.modOffset; dataOverwritten = true; break; } } emptyLine++; } } catch (Exception ex) { MessageBox.Show("[Import] Error Accessing .modlist File \n" + ex.Message, "Error", MessageBoxButton.OK, MessageBoxImage.Error); } } if (!dataOverwritten) { bw.BaseStream.Seek(0, SeekOrigin.End); while ((bw.BaseStream.Position & 0xFF) != 0) { bw.Write((byte)0); } int eof = (int)bw.BaseStream.Position + data.Count; while ((eof & 0xFF) != 0) { data.AddRange(new byte[16]); eof = eof + 16; } offset = (int)bw.BaseStream.Position + DatOffsetAmount; bw.Write(data.ToArray()); } } } } catch (Exception ex) { MessageBox.Show("[Import] Error Accessing .dat4 File \n" + ex.Message, "Error", MessageBoxButton.OK, MessageBoxImage.Error); return(0); } if (!dataOverwritten && Properties.Settings.Default.Mod_List == 0) { int oldOffset = Helper.UpdateIndex(offset, internalFilePath) * 8; Helper.UpdateIndex2(offset, internalFilePath); /* * If the item has been previously modifed, but the new compressed data to be imported is larger than the existing data * remove the data from the modlist, leaving the offset and size intact for future use */ if (inModList && data.Count > modEntry.modSize && modEntry != null) { oldOffset = modEntry.originalOffset; JsonEntry replaceEntry = new JsonEntry() { category = String.Empty, name = String.Empty, fullPath = String.Empty, originalOffset = 0, modOffset = modEntry.modOffset, modSize = modEntry.modSize }; string[] lines = File.ReadAllLines(Info.modListDir); lines[lineNum] = JsonConvert.SerializeObject(replaceEntry); File.WriteAllLines(Info.modListDir, lines); } JsonEntry entry = new JsonEntry() { category = category, name = itemName, fullPath = internalFilePath, originalOffset = oldOffset, modOffset = offset, modSize = data.Count }; try { using (StreamWriter modFile = new StreamWriter(Info.modListDir, true)) { modFile.BaseStream.Seek(0, SeekOrigin.End); modFile.WriteLine(JsonConvert.SerializeObject(entry)); } } catch (Exception ex) { MessageBox.Show("[Import] Error Accessing .modlist File \n" + ex.Message, "Error", MessageBoxButton.OK, MessageBoxImage.Error); } } return(offset); }
public ModListModel ParseEntry(JsonEntry entry) { ModListModel mlm = new ModListModel(); string race, map, part, type; if (entry.fullPath.Contains("weapon") || entry.fullPath.Contains("accessory") || entry.fullPath.Contains("decal") || entry.fullPath.Contains("vfx") || entry.fullPath.Contains("ui/")) { race = Strings.All; } else if (entry.fullPath.Contains("monster") || entry.fullPath.Contains("demihuman")) { race = Strings.Monster; } else { race = entry.fullPath.Substring(entry.fullPath.LastIndexOf('/')); if ((entry.fullPath.Contains("_fac_") || entry.fullPath.Contains("_etc_") || entry.fullPath.Contains("_acc_")) && Properties.Settings.Default.DX_Ver.Equals(Strings.DX11)) { race = race.Substring(race.LastIndexOf("--c") + 3, 4); } else if (entry.fullPath.Contains("_fac_") || entry.fullPath.Contains("_etc_") || entry.fullPath.Contains("_acc_")) { race = race.Substring(race.LastIndexOf("/c") + 2, 4); } else if (entry.fullPath.Contains("_c_")) { race = race.Substring(race.IndexOf("_c") + 2, 4); } else { race = race.Substring(race.LastIndexOf('c') + 1, 4); } race = Info.IDRace[race]; } mlm.Race = race; if (entry.fullPath.Contains("_d.")) { map = Strings.Diffuse; } else if (entry.fullPath.Contains("_n.")) { map = Strings.Normal; } else if (entry.fullPath.Contains("_s.")) { map = Strings.Specular; } else if (entry.fullPath.Contains("material")) { map = Strings.ColorSet; } else if (entry.fullPath.Contains("model")) { map = "3D"; } else if (entry.fullPath.Contains("ui/")) { map = "UI"; } else { map = Strings.Mask; } mlm.Map = map; if (entry.fullPath.Contains("_b_")) { part = "b"; } else if (entry.fullPath.Contains("_c_")) { part = "c"; } else if (entry.fullPath.Contains("_d_")) { part = "d"; } else if (entry.fullPath.Contains("decal")) { part = entry.fullPath.Substring(entry.fullPath.LastIndexOf('_') + 1, entry.fullPath.LastIndexOf('.') - (entry.fullPath.LastIndexOf('_') + 1)); } else { part = "a"; } mlm.Part = part; if (entry.fullPath.Contains("_iri_")) { type = "Iris"; } else if (entry.fullPath.Contains("_etc_")) { type = "Etc."; } else if (entry.fullPath.Contains("_fac_")) { type = "Face"; } else if (entry.fullPath.Contains("_hir_")) { type = "Hair"; } else if (entry.fullPath.Contains("_acc_")) { type = "Accessory"; } else if (entry.fullPath.Contains("demihuman")) { type = entry.fullPath.Substring(entry.fullPath.LastIndexOf('_') - 3, 3); type = (Info.slotAbr).FirstOrDefault(x => x.Value == type).Key; } else { type = "-"; } mlm.Type = type; if (entry.fullPath.Contains("material")) { var info = MTRL.GetMTRLInfo(entry.modOffset, false); var bitmap = TEX.TextureToBitmap(info.ColorData, 9312, 4, 16); mlm.BMP = Imaging.CreateBitmapSourceFromHBitmap(bitmap.GetHbitmap(), IntPtr.Zero, Int32Rect.Empty, BitmapSizeOptions.FromEmptyOptions()); } else if (entry.fullPath.Contains("model")) { mlm.BMP = new BitmapImage(new Uri("pack://application:,,,/FFXIV TexTools 2;component/Resources/3DModel.png")); } else { TEXData texData; if (entry.fullPath.Contains("vfx")) { texData = TEX.GetVFX(entry.modOffset, entry.datFile); } else { if (entry.fullPath.Contains("icon")) { texData = TEX.GetTex(entry.modOffset, entry.datFile); } else { texData = TEX.GetTex(entry.modOffset, entry.datFile); } } mlm.BMP = Imaging.CreateBitmapSourceFromHBitmap(texData.BMP.GetHbitmap(), IntPtr.Zero, Int32Rect.Empty, BitmapSizeOptions.FromEmptyOptions()); } var offset = Helper.GetDataOffset(FFCRC.GetHash(entry.fullPath.Substring(0, entry.fullPath.LastIndexOf("/"))), FFCRC.GetHash(Path.GetFileName(entry.fullPath)), entry.datFile); if (offset == entry.modOffset) { mlm.ActiveBorder = Brushes.Green; mlm.Active = Brushes.Transparent; mlm.ActiveOpacity = 1; } else if (offset == entry.originalOffset) { mlm.ActiveBorder = Brushes.Red; mlm.Active = Brushes.Gray; mlm.ActiveOpacity = 0.5f; } else { mlm.ActiveBorder = Brushes.Red; mlm.Active = Brushes.Red; mlm.ActiveOpacity = 1; } mlm.Entry = entry; return(mlm); }
/// <summary> /// Writes the newly imported data to the .dat for modifications. /// </summary> /// <param name="data">The data to be written.</param> /// <param name="modEntry">The modlist entry (if any) for the given file.</param> /// <param name="inModList">Is the item already contained within the mod list.</param> /// <param name="internalFilePath">The internal file path of the item being modified.</param> /// <param name="category">The category of the item.</param> /// <param name="itemName">The name of the item being modified.</param> /// <param name="lineNum">The line number of the existing mod list entry for the item if it exists.</param> /// <returns>The new offset in which the modified data was placed.</returns> public static int WriteToDat(List <byte> data, JsonEntry modEntry, bool inModList, string internalFilePath, string category, string itemName, int lineNum, string datName) { int offset = 0; bool dataOverwritten = false; var datNum = int.Parse(Info.ModDatDict[datName]); var modDatPath = string.Format(Info.datDir, datName, datNum); if (inModList) { datNum = ((modEntry.modOffset / 8) & 0x0F) / 2; modDatPath = string.Format(Info.datDir, modEntry.datFile, datNum); } else { var fileLength = new FileInfo(modDatPath).Length; while (fileLength >= 2000000000) { datNum += 1; modDatPath = string.Format(Info.datDir, datName, datNum); if (!File.Exists(modDatPath)) { CreateDat.MakeNewDat(datName); } fileLength = new FileInfo(modDatPath).Length; } } var datOffsetAmount = 16 * datNum; if (inModList) { if (modEntry.modOffset == 0) { FlexibleMessageBox.Show("TexTools detected a Mod List entry with a Mod Offset of 0.\n\n" + "Please submit a bug report along with your modlist file.", "ImportTex Error " + Info.appVersion, MessageBoxButtons.OK, MessageBoxIcon.Error); return(0); } else if (modEntry.originalOffset == 0) { FlexibleMessageBox.Show("TexTools detected a Mod List entry with an Original Offset of 0.\n\n" + "Please submit a bug report along with your modlist file.", "ImportTex Error " + Info.appVersion, MessageBoxButtons.OK, MessageBoxIcon.Error); return(0); } } try { using (BinaryWriter bw = new BinaryWriter(File.OpenWrite(modDatPath))) { /* * If the item has been previously modified and the compressed data being imported is smaller or equal to the exisiting data * replace the existing data with new data. */ if (inModList && data.Count <= modEntry.modSize) { if (modEntry.modOffset != 0) { int sizeDiff = modEntry.modSize - data.Count; bw.BaseStream.Seek(modEntry.modOffset - datOffsetAmount, SeekOrigin.Begin); bw.Write(data.ToArray()); bw.Write(new byte[sizeDiff]); Helper.UpdateIndex(modEntry.modOffset, internalFilePath, datName); Helper.UpdateIndex2(modEntry.modOffset, internalFilePath, datName); offset = modEntry.modOffset; dataOverwritten = true; } } else { int emptyLength = 0; int emptyLine = 0; /* * If there is an empty entry in the modlist and the compressed data being imported is smaller or equal to the available space * write the compressed data in the existing space. */ try { foreach (string line in File.ReadAllLines(Properties.Settings.Default.Modlist_Directory)) { JsonEntry emptyEntry = JsonConvert.DeserializeObject <JsonEntry>(line); if (emptyEntry.fullPath.Equals("") && emptyEntry.datFile.Equals(datName)) { if (emptyEntry.modOffset != 0) { emptyLength = emptyEntry.modSize; if (emptyLength > data.Count) { int sizeDiff = emptyLength - data.Count; bw.BaseStream.Seek(emptyEntry.modOffset - datOffsetAmount, SeekOrigin.Begin); bw.Write(data.ToArray()); bw.Write(new byte[sizeDiff]); int originalOffset = Helper.UpdateIndex(emptyEntry.modOffset, internalFilePath, datName) * 8; Helper.UpdateIndex2(emptyEntry.modOffset, internalFilePath, datName); if (inModList) { originalOffset = modEntry.originalOffset; JsonEntry replaceOriginalEntry = new JsonEntry() { category = String.Empty, name = "Empty Replacement", fullPath = String.Empty, originalOffset = 0, modOffset = modEntry.modOffset, modSize = modEntry.modSize, datFile = datName }; string[] oLines = File.ReadAllLines(Properties.Settings.Default.Modlist_Directory); oLines[lineNum] = JsonConvert.SerializeObject(replaceOriginalEntry); File.WriteAllLines(Properties.Settings.Default.Modlist_Directory, oLines); } JsonEntry replaceEntry = new JsonEntry() { category = category, name = itemName, fullPath = internalFilePath, originalOffset = originalOffset, modOffset = emptyEntry.modOffset, modSize = emptyEntry.modSize, datFile = datName }; string[] lines = File.ReadAllLines(Properties.Settings.Default.Modlist_Directory); lines[emptyLine] = JsonConvert.SerializeObject(replaceEntry); File.WriteAllLines(Properties.Settings.Default.Modlist_Directory, lines); offset = emptyEntry.modOffset; dataOverwritten = true; break; } } } emptyLine++; } } catch (Exception ex) { FlexibleMessageBox.Show("Error Accessing .modlist File \n" + ex.Message, "ImportTex Error " + Info.appVersion, MessageBoxButtons.OK, MessageBoxIcon.Error); } if (!dataOverwritten) { bw.BaseStream.Seek(0, SeekOrigin.End); while ((bw.BaseStream.Position & 0xFF) != 0) { bw.Write((byte)0); } int eof = (int)bw.BaseStream.Position + data.Count; while ((eof & 0xFF) != 0) { data.AddRange(new byte[16]); eof = eof + 16; } offset = (int)bw.BaseStream.Position + datOffsetAmount; if (offset != 0) { bw.Write(data.ToArray()); } else { FlexibleMessageBox.Show("There was an issue obtaining the .dat4 offset to write data to, try importing again. " + "\n\n If the problem persists, please submit a bug report.", "ImportTex Error " + Info.appVersion, MessageBoxButtons.OK, MessageBoxIcon.Error); } } } } } catch (Exception ex) { FlexibleMessageBox.Show("Error Accessing .dat4 File \n" + ex.Message, "ImportTex Error " + Info.appVersion, MessageBoxButtons.OK, MessageBoxIcon.Error); return(0); } if (!dataOverwritten) { if (offset != 0) { int oldOffset = Helper.UpdateIndex(offset, internalFilePath, datName) * 8; Helper.UpdateIndex2(offset, internalFilePath, datName); /* * If the item has been previously modifed, but the new compressed data to be imported is larger than the existing data * remove the data from the modlist, leaving the offset and size intact for future use */ if (inModList && data.Count > modEntry.modSize && modEntry != null) { oldOffset = modEntry.originalOffset; JsonEntry replaceEntry = new JsonEntry() { category = String.Empty, name = String.Empty, fullPath = String.Empty, originalOffset = 0, modOffset = modEntry.modOffset, modSize = modEntry.modSize, datFile = datName }; string[] lines = File.ReadAllLines(Properties.Settings.Default.Modlist_Directory); lines[lineNum] = JsonConvert.SerializeObject(replaceEntry); File.WriteAllLines(Properties.Settings.Default.Modlist_Directory, lines); } JsonEntry entry = new JsonEntry() { category = category, name = itemName, fullPath = internalFilePath, originalOffset = oldOffset, modOffset = offset, modSize = data.Count, datFile = datName }; try { using (StreamWriter modFile = new StreamWriter(Properties.Settings.Default.Modlist_Directory, true)) { modFile.BaseStream.Seek(0, SeekOrigin.End); modFile.WriteLine(JsonConvert.SerializeObject(entry)); } } catch (Exception ex) { FlexibleMessageBox.Show("Error Accessing .modlist File \n" + ex.Message, "ImportTex Error " + Info.appVersion, MessageBoxButtons.OK, MessageBoxIcon.Error); } } } return(offset); }
/// <summary> /// Imports VFX files /// </summary> /// <param name="category">The category of the item</param> /// <param name="itemName">The selected items name</param> /// <param name="internalFilePath">The full path of the internal file</param> public static int ImportVFX(TEXData texData, string category, string itemName, string internalFilePath) { JsonEntry modEntry = null; int textureType, newHeight, newWidth, newMipCount; int lineNum = 0; int newOffset = 0; bool inModList = false; string dxPath = Path.GetFileNameWithoutExtension(internalFilePath); var savePath = Properties.Settings.Default.Save_Directory + "/" + category + "/" + itemName + "/" + dxPath + ".dds"; if (File.Exists(savePath)) { List <byte> newVFX = new List <byte>(); List <byte> uncompressedVFX = new List <byte>(); List <byte> headerData = new List <byte>(); List <byte> dataBlocks = new List <byte>(); try { using (StreamReader sr = new StreamReader(Properties.Settings.Default.Modlist_Directory)) { string line; while ((line = sr.ReadLine()) != null) { modEntry = JsonConvert.DeserializeObject <JsonEntry>(line); if (modEntry.fullPath.Equals(internalFilePath)) { inModList = true; break; } lineNum++; } } } catch (Exception ex) { FlexibleMessageBox.Show("Error Accessing .modlist File \n" + ex.Message, "ImportTex Error " + Info.appVersion, MessageBoxButtons.OK, MessageBoxIcon.Error); } using (BinaryReader br = new BinaryReader(File.OpenRead(savePath))) { br.BaseStream.Seek(12, SeekOrigin.Begin); newHeight = br.ReadInt32(); newWidth = br.ReadInt32(); br.ReadBytes(8); newMipCount = br.ReadInt32(); br.BaseStream.Seek(80, SeekOrigin.Begin); var textureFlags = br.ReadInt32(); textureType = Info.DDSType[br.ReadInt32()]; if (textureFlags == 2 && textureType == 5200) { textureType = TextureTypes.A8; } if (textureType == texData.Type) { br.BaseStream.Seek(128, SeekOrigin.Begin); uncompressedVFX.AddRange(MakeTextureInfoHeader(texData, newWidth, newHeight, newMipCount)); int dataLength = (int)new FileInfo(savePath).Length - 128; uncompressedVFX.AddRange(br.ReadBytes(dataLength)); } else { FlexibleMessageBox.Show("Incorrect file type \nExpected: " + Info.TextureTypes[texData.Type] + " Given: " + Info.TextureTypes[textureType], "Texture format error", MessageBoxButtons.OK, MessageBoxIcon.Error); return(0); } } headerData.AddRange(BitConverter.GetBytes(128)); headerData.AddRange(BitConverter.GetBytes(2)); headerData.AddRange(BitConverter.GetBytes(uncompressedVFX.Count)); int dataOffset = 0; int totalCompSize = 0; int uncompressedLength = uncompressedVFX.Count; int partCount = (int)Math.Ceiling(uncompressedLength / 16000f); headerData.AddRange(BitConverter.GetBytes(partCount)); int remainder = uncompressedLength; using (BinaryReader br = new BinaryReader(new MemoryStream(uncompressedVFX.ToArray()))) { br.BaseStream.Seek(0, SeekOrigin.Begin); for (int i = 1; i <= partCount; i++) { if (i == partCount) { var compData = Compressor(br.ReadBytes(remainder)); int padding = 128 - ((compData.Length + 16) % 128); dataBlocks.AddRange(BitConverter.GetBytes(16)); dataBlocks.AddRange(BitConverter.GetBytes(0)); dataBlocks.AddRange(BitConverter.GetBytes(compData.Length)); dataBlocks.AddRange(BitConverter.GetBytes(remainder)); dataBlocks.AddRange(compData); dataBlocks.AddRange(new byte[padding]); headerData.AddRange(BitConverter.GetBytes(dataOffset)); headerData.AddRange(BitConverter.GetBytes((short)((compData.Length + 16) + padding))); headerData.AddRange(BitConverter.GetBytes((short)remainder)); totalCompSize = dataOffset + ((compData.Length + 16) + padding); } else { var compData = Compressor(br.ReadBytes(16000)); int padding = 128 - ((compData.Length + 16) % 128); dataBlocks.AddRange(BitConverter.GetBytes(16)); dataBlocks.AddRange(BitConverter.GetBytes(0)); dataBlocks.AddRange(BitConverter.GetBytes(compData.Length)); dataBlocks.AddRange(BitConverter.GetBytes(16000)); dataBlocks.AddRange(compData); dataBlocks.AddRange(new byte[padding]); headerData.AddRange(BitConverter.GetBytes(dataOffset)); headerData.AddRange(BitConverter.GetBytes((short)((compData.Length + 16) + padding))); headerData.AddRange(BitConverter.GetBytes((short)16000)); dataOffset += ((compData.Length + 16) + padding); remainder -= 16000; } } } headerData.InsertRange(12, BitConverter.GetBytes(totalCompSize / 128)); headerData.InsertRange(16, BitConverter.GetBytes(totalCompSize / 128)); int headerPadding = 128 - headerData.Count; headerData.AddRange(new byte[headerPadding]); newVFX.AddRange(headerData); newVFX.AddRange(dataBlocks); newOffset = WriteToDat(newVFX, modEntry, inModList, internalFilePath, category, itemName, lineNum, texData.TEXDatName); } return(newOffset); }
/// <summary> /// Constructor of String Table /// </summary> /// <param name="jsonEntry">String table Json Entry</param> public StringTable( JsonEntry jsonEntry ) { stringTable = jsonEntry; if ( stringTable [ "tableversion" ] as string != "1.0" ) throw new VersionMismatchException (); }
private bool CheckModlist() { string line; JsonEntry modEntry = null; bool check = false; if (File.ReadLines(Properties.Settings.Default.Modlist_Directory).Count() > 0) { try { using (StreamReader sr = new StreamReader(Properties.Settings.Default.Modlist_Directory)) { while ((line = sr.ReadLine()) != null) { modEntry = JsonConvert.DeserializeObject <JsonEntry>(line); if (!modEntry.fullPath.Equals("")) { var originalOffset = modEntry.originalOffset / 8; var modOffset = modEntry.modOffset / 8; int datNum = (originalOffset & 0xF) / 2; var tabs = ""; if (Path.GetFileName(modEntry.fullPath).Length < 21) { tabs = "\t"; } AddText("\t" + Path.GetFileName(modEntry.fullPath) + tabs, "Black"); if (modEntry.datFile.Equals(Strings.ItemsDat)) { if (datNum > 3 || originalOffset == 0) { AddText("\u2716\n", "Red"); check = true; } else if (modOffset == 0) { AddText("\u2716\n", "Red"); AddText("\tMod Offset for the above texture was 0, Disable from File > Modlist and reimport.\n", "Red"); check = true; } else { AddText("\t\u2714\n", "Green"); } } else if (modEntry.datFile.Equals(Strings.UIDat)) { if (datNum > 0 || originalOffset == 0) { AddText("\u2716\n", "Red"); check = true; } else if (modOffset == 0) { AddText("\u2716\n", "Red"); AddText("\tMod Offset for the above texture was 0, Disable from File > Modlist and reimport.\n", "Red"); check = true; } else { AddText("\t\u2714\n", "Green"); } } modOffsetList.Add(modOffset); originalOffsetList.Add(originalOffset); } } } } catch (Exception e) { AddText("\t\nError: " + e.Message + "\n", "Red"); } } else { AddText("\tNo entries found in modlist.\n", "Orange"); } return(check); }
/// <summary> /// Gets the texture data and displays it for the currently selected item given a specified race, part, type(if applicable), and map /// </summary> private void MapComboBoxChanged() { Bitmap colorBmp = null; int offset = 0; bool isVFX = false; if (selectedMap.Name.Equals(Strings.Normal)) { fullPath = mtrlData.NormalPath; offset = mtrlData.NormalOffset; FullPathString = fullPath + " [" + FFCRC.GetHash(fullPath) + "]"; } else if (selectedMap.Name.Equals(Strings.Specular)) { fullPath = mtrlData.SpecularPath; offset = mtrlData.SpecularOffset; FullPathString = fullPath + " [" + FFCRC.GetHash(fullPath) + "]"; } else if (selectedMap.Name.Equals(Strings.Diffuse)) { fullPath = mtrlData.DiffusePath; offset = mtrlData.DiffuseOffset; FullPathString = fullPath + " [" + FFCRC.GetHash(fullPath) + "]"; } else if (selectedMap.Name.Equals(Strings.Mask) || selectedMap.Name.Equals(Strings.Skin)) { if (selectedItem.ItemName.Equals(Strings.Face_Paint) || selectedItem.ItemName.Equals(Strings.Equipment_Decals)) { string part; if (selectedItem.ItemName.Equals(Strings.Equipment_Decals)) { part = selectedPart.Name.PadLeft(3, '0'); } else { part = selectedPart.Name; } fullPath = String.Format(mtrlData.MaskPath, part); offset = MTRL.GetDecalOffset(selectedItem.ItemName, selectedPart.Name); FullPathString = fullPath + " [" + FFCRC.GetHash(fullPath) + "]"; } else { fullPath = mtrlData.MaskPath; offset = mtrlData.MaskOffset; FullPathString = fullPath + " [" + FFCRC.GetHash(fullPath) + "]"; } } else if (selectedMap.Name.Equals(Strings.ColorSet)) { colorBmp = TEX.TextureToBitmap(mtrlData.ColorData, 9312, 4, 16); fullPath = mtrlData.MTRLPath; FullPathString = fullPath + " [" + FFCRC.GetHash(fullPath) + "]"; } else { fullPath = SelectedMap.ID; var VFXFolder = fullPath.Substring(0, fullPath.LastIndexOf("/")); var VFXFile = fullPath.Substring(fullPath.LastIndexOf("/") + 1); offset = Helper.GetItemOffset(FFCRC.GetHash(VFXFolder), FFCRC.GetHash(VFXFile)); FullPathString = fullPath; isVFX = true; } if (Properties.Settings.Default.Mod_List == 0) { string line; JsonEntry modEntry = null; bool inModList = false; try { using (StreamReader sr = new StreamReader(Info.modListDir)) { while ((line = sr.ReadLine()) != null) { modEntry = JsonConvert.DeserializeObject <JsonEntry>(line); if (modEntry.fullPath.Equals(fullPath)) { inModList = true; break; } } } } catch (Exception ex) { MessageBox.Show("[Main] Error Accessing .modlist File \n" + ex.Message, "Error", MessageBoxButton.OK, MessageBoxImage.Error); } if (inModList) { var currOffset = Helper.GetItemOffset(FFCRC.GetHash(modEntry.fullPath.Substring(0, modEntry.fullPath.LastIndexOf("/"))), FFCRC.GetHash(Path.GetFileName(modEntry.fullPath))); if (currOffset == modEntry.modOffset) { ActiveToggle = "Disable"; } else if (currOffset == modEntry.originalOffset) { ActiveToggle = "Enable"; } else { ActiveToggle = "Error"; } ActiveEnabled = true; } else { ActiveEnabled = false; ActiveToggle = "Enable/Disable"; } } else { ActiveEnabled = false; ActiveToggle = "Enable/Disable"; } if (offset == 0) { TextureType = "A16B16G16R16F"; textureType = "A16B16G16R16F"; TextureDimensions = "(4 x 16)"; textureDimensions = "(4 x 16)"; alphaBitmap = Imaging.CreateBitmapSourceFromHBitmap(colorBmp.GetHbitmap(), IntPtr.Zero, Int32Rect.Empty, BitmapSizeOptions.FromEmptyOptions()); var removeAlphaBitmap = SetAlpha(colorBmp, 255); noAlphaBitmap = Imaging.CreateBitmapSourceFromHBitmap(removeAlphaBitmap.GetHbitmap(), IntPtr.Zero, Int32Rect.Empty, BitmapSizeOptions.FromEmptyOptions()); colorBmp.Dispose(); removeAlphaBitmap.Dispose(); } else { if (!isVFX) { texData = TEX.GetTex(offset); } else { texData = TEX.GetVFX(offset); } TextureType = texData.TypeString; TextureDimensions = "(" + texData.Width + " x " + texData.Height + ")"; alphaBitmap = Imaging.CreateBitmapSourceFromHBitmap(texData.BMP.GetHbitmap(), IntPtr.Zero, Int32Rect.Empty, BitmapSizeOptions.FromEmptyOptions()); var removeAlphaBitmap = SetAlpha(texData.BMP, 255); noAlphaBitmap = Imaging.CreateBitmapSourceFromHBitmap(removeAlphaBitmap.GetHbitmap(), IntPtr.Zero, Int32Rect.Empty, BitmapSizeOptions.FromEmptyOptions()); removeAlphaBitmap.Dispose(); } try { ImageEffect = new ColorChannels() { Channel = new System.Windows.Media.Media3D.Point4D(1.0f, 1.0f, 1.0f, 0.0f) }; } catch (Exception ex) { Debug.WriteLine(ex.StackTrace); } ImageSource = noAlphaBitmap; SetColorChannelFilter(); SaveEnabled = true; texData.Dispose(); string dxPath = Path.GetFileNameWithoutExtension(fullPath); if (File.Exists(Properties.Settings.Default.Save_Directory + "/" + selectedCategory + "/" + selectedItem.ItemName + "/" + dxPath + ".dds")) { ImportEnabled = true; } else { ImportEnabled = false; } }
public MakeModPack() { InitializeComponent(); var mpiList = new List <ModPackItems>(); dt.Tick += new EventHandler(dt_Tick); InfoHeader.Content = "This tool will create a zipped TexTools Mod Pack (*.ttmp) file of the selected mods in the following directory:\n" + mpDir; try { using (StreamReader sr = new StreamReader(Properties.Settings.Default.Modlist_Directory)) { string line; while ((line = sr.ReadLine()) != null) { modEntry = JsonConvert.DeserializeObject <JsonEntry>(line); var r = "-"; var num = "-"; var type = "-"; if (!modEntry.fullPath.Equals("")) { if (modEntry.fullPath.Contains("ui/")) { r = "UI"; } else if (modEntry.fullPath.Contains("monster")) { r = "Monster"; } else if (modEntry.fullPath.Contains(".tex") || modEntry.fullPath.Contains(".mdl") || modEntry.fullPath.Contains(".atex")) { if (modEntry.fullPath.Contains("accessory") || modEntry.fullPath.Contains("weapon") || modEntry.fullPath.Contains("/common/")) { r = Strings.All; } else { if (modEntry.fullPath.Contains("demihuman")) { r = "DemiHuman"; type = slotAbr[modEntry.fullPath.Substring(modEntry.fullPath.LastIndexOf("_") - 3, 3)]; } else if (modEntry.fullPath.Contains("/v")) { r = modEntry.fullPath.Substring(modEntry.fullPath.IndexOf("_c") + 2, 4); r = Info.IDRace[r]; } else { r = modEntry.fullPath.Substring(modEntry.fullPath.IndexOf("/c") + 2, 4); r = Info.IDRace[r]; } } if (modEntry.fullPath.Contains("/human/") && modEntry.fullPath.Contains("/body/")) { var t = modEntry.fullPath.Substring(modEntry.fullPath.LastIndexOf("/b") + 2, 4); num = int.Parse(t).ToString(); } if (modEntry.fullPath.Contains("/face/")) { var t = modEntry.fullPath.Substring(modEntry.fullPath.LastIndexOf("/f") + 2, 4); num = int.Parse(t).ToString(); if (modEntry.fullPath.Contains(".tex")) { type = FaceTypes[modEntry.fullPath.Substring(modEntry.fullPath.LastIndexOf("_") - 3, 3)]; } } if (modEntry.fullPath.Contains("decal_face")) { var length = modEntry.fullPath.LastIndexOf(".") - (modEntry.fullPath.LastIndexOf("_") + 1); var t = modEntry.fullPath.Substring(modEntry.fullPath.LastIndexOf("_") + 1, length); num = int.Parse(t).ToString(); } if (modEntry.fullPath.Contains("decal_equip")) { var t = modEntry.fullPath.Substring(modEntry.fullPath.LastIndexOf("_") + 1, 3); try { num = int.Parse(t).ToString(); } catch { if (modEntry.fullPath.Contains("stigma")) { num = "stigma"; } else { num = "Error"; } } } if (modEntry.fullPath.Contains("/hair/")) { var t = modEntry.fullPath.Substring(modEntry.fullPath.LastIndexOf("/h") + 2, 4); num = int.Parse(t).ToString(); if (modEntry.fullPath.Contains(".tex")) { type = HairTypes[modEntry.fullPath.Substring(modEntry.fullPath.LastIndexOf("_") - 3, 3)]; } } if (modEntry.fullPath.Contains("/vfx/")) { type = "VFX"; } } else if (modEntry.fullPath.Contains(".avfx")) { r = Strings.All; type = "AVFX"; } var m = "3D"; if (modEntry.fullPath.Contains("ui/")) { var t = modEntry.fullPath.Substring(modEntry.fullPath.IndexOf("/") + 1); m = t.Substring(0, t.IndexOf("/")); } else if (modEntry.fullPath.Contains(".tex") || modEntry.fullPath.Contains(".atex")) { m = GetMapName(modEntry.fullPath); } else if (modEntry.fullPath.Contains(".mtrl")) { m = "ColorSet"; } var isActive = Helper.IsActive(modEntry.fullPath, modEntry.datFile); mpiList.Add(new ModPackItems { Name = modEntry.name, Race = r, Part = type, Num = num, Map = m, Active = isActive, Entry = modEntry }); } } } mpiList.Sort(); FullModList = mpiList; ListItems = new ObservableCollection <ModPackItems>(mpiList); listView.ItemsSource = ListItems; SearchBox.Focus(); } catch (Exception ex) { FlexibleMessageBox.Show("Error accessing or reading .modlist file \n" + ex.Message, "MakeModPack Error " + Info.appVersion, Forms.MessageBoxButtons.OK, Forms.MessageBoxIcon.Error); Debug.WriteLine(ex.StackTrace); } var fn = 1; if (!Directory.Exists(mpDir)) { Directory.CreateDirectory(mpDir); } else { while (File.Exists(mpDir + "\\ModPack " + fn + ".ttmp")) { fn++; } modPackName.Text = "ModPack " + fn; } }
public ModListModel ParseEntry(JsonEntry entry) { ModListModel mlm = new ModListModel(); string race, map, part, type; if (entry.fullPath.Contains("mt_")) { Debug.WriteLine(entry.fullPath); } if (entry.fullPath.Contains("weapon") || entry.fullPath.Contains("accessory") || entry.fullPath.Contains("decal") || entry.fullPath.Contains("vfx") || entry.fullPath.Contains("ui/")) { race = Strings.All; } else if (entry.fullPath.Contains("monster") || entry.fullPath.Contains("demihuman")) { race = Strings.Monster; } else { race = entry.fullPath.Substring(entry.fullPath.LastIndexOf('/')); if (entry.fullPath.Contains("mt_") && entry.fullPath.Contains("_acc_")) { race = race.Substring(race.IndexOf("_") + 2, 4); } else if ((entry.fullPath.Contains("_fac_") || entry.fullPath.Contains("_etc_") || entry.fullPath.Contains("_acc_")) && Properties.Settings.Default.DX_Ver.Equals(Strings.DX11)) { race = race.Substring(race.LastIndexOf("--c") + 3, 4); } else if (entry.fullPath.Contains("_fac_") || entry.fullPath.Contains("_etc_") || entry.fullPath.Contains("_acc_")) { race = race.Substring(race.LastIndexOf("/c") + 2, 4); } else if (entry.fullPath.Contains("_c_")) { race = race.Substring(race.IndexOf("_c") + 2, 4); } else { if (entry.fullPath.Contains(".mdl") && entry.fullPath.Contains("_fac")) { race = race.Substring(race.IndexOf('c') + 1, 4); } else { race = race.Substring(race.LastIndexOf('c') + 1, 4); } } if (entry.fullPath.Contains("mt_")) { Debug.WriteLine(race + "\n"); } race = Info.IDRace[race]; } mlm.Race = race; if (entry.fullPath.Contains("_d.")) { map = Strings.Diffuse; } else if (entry.fullPath.Contains("_n.")) { map = Strings.Normal; } else if (entry.fullPath.Contains("_s.")) { map = Strings.Specular; } else if (entry.fullPath.Contains("material")) { map = Strings.ColorSet; } else if (entry.fullPath.Contains("model")) { map = "3D"; } else if (entry.fullPath.Contains("ui/")) { map = "UI"; } else { map = Strings.Mask; } mlm.Map = map; if (entry.fullPath.Contains("_b_")) { part = "b"; } else if (entry.fullPath.Contains("_c_")) { part = "c"; } else if (entry.fullPath.Contains("_d_")) { part = "d"; } else if (entry.fullPath.Contains("decal")) { part = entry.fullPath.Substring(entry.fullPath.LastIndexOf('_') + 1, entry.fullPath.LastIndexOf('.') - (entry.fullPath.LastIndexOf('_') + 1)); } else { part = "a"; } mlm.Part = part; if (entry.fullPath.Contains("_iri_")) { type = "Iris"; } else if (entry.fullPath.Contains("_etc_")) { type = "Etc."; } else if (entry.fullPath.Contains("_fac_")) { type = "Face"; } else if (entry.fullPath.Contains("_hir_")) { type = "Hair"; } else if (entry.fullPath.Contains("_acc_")) { type = "Accessory"; } else if (entry.fullPath.Contains("demihuman")) { type = entry.fullPath.Substring(entry.fullPath.LastIndexOf('_') - 3, 3); type = (Info.slotAbr).FirstOrDefault(x => x.Value == type).Key; } else { type = "-"; } mlm.Type = type; if (entry.fullPath.Contains("material")) { var info = MTRL.GetMTRLInfo(entry.modOffset, false); using (var bitmap = TEX.ColorSetToBitmap(info.ColorData)) mlm.BMP = TexHelper.CreateBitmapSource(bitmap); mlm.BMP.Freeze(); } else if (entry.fullPath.Contains("model")) { mlm.BMP = new BitmapImage(new Uri("pack://application:,,,/FFXIV TexTools 2;component/Resources/3DModel.png")); } else { TEXData texData; if (entry.fullPath.Contains("vfx")) { texData = TEX.GetVFX(entry.modOffset, entry.datFile); } else { if (entry.fullPath.Contains("icon")) { texData = TEX.GetTex(entry.modOffset, entry.datFile); } else { texData = TEX.GetTex(entry.modOffset, entry.datFile); } } var scale = 1; if (texData.Width >= 4096 || texData.Height >= 4096) { scale = 16; } else if (texData.Width >= 2048 || texData.Height >= 2048) { scale = 8; } else if (texData.Width >= 1024 || texData.Height >= 1024) { scale = 4; } var nWidth = texData.Width / scale; var nHeight = texData.Height / scale; var resizedImage = TexHelper.CreateResizedImage(texData.BMPSouceNoAlpha, nWidth, nHeight); mlm.BMP = (BitmapSource)resizedImage; mlm.BMP.Freeze(); } var offset = Helper.GetDataOffset(FFCRC.GetHash(entry.fullPath.Substring(0, entry.fullPath.LastIndexOf("/"))), FFCRC.GetHash(Path.GetFileName(entry.fullPath)), entry.datFile); if (offset == entry.modOffset) { mlm.ActiveBorder = Brushes.Green; mlm.Active = Brushes.Transparent; mlm.ActiveOpacity = 1; } else if (offset == entry.originalOffset) { mlm.ActiveBorder = Brushes.Red; mlm.Active = Brushes.Gray; mlm.ActiveOpacity = 0.5f; } else { mlm.ActiveBorder = Brushes.Red; mlm.Active = Brushes.Red; mlm.ActiveOpacity = 1; } mlm.Entry = entry; return(mlm); }
public void Run( params string [] args ) { if ( args.Length == 0 || args [ 0 ] == "-h" ) { Console.WriteLine ( "USECASE:" ); Console.WriteLine ( " lemon.exe -stt filename" ); } else { CultureInfo cultureInfo = CultureInfo.CurrentCulture; using ( FileStream stream = new FileStream ( args [ 0 ], FileMode.OpenOrCreate, FileAccess.ReadWrite ) ) { JsonEntry entry; if ( stream.Length != 0 ) entry = JsonParser.Parse ( stream ); else entry = new JsonEntry (); while ( true ) { Console.WriteLine ( "==========================================" ); Console.WriteLine ( "CURRENT CULTURE: {0}", cultureInfo ); Console.WriteLine ( "MENU:" ); Console.WriteLine ( " 1. Add string" ); Console.WriteLine ( " 2. Remove string" ); Console.WriteLine ( " 3. Show strings of current culture" ); Console.WriteLine ( " 4. Change current culture" ); Console.WriteLine ( " 5. Quit without save" ); Console.WriteLine ( " else. save and quit" ); Console.Write ( ">" ); int menuSelect; if ( !int.TryParse ( Console.ReadLine (), out menuSelect ) ) menuSelect = 6; Console.WriteLine ( "-----------------------------------------" ); switch ( menuSelect ) { case 1: { Console.Write ( "KEY>" ); string key = Console.ReadLine (); Console.Write ( "VALUE>" ); string value = Console.ReadLine (); if ( !entry.Contains ( cultureInfo.Name ) ) entry.Add ( cultureInfo.Name, new JsonEntry () ); JsonEntry json = entry [ cultureInfo.Name ] as JsonEntry; if ( !json.Contains ( key ) ) json.Add ( key, value ); else json [ key ] = value; } break; case 2: { Console.Write ( "KEY>" ); string key = Console.ReadLine (); if ( !entry.Contains ( cultureInfo.Name ) ) break; JsonEntry json = entry [ cultureInfo.Name ] as JsonEntry; if ( !json.Contains ( key ) ) break; json.Remove ( key ); } break; case 3: { if ( !entry.Contains ( cultureInfo.Name ) ) break; JsonEntry json = entry [ cultureInfo.Name ] as JsonEntry; foreach ( KeyValuePair<string, object> item in json ) Console.WriteLine ( "{0}: {1}", item.Key, item.Value ); } break; case 4: { Console.Write ( "CULTURE>" ); string culture = Console.ReadLine (); cultureInfo = new CultureInfo ( culture ); } break; case 5: return; default: stream.Position = 0; using ( StreamWriter writer = new StreamWriter ( stream ) ) { writer.Write ( entry.ToString () ); writer.Flush (); } return; } } } } }
public static JsonEntry Parse( Stream stream ) { JsonEntry jsonEntry = new JsonEntry (); StringBuilder automataToken = null; Stack<object> tokenStack = new Stack<object> (); TokenType tokenType = TokenType.Unknown; BinaryReader br = new BinaryReader ( stream ); br.ReadChar (); while ( stream.CanRead && stream.Position != stream.Length ) { char readedCharacter = br.ReadChar (); switch ( tokenType ) { case TokenType.Unknown: { if ( readedCharacter == '"' ) tokenType = TokenType.String; else if ( readedCharacter == '{' ) tokenStack.Push ( Parse ( stream ) ); else if ( readedCharacter == '}' ) { if ( tokenStack.Count >= 2 ) { object data = tokenStack.Pop (); string name = tokenStack.Pop () as string; jsonEntry.Add ( name, data ); } return jsonEntry; } else if ( readedCharacter == '[' ) tokenStack.Push ( ArrayParse ( stream ) ); else if ( readedCharacter == ',' ) { object data = tokenStack.Pop (); string name = tokenStack.Pop () as string; jsonEntry.Add ( name, data ); tokenType = TokenType.Unknown; automataToken = null; } else if ( ( readedCharacter == 't' || readedCharacter == 'f' ) || ( readedCharacter == 'T' || readedCharacter == 'F' ) ) { tokenType = TokenType.Boolean; stream.Seek ( -1, SeekOrigin.Current ); } else if ( readedCharacter == 'n' || readedCharacter == 'N' ) { tokenType = TokenType.Null; stream.Seek ( -1, SeekOrigin.Current ); } else if ( readedCharacter >= '0' && readedCharacter <= '9' ) { tokenType = TokenType.Integer; stream.Seek ( -1, SeekOrigin.Current ); } automataToken = new StringBuilder (); } break; case TokenType.String: { if ( readedCharacter == '"' ) { tokenStack.Push ( automataToken.ToString () ); tokenType = TokenType.Unknown; automataToken = null; break; } else if ( readedCharacter == '\\' ) { readedCharacter = br.ReadChar (); if ( readedCharacter == 'n' ) automataToken.Append ( '\n' ); else automataToken.Append ( readedCharacter ); } automataToken.Append ( readedCharacter ); } break; case TokenType.Boolean: { automataToken.Append ( readedCharacter ); if ( automataToken.ToString ().ToLower () == "true" || automataToken.ToString ().ToLower () == "false" ) { tokenStack.Push ( bool.Parse ( automataToken.ToString () ) ); tokenType = TokenType.Unknown; automataToken = null; break; } } break; case TokenType.Null: { automataToken.Append ( readedCharacter ); if ( automataToken.ToString ().ToLower () == "null" ) { tokenStack.Push ( null ); tokenType = TokenType.Unknown; automataToken = null; break; } } break; case TokenType.Integer: { if ( readedCharacter == '.' ) tokenType = TokenType.FloatingPoint; else if ( !( readedCharacter >= '0' && readedCharacter <= '9' ) ) { stream.Seek ( -1, SeekOrigin.Current ); tokenStack.Push ( int.Parse ( automataToken.ToString () ) ); tokenType = TokenType.Unknown; automataToken = null; break; } automataToken.Append ( readedCharacter ); } break; case TokenType.FloatingPoint: { if ( !( readedCharacter >= '0' && readedCharacter <= '9' ) ) { stream.Seek ( -1, SeekOrigin.Current ); tokenStack.Push ( double.Parse ( automataToken.ToString () ) ); tokenType = TokenType.Unknown; automataToken = null; break; } automataToken.Append ( readedCharacter ); } break; } } return jsonEntry; }
/// <summary> /// Imports the items color set into a dat file /// </summary> /// <param name="mtrlData">MTRL data for the currently displayed color set</param> /// <param name="category">The items category</param> /// <param name="itemName">The items name</param> public static Tuple <int, byte[]> ImportColor(MTRLData mtrlData, string category, string itemName) { var savePath = Properties.Settings.Default.Save_Directory + "/" + category + "/" + itemName + "/" + Path.GetFileNameWithoutExtension(mtrlData.MTRLPath) + ".dds"; int newOffset = 0; if (File.Exists(savePath)) { List <byte> mtrlBytes = new List <byte>(); List <byte> newMTRL = new List <byte>(); JsonEntry modEntry = null; int offset = mtrlData.MTRLOffset; int lineNum = 0; short fileSize; bool inModList = false; byte[] colorData; int datNum = ((offset / 8) & 0x000f) / 2; try { using (StreamReader sr = new StreamReader(Properties.Settings.Default.Modlist_Directory)) { string line; while ((line = sr.ReadLine()) != null) { modEntry = JsonConvert.DeserializeObject <JsonEntry>(line); if (modEntry.fullPath.Equals(mtrlData.MTRLPath)) { inModList = true; break; } lineNum++; } } } catch (Exception ex) { FlexibleMessageBox.Show("Error Accessing .modlist File \n" + ex.Message, "ImportTex Error " + Info.appVersion, MessageBoxButtons.OK, MessageBoxIcon.Error); } using (BinaryReader br = new BinaryReader(new MemoryStream(Helper.GetType2DecompressedData(offset, datNum, Strings.ItemsDat)))) { br.BaseStream.Seek(4, SeekOrigin.Begin); fileSize = br.ReadInt16(); short colorDataSize = br.ReadInt16(); short textureNameSize = br.ReadInt16(); short toSHPK = br.ReadInt16(); byte numOfTextures = br.ReadByte(); byte numOfMaps = br.ReadByte(); byte numOfColorSets = br.ReadByte(); byte unknown = br.ReadByte(); int endOfHeader = 16 + ((numOfTextures + numOfMaps + numOfColorSets) * 4); br.BaseStream.Seek(0, SeekOrigin.Begin); mtrlBytes.AddRange(br.ReadBytes(endOfHeader)); mtrlBytes.AddRange(br.ReadBytes(textureNameSize + 4)); br.ReadBytes(colorDataSize); if (colorDataSize == 544) { using (BinaryReader br1 = new BinaryReader(File.OpenRead(savePath))) { br1.BaseStream.Seek(128, SeekOrigin.Begin); colorData = br1.ReadBytes(colorDataSize - 32); mtrlBytes.AddRange(colorData); } string flagsPath = Path.Combine(Path.GetDirectoryName(savePath), (Path.GetFileNameWithoutExtension(savePath) + ".dat")); using (BinaryReader br1 = new BinaryReader(File.OpenRead(flagsPath))) { br1.BaseStream.Seek(0, SeekOrigin.Begin); mtrlBytes.AddRange(br1.ReadBytes(32)); } } else { using (BinaryReader br1 = new BinaryReader(File.OpenRead(savePath))) { br1.BaseStream.Seek(128, SeekOrigin.Begin); colorData = br1.ReadBytes(colorDataSize); mtrlBytes.AddRange(colorData); } } mtrlBytes.AddRange(br.ReadBytes(fileSize - (int)br.BaseStream.Position)); } var compressed = Compressor(mtrlBytes.ToArray()); int padding = 128 - (compressed.Length % 128); newMTRL.AddRange(MakeMTRLHeader(fileSize, compressed.Length + padding)); newMTRL.AddRange(BitConverter.GetBytes(16)); newMTRL.AddRange(BitConverter.GetBytes(0)); newMTRL.AddRange(BitConverter.GetBytes(compressed.Length)); newMTRL.AddRange(BitConverter.GetBytes((int)fileSize)); newMTRL.AddRange(compressed); newMTRL.AddRange(new byte[padding]); newOffset = WriteToDat(newMTRL, modEntry, inModList, mtrlData.MTRLPath, category, itemName, lineNum, Strings.ItemsDat); return(new Tuple <int, byte[]>(newOffset, colorData)); } else { FlexibleMessageBox.Show("Could not find file \n" + savePath, "File read Error", MessageBoxButtons.OK, MessageBoxIcon.Error); return(new Tuple <int, byte[]>(0, null)); } }
/// <summary> /// Enables or Disables the modification on the current item's texture map /// </summary> /// <param name="obj"></param> private void Revert(object obj) { if (!Helper.IsIndexLocked(true)) { JsonEntry modEntry = null; string line; try { using (StreamReader sr = new StreamReader(Properties.Settings.Default.Modlist_Directory)) { while ((line = sr.ReadLine()) != null) { modEntry = JsonConvert.DeserializeObject <JsonEntry>(line); if (modEntry.fullPath.Equals(fullPath)) { break; } } } } catch (Exception ex) { MessageBox.Show("[TVM] Error Accessing .modlist File \n" + ex.Message, "Error", MessageBoxButton.OK, MessageBoxImage.Error); } if (modEntry != null) { int offset = 0; string toggle = ""; if (ActiveToggle.Equals("Enable")) { offset = modEntry.modOffset; toggle = "Disable"; } else if (ActiveToggle.Equals("Disable")) { offset = modEntry.originalOffset; toggle = "Enable"; } if (offset != 0) { ActiveToggle = toggle; Helper.UpdateIndex(offset, fullPath, modEntry.datFile); Helper.UpdateIndex2(offset, fullPath, modEntry.datFile); if (selectedMap.Name.Equals(Strings.Normal)) { mtrlData.NormalOffset = offset; } else if (selectedMap.Name.Equals(Strings.Diffuse)) { mtrlData.DiffuseOffset = offset; } else if (selectedMap.Name.Equals(Strings.Specular)) { mtrlData.SpecularOffset = offset; } else if (selectedMap.Name.Equals(Strings.Mask)) { mtrlData.MaskOffset = offset; } if (SelectedMap.Name.Equals(Strings.ColorSet)) { UpdateImage(offset, true); } else { UpdateImage(offset, false); } } } } }
/// <summary> /// Imports the items texture into a dat file /// </summary> /// <param name="texData">Data for the currently displayed texture</param> /// <param name="category">The items category</param> /// <param name="itemName">The items name</param> /// <param name="internalFilePath">The internal file path of the texture map</param> /// <returns>The offset in which the data was placed</returns> public static int ImportTexture(TEXData texData, string category, string subCategory, string itemName, string internalFilePath) { int textureType, lineNum = 0, offset = 0; bool inModList = false; JsonEntry modEntry = null; string dxPath = Path.GetFileNameWithoutExtension(internalFilePath); var savePath = Properties.Settings.Default.Save_Directory + "/" + category + "/" + itemName + "/" + dxPath + ".dds"; if (category.Equals("UI")) { savePath = Properties.Settings.Default.Save_Directory + "/" + category + "/" + subCategory + "/" + dxPath + ".dds"; } if (File.Exists(savePath)) { try { using (StreamReader sr = new StreamReader(Properties.Settings.Default.Modlist_Directory)) { string line; while ((line = sr.ReadLine()) != null) { modEntry = JsonConvert.DeserializeObject <JsonEntry>(line); if (modEntry.fullPath.Equals(internalFilePath)) { inModList = true; break; } lineNum++; } } } catch (Exception ex) { FlexibleMessageBox.Show("Error Accessing .modlist File \n" + ex.Message, "ImportTex Error " + Info.appVersion, MessageBoxButtons.OK, MessageBoxIcon.Error); } using (BinaryReader br = new BinaryReader(File.OpenRead(savePath))) { br.BaseStream.Seek(12, SeekOrigin.Begin); var newHeight = br.ReadInt32(); var newWidth = br.ReadInt32(); br.ReadBytes(8); var newMipCount = br.ReadInt32(); br.BaseStream.Seek(80, SeekOrigin.Begin); var textureFlags = br.ReadInt32(); var texType = br.ReadInt32(); try { textureType = Info.DDSType[texType]; } catch (Exception e) { FlexibleMessageBox.Show("DDS Type (" + texType + ") not recognized \n" + e.Message, "ImportTex Error " + Info.appVersion, MessageBoxButtons.OK, MessageBoxIcon.Error); return(0); } if (textureFlags == 2 && textureType == 5200) { textureType = TextureTypes.A8; } else if (textureFlags == 65 && textureType == 5200) { int bpp = br.ReadInt32(); if (bpp == 32) { textureType = TextureTypes.A8R8G8B8; } else { int red = br.ReadInt32(); if (red == 31744) { textureType = TextureTypes.A1R5G5B5; } else if (red == 3840) { textureType = TextureTypes.A4R4G4B4; } } } if (textureType == texData.Type) { List <byte> newTEX = new List <byte>(); int uncompressedLength = (int)new FileInfo(savePath).Length - 128; var DDSInfo = ReadDDS(br, texData, newWidth, newHeight, newMipCount); newTEX.AddRange(MakeType4DATHeader(texData, DDSInfo.Item2, DDSInfo.Item3, uncompressedLength, newMipCount, newWidth, newHeight)); newTEX.AddRange(MakeTextureInfoHeader(texData, newWidth, newHeight, newMipCount)); newTEX.AddRange(DDSInfo.Item1); offset = WriteToDat(newTEX, modEntry, inModList, internalFilePath, category, itemName, lineNum, texData.TEXDatName); } else { FlexibleMessageBox.Show("Incorrect file type \nExpected: " + Info.TextureTypes[texData.Type] + " Given: " + Info.TextureTypes[textureType], "Texture format error", MessageBoxButtons.OK, MessageBoxIcon.Error); } } } else { FlexibleMessageBox.Show("Could not find file \n" + savePath, "File read Error", MessageBoxButtons.OK, MessageBoxIcon.Error); } return(offset); }
/// <summary> /// Gets the texture data and displays it for the currently selected item given a specified race, part, type(if applicable), and map /// </summary> private void MapComboBoxChanged() { if (saveClone != null) { //saveClone.UnlockBits(cloneLock); saveClone.Dispose(); } Bitmap colorBmp = null; int offset = 0; bool isVFX = false; bool isUI = false; if (selectedMap.Name.Equals(Strings.Normal)) { fullPath = mtrlData.NormalPath; offset = mtrlData.NormalOffset; FullPathString = fullPath; } else if (selectedMap.Name.Equals(Strings.Specular)) { fullPath = mtrlData.SpecularPath; offset = mtrlData.SpecularOffset; FullPathString = fullPath; } else if (selectedMap.Name.Equals(Strings.Diffuse)) { fullPath = mtrlData.DiffusePath; offset = mtrlData.DiffuseOffset; FullPathString = fullPath; } else if (selectedMap.Name.Equals(Strings.Mask) || selectedMap.Name.Equals(Strings.Skin)) { if (selectedItem.ItemName.Equals(Strings.Face_Paint) || selectedItem.ItemName.Equals(Strings.Equipment_Decals)) { string part; if (selectedItem.ItemName.Equals(Strings.Equipment_Decals)) { if (!SelectedPart.Name.Contains("stigma")) { part = selectedPart.Name.PadLeft(3, '0'); } else { part = SelectedPart.Name; } } else { part = selectedPart.Name; } fullPath = String.Format(mtrlData.MaskPath, part); offset = MTRL.GetDecalOffset(selectedItem.ItemName, selectedPart.Name); } else { fullPath = mtrlData.MaskPath; offset = mtrlData.MaskOffset; } FullPathString = fullPath; } else if (selectedMap.Name.Equals(Strings.ColorSet)) { colorBmp = TEX.TextureToBitmap(mtrlData.ColorData, 9312, 4, 16); fullPath = mtrlData.MTRLPath; FullPathString = fullPath; } else if (SelectedMap.Name.Contains("Icon")) { if (SelectedMap.Name.Contains("HQ")) { fullPath = mtrlData.UIHQPath; offset = mtrlData.UIHQOffset; } else { fullPath = mtrlData.UIPath; offset = mtrlData.UIOffset; } FullPathString = fullPath; isUI = true; } else if (selectedItem.ItemCategory.Equals(Strings.Maps)) { if (selectedMap.Name.Contains("HighRes Map")) { fullPath = string.Format(mtrlData.UIPath, "_m"); offset = mtrlData.UIOffset = int.Parse(selectedMap.ID); } else if (selectedMap.Name.Contains("LowRes Map")) { fullPath = string.Format(mtrlData.UIPath, "_s"); offset = mtrlData.UIOffset = int.Parse(selectedMap.ID); } else if (selectedMap.Name.Contains("PoI")) { fullPath = string.Format(mtrlData.UIPath, "d"); offset = mtrlData.UIOffset = int.Parse(selectedMap.ID); } else if (selectedMap.Name.Contains("HighRes Mask")) { fullPath = string.Format(mtrlData.UIPath, "m_m"); offset = mtrlData.UIOffset = int.Parse(selectedMap.ID); } else if (selectedMap.Name.Contains("LowRes Mask")) { fullPath = string.Format(mtrlData.UIPath, "m_s"); offset = mtrlData.UIOffset = int.Parse(selectedMap.ID); } FullPathString = fullPath; isUI = true; } else if (selectedItem.ItemCategory.Equals("HUD") || selectedItem.ItemCategory.Equals("LoadingImage")) { fullPath = mtrlData.UIPath; offset = mtrlData.UIOffset; FullPathString = fullPath; isUI = true; } else { fullPath = SelectedMap.ID; var VFXFolder = fullPath.Substring(0, fullPath.LastIndexOf("/")); var VFXFile = fullPath.Substring(fullPath.LastIndexOf("/") + 1); offset = Helper.GetDataOffset(FFCRC.GetHash(VFXFolder), FFCRC.GetHash(VFXFile), Strings.ItemsDat); FullPathString = fullPath; isVFX = true; } string line; JsonEntry modEntry = null; bool inModList = false; try { using (StreamReader sr = new StreamReader(Properties.Settings.Default.Modlist_Directory)) { while ((line = sr.ReadLine()) != null) { modEntry = JsonConvert.DeserializeObject <JsonEntry>(line); if (modEntry.fullPath.Equals(fullPath)) { inModList = true; break; } } } } catch (Exception ex) { MessageBox.Show("[TVM] Error Accessing .modlist File \n" + ex.Message, "Error", MessageBoxButton.OK, MessageBoxImage.Error); } if (inModList) { var currOffset = Helper.GetDataOffset(FFCRC.GetHash(modEntry.fullPath.Substring(0, modEntry.fullPath.LastIndexOf("/"))), FFCRC.GetHash(Path.GetFileName(modEntry.fullPath)), modEntry.datFile); if (currOffset == modEntry.modOffset) { ActiveToggle = "Disable"; } else if (currOffset == modEntry.originalOffset) { ActiveToggle = "Enable"; } else { ActiveToggle = "Error"; } ActiveEnabled = true; } else { ActiveEnabled = false; ActiveToggle = "Enable/Disable"; } if (offset == 0) { TextureType = "Type: 16.16.16.16f ABGR\nMipMaps: None"; TextureDimensions = "(4 x 16)"; alphaBitmap = Imaging.CreateBitmapSourceFromHBitmap(colorBmp.GetHbitmap(), IntPtr.Zero, Int32Rect.Empty, BitmapSizeOptions.FromEmptyOptions()); alphaBitmap.Freeze(); var removeAlphaBitmap = SetAlpha(colorBmp, 255); noAlphaBitmap = Imaging.CreateBitmapSourceFromHBitmap(removeAlphaBitmap.GetHbitmap(), IntPtr.Zero, Int32Rect.Empty, BitmapSizeOptions.FromEmptyOptions()); noAlphaBitmap.Freeze(); colorBmp.Dispose(); removeAlphaBitmap.Dispose(); } else { if (!isVFX) { if (!isUI) { texData = TEX.GetTex(offset, Strings.ItemsDat); } else { texData = TEX.GetTex(offset, Strings.UIDat); } } else { texData = TEX.GetVFX(offset, Strings.ItemsDat); } string mipMaps = "Yes (" + texData.MipCount + ")"; if (texData.MipCount < 1) { mipMaps = "None"; } TextureType = "Type: " + texData.TypeString + "\nMipMaps: " + mipMaps; TextureDimensions = "(" + texData.Width + " x " + texData.Height + ")"; var clonerect = new Rectangle(0, 0, texData.Width, texData.Height); saveClone = texData.BMP.Clone(new Rectangle(0, 0, texData.Width, texData.Height), PixelFormat.Format32bppArgb); alphaBitmap = Imaging.CreateBitmapSourceFromHBitmap(texData.BMP.GetHbitmap(), IntPtr.Zero, Int32Rect.Empty, BitmapSizeOptions.FromEmptyOptions()); alphaBitmap.Freeze(); if (!isUI) { var removeAlphaBitmap = SetAlpha(texData.BMP, 255); noAlphaBitmap = Imaging.CreateBitmapSourceFromHBitmap(removeAlphaBitmap.GetHbitmap(), IntPtr.Zero, Int32Rect.Empty, BitmapSizeOptions.FromEmptyOptions()); noAlphaBitmap.Freeze(); removeAlphaBitmap.Dispose(); } } try { ImageEffect = new ColorChannels() { Channel = new System.Windows.Media.Media3D.Point4D(1.0f, 1.0f, 1.0f, 0.0f) }; } catch (Exception ex) { Debug.WriteLine(ex.StackTrace); } if (!isUI) { ImageSource = noAlphaBitmap; SetColorChannelFilter(imageEffect); ChannelsEnabled = true; } else { ImageSource = alphaBitmap; SetColorChannelFilter(imageEffect); ChannelsEnabled = true; } SaveEnabled = true; texData.Dispose(); string dxPath = Path.GetFileNameWithoutExtension(fullPath); string savePath = Properties.Settings.Default.Save_Directory + "/" + selectedCategory + "/" + selectedItem.ItemName + "/" + dxPath + ".dds"; if (selectedCategory.Equals("UI")) { savePath = Properties.Settings.Default.Save_Directory + "/" + selectedCategory + "/" + selectedItem.ItemCategory + "/" + dxPath + ".dds"; } if (File.Exists(savePath)) { ImportEnabled = true; } else { ImportEnabled = false; } string folderPath = Properties.Settings.Default.Save_Directory + "/" + selectedCategory + "/" + selectedItem.ItemName; if (selectedCategory.Equals("UI")) { folderPath = Properties.Settings.Default.Save_Directory + "/" + selectedCategory + "/" + selectedItem.ItemCategory; } if (Directory.Exists(folderPath)) { OpenEnabled = true; } else { OpenEnabled = false; } }
private bool CheckModlist() { string line; JsonEntry modEntry = null; bool check = false; if (File.ReadLines(Properties.Settings.Default.Modlist_Directory).Count() > 0) { try { using (StreamReader sr = new StreamReader(Properties.Settings.Default.Modlist_Directory)) { while ((line = sr.ReadLine()) != null) { modEntry = JsonConvert.DeserializeObject <JsonEntry>(line); if (!modEntry.fullPath.Equals("")) { var originalOffset = modEntry.originalOffset / 8; //var modOffset = modEntry.modOffset / 8; var modOffset = modEntry.modOffset; int datNum = (originalOffset & 0xF) / 2; int nDatNum = ((modOffset / 8) & 0xF) / 2; var tabs = ""; if (Path.GetFileName(modEntry.fullPath).Length < 21) { tabs = "\t"; } AddText("\t" + Path.GetFileName(modEntry.fullPath) + tabs, "Black"); var datPath = string.Format(Info.datDir, modEntry.datFile, nDatNum); modOffsetList.Add(modOffset); modOffset -= nDatNum * 16; using (BinaryReader br = new BinaryReader(File.OpenRead(datPath))) { br.BaseStream.Seek(modOffset, SeekOrigin.Begin); var hSize = br.ReadInt32(); var type = br.ReadInt32(); if (type != 2 && type != 3 && type != 4) { AddText("\t\u2716\n", "Red"); AddText("\tFound unkown file type ( " + type + " ) offset is most likely corrupt.\n", "Red"); } else { AddText("\t\u2714", "Green"); } } if (modEntry.datFile.Equals(Strings.ItemsDat)) { if (datNum > 3 || originalOffset == 0) { AddText("\t\u2716\n", "Red"); check = true; } else if (modOffset == 0) { AddText("\t\u2716\n", "Red"); AddText("\tMod Offset for the above texture was 0, Disable from File > Modlist and reimport.\n", "Red"); check = true; } else { AddText("\t\u2714\n", "Green"); } } else if (modEntry.datFile.Equals(Strings.UIDat)) { if (datNum > 0 || originalOffset == 0) { AddText("\t\u2716\n", "Red"); check = true; } else if (modOffset == 0) { AddText("\t\u2716\n", "Red"); AddText("\tMod Offset for the above texture was 0, Disable from File > Modlist and reimport.\n", "Red"); check = true; } else { AddText("\t\u2714\n", "Green"); } } originalOffsetList.Add(originalOffset); } } } } catch (Exception e) { AddText("\t\nError: " + e.Message + "\n", "Red"); } } else { AddText("\tNo entries found in modlist.\n", "Orange"); } return(check); }
private void BackgroundWorker_DoWork(object sender, DoWorkEventArgs e) { var backgroundWorker = sender as BackgroundWorker; var packListCount = packList.Count; float i = 0; List <string> modFileLines = new List <string>(File.ReadAllLines(Properties.Settings.Default.Modlist_Directory)); try { using (ZipArchive archive = ZipFile.OpenRead(packPath)) { backgroundWorker.ReportProgress(0, "Opening TTMP Data File...\n"); foreach (var entry in archive.Entries) { if (entry.FullName.EndsWith(".mpd")) { var stream = entry.Open(); var remainingPack = packListCount; var currentPack = 0; var prevPack = 0; long newOffset = 0; long offsetSum = 0; List <ModPackItems> pack; long cursor = 0; while (currentPack != packListCount) { prevPack = currentPack; if (remainingPack > 100) { pack = packList.GetRange(currentPack, 100); currentPack += 100; remainingPack -= 100; } else { pack = packList.GetRange(currentPack, remainingPack); currentPack += remainingPack; } backgroundWorker.ReportProgress((int)((i / packListCount) * 100), $"\nReading Entries ({prevPack} - {currentPack}/{packListCount})\n\n"); long totalSize = 0; var modPackBytes = new List <byte>(); foreach (var p in pack) { if (p.mEntry.ModOffset < cursor) { backgroundWorker.ReportProgress((int)((i / packListCount) * 100), $"There was an warning in importing. \nImproper Mod Offset in ModPack for {p.mEntry.Name}. \nUnable to import {p.mEntry.Name}."); continue; } totalSize += p.mEntry.ModSize; var buf = new byte[p.mEntry.ModSize]; while (p.mEntry.ModOffset > cursor) { cursor++; stream.ReadByte(); //seek forward for next offset } stream.Read(buf, 0, buf.Length); cursor += buf.Length; modPackBytes.AddRange(buf); } var uncompBytes = modPackBytes.ToArray(); offsetSum += newOffset; newOffset = totalSize; using (var ms = new MemoryStream(uncompBytes)) { //backgroundWorker.ReportProgress((int)((i / packListCount) * 100), "Reading TTMP Data...\n"); var dataOffset = 0; using (var br = new BinaryReader(ms)) { //backgroundWorker.ReportProgress((int)((i / packListCount) * 100), "Begining Import...\n"); foreach (var mpi in pack) { currentImport = mpi.Name + "...."; backgroundWorker.ReportProgress((int)((i / packListCount) * 100), currentImport); JsonEntry modEntry = null; bool inModList = false; bool overwrite = false; int lineNum = 0; int originalOffset = 0; int offset = 0; byte[] dataBytes = new byte[mpi.mEntry.ModSize]; List <byte> modDataList = new List <byte>(); br.BaseStream.Seek(dataOffset, SeekOrigin.Begin); modDataList.AddRange(br.ReadBytes(mpi.mEntry.ModSize)); try { foreach (var line in modFileLines) { modEntry = JsonConvert.DeserializeObject <JsonEntry>(line); if (modEntry.fullPath.Equals(mpi.mEntry.FullPath)) { inModList = true; break; } lineNum++; } var datNum = int.Parse(Info.ModDatDict[mpi.mEntry.DatFile]); var modDatPath = string.Format(Info.datDir, mpi.mEntry.DatFile, datNum); var fileLength = new FileInfo(modDatPath).Length; while (fileLength + mpi.mEntry.ModSize >= 2000000000) { datNum += 1; modDatPath = string.Format(Info.datDir, mpi.mEntry.DatFile, datNum); if (!File.Exists(modDatPath)) { CreateDat.MakeNewDat(mpi.mEntry.DatFile); } fileLength = new FileInfo(modDatPath).Length; } //is in modlist and size of new mod is less than or equal to existing mod size if (inModList && mpi.mEntry.ModSize <= modEntry.modSize) { int sizeDiff = modEntry.modSize - modDataList.Count; datNum = ((modEntry.modOffset / 8) & 0x0F) / 2; modDatPath = string.Format(Info.datDir, modEntry.datFile, datNum); var datOffsetAmount = 16 * datNum; using (BinaryWriter bw = new BinaryWriter(File.OpenWrite(modDatPath))) { bw.BaseStream.Seek(modEntry.modOffset - datOffsetAmount, SeekOrigin.Begin); bw.Write(modDataList.ToArray()); bw.Write(new byte[sizeDiff]); } Helper.UpdateIndex(modEntry.modOffset, mpi.mEntry.FullPath, mpi.mEntry.DatFile); Helper.UpdateIndex2(modEntry.modOffset, mpi.mEntry.FullPath, mpi.mEntry.DatFile); offset = modEntry.modOffset; overwrite = true; } if (!overwrite) { using (BinaryWriter bw = new BinaryWriter(File.OpenWrite(modDatPath))) { bw.BaseStream.Seek(0, SeekOrigin.End); while ((bw.BaseStream.Position & 0xFF) != 0) { bw.Write((byte)0); } int eof = (int)bw.BaseStream.Position + modDataList.Count; while ((eof & 0xFF) != 0) { modDataList.AddRange(new byte[16]); eof = eof + 16; } var datOffsetAmount = 16 * datNum; offset = (int)bw.BaseStream.Position + datOffsetAmount; if (offset != 0) { bw.Write(modDataList.ToArray()); } else { FlexibleMessageBox.Show("There was an issue obtaining the .dat4 offset to write data to, try importing again. " + "\n\n If the problem persists, please submit a bug report.", "ImportModel Error " + Info.appVersion, MessageBoxButtons.OK, MessageBoxIcon.Error); return; } } int oldOffset = Helper.UpdateIndex(offset, mpi.mEntry.FullPath, mpi.mEntry.DatFile) * 8; Helper.UpdateIndex2(offset, mpi.mEntry.FullPath, mpi.mEntry.DatFile); //is in modlist and size of new mod is larger than existing mod size if (inModList && mpi.mEntry.ModSize > modEntry.modSize) { oldOffset = modEntry.originalOffset; JsonEntry replaceEntry = new JsonEntry() { category = String.Empty, name = String.Empty, fullPath = String.Empty, originalOffset = 0, modOffset = modEntry.modOffset, modSize = modEntry.modSize, datFile = mpi.mEntry.DatFile }; modFileLines[lineNum] = JsonConvert.SerializeObject(replaceEntry); File.WriteAllLines(Properties.Settings.Default.Modlist_Directory, modFileLines); } JsonEntry jsonEntry = new JsonEntry() { category = mpi.Category, name = mpi.Name, fullPath = mpi.mEntry.FullPath, originalOffset = oldOffset, modOffset = offset, modSize = mpi.mEntry.ModSize, datFile = mpi.mEntry.DatFile }; try { modFileLines.Add(JsonConvert.SerializeObject(jsonEntry)); File.WriteAllLines(Properties.Settings.Default.Modlist_Directory, modFileLines); } catch (Exception ex) { FlexibleMessageBox.Show("Error Accessing .modlist File \n" + ex.Message, "ImportModel Error " + Info.appVersion, MessageBoxButtons.OK, MessageBoxIcon.Error); } } } catch (Exception ex) { FlexibleMessageBox.Show("There was an error in importing. \n" + ex.Message, "ImportModPack Error " + Info.appVersion, MessageBoxButtons.OK, MessageBoxIcon.Error); Debug.WriteLine(ex.StackTrace); } i++; backgroundWorker.ReportProgress((int)((i / packListCount) * 100), "Done."); dataOffset += mpi.mEntry.ModSize; } } } } stream.Dispose(); stream.Close(); } } } } catch (Exception ex) { FlexibleMessageBox.Show("Error opening TexTools ModPack file. \n" + ex.Message, "ImportModPack Error " + Info.appVersion, MessageBoxButtons.OK, MessageBoxIcon.Error); Debug.WriteLine(ex.StackTrace); } }
/// <summary> /// Imports the items color set into a dat file /// </summary> /// <param name="mtrlData">MTRL data for the currently displayed color set</param> /// <param name="category">The items category</param> /// <param name="itemName">The items name</param> /// <param name="toggle">Toggle value for translucency</param> public static int TranslucencyToggle(MTRLData mtrlData, string category, string itemName, bool toggle) { int newOffset = 0; List <byte> mtrlBytes = new List <byte>(); List <byte> newMTRL = new List <byte>(); JsonEntry modEntry = null; int offset = mtrlData.MTRLOffset; int lineNum = 0; short fileSize; bool inModList = false; int datNum = ((offset / 8) & 0x000f) / 2; try { using (StreamReader sr = new StreamReader(Properties.Settings.Default.Modlist_Directory)) { string line; while ((line = sr.ReadLine()) != null) { modEntry = JsonConvert.DeserializeObject <JsonEntry>(line); if (modEntry.fullPath.Equals(mtrlData.MTRLPath)) { inModList = true; break; } lineNum++; } } } catch (Exception ex) { FlexibleMessageBox.Show("Error Accessing .modlist File \n" + ex.Message, "ImportTex Error " + Info.appVersion, MessageBoxButtons.OK, MessageBoxIcon.Error); } using (BinaryReader br = new BinaryReader(new MemoryStream(Helper.GetType2DecompressedData(offset, datNum, Strings.ItemsDat)))) { bool enableAlpha = false; br.BaseStream.Seek(4, SeekOrigin.Begin); fileSize = br.ReadInt16(); short colorDataSize = br.ReadInt16(); short textureNameSize = br.ReadInt16(); short toSHPK = br.ReadInt16(); byte numOfTextures = br.ReadByte(); byte numOfMaps = br.ReadByte(); byte numOfColorSets = br.ReadByte(); byte unknown = br.ReadByte(); int endOfHeader = 16 + ((numOfTextures + numOfMaps + numOfColorSets) * 4); br.BaseStream.Seek(0, SeekOrigin.Begin); mtrlBytes.AddRange(br.ReadBytes(endOfHeader)); mtrlBytes.AddRange(br.ReadBytes(textureNameSize + 4)); mtrlBytes.AddRange(br.ReadBytes(colorDataSize)); mtrlBytes.AddRange(br.ReadBytes(8)); br.ReadByte(); mtrlBytes.Add(toggle ? (byte)0x1D : (byte)0x0D); mtrlBytes.AddRange(br.ReadBytes(fileSize - (int)br.BaseStream.Position)); } var compressed = Compressor(mtrlBytes.ToArray()); int padding = 128 - (compressed.Length % 128); newMTRL.AddRange(MakeMTRLHeader(fileSize, compressed.Length + padding)); newMTRL.AddRange(BitConverter.GetBytes(16)); newMTRL.AddRange(BitConverter.GetBytes(0)); newMTRL.AddRange(BitConverter.GetBytes(compressed.Length)); newMTRL.AddRange(BitConverter.GetBytes((int)fileSize)); newMTRL.AddRange(compressed); newMTRL.AddRange(new byte[padding]); return(ImportTex.WriteToDat(newMTRL, modEntry, inModList, mtrlData.MTRLPath, category, itemName, lineNum, Strings.ItemsDat)); }
/// <summary> /// Constructor of String Table /// </summary> /// <param name="stream">String table stream</param> public StringTable( Stream stream ) { stringTable = JsonParser.Parse ( stream ); if ( stringTable [ "tableversion" ] as string != "1.0" ) throw new VersionMismatchException (); }