Exemple #1
0
        /// <summary>
        /// Groups children by MapKey and ParentTemplateId
        /// </summary>
        /// <returns>Whether the GameObjects list was sorted.</returns>
        private bool SortRootTemplate()
        {
            if (GameObjectsCached)
            {
                return(true);
            }
            GeneralHelper.WriteToConsole($"Sorting GameObjects...\n");
            GameObjects = GameObjectBag.OrderBy(go => string.IsNullOrEmpty(go.Name)).ThenBy(go => go.Name).ToList();
            var children = GameObjects.Where(go => !string.IsNullOrEmpty(go.ParentTemplateId)).ToList();
            var lookup   = GameObjects.Where(go => !string.IsNullOrEmpty(go.MapKey)).GroupBy(go => go.MapKey).ToDictionary(go => go.Key, go => go.Last());

            Parallel.ForEach(children.AsParallel().OrderBy(go => string.IsNullOrEmpty(go.Name)).ThenBy(go => go.Name), gameObject =>
            {
                var goChildren = lookup.FirstOrDefault(l => l.Key == gameObject.ParentTemplateId).Value?.Children;
                if (goChildren != null)
                {
                    lock (goChildren)
                        goChildren.Add(gameObject);
                }
            });
            GameObjects = GameObjects.Where(go => string.IsNullOrEmpty(go.ParentTemplateId)).ToList();
            foreach (var gameObject in GameObjects)
            {
                gameObject.PassOnStats();
            }
            FileHelper.SerializeObject(GameObjects, "GameObjects");

            return(true);
        }
Exemple #2
0
        /// <summary>
        /// Reads the visual banks for a list of id/filepath references for quick lookup.
        /// </summary>
        /// <returns>Whether the visual bank lists were created.</returns>
        private bool ReadVisualBanks()
        {
            var deserializedCharacterVisualBanks = FileHelper.DeserializeObject <Dictionary <string, string> >("CharacterVisualBanks");
            var deserializedVisualBanks          = FileHelper.DeserializeObject <Dictionary <string, string> >("VisualBanks");
            var deserializedBodySetVisuals       = FileHelper.DeserializeObject <Dictionary <string, string> >("BodySetVisuals");
            var deserializedMaterialBanks        = FileHelper.DeserializeObject <Dictionary <string, string> >("MaterialBanks");
            var deserializedTextureBanks         = FileHelper.DeserializeObject <Dictionary <string, string> >("TextureBanks");

            if (deserializedVisualBanks != null && deserializedCharacterVisualBanks != null && deserializedBodySetVisuals != null && deserializedMaterialBanks != null && deserializedTextureBanks != null)
            {
                CharacterVisualBanks = deserializedCharacterVisualBanks;
                VisualBanks          = deserializedVisualBanks;
                BodySetVisuals       = deserializedBodySetVisuals;
                MaterialBanks        = deserializedMaterialBanks;
                TextureBanks         = deserializedTextureBanks;
                return(true);
            }

            // Lookup CharacterVisualBank file from CharacterVisualResourceID
            var characterVisualBanks = new ConcurrentDictionary <string, string>();
            var visualBanks          = new ConcurrentDictionary <string, string>();
            var bodySetVisuals       = new ConcurrentDictionary <string, string>();
            var materialBanks        = new ConcurrentDictionary <string, string>();
            var textureBanks         = new ConcurrentDictionary <string, string>();
            var visualBankFiles      = GetFileList("VisualBank");
            var materialBankFiles    = GetFileList("MaterialBank");
            var textureBankFiles     = GetFileList("TextureBank");

            visualBankFiles.AddRange(materialBankFiles);
            visualBankFiles.AddRange(textureBankFiles);
            visualBankFiles = visualBankFiles.Distinct().ToList();
            Parallel.ForEach(visualBankFiles, visualBankFile => {
                if (File.Exists(visualBankFile))
                {
                    var visualBankFilePath = FileHelper.Convert(visualBankFile, "lsx", visualBankFile.Replace(".lsf", ".lsx"));
                    var filePath           = visualBankFilePath.Replace($"\\\\?\\{Directory.GetCurrentDirectory()}\\UnpackedData", string.Empty);
                    var stream             = File.OpenText(visualBankFilePath);
                    using (var fileStream = stream)
                        using (var reader = new XmlTextReader(fileStream))
                        {
                            reader.Read();
                            while (!reader.EOF)
                            {
                                try
                                {
                                    var sectionId = reader.GetAttribute("id");
                                    var isNode    = reader.NodeType == XmlNodeType.Element && reader.IsStartElement() && reader.Name == "node";
                                    if (isNode && (sectionId == "CharacterVisualBank" || sectionId == "VisualBank"))
                                    {
                                        // read children for resource nodes
                                        var xml      = (XElement)XNode.ReadFrom(reader);
                                        var children = xml.Element("children");
                                        if (children != null)
                                        {
                                            var nodes = children.Elements("node");
                                            foreach (XElement node in nodes)
                                            {
                                                var id = node.Elements("attribute").Single(a => a.Attribute("id").Value == "ID").Attribute("value").Value;
                                                if (sectionId == "CharacterVisualBank")
                                                {
                                                    characterVisualBanks.TryAdd(id, filePath);
                                                    var bodySetVisual = node.Elements("attribute").Single(a => a.Attribute("id").Value == "BodySetVisual").Attribute("value").Value;
                                                    if (bodySetVisual != null)
                                                    {
                                                        bodySetVisuals.TryAdd(bodySetVisual, filePath);
                                                    }
                                                }
                                                else
                                                {
                                                    visualBanks.TryAdd(id, filePath);
                                                }
                                            }
                                        }

                                        reader.Skip();
                                    }
                                    else if (isNode && sectionId == "MaterialBank")
                                    {
                                        var xml      = (XElement)XNode.ReadFrom(reader);
                                        var children = xml.Element("children");
                                        if (children != null)
                                        {
                                            var nodes = children.Elements("node");
                                            foreach (XElement node in nodes)
                                            {
                                                var id = node.Elements("attribute").Single(a => a.Attribute("id").Value == "ID").Attribute("value").Value;
                                                materialBanks.TryAdd(id, filePath);
                                            }
                                        }
                                        reader.Skip();
                                    }
                                    else if (isNode && sectionId == "TextureBank")
                                    {
                                        var xml      = (XElement)XNode.ReadFrom(reader);
                                        var children = xml.Element("children");
                                        if (children != null)
                                        {
                                            var nodes = children.Elements("node");
                                            foreach (XElement node in nodes)
                                            {
                                                var id = node.Elements("attribute").Single(a => a.Attribute("id").Value == "ID").Attribute("value").Value;
                                                textureBanks.TryAdd(id, filePath);
                                            }
                                        }
                                        reader.Skip();
                                    }
                                    else
                                    {
                                        reader.Read();
                                    }
                                }
                                catch (Exception ex)
                                {
                                    GeneralHelper.WriteToConsole($"Failed to load {filePath}.\n");
                                    break;
                                }
                            }
                            reader.Close();
                        }
                }
            });

            CharacterVisualBanks = characterVisualBanks.ToDictionary(kvp => kvp.Key, kvp => kvp.Value);
            VisualBanks          = visualBanks.ToDictionary(kvp => kvp.Key, kvp => kvp.Value);
            BodySetVisuals       = bodySetVisuals.ToDictionary(kvp => kvp.Key, kvp => kvp.Value);
            MaterialBanks        = materialBanks.ToDictionary(kvp => kvp.Key, kvp => kvp.Value);
            TextureBanks         = textureBanks.ToDictionary(kvp => kvp.Key, kvp => kvp.Value);

            FileHelper.SerializeObject(CharacterVisualBanks, "CharacterVisualBanks");
            FileHelper.SerializeObject(VisualBanks, "VisualBanks");
            FileHelper.SerializeObject(BodySetVisuals, "BodySetVisuals");
            FileHelper.SerializeObject(MaterialBanks, "MaterialBanks");
            FileHelper.SerializeObject(TextureBanks, "TextureBanks");
            return(true);
        }
