Esempio n. 1
0
        private void UpdateHash()
        {
            string itemName         = ItemName.Text;
            string maleMeshFilename = MaleMeshFilename.Text;
            uint   variantId        = (uint)VariantID.Value;

            int hash = Hashes.CustomizationItemCrc(itemName, maleMeshFilename, variantId);

            MaleStr2PCName.Text   = String.Format("custmesh_{0}.str2_pc", hash);
            FemaleStr2PCName.Text = String.Format("custmesh_{0}f.str2_pc", hash);
        }
Esempio n. 2
0
        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
        }