private void InputBox_TextChanged(object sender, EventArgs e) { string text = InputBox.Text; HashVolitionOut.Text = Hashes.HashVolition(text).ToString("X8"); CrcVolitionOut.Text = Hashes.CrcVolition(text).ToString("X8"); CrcVolitionDecimal.Text = BitConverter.ToInt32(BitConverter.GetBytes(Hashes.CrcVolition(text)), 0).ToString(); AudiokineticHashOut.Text = Hashes.AudiokineticHash(text).ToString("X8"); }
public void Save(Stream s) { byte[] sectionData = null; using (MemoryStream ms = new MemoryStream()) { foreach (Section section in Sections.Values) { section.Save(ms); } sectionData = ms.ToArray(); } MainHeader.Checksum = Hashes.CrcVolition(sectionData); s.WriteStruct(MainHeader); s.Write(sectionData, 0, sectionData.Length); }
public void Save(Stream s) { byte[] slotData = null; using (MemoryStream ms = new MemoryStream()) { for (int i = 0; i < 24; i++) { Slots[i].Save(ms); } ms.Seek(0, SeekOrigin.Begin); slotData = ms.ToArray(); } SlotsDataChecksum = Hashes.CrcVolition(slotData); s.WriteUInt32(SlotsDataChecksum); s.WriteUInt32(SlotsUsed); s.Write(slotData, 0, 600); }
static void Main(string[] args) { Options options = null; try { options = CommandLine.Parse <Options>(); } catch (CommandLineException exception) { Console.WriteLine(exception.ArgumentHelp.Message); Console.WriteLine(); Console.WriteLine(exception.ArgumentHelp.GetHelpText(Console.BufferWidth)); #if DEBUG Console.ReadLine(); #endif return; } if (options.Output == null) { options.Output = options.NewName; } string outputFolder = options.Output; Directory.CreateDirectory(outputFolder); IGameInstance sriv = GameInstance.GetFromSteamId(GameSteamID.SaintsRowIV); LoadStrings(sriv); IAssetAssemblerFile newAsm; using (Stream newAsmStream = File.OpenRead(Path.Combine("templates", "template_customize_item.asm_pc"))) { newAsm = AssetAssemblerFile.FromStream(newAsmStream); } XDocument customizationItem = null; using (Stream itemsTemplateStream = File.OpenRead(Path.Combine("templates", "template_customization_items.xtbl"))) { customizationItem = XDocument.Load(itemsTemplateStream); } var customizationItemTable = customizationItem.Descendants("Table").First(); XElement itemNode = FindCustomizationItem(options.Source, sriv); if (itemNode == null) { Console.WriteLine("Couldn't find {0}.", options.Source); #if DEBUG Console.ReadLine(); #endif return; } string itemName = itemNode.Element("Name").Value; itemNode.Element("Name").Value = options.NewName; string originalDisplayName = itemNode.Element("DisplayName").Value; uint originalStringCrc = Hashes.CrcVolition(originalDisplayName); string newDisplayName = "DUPLICATED_" + options.NewName.ToUpperInvariant(); itemNode.Element("DisplayName").Value = newDisplayName; List <string> str2Names = new List <string>(); bool found = false; var dlcElement = itemNode.Element("Is_DLC"); if (dlcElement != null) { string isDLCString = dlcElement.Value; // Remove Is_DLC element so DLC items show up in SRIV dlcElement.Remove(); } var wearOptionsNode = itemNode.Element("Wear_Options"); int wearOption = 0; foreach (var wearOptionNode in wearOptionsNode.Descendants("Wear_Option")) { var meshInformationNode = wearOptionNode.Element("Mesh_Information"); var maleMeshFilenameNode = meshInformationNode.Element("Male_Mesh_Filename"); var filenameNode = maleMeshFilenameNode.Element("Filename"); string maleMeshFilename = filenameNode.Value; string newMaleMeshFilename = (wearOption == 0) ? String.Format("cm_{0}.cmeshx", options.NewName) : String.Format("cm_{0}_{1}.cmeshx", options.NewName, wearOption); filenameNode.Value = newMaleMeshFilename; var femaleMeshFilenameNode = meshInformationNode.Element("Female_Mesh_Filename"); filenameNode = femaleMeshFilenameNode.Element("Filename"); string femaleMeshFilename = filenameNode.Value; string newFemaleMeshFilename = (wearOption == 0) ? String.Format("cf_{0}.cmeshx", options.NewName) : String.Format("cf_{0}_{1}.cmeshx", options.NewName, wearOption); filenameNode.Value = newFemaleMeshFilename; Console.WriteLine("Mapping mesh {0} -> {1}", maleMeshFilename, newMaleMeshFilename); Console.WriteLine("Mapping mesh {0} -> {1}", femaleMeshFilename, newFemaleMeshFilename); string clothSimFilename = null; var clothSimFilenameNode = meshInformationNode.Element("Cloth_Sim_Filename"); if (clothSimFilenameNode != null) { filenameNode = clothSimFilenameNode.Element("Filename"); string xmlClothSimFilename = filenameNode.Value; clothSimFilename = Path.ChangeExtension(xmlClothSimFilename, ".sim_pc"); string newClothSimFilename = (wearOption == 0) ? String.Format("cm_{0}.simx", options.NewName) : String.Format("cm_{0}_{1}.simx", options.NewName, wearOption); filenameNode.Value = newClothSimFilename; Console.WriteLine("Mapping cloth sim {0} -> {1}", xmlClothSimFilename, newClothSimFilename); } var variantNodes = itemNode.Element("Variants").Descendants("Variant"); foreach (var variantNode in variantNodes) { var meshVariantInfoNode = variantNode.Element("Mesh_Variant_Info"); var variantIdNode = meshVariantInfoNode.Element("VariantID"); uint variantId = uint.Parse(variantIdNode.Value); int crc = Hashes.CustomizationItemCrc(itemName, maleMeshFilename, variantId); string maleStr2 = String.Format("custmesh_{0}.str2_pc", crc); string femaleStr2 = String.Format("custmesh_{0}f.str2_pc", crc); int newCrc = Hashes.CustomizationItemCrc(options.NewName, newMaleMeshFilename, variantId); string newMaleStr2 = String.Format("custmesh_{0}.str2_pc", newCrc); string newFemaleStr2 = String.Format("custmesh_{0}f.str2_pc", newCrc); string newMaleName = (wearOption == 0) ? String.Format("cm_{0}", options.NewName) : String.Format("cm_{0}_{1}", options.NewName, wearOption); string newFemaleName = (wearOption == 0) ? String.Format("cf_{0}", options.NewName) : String.Format("cf_{0}_{1}", options.NewName, wearOption); bool foundMale = ClonePackfile(sriv, maleStr2, clothSimFilename, options.Output, newAsm, itemName, newMaleName, Path.Combine(outputFolder, newMaleStr2)); bool foundFemale = ClonePackfile(sriv, femaleStr2, clothSimFilename, options.Output, newAsm, itemName, newFemaleName, Path.Combine(outputFolder, newFemaleStr2)); if (foundMale || foundFemale) { found = true; } } wearOption++; } if (found) { customizationItemTable.Add(itemNode); } using (Stream xtblOutStream = File.Create(Path.Combine(outputFolder, "customization_items.xtbl"))) { XmlWriterSettings settings = new XmlWriterSettings(); settings.OmitXmlDeclaration = true; settings.Encoding = new UTF8Encoding(false); settings.NewLineChars = "\r\n"; settings.Indent = true; settings.IndentChars = "\t"; using (XmlWriter writer = XmlWriter.Create(xtblOutStream, settings)) { customizationItem.Save(writer); } } using (Stream asmOutStream = File.Create(Path.Combine(outputFolder, "customize_item.asm_pc"))) { newAsm.Save(asmOutStream); } string stringXmlFolder = Path.Combine(outputFolder, "stringxml"); Directory.CreateDirectory(stringXmlFolder); foreach (var pair in languageStrings) { Language language = pair.Key; Dictionary <uint, string> strings = pair.Value; StringFile file = new StringFile(language, sriv); string newString = "CLONE: " + options.NewName; if (strings.ContainsKey(originalStringCrc)) { string originalString = strings[originalStringCrc]; newString = "CLONE: " + originalString; } else { Console.WriteLine("Warning: original language string could not be found for {0}.", language); } file.AddString(newDisplayName, newString); string newFilename = Path.Combine(outputFolder, String.Format("{0}_{1}.le_strings", options.NewName, LanguageUtility.GetLanguageCode(language))); string newXmlFilename = Path.Combine(stringXmlFolder, String.Format("{0}_{1}.xml", options.NewName, LanguageUtility.GetLanguageCode(language))); using (Stream s = File.Create(newFilename)) { file.Save(s); } XmlWriterSettings settings = new XmlWriterSettings(); settings.Indent = true; settings.IndentChars = "\t"; settings.NewLineChars = "\r\n"; using (XmlWriter xml = XmlTextWriter.Create(newXmlFilename, settings)) { xml.WriteStartDocument(); xml.WriteStartElement("Strings"); xml.WriteAttributeString("Language", language.ToString()); xml.WriteAttributeString("Game", sriv.Game.ToString()); xml.WriteStartElement("String"); xml.WriteAttributeString("Name", newDisplayName); xml.WriteString(newString); xml.WriteEndElement(); // String xml.WriteEndElement(); // Strings xml.WriteEndDocument(); } } Console.WriteLine("Finished cloning customization item {0} to {1}!", options.Source, options.NewName); #if DEBUG Console.ReadLine(); #endif }
public static void Main(string[] args) { Options options = null; try { options = CommandLine.Parse <Options>(); } catch (CommandLineException exception) { Console.WriteLine(exception.ArgumentHelp.Message); Console.WriteLine(); Console.WriteLine(exception.ArgumentHelp.GetHelpText(Console.BufferWidth)); #if DEBUG Console.ReadLine(); #endif return; } string outputFile = options.Output != null ? options.Output : Path.ChangeExtension(options.Input, ".le_strings"); Console.WriteLine("Packing {0} and creating {1}...", options.Input, outputFile); XDocument xml = null; using (Stream s = File.OpenRead(options.Input)) { xml = XDocument.Load(s); } var stringsNode = xml.Descendants("Strings").First(); string languageString = stringsNode.Attribute("Language").Value; string gameString = stringsNode.Attribute("Game").Value; Language language = LanguageUtility.GetLanguageFromCode(languageString); IGameInstance instance = GameInstance.GetFromString(gameString); StringFile stringFile = new StringFile(language, instance); var stringNodes = stringsNode.Descendants("String"); foreach (var stringNode in stringNodes) { uint hash; var nameAttribute = stringNode.Attribute("Name"); if (nameAttribute != null) { hash = Hashes.CrcVolition(nameAttribute.Value); } else { hash = uint.Parse(stringNode.Attribute("Hash").Value, System.Globalization.NumberStyles.HexNumber); } string value = stringNode.Value; if (stringFile.ContainsKey(hash)) { Console.WriteLine("You are attempting to add a duplicate key to the strings file."); Console.WriteLine("Name: \"{0}\", Hash: {1}, Value: {2}", nameAttribute != null ? nameAttribute.Value : "", hash, value); Console.WriteLine("Other value: {0}", stringFile.GetString(hash)); return; } stringFile.AddString(hash, value); } using (Stream s = File.Create(outputFile)) { stringFile.Save(s); } Console.WriteLine("Done."); #if DEBUG Console.ReadLine(); #endif }
public static void Main(string[] args) { Options options = null; try { options = CommandLine.Parse <Options>(); } catch (CommandLineException exception) { Console.WriteLine(exception.ArgumentHelp.Message); Console.WriteLine(); Console.WriteLine(exception.ArgumentHelp.GetHelpText(Console.BufferWidth)); #if DEBUG Console.ReadLine(); #endif return; } IGameInstance instance = GameInstance.GetFromString(options.Game); string filename = Path.GetFileNameWithoutExtension(options.Input); string languageCode = filename.Remove(0, filename.Length - 2); Language language = LanguageUtility.GetLanguageFromCode(languageCode); Dictionary <UInt32, string> hashLookup = new Dictionary <UInt32, string>(); if (options.LoadXtbls) { Console.WriteLine("Loading XTBL files..."); Dictionary <string, FileSearchResult> results = instance.SearchForFiles("*.xtbl"); int i = 0; foreach (var pair in results) { i++; Console.WriteLine("[{0}/{1}] Loading xtbl: {2}", i, results.Count, pair.Key); string xtbl = null; using (StreamReader reader = new StreamReader(pair.Value.GetStream())) { xtbl = reader.ReadToEnd(); } Regex regex = new Regex("<Name>(.*?)</Name>", RegexOptions.Compiled); foreach (Match m in regex.Matches(xtbl)) { uint hash = Hashes.CrcVolition(m.Groups[1].Value); if (!hashLookup.ContainsKey(hash)) { hashLookup.Add(hash, m.Groups[1].Value); } } } } string outputFile = (options.Output != null) ? options.Output : Path.ChangeExtension(options.Input, ".xml"); Console.WriteLine("Extracting {0} to {1}...", options.Input, outputFile); StringFile stringFile = null; using (Stream stream = File.OpenRead(options.Input)) { stringFile = new StringFile(stream, language, instance); } XmlWriterSettings settings = new XmlWriterSettings(); settings.Indent = true; settings.IndentChars = "\t"; settings.NewLineChars = "\r\n"; Dictionary <string, string> stringsWithName = new Dictionary <string, string>(); Dictionary <uint, string> stringsWithHash = new Dictionary <uint, string>(); foreach (uint hash in stringFile.GetHashes()) { string text = stringFile.GetString(hash); if (hashLookup.ContainsKey(hash)) { stringsWithName.Add(hashLookup[hash], text); } else { stringsWithHash.Add(hash, text); } } using (XmlWriter xml = XmlTextWriter.Create(outputFile, settings)) { xml.WriteStartDocument(); xml.WriteStartElement("Strings"); xml.WriteAttributeString("Language", language.ToString()); xml.WriteAttributeString("Game", instance.Game.ToString()); foreach (var pair in stringsWithName.OrderBy(x => x.Key)) { xml.WriteStartElement("String"); xml.WriteAttributeString("Name", pair.Key); xml.WriteString(pair.Value); xml.WriteEndElement(); // String } foreach (var pair in stringsWithHash) { xml.WriteStartElement("String"); xml.WriteAttributeString("Hash", pair.Key.ToString("X8")); xml.WriteString(pair.Value); xml.WriteEndElement(); // String } xml.WriteEndElement(); // Strings xml.WriteEndDocument(); } Console.WriteLine("Done."); #if DEBUG Console.ReadLine(); #endif }
public void Save(Stream stream) { long dataStart = CalculateDataStartOffset(); stream.Seek(dataStart, SeekOrigin.Begin); long fileStart = 0; long compressedSize = 0; long uncompressedSize = 0; // Output file data ZlibStream dataStream = null; if (IsCompressed && IsCondensed) { dataStream = new ZlibStream(stream, CompressionMode.Compress, CompressionLevel.BestCompression, true); dataStream.FlushMode = FlushType.Sync; } long compressedStart = 0; for (int i = 0; i < Files.Count; i++) { IPackfileEntry entry = Files[i]; Stream fs = m_Streams[entry.Name]; bool isLast = (i == (Files.Count - 1)); PackfileEntry pfE = (PackfileEntry)entry; var data = pfE.Data; data.Start = (uint)fileStart; data.Size = (uint)fs.Length; data.Alignment = (IsCondensed) ? (ushort)16 : (ushort)1; if (this.IsCompressed) { data.Flags = PackfileEntryFlags.Compressed; } if (IsCompressed && IsCondensed) { fs.CopyTo(dataStream); dataStream.Flush(); long afterData = dataStream.TotalOut; data.CompressedSize = (uint)(afterData - compressedStart); compressedStart = afterData; if (IsStr2) { fileStart += data.Size.Align(16); uncompressedSize += data.Size.Align(16); compressedSize += data.CompressedSize; } else { fileStart += data.Size; //.Align(16); if (!isLast) { uncompressedSize += data.Size; //.Align(16); //uint toSkip = data.Size.Align(16) - data.Size; // for (int j = 0; j < toSkip; j++) //dataStream.WriteByte(0); } else { uncompressedSize += data.Size; } compressedSize += data.CompressedSize; } } else if (IsCondensed) { fs.CopyTo(stream); data.CompressedSize = 0xFFFFFFFF; fileStart += data.Size.Align(16); if (isLast) { uncompressedSize += data.Size; } else { uint toSkip = data.Size.Align(16) - data.Size; uncompressedSize += data.Size.Align(16); stream.Seek(toSkip, SeekOrigin.Current); } } else if (IsCompressed) { long beforeData = stream.Position; using (dataStream = new ZlibStream(stream, CompressionMode.Compress, CompressionLevel.BestCompression, true)) { dataStream.FlushMode = FlushType.Sync; fs.CopyTo(dataStream); dataStream.Flush(); } long afterData = stream.Position; data.CompressedSize = (uint)(afterData - beforeData); fileStart += data.CompressedSize; uncompressedSize += data.Size; compressedSize += data.CompressedSize; } else { fs.CopyTo(stream); data.CompressedSize = 0xFFFFFFFF; fileStart += data.Size; uncompressedSize += data.Size; } fs.Close(); pfE.Data = data; } if (IsCompressed && IsCondensed) { dataStream.Close(); } // Output file names stream.Seek(CalculateEntryNamesOffset(), SeekOrigin.Begin); long startOffset = CalculateEntryNamesOffset(); foreach (IPackfileEntry entry in Files) { PackfileEntry pfE = (PackfileEntry)entry; stream.Align(2); pfE.Data.FilenameOffset = (UInt32)(stream.Position - startOffset); stream.WriteAsciiNullTerminatedString(entry.Name); stream.Seek(1, SeekOrigin.Current); stream.Align(2); } long nameSize = stream.Position - CalculateEntryNamesOffset(); // Output file info stream.Seek(GetEntryDataOffset(), SeekOrigin.Begin); foreach (IPackfileEntry entry in Files) { PackfileEntry pfE = (PackfileEntry)entry; stream.WriteStruct(pfE.Data); } long dirSize = stream.Position - GetEntryDataOffset(); // Output header stream.Seek(0, SeekOrigin.Begin); FileData.Descriptor = 0x51890ACE; FileData.Version = 0x0A; FileData.HeaderChecksum = 0; FileData.FileSize = (uint)stream.Length; FileData.NumFiles = (uint)Files.Count; FileData.DirSize = (uint)dirSize; FileData.FilenameSize = (uint)nameSize; FileData.DataSize = (uint)uncompressedSize; if (IsCompressed) { FileData.CompressedDataSize = (uint)compressedSize; } else { FileData.CompressedDataSize = 0xFFFFFFFF; } stream.WriteStruct(FileData); uint checksum = 0; byte[] checksumBuffer = new byte[0x1C]; stream.Seek(0x0C, SeekOrigin.Begin); stream.Read(checksumBuffer, 0, checksumBuffer.Length); checksum = Hashes.CrcVolition(checksumBuffer); stream.Seek(0x08, SeekOrigin.Begin); stream.WriteUInt32(checksum); stream.Flush(); }
public bool ContainsKey(string key) { UInt32 hash = Hashes.CrcVolition(key); return(ContainsKey(hash)); }
public string GetString(string key) { UInt32 hash = Hashes.CrcVolition(key); return(GetString(hash)); }
public void AddString(string key, string text) { UInt32 hash = Hashes.CrcVolition(key); AddString(hash, text); }