Exemple #3
0
        /// <summary>
        /// Reads the root template and converts it into a GameObject list.
        /// </summary>
        /// <returns>Whether the root template was read.</returns>
        private bool ReadRootTemplate()
        {
            var deserializedGameObjects = FileHelper.DeserializeObject <List <GameObject> >("GameObjects");

            if (deserializedGameObjects != null)
            {
                GameObjects       = deserializedGameObjects;
                GameObjectsCached = true;
                return(true);
            }
            var rootTemplates = GetFileList("GameObjects");
            var typeBag       = new ConcurrentBag <string>();

            #if DEBUG
            var idBag    = new ConcurrentBag <string>();
            var classBag = new ConcurrentBag <Tuple <string, string> >();
            #endif
            Parallel.ForEach(rootTemplates, rootTemplate =>
            {
                if (File.Exists(rootTemplate))
                {
                    var rootTemplatePath = FileHelper.Convert(rootTemplate, "lsx", rootTemplate.Replace(".lsf", ".lsx"));
                    var pak    = Regex.Match(rootTemplatePath, @"(?<=UnpackedData\\).*?(?=\\)").Value;
                    var stream = File.OpenText(rootTemplatePath);
                    using (var fileStream = stream)
                        using (var reader = new XmlTextReader(fileStream))
                        {
                            reader.Read();
                            while (!reader.EOF)
                            {
                                if (reader.NodeType == XmlNodeType.Element && reader.IsStartElement() && reader.GetAttribute("id") == "GameObjects")
                                {
                                    var xml        = (XElement)XNode.ReadFrom(reader);
                                    var gameObject = new GameObject {
                                        Pak = pak, Children = new List <GameObject>(), FileLocation = rootTemplatePath.Replace($"\\\\?\\{Directory.GetCurrentDirectory()}\\UnpackedData", string.Empty)
                                    };
                                    var attributes = xml.Elements("attribute");

                                    foreach (XElement attribute in attributes)
                                    {
                                        var id     = attribute.Attribute("id").Value;
                                        var handle = attribute.Attribute("handle")?.Value;
                                        var value  = handle ?? attribute.Attribute("value").Value;
                                        var type   = attribute.Attribute("type").Value;
                                        if (int.TryParse(type, out int typeInt))
                                        {
                                            type = GeneralHelper.LarianTypeEnumConvert(type);
                                        }

                                    #if DEBUG
                                        typeBag.Add(type);
                                        idBag.Add(id);
                                        classBag.Add(new Tuple <string, string>(id, type));
                                    #endif
                                        if (string.IsNullOrEmpty(handle))
                                        {
                                            gameObject.LoadProperty(id, type, value);
                                        }
                                        else
                                        {
                                            gameObject.LoadProperty($"{id}Handle", type, value);
                                            var translationText = TranslationLookup.FirstOrDefault(tl => tl.Key.Equals(value)).Value?.Value;
                                            gameObject.LoadProperty(id, type, translationText);
                                        }
                                    }

                                    if (string.IsNullOrEmpty(gameObject.ParentTemplateId))
                                    {
                                        gameObject.ParentTemplateId = gameObject.TemplateName;
                                    }
                                    if (string.IsNullOrEmpty(gameObject.Name))
                                    {
                                        gameObject.Name = gameObject.DisplayName;
                                    }
                                    if (string.IsNullOrEmpty(gameObject.Name))
                                    {
                                        gameObject.Name = gameObject.Stats;
                                    }

                                    GameObjectBag.Add(gameObject);
                                    reader.Skip();
                                }
                                else
                                {
                                    reader.Read();
                                }
                            }
                            reader.Close();
                        }
                }
            });
            #if DEBUG
            FileHelper.SerializeObject(typeBag.ToList().Distinct().ToList(), "GameObjectTypes");
            FileHelper.SerializeObject(idBag.ToList().Distinct().ToList(), "GameObjectAttributeIds");
            GeneralHelper.ClassBuilder(classBag.ToList().Distinct().ToList());
            #endif
            return(true);
        }
