private void modExportButton_Click(object sender, EventArgs e) { int count = listView1.CheckedItems.Count; Directory.CreateDirectory(Directory.GetCurrentDirectory() + "/exported/"); if (count > 0) { List <string> exportModList = new List <string>(); using (FileStream fs = File.Create(Directory.GetCurrentDirectory() + "/exported/xivMods.dat")) { using (BinaryWriter bw = new BinaryWriter(fs)) { bw.BaseStream.Seek(0, SeekOrigin.Begin); using (BinaryReader br = new BinaryReader(File.OpenRead(Properties.Settings.Default.DefaultDir + "/040000.win32.dat3"))) { int nextOffset; foreach (ListViewItem item in listView1.CheckedItems) { jModEntry entry = modList[item.Index]; try { jModEntry nextEntry = modList[item.Index + 1]; nextOffset = int.Parse(nextEntry.modOffset, NumberStyles.HexNumber); } catch { nextOffset = (int)br.BaseStream.Length; } int size = nextOffset - int.Parse(entry.modOffset, NumberStyles.HexNumber); br.BaseStream.Seek(int.Parse(entry.modOffset, NumberStyles.HexNumber) - 48, SeekOrigin.Begin); entry.modOffset = bw.BaseStream.Position.ToString("X").PadLeft(8, '0'); exportModList.Add(JsonConvert.SerializeObject(entry)); bw.Write(br.ReadBytes(size)); } } } } File.WriteAllLines(Directory.GetCurrentDirectory() + "/exported/xivMods.modlist", exportModList.ToArray()); } }
private void switchButton_Click(object sender, EventArgs e) { string active = listView1.SelectedItems[0].SubItems[5].Text; IOHelper ioHelper = new IOHelper(); if (active.Equals("False")) { jModEntry modEntry = modList[listView1.SelectedItems[0].Index]; string name; if (!modEntry.name.Contains("mt_")) { name = modEntry.name + ".tex"; } else { name = modEntry.name + ".mtrl"; } int modded = int.Parse(modEntry.modOffset, NumberStyles.HexNumber); ioHelper.modifyIndexOffset(modded, name, modEntry.folder); listView1.SelectedItems[0].SubItems[5].Text = "True"; } else { jModEntry modEntry = modList[listView1.SelectedItems[0].Index]; string name; if (!modEntry.name.Contains("mt_")) { name = modEntry.name + ".tex"; } else { name = modEntry.name + ".mtrl"; } int orig = int.Parse(modEntry.origOffset, NumberStyles.HexNumber); ioHelper.modifyIndexOffset(orig, name, modEntry.folder); listView1.SelectedItems[0].SubItems[5].Text = "False"; } }
/// <summary> /// Importer dialog, used to import shared mods /// </summary> /// <param name="xivModsDirectory"></param> public Importer(string xivModsDirectory) { InitializeComponent(); listView1.View = View.Details; listView1.GridLines = true; this.xivModsDirectory = xivModsDirectory; Dictionary <string, string> raceIDDict = new Dictionary <string, string>(); raceIDDict.Add("0101", Resources.strings.Hyur + " " + Resources.strings.Midlander + " " + Resources.strings.Male); raceIDDict.Add("0104", Resources.strings.Hyur + " " + Resources.strings.Male + " NPC"); raceIDDict.Add("0201", Resources.strings.Hyur + " " + Resources.strings.Midlander + " " + Resources.strings.Female); raceIDDict.Add("0204", Resources.strings.Hyur + " " + Resources.strings.Female + " NPC"); raceIDDict.Add("0301", Resources.strings.Hyur + " " + Resources.strings.Midlander + " " + Resources.strings.Male); raceIDDict.Add("0401", Resources.strings.Hyur + " " + Resources.strings.Midlander + " " + Resources.strings.Female); raceIDDict.Add("0501", Resources.strings.Elezen + " " + Resources.strings.Male); raceIDDict.Add("0504", Resources.strings.Elezen + " " + Resources.strings.Male + " NPC"); raceIDDict.Add("0601", Resources.strings.Elezen + " " + Resources.strings.Female); raceIDDict.Add("0604", Resources.strings.Elezen + " " + Resources.strings.Female + " NPC"); raceIDDict.Add("0701", Resources.strings.Miqote + " " + Resources.strings.Male); raceIDDict.Add("0801", Resources.strings.Miqote + " " + Resources.strings.Female); raceIDDict.Add("0804", Resources.strings.Miqote + " " + Resources.strings.Female + " NPC"); raceIDDict.Add("0901", Resources.strings.Roegadyn + " " + Resources.strings.Male); raceIDDict.Add("1001", Resources.strings.Roegadyn + " " + Resources.strings.Female); raceIDDict.Add("1101", Resources.strings.Lalafell + " " + Resources.strings.Male); raceIDDict.Add("1201", Resources.strings.Lalafell + " " + Resources.strings.Female); raceIDDict.Add("1301", Resources.strings.Au_Ra + " " + Resources.strings.Male); raceIDDict.Add("1401", Resources.strings.Au_Ra + " " + Resources.strings.Female); raceIDDict.Add("9104", "NPC " + Resources.strings.Male); raceIDDict.Add("9204", "NPC " + Resources.strings.Female); string partName = "", partNum = "", race; listView1.Columns.Add("Name", -2, HorizontalAlignment.Left); listView1.Columns.Add("Race", -2, HorizontalAlignment.Left); listView1.Columns.Add("Map", -2, HorizontalAlignment.Left); listView1.Columns.Add("Part", -2, HorizontalAlignment.Left); listView1.Columns.Add("Part 2", -2, HorizontalAlignment.Left); foreach (string line in File.ReadLines(xivModsDirectory)) { jModEntry modEntry = JsonConvert.DeserializeObject <jModEntry>(line); modList.Add(modEntry); if (!modEntry.name.Contains("decal") && !modEntry.name.Contains("mt_m") && !modEntry.name.Contains("1_m") && !modEntry.name.Contains("2_m") && !modEntry.name.Contains("1_d")) { string sName = modEntry.name; race = raceIDDict[sName.Substring(sName.IndexOf('c') + 1, 4)]; if (race == null && sName.Contains("_w")) { race = "ALL"; } } else if (modEntry.name.Contains("decal")) { race = "ALL"; } else { race = "Monsters"; } if (modEntry.name.Contains("f0")) { string sName = modEntry.name; int val = int.Parse(sName.Substring(sName.IndexOf('f') + 1, 4)); partName = val.ToString();; } else if (modEntry.name.Contains("b0")) { string sName = modEntry.name; int val = int.Parse(sName.Substring(sName.IndexOf('b') + 1, 4)); partName = val.ToString();; } else if (modEntry.name.Contains("h0")) { string sName = modEntry.name; int val = int.Parse(sName.Substring(sName.IndexOf('h') + 1, 4)); partName = val.ToString();; } else if (modEntry.name.Contains("t0")) { string sName = modEntry.name; int val = int.Parse(sName.Substring(sName.IndexOf('t') + 1, 4)); partName = val.ToString();; } else if (modEntry.name.Contains("decal")) { string sName = modEntry.name; int val = int.Parse(sName.Substring(sName.LastIndexOf('_') + 1)); partName = val.ToString();; } else if (modEntry.name.Contains("mt")) { string sName = modEntry.name; partName = sName.Substring(sName.LastIndexOf('_') + 1); } else if (modEntry.name.Contains("1_d")) { string sName = modEntry.name; partName = sName.Substring(sName.LastIndexOf('_') - 3, 3); } else { partName = "a"; } if (modEntry.name.Contains("f0")) { if (modEntry.name.Contains("_fac")) { partNum = "Face"; } else if (modEntry.name.Contains("_iri")) { partNum = "Iris"; } else if (modEntry.name.Contains("_etc")) { partNum = "Etc"; } } else if (modEntry.name.Contains("h0")) { if (modEntry.name.Contains("_hir")) { partNum = "Hair"; } if (modEntry.name.Contains("_acc")) { partNum = "Accessory"; } } else { partNum = ""; } ListViewItem itemsList = new ListViewItem(modEntry.textureName); itemsList.SubItems.Add(race); itemsList.SubItems.Add(texMap(modEntry.name)); itemsList.SubItems.Add(partName); itemsList.SubItems.Add(partNum); listView1.Items.Add(itemsList); } }
/// <summary> /// Writes the modified texture into the .dat file /// </summary> /// <param name="inModList">Mod list presense check</param> /// <param name="selectedMap">Currently selected texture map</param> /// <param name="ddsFile">DDS file directory</param> /// <param name="modListEntry">Modlist entry</param> /// <param name="fileOffset">Offset of texture file</param> /// <param name="mMtrlOffset">Offset of MTRL file</param> /// <param name="datLoc">Which dat the file is located in</param> public DatWriter(bool inModList, string selectedMap, string ddsFile, jModEntry modListEntry, string fileOffset, int mMtrlOffset, int datLoc) { List <byte> modBytes = new List <byte>(); List <byte> recomp = new List <byte>(); List <byte> nSize = new List <byte>(); string originalOffset = fileOffset; string fileDirectory; short nPadSize; int partPSize = 0; int partPSize2 = 0; int partSum = 0; int datNum = 0; IOHelper ioHelper = new IOHelper(); if (inModList) { datNum = ((int.Parse(modListEntry.origOffset, NumberStyles.HexNumber) / 8) & 0x000f) / 2; fileOffset = modListEntry.origOffset; } else if (selectedMap.Equals("ColorSet1")) { datNum = ((mMtrlOffset / 8) & 0x000f) / 2; fileOffset = mMtrlOffset.ToString("X").PadLeft(8, '0'); } else { datNum = datLoc; } if (selectedMap.Equals("ColorSet1")) { try { List <byte> colorFix; using (BinaryReader br = new BinaryReader(File.OpenRead(ddsFile))) { string dye = ddsFile.Substring(0, ddsFile.LastIndexOf('/')) + "/dye.dat"; using (BinaryReader br1 = new BinaryReader(File.OpenRead(dye))) { colorFix = new List <byte>(); br.BaseStream.Seek(0, SeekOrigin.Begin); br1.BaseStream.Seek(0, SeekOrigin.Begin); colorFix.AddRange(br.ReadBytes(640).ToArray()); colorFix.AddRange(br1.ReadBytes(32).ToArray()); } } File.WriteAllBytes(ddsFile, colorFix.ToArray()); } catch (Exception e) { } } fileDirectory = Properties.Settings.Default.DefaultDir + "/040000.win32.dat" + datNum; using (BinaryReader br = new BinaryReader(File.OpenRead(fileDirectory))) { using (BinaryReader br1 = new BinaryReader(File.OpenRead(ddsFile))) { using (BinaryWriter bw = new BinaryWriter(File.OpenWrite(Properties.Settings.Default.DefaultDir + "/040000.win32.dat3"))) { br1.BaseStream.Seek(128, SeekOrigin.Begin); int initialOffset = int.Parse(fileOffset, NumberStyles.HexNumber); if (fileDirectory.Contains(".dat1")) { initialOffset = initialOffset - 16; } else if (fileDirectory.Contains(".dat2")) { initialOffset = initialOffset - 32; } else if (fileDirectory.Contains(".dat3")) { initialOffset = initialOffset - 48; } br.BaseStream.Seek(initialOffset, SeekOrigin.Begin); byte[] b_header = br.ReadBytes(24); uint hLength = BitConverter.ToUInt32(b_header, 0x00); uint type = BitConverter.ToUInt32(b_header, 0x04); if (type == 4) { uint numMipMaps = BitConverter.ToUInt32(b_header, 0x14); int endHeader = initialOffset + (int)hLength; uint toInitPartInfo = (uint)(initialOffset + 24 + (numMipMaps * 20)); int[] nOffsetsSizes = new int[numMipMaps]; modBytes.AddRange(b_header); for (int i = 0; i < numMipMaps; i++) { partSum = 0; int nMipPadSize = 0; uint toPartInfo = (uint)(initialOffset + 24 + (numMipMaps * 20) + partPSize2); br.BaseStream.Seek(initialOffset + 24 + (i * 20), SeekOrigin.Begin); byte[] mipPart = br.ReadBytes(20); uint fromEnd = BitConverter.ToUInt32(mipPart, 0x00); uint mipLength = BitConverter.ToUInt32(mipPart, 0x04); uint partsToRead = BitConverter.ToUInt32(mipPart, 0x10); partPSize = (int)partsToRead * 2; partPSize2 = partPSize2 + partPSize; //get padded part sizes including 16byte header br.BaseStream.Seek(toPartInfo, SeekOrigin.Begin); byte[] mipPartPadSizes = br.ReadBytes(partPSize); //read mip1 header int mip = endHeader + (int)fromEnd; br.BaseStream.Seek(mip, SeekOrigin.Begin); byte[] mipHeader = br.ReadBytes(16); uint compSize = BitConverter.ToUInt32(mipHeader, 0x08); uint uncompSize = BitConverter.ToUInt32(mipHeader, 0x0C); recomp.AddRange(mipHeader.Take(8)); if (partsToRead > 1) { mipPart = ioHelper.compressor(br1.ReadBytes((int)uncompSize)); int count = mipPart.Length; recomp.AddRange(BitConverter.GetBytes(count)); recomp.AddRange(mipHeader.Skip(12)); recomp.AddRange(mipPart); if (count % 16 != 0) { int difference = 16 - ((int)count % 16); byte[] padd = new byte[difference]; Array.Clear(padd, 0, difference); recomp.AddRange(padd); //padded size of compressed data for header nPadSize = (short)(16 + count + difference); nSize.AddRange(BitConverter.GetBytes(nPadSize)); nMipPadSize = nMipPadSize + nPadSize; } else { nPadSize = (short)(16 + count); nSize.AddRange(BitConverter.GetBytes(nPadSize)); nMipPadSize = nMipPadSize + nPadSize; } for (int j = 1; j < partsToRead; j++) { partSum = partSum + BitConverter.ToUInt16(mipPartPadSizes, ((j - 1) * 2)); br.BaseStream.Seek(mip + partSum, SeekOrigin.Begin); mipHeader = br.ReadBytes(16); compSize = BitConverter.ToUInt32(mipHeader, 0x08); uncompSize = BitConverter.ToUInt32(mipHeader, 0x0C); recomp.AddRange(mipHeader.Take(8)); mipPart = ioHelper.compressor(br1.ReadBytes((int)uncompSize)); count = mipPart.Length; recomp.AddRange(BitConverter.GetBytes(count)); recomp.AddRange(mipHeader.Skip(12)); recomp.AddRange(mipPart); if (count % 16 != 0) { int difference = 16 - ((int)count % 16); byte[] padd = new byte[difference]; Array.Clear(padd, 0, difference); recomp.AddRange(padd); nPadSize = (short)(16 + count + difference); nSize.AddRange(BitConverter.GetBytes(nPadSize)); nMipPadSize = nMipPadSize + nPadSize; } else { nPadSize = (short)(16 + count); nSize.AddRange(BitConverter.GetBytes(nPadSize)); nMipPadSize = nMipPadSize + nPadSize; } } nOffsetsSizes[i] = nMipPadSize; } else { byte[] padd; int count; br.BaseStream.Seek(mip, SeekOrigin.Begin); mipPart = ioHelper.compressor(br1.ReadBytes((int)uncompSize)); count = mipPart.Length; recomp.AddRange(BitConverter.GetBytes(count)); recomp.AddRange(mipHeader.Skip(12)); recomp.AddRange(mipPart); if (count % 16 != 0) { int difference = 16 - ((int)count % 16); padd = new byte[difference]; Array.Clear(padd, 0, difference); recomp.AddRange(padd); nPadSize = (short)(16 + count + difference); nSize.AddRange(BitConverter.GetBytes(nPadSize)); nMipPadSize = nMipPadSize + nPadSize; } else { nPadSize = (Int16)(16 + count); nSize.AddRange(BitConverter.GetBytes(nPadSize)); nMipPadSize = nMipPadSize + nPadSize; } nOffsetsSizes[i] = nMipPadSize; } } int noffset = 80; for (int i = 0; i < numMipMaps; i++) { br.BaseStream.Seek((initialOffset + 32) + (i * 20), SeekOrigin.Begin); if (i == 0) { modBytes.AddRange(BitConverter.GetBytes(80)); } else { noffset = noffset + nOffsetsSizes[i - 1]; modBytes.AddRange(BitConverter.GetBytes(noffset)); } modBytes.AddRange(BitConverter.GetBytes(nOffsetsSizes[i])); modBytes.AddRange(br.ReadBytes(12)); } modBytes.AddRange(nSize.ToArray()); int remaining = (int)hLength - modBytes.Count; for (int i = 0; i < remaining; i++) { modBytes.Add((byte)0); } br.BaseStream.Seek(endHeader, SeekOrigin.Begin); modBytes.AddRange(br.ReadBytes(80)); modBytes.AddRange(recomp.ToArray()); byte pad = 0; for (int i = 0; i < 1024; i++) { modBytes.Add(pad); } if (inModList) { bw.BaseStream.Seek(int.Parse(originalOffset, NumberStyles.HexNumber) - 48, SeekOrigin.Begin); } else { bw.BaseStream.Seek(0, SeekOrigin.End); int lastPos = (int)bw.BaseStream.Position + modBytes.Count; byte[] padto = new byte[16]; while ((lastPos & 0xff) != 0) { modBytes.AddRange(padto); lastPos = lastPos + 16; } } datOffset = (int)bw.BaseStream.Position; bw.Write(modBytes.ToArray()); } else { List <byte> uncompMTRLbytes = new List <byte>(); int endHeader = initialOffset + (int)hLength; modBytes.AddRange(b_header); modBytes.AddRange(br.ReadBytes(112).ToArray()); uint compSize = br.ReadUInt32(); uint uncompSize = br.ReadUInt32(); byte[] forlist = br.ReadBytes((int)compSize); byte[] uncompressedbytes = new byte[uncompSize]; using (MemoryStream ms = new MemoryStream(forlist)) { using (DeflateStream ds = new DeflateStream(ms, CompressionMode.Decompress)) { int count = ds.Read(uncompressedbytes, 0x00, (int)uncompSize); } } using (BinaryReader b2 = new BinaryReader(new MemoryStream(uncompressedbytes))) { b2.BaseStream.Seek(4, SeekOrigin.Begin); short fileSize = b2.ReadInt16(); short clrSize = b2.ReadInt16(); short texNameSize = b2.ReadInt16(); b2.ReadBytes(2); byte texNum = b2.ReadByte(); byte mapNum = b2.ReadByte(); byte clrNum = b2.ReadByte(); byte unkNum = b2.ReadByte(); b2.ReadBytes(4); int mHeaderLength = 20 + 4 * (texNum + mapNum + clrNum) + texNameSize; b2.BaseStream.Seek(0, SeekOrigin.Begin); uncompMTRLbytes.AddRange(b2.ReadBytes(mHeaderLength).ToArray()); byte[] comp = br1.ReadBytes(clrSize); colorMapBytes = comp; uncompMTRLbytes.AddRange(comp); int headerColorSum = mHeaderLength + clrSize; b2.BaseStream.Seek(headerColorSum, SeekOrigin.Begin); uncompMTRLbytes.AddRange(b2.ReadBytes(fileSize - headerColorSum)); } byte[] compMTRL = ioHelper.compressor(uncompMTRLbytes.ToArray()); modBytes.AddRange(BitConverter.GetBytes(compMTRL.Length)); modBytes.AddRange(BitConverter.GetBytes(uncompSize)); modBytes.AddRange(compMTRL); int mCount = compMTRL.Length; if (mCount % 16 != 0) { int difference = 16 - (mCount % 16); byte[] padd = new byte[difference]; Array.Clear(padd, 0, difference); modBytes.AddRange(padd); } byte pad = 0; for (int i = 0; i < 1024; i++) { modBytes.Add(pad); } if (inModList) { bw.BaseStream.Seek(int.Parse(originalOffset, NumberStyles.HexNumber) - 48, SeekOrigin.Begin); } else { bw.BaseStream.Seek(0, SeekOrigin.End); int lastPos = (int)bw.BaseStream.Position + modBytes.Count; byte[] padto = new byte[16]; while ((lastPos & 0xff) != 0) { modBytes.AddRange(padto); lastPos = lastPos + 16; } } datOffset = (int)bw.BaseStream.Position; bw.Write(modBytes.ToArray()); } } } } }
/// <summary> /// Imports a DDS file /// </summary> /// <param name="childNode">Name of item</param> /// <param name="currTexName">Name of texture</param> /// <param name="ddsFile">DDS file directory</param> /// <param name="filetype">DDS file type</param> /// <param name="inModList">Included in Mod List boolean</param> /// <param name="modListEntry">Modlist entry</param> /// <param name="mFolderHex">Folder CRC</param> /// <param name="currMap">Currently selected texture map</param> /// <param name="MTRLOffset">Offset of MTRL file</param> /// <param name="fileHex">File CRC</param> /// <param name="datLoc">Dat number file is located in</param> /// <param name="worker">BackgroundWorker</param> /// <param name="e">BackgroundWorker event args</param> public Import(string childNode, string currTexName, string ddsFile, int filetype, bool inModList, jModEntry modListEntry, string mFolderHex, string currMap, int MTRLOffset, string fileHex, int datLoc, BackgroundWorker worker, DoWorkEventArgs e) { IOHelper ioHelper = new IOHelper(); importStatus = false; uint typecheck; try { using (BinaryReader b1 = new BinaryReader(File.OpenRead(ddsFile))) { b1.BaseStream.Seek(84, SeekOrigin.Begin); typecheck = b1.ReadUInt32(); } if (typecheck == 827611204) { typecheck = 13344; } else if (typecheck == 894720068) { typecheck = 13361; } else if (typecheck == 861165636) { typecheck = 13360; } else if (typecheck == 113) { typecheck = 9312; } else if (typecheck == 0) { typecheck = 5200; } if (typecheck == filetype) { if (inModList) { string moddedOffset = modListEntry.modOffset; DatWriter dw = new DatWriter(inModList, currMap, ddsFile, modListEntry, moddedOffset, MTRLOffset, datLoc); newOffset = dw.getNewDatOffset() + 48; colorMapBytes = dw.getColorMapBytes(); ioHelper.modifyIndexOffset(newOffset, currTexName, mFolderHex); importStatus = true; } else { DatWriter dw = new DatWriter(inModList, currMap, ddsFile, modListEntry, fileHex, MTRLOffset, datLoc); newOffset = dw.getNewDatOffset() + 48; colorMapBytes = dw.getColorMapBytes(); jModEntry newEntry; if (currMap.Equals("ColorSet1")) { newEntry = new jModEntry(childNode, currTexName.Substring(0, currTexName.LastIndexOf('.')), MTRLOffset.ToString("X").PadLeft(8, '0'), newOffset.ToString("X").PadLeft(8, '0'), mFolderHex); } else { newEntry = new jModEntry(childNode, currTexName.Substring(0, currTexName.LastIndexOf('.')), fileHex, newOffset.ToString("X").PadLeft(8, '0'), ""); } string nEntry = JsonConvert.SerializeObject(newEntry); using (StreamWriter file = new StreamWriter(Properties.Settings.Default.DefaultDir + "/040000.modlist", true)) { file.BaseStream.Seek(0, SeekOrigin.End); file.WriteLine(nEntry); } ioHelper.modifyIndexOffset(newOffset, currTexName, mFolderHex); importStatus = true; } } else { worker.CancelAsync(); e.Cancel = true; } } catch (Exception ex) { importStatus = false; MessageBox.Show("Cannot import while game is running. \n\n" + ex.Message, "Import Error"); } }
/// <summary> /// Imports shared mods /// </summary> /// <param name="importDatDirectory">Directory being imported from</param> /// <param name="modEntries">The mod entries</param> public Import(string importDatDirectory, jModEntry[] modEntries) { IOHelper ioHelper = new IOHelper(); List <byte> modBytes = new List <byte>(); string[] currentMods = File.ReadAllLines(Properties.Settings.Default.DefaultDir + "/040000.modlist"); using (BinaryReader br = new BinaryReader(File.OpenRead(importDatDirectory))) { using (BinaryWriter bw = new BinaryWriter(File.OpenWrite(Properties.Settings.Default.DefaultDir + "/040000.win32.dat3"))) { for (int i = 0; i < modEntries.Length; i++) { modBytes.Clear(); int size; bool inModList = false; try { size = int.Parse(modEntries[i + 1].modOffset, System.Globalization.NumberStyles.HexNumber) - int.Parse(modEntries[i].modOffset, System.Globalization.NumberStyles.HexNumber); } catch { size = (int)br.BaseStream.Length - int.Parse(modEntries[i].modOffset, System.Globalization.NumberStyles.HexNumber); } br.BaseStream.Seek(int.Parse(modEntries[i].modOffset, System.Globalization.NumberStyles.HexNumber), SeekOrigin.Begin); bw.BaseStream.Seek(0, SeekOrigin.End); foreach (string line in currentMods) { jModEntry modEntry = JsonConvert.DeserializeObject <jModEntry>(line); if (modEntries[i].name.Equals(modEntry.name)) { bw.BaseStream.Seek(int.Parse(modEntry.modOffset, System.Globalization.NumberStyles.HexNumber) - 48, SeekOrigin.Begin); inModList = true; break; } } modBytes.AddRange(br.ReadBytes(size)); newOffset = (int)bw.BaseStream.Position; if (!inModList) { int lastPos = (int)bw.BaseStream.Position + size; byte[] padto = new byte[16]; while ((lastPos & 0xff) != 0) { modBytes.AddRange(padto); lastPos = lastPos + 16; } newOffset = (int)bw.BaseStream.Position + 48; } bw.Write(modBytes.ToArray()); string name; if (!modEntries[i].name.Contains("mt_")) { name = modEntries[i].name + ".tex"; } else { name = modEntries[i].name + ".mtrl"; } if (!inModList) { modEntries[i].modOffset = newOffset.ToString("X").PadLeft(8, '0'); string nEntry = JsonConvert.SerializeObject(modEntries[i]); using (StreamWriter file = new StreamWriter(Properties.Settings.Default.DefaultDir + "/040000.modlist", true)) { file.BaseStream.Seek(0, SeekOrigin.End); file.WriteLine(nEntry); } } if (!inModList) { ioHelper.modifyIndexOffset(newOffset, name, modEntries[i].folder); } else { ioHelper.modifyIndexOffset(newOffset + 48, name, modEntries[i].folder); } } } } }
/// <summary> /// Dialog for Mod List /// </summary> public ModListForm() { InitializeComponent(); listView1.View = View.Details; listView1.GridLines = true; FFCRC crc = new FFCRC(); Dictionary <string, string> raceIDDict = new Dictionary <string, string>(); raceIDDict.Add("0101", Resources.strings.Hyur + " " + Resources.strings.Midlander + " " + Resources.strings.Male); raceIDDict.Add("0104", Resources.strings.Hyur + " " + Resources.strings.Male + " NPC"); raceIDDict.Add("0201", Resources.strings.Hyur + " " + Resources.strings.Midlander + " " + Resources.strings.Female); raceIDDict.Add("0204", Resources.strings.Hyur + " " + Resources.strings.Female + " NPC"); raceIDDict.Add("0301", Resources.strings.Hyur + " " + Resources.strings.Midlander + " " + Resources.strings.Male); raceIDDict.Add("0401", Resources.strings.Hyur + " " + Resources.strings.Midlander + " " + Resources.strings.Female); raceIDDict.Add("0501", Resources.strings.Elezen + " " + Resources.strings.Male); raceIDDict.Add("0504", Resources.strings.Elezen + " " + Resources.strings.Male + " NPC"); raceIDDict.Add("0601", Resources.strings.Elezen + " " + Resources.strings.Female); raceIDDict.Add("0604", Resources.strings.Elezen + " " + Resources.strings.Female + " NPC"); raceIDDict.Add("0701", Resources.strings.Miqote + " " + Resources.strings.Male); raceIDDict.Add("0801", Resources.strings.Miqote + " " + Resources.strings.Female); raceIDDict.Add("0804", Resources.strings.Miqote + " " + Resources.strings.Female + " NPC"); raceIDDict.Add("0901", Resources.strings.Roegadyn + " " + Resources.strings.Male); raceIDDict.Add("1001", Resources.strings.Roegadyn + " " + Resources.strings.Female); raceIDDict.Add("1101", Resources.strings.Lalafell + " " + Resources.strings.Male); raceIDDict.Add("1201", Resources.strings.Lalafell + " " + Resources.strings.Female); raceIDDict.Add("1301", Resources.strings.Au_Ra + " " + Resources.strings.Male); raceIDDict.Add("1401", Resources.strings.Au_Ra + " " + Resources.strings.Female); raceIDDict.Add("9104", "NPC " + Resources.strings.Male); raceIDDict.Add("9204", "NPC " + Resources.strings.Female); string isActive, partName = "", partNum = "", race; listView1.Columns.Add("Name", -2, HorizontalAlignment.Left); listView1.Columns.Add("Race", -2, HorizontalAlignment.Left); listView1.Columns.Add("Map", -2, HorizontalAlignment.Left); listView1.Columns.Add("Part", -2, HorizontalAlignment.Left); listView1.Columns.Add("Part 2", -2, HorizontalAlignment.Left); listView1.Columns.Add("Active", -2, HorizontalAlignment.Left); foreach (string line in File.ReadLines(Properties.Settings.Default.DefaultDir + "/040000.modlist")) { jModEntry modEntry = JsonConvert.DeserializeObject <jModEntry>(line); modList.Add(modEntry); if (!modEntry.name.Contains("decal") && !modEntry.name.Contains("mt_m") && !modEntry.name.Contains("1_m") && !modEntry.name.Contains("2_m") && !modEntry.name.Contains("1_d")) { string sName = modEntry.name; race = raceIDDict[sName.Substring(sName.IndexOf('c') + 1, 4)]; if (race == null && sName.Contains("_w")) { race = "ALL"; } } else if (modEntry.name.Contains("decal")) { race = "ALL"; } else { race = "Monsters"; } if (modEntry.textureName == null) { isActive = "Unknown"; } else { IOHelper ioHelper = new IOHelper(); if (!modEntry.name.Contains("mt_")) { isActive = ioHelper.isActive(crc.text(modEntry.name + ".tex"), modEntry.folder, modEntry.modOffset).ToString(); } else { isActive = ioHelper.isActive(crc.text(modEntry.name + ".mtrl"), modEntry.folder, modEntry.modOffset).ToString(); } } if (modEntry.textureName == null) { canGo = false; modEntry.textureName = modEntry.name; } else { canGo = true; } if (modEntry.name.Contains("f0")) { string sName = modEntry.name; int val = int.Parse(sName.Substring(sName.IndexOf('f') + 1, 4)); partName = val.ToString();; } else if (modEntry.name.Contains("b0")) { string sName = modEntry.name; int val = int.Parse(sName.Substring(sName.IndexOf('b') + 1, 4)); partName = val.ToString();; } else if (modEntry.name.Contains("h0")) { string sName = modEntry.name; int val = int.Parse(sName.Substring(sName.IndexOf('h') + 1, 4)); partName = val.ToString();; } else if (modEntry.name.Contains("t0")) { string sName = modEntry.name; int val = int.Parse(sName.Substring(sName.IndexOf('t') + 1, 4)); partName = val.ToString();; } else if (modEntry.name.Contains("decal")) { string sName = modEntry.name; int val = int.Parse(sName.Substring(sName.LastIndexOf('_') + 1)); partName = val.ToString();; } else if (modEntry.name.Contains("mt")) { string sName = modEntry.name; partName = sName.Substring(sName.LastIndexOf('_') + 1); } else if (modEntry.name.Contains("1_d")) { string sName = modEntry.name; partName = sName.Substring(sName.LastIndexOf('_') - 3, 3); } else { partName = "a"; } if (modEntry.name.Contains("f0")) { if (modEntry.name.Contains("_fac")) { partNum = "Face"; } else if (modEntry.name.Contains("_iri")) { partNum = "Iris"; } else if (modEntry.name.Contains("_etc")) { partNum = "Etc"; } } else if (modEntry.name.Contains("h0")) { if (modEntry.name.Contains("_hir")) { partNum = "Hair"; } if (modEntry.name.Contains("_acc")) { partNum = "Accessory"; } } else { partNum = ""; } ListViewItem itemsList = new ListViewItem(modEntry.textureName); itemsList.SubItems.Add(race); itemsList.SubItems.Add(texMap(modEntry.name)); itemsList.SubItems.Add(partName); itemsList.SubItems.Add(partNum); itemsList.SubItems.Add(isActive); listView1.Items.Add(itemsList); } modGoToButton.Enabled = false; switchButton.Enabled = false; }