Exemple #4
0
        /// <summary>
        /// Creates a file containing class properties for GameObjects. For development use.
        /// </summary>
        /// <param name="attributeClasses">The distinct list of ids and types</param>
        public static void ClassBuilder(List <Tuple <string, string> > attributeClasses)
        {
            FileHelper.SerializeObject(attributeClasses, "GameObjectAttributeClasses");
            var classList = string.Empty;

            foreach (var attribute in attributeClasses.OrderBy(at => at.Item1))
            {
                if (!char.IsLetter(attribute.Item1[0]))
                {
                    continue;
                }
                var type = string.Empty;

                switch (attribute.Item2)
                {
                case "guid":
                    type = "Guid";
                    break;

                case "bool":
                    type = "bool";
                    break;

                case "float":
                    type = "float";
                    break;

                case "double":
                    type = "double";
                    break;

                case "int8":
                    type = "sbyte";
                    break;

                case "int16":
                    type = "short";
                    break;

                case "int":
                case "int32":
                    type = "int";
                    break;

                case "uint8":
                    type = "byte";
                    break;

                case "uint16":
                    type = "uint16";
                    break;

                case "uint32":
                    type = "uint";
                    break;

                case "uint64":
                    type = "ulong";
                    break;

                case "fvec2":
                    type = "Tuple<float, float>";
                    break;

                case "fvec3":
                    type = "Tuple<float, float, float>";
                    break;

                case "fvec4":
                    type = "Tuple<float, float, float, float>";
                    break;

                case "FixedString":
                case "LSString":
                case "TranslatedString":
                    type = attribute.Item2;
                    break;

                case "mat4x4":
                    type = "List<Tuple<float, float, float, float>>";
                    break;

                default:
                    throw new Exception($"Attribute type not covered: {attribute.Item2}");
                }
                var camelCaseId = char.ToLowerInvariant(attribute.Item1[0]) + attribute.Item1.Substring(1);
                classList += $"private {type} _{camelCaseId};\n\n" +
                             $"public {type} {attribute.Item1} {{\n" +
                             $"\tget {{ return _{camelCaseId}; }}\n" +
                             $"\tset {{ _{camelCaseId} = value; }}\n" +
                             $"}}\n\n";
            }
            if (!Directory.Exists("Development"))
            {
                Directory.CreateDirectory("Development");
            }
            File.WriteAllText("Development/classList.txt", classList);
        }