Пример #1
0
        static void HandleGenericOptions(string[] args)
        {
            CommandLine.Parse <GenericOptions>(args, (opts, gOpts) =>
            {
                int level = DLCList.Length - 1;

                if (opts.DlcLevel != null)
                {
                    level = Array.IndexOf(DLCList, opts.DlcLevel.ToLowerInvariant());

                    if (level == -1)
                    {
                        level = DLCList.Length - 1;
                    }
                }

                EnsureFiles(level);
                // EnsureArchetypes(level);

                if (opts.Mods != null)
                {
                    Console.WriteLine("Loading mods");

                    var infos = Utils.Expand(opts.Mods);
                    int count = 0;

                    for (int i = 0; i < infos.Length; i++)
                    {
                        var name = Path.GetFileNameWithoutExtension(infos[i].Name);
                        var ext  = Path.GetExtension(infos[i].Name);

                        if (ext.Length > 0)
                        {
                            ext = ext.Substring(1);
                        }

                        var hash = Jenkins.Hash(name.ToLowerInvariant());

                        switch (ext)
                        {
                        case "ydr":
                            {
                                var ydr = new YdrFile();
                                ydr.Load(infos[i].FullName);
                                DrawableCache[hash] = ydr.Drawable;
                                count++;
                                break;
                            }

                        default: break;
                        }
                    }

                    Console.Error.WriteLine("Loaded " + count + " mods");
                }

                return;
            });
        }
Пример #2
0
        public void UpdateClass()
        {
            // structure

            textureDictionary.VFT = 0x0000000140570fd0;
            textureDictionary.PagesInfoPointer = 0x0000000000000000;
            textureDictionary.Count            = 0x00000001;
            textureDictionary.Unknown_1Ch      = 0x00000000;

            // references

            textureDictionary.PagesInfo = null;

            if (textureDictionary.Values.Entries != null)
            {
                var theHashList = new List <uint>();
                foreach (var texture in textureDictionary.Values.Entries)
                {
                    uint hash = Jenkins.Hash((string)texture.Name);
                    theHashList.Add(hash);
                }
                theHashList.Sort();

                var bak = textureDictionary.Values.Entries;
                textureDictionary.Hashes.Entries = new SimpleArray <uint>(theHashList.ToArray());
                textureDictionary.Values.Entries = new ResourcePointerArray64 <TextureDX11>();
                foreach (uint x in theHashList)
                {
                    foreach (var g in bak)
                    {
                        uint tx = Jenkins.Hash((string)g.Name);
                        if (tx == x)
                        {
                            textureDictionary.Values.Entries.Add(g);
                        }
                    }
                }

                //textureDictionary.Hashes = new SimpleArray<uint>();
                //foreach (var texture in textureDictionary.Textures)
                //{
                //    uint hash = Jenkins.Hash((string)texture.Name);
                //    textureDictionary.Hashes.Add((uint_r)hash);
                //}


                //var bak = textureDictionary.Textures;
                //textureDictionary.Textures = new ResourcePointerArray64<Texture_GTA5_pc>();


                foreach (var texture in textureDictionary.Values.Entries)
                {
                    (new TextureWrapper_GTA5_pc(texture)).UpdateClass();
                }
            }
            else
            {
            }
        }
Пример #3
0
        public static uint Hash(string str)
        {
            if (!uint.TryParse(str, out uint hash))
            {
                hash = Jenkins.Hash(str);
                Jenkins.Ensure(str);
            }

            return(hash);
        }
Пример #4
0
        public static void EnsureFiles(int targetDlcLevel)
        {
            Console.Error.WriteLine("Loading file tree");

            ArchiveUtilities.ForEachFile(Settings.Default.GTAFolder, (string fullFileName, IArchiveFile file, RageArchiveEncryption7 encryption) =>
            {
                var dlcLevel = GetDLCLevel(fullFileName);

                if (dlcLevel > targetDlcLevel)
                {
                    return;
                }

                string[] path  = fullFileName.Split('\\');
                string[] split = path[path.Length - 1].ToLowerInvariant().Split('.');
                string name    = split[0];
                string ext     = split[split.Length - 1];
                uint hash      = Jenkins.Hash(name);

                var rpfEntry = new RpfFileEntry()
                {
                    Hash         = hash,
                    Name         = fullFileName.Replace('/', '\\').ToLowerInvariant().Split('\\').Last(),
                    FullFileName = fullFileName,
                    DlcLevel     = dlcLevel,
                    Ext          = ext,
                };

                if (DLCFiles.ContainsKey(rpfEntry.Name))
                {
                    if (rpfEntry.DlcLevel > DLCFiles[rpfEntry.Name].DlcLevel)
                    {
                        DLCFiles[rpfEntry.Name] = rpfEntry;
                    }
                }
                else
                {
                    DLCFiles[rpfEntry.Name] = rpfEntry;
                }

                Files.Add(rpfEntry);

                Dictionary <uint, RpfFileEntry> dict;

                if (!(FileHashes.TryGetValue(ext, out dict)))
                {
                    dict = new Dictionary <uint, RpfFileEntry>();
                }

                dict[hash] = rpfEntry;

                FileHashes[ext] = dict;
            });
        }
Пример #5
0
 private static MetaName GetHash(string str)
 {
     if (str.StartsWith("hash_"))
     {
         return((MetaName)Convert.ToUInt32(str.Substring(5), 16));
     }
     else
     {
         return((MetaName)Jenkins.Hash(str));
     }
 }
Пример #6
0
 public int GetHashForName(string hashName)
 {
     if (hashName.StartsWith("hash_", StringComparison.OrdinalIgnoreCase))
     {
         int intAgain = int.Parse(hashName.AsSpan(5), NumberStyles.HexNumber, CultureInfo.InvariantCulture);
         return(intAgain);
     }
     else
     {
         return((int)Jenkins.Hash(hashName));
     }
 }
Пример #7
0
 public int GetHashForName(string hashName)
 {
     if (hashName.StartsWith("hash_", StringComparison.OrdinalIgnoreCase))
     {
         var x        = hashName.Substring(5);
         int intAgain = int.Parse(x, NumberStyles.HexNumber);
         return(intAgain);
     }
     else
     {
         return((int)Jenkins.Hash(hashName));
     }
 }
Пример #8
0
        /*public static HashSet<string> GetAllStringsFromAllXmls(string gameDirectoryName)
         * {
         *  var xmlStrings = new HashSet<string>();
         *
         *  ArchiveUtilities.ForEachBinaryFile(gameDirectoryName, (fullFileName, file, encryption) =>
         *  {
         *      if (file.Name.EndsWith(".meta", StringComparison.OrdinalIgnoreCase) ||
         *       file.Name.EndsWith(".xml", StringComparison.OrdinalIgnoreCase))
         *      {
         *          var fileStream = new MemoryStream();
         *          file.Export(fileStream);
         *
         *          var buf = new byte[fileStream.Length];
         *          fileStream.Position = 0;
         *          fileStream.Read(buf, 0, buf.Length);
         *
         *          if (file.IsEncrypted)
         *          {
         *              if (encryption == RageArchiveEncryption7.AES)
         *              {
         *                  buf = AesEncryption.DecryptData(buf, GTA5Constants.PC_AES_KEY);
         *              }
         *              else
         *              {
         *                  var qq = GTA5Hash.CalculateHash(file.Name);
         *                  var gg = (qq + (uint)file.UncompressedSize + (101 - 40)) % 0x65;
         *                  buf = GTA5Crypto.Decrypt(buf, GTA5Constants.PC_NG_KEYS[gg]);
         *              }
         *          }
         *
         *          if (file.IsCompressed)
         *          {
         *              var def = new DeflateStream(new MemoryStream(buf), CompressionMode.Decompress);
         *              var bufnew = new byte[file.UncompressedSize];
         *              def.Read(bufnew, 0, (int)file.UncompressedSize);
         *              buf = bufnew;
         *          }
         *
         *          var cleanedStream = new MemoryStream(buf);
         *          foreach (string xmlString in GetAllStringsFromXml(cleanedStream))
         *          {
         *              xmlStrings.Add(xmlString);
         *          }
         *
         *          Console.WriteLine(file.Name);
         *      }
         *  });
         *
         *  return xmlStrings;
         * }*/

        /*public static HashSet<string> GetAllStringsFromXml(string xmlFileName)
         * {
         *  using (var xmlFileStream = new FileStream(xmlFileName, FileMode.Open))
         *  {
         *      return GetAllStringsFromXml(xmlFileStream);
         *  }
         * }*/

        /*public static HashSet<string> GetAllStringsFromXml(Stream xmlFileStream)
         * {
         *  var xmlStrings = new HashSet<string>();
         *
         *  var document = new HtmlDocument();
         *  document.OptionOutputOriginalCase = true;
         *  document.OptionWriteEmptyNodes = true;
         *  document.Load(xmlFileStream);
         *
         *  var stack = new Stack<HtmlNode>();
         *  stack.Push(document.DocumentNode);
         *  while (stack.Count > 0)
         *  {
         *      var node = stack.Pop();
         *      foreach (var descendantNode in node.Descendants())
         *      {
         *          stack.Push(descendantNode);
         *      }
         *      if (node.NodeType == HtmlNodeType.Text)
         *      {
         *          xmlStrings.Add(node.InnerText.Trim());
         *
         *          // for flags...
         *          string[] splitted = node.InnerText.Split(new char[] {' ','\t','\n' },StringSplitOptions.RemoveEmptyEntries);
         *          foreach (var x in splitted)
         *          {
         *              xmlStrings.Add(x.Trim());
         *          }
         *      }
         *      if (node.NodeType == HtmlNodeType.Element)
         *      {
         *          xmlStrings.Add(node.OriginalName.Trim());
         *          foreach (var attribute in node.Attributes)
         *          {
         *              xmlStrings.Add(attribute.OriginalName.Trim());
         *              xmlStrings.Add(attribute.Value.Trim());
         *          }
         *      }
         *  }
         *
         *  return xmlStrings;
         * }*/

        public static HashSet <string> GetAllStringsThatMatchAHash(IEnumerable <string> listOfStrings, ISet <int> listOfHashes)
        {
            var matchingStrings = new HashSet <string>();

            foreach (var s in listOfStrings)
            {
                int hash = unchecked ((int)Jenkins.Hash(s));
                if (listOfHashes.Contains(hash))
                {
                    matchingStrings.Add(s);
                }
            }
            return(matchingStrings);
        }
Пример #9
0
        private void AddHashForStrings(PsoXmlExporter exporter, string resourceFileName)
        {
            var assembly = Assembly.GetExecutingAssembly();

            using (Stream namesStream = assembly.GetManifestResourceStream(resourceFileName))
                using (StreamReader namesReader = new StreamReader(namesStream))
                {
                    while (!namesReader.EndOfStream)
                    {
                        string name = namesReader.ReadLine();
                        uint   hash = Jenkins.Hash(name);
                        if (!exporter.HashMapping.ContainsKey((int)hash))
                        {
                            exporter.HashMapping.Add((int)hash, name);
                        }
                    }
                }
        }
Пример #10
0
        private void AddHashForStrings(Dictionary <int, string> dictionary, string resourceFileName)
        {
            var assembly = Assembly.GetExecutingAssembly();

            using (Stream namesStream = assembly.GetManifestResourceStream(resourceFileName))
                using (StreamReader namesReader = new StreamReader(namesStream))
                {
                    while (!namesReader.EndOfStream)
                    {
                        string name = namesReader.ReadLine();
                        uint   hash = Jenkins.Hash(name);
                        if (!dictionary.ContainsKey((int)hash))
                        {
                            dictionary.Add((int)hash, name);
                        }
                    }
                }
        }
Пример #11
0
        static void HashEmbeddedStrings()
        {
            var metanames = Resource.metanames.Split(new string[] { "\r\n" }, StringSplitOptions.None);

            Hashes.Add(-489959468, "VECTOR3"); //0xe2cbcfd4, //this hash isn't correct, but is used in CDistantLODLight
            Hashes.Add(0x33, "VECTOR4");
            Hashes.Add(0x4a, "HASH");
            Hashes.Add(0x10, "STRING");
            Hashes.Add(0x7, "POINTER");
            Hashes.Add(0x13, "USHORT");
            Hashes.Add(0x15, "UINT");
            Hashes.Add(0x100, "ARRAYINFO");
            Hashes.Add(17, "BYTE");
            Hashes.Add(33, "FLOAT");
            Hashes.Add(12, "PsoPOINTER");

            for (int i = 0; i < metanames.Length; i++)
            {
                int hash = (int)Jenkins.Hash(metanames[i]);

                if (!String.IsNullOrEmpty(metanames[i]) && !Hashes.ContainsKey(hash))
                {
                    bool found = false;

                    foreach (var kvp in Hashes)
                    {
                        if (kvp.Value == metanames[i])
                        {
                            found = true;
                            break;
                        }
                    }

                    if (!found)
                    {
                        Hashes.Add(hash, metanames[i]);
                    }
                }
            }
        }
Пример #12
0
        private void AddHashForUserStrings(Dictionary <int, string> dictionary, string resourceFileName)
        {
            var path = Path.Combine(Directory.GetCurrentDirectory(), resourceFileName);

            if (!File.Exists(path))
            {
                return;
            }

            using (Stream namesStream = new FileStream(path, FileMode.Open, FileAccess.Read))
                using (StreamReader namesReader = new StreamReader(namesStream))
                {
                    while (!namesReader.EndOfStream)
                    {
                        string name = namesReader.ReadLine();
                        uint   hash = Jenkins.Hash(name);
                        if (!dictionary.ContainsKey((int)hash))
                        {
                            dictionary.Add((int)hash, name);
                        }
                    }
                }
        }
Пример #13
0
        public void Load(byte[] data, string name = "")
        {
            Name = name;
            Hash = Jenkins.Hash(name.Replace(".fxc", ""));

            LastError = string.Empty;

            MemoryStream ms = new MemoryStream(data);
            BinaryReader br = new BinaryReader(ms);

            uint magic_rgxe = br.ReadUInt32();

            if (magic_rgxe != 1702389618) //"rgxe"
            {
                return;
            }

            VertexType = (VertexType)br.ReadUInt32();

            byte ec0   = br.ReadByte();
            var  exts1 = new List <FxcHeaderExt>();

            for (int e = 0; e < ec0; e++)
            {
                FxcHeaderExt ext = new FxcHeaderExt();
                ext.Name     = ReadString(br);
                ext.Unk0Byte = br.ReadByte();   //0
                ext.Unk1Uint = br.ReadUInt32(); //2
                exts1.Add(ext);
            }
            Exts = exts1.ToArray();


            List <FxcShader>[] shadergrps = new List <FxcShader> [6];

            var chunks  = new List <FxcHeaderChunk>();
            var shaders = new List <FxcShader>();
            int gindex  = 0;

            while (gindex < 6)// (sc0 > 0)
            {
                var shadergrp = new List <FxcShader>();
                shadergrps[gindex] = shadergrp;

                gindex++;
                byte sc0 = br.ReadByte();
                if (sc0 == 0)
                {
                    sc0 = br.ReadByte(); //this is a little odd, sometimes a byte skip
                }
                FxcHeaderChunk chunk = new FxcHeaderChunk();
                chunk.Read(br);
                chunk.Gindex      = gindex;
                chunk.ShaderCount = sc0;
                chunks.Add(chunk);
                for (int s = 1; s < sc0; s++)
                {
                    bool      exbyteflag1 = (gindex == 5); //GS seems to be in diff format??
                    bool      vsgsps      = (gindex == 1) || (gindex == 2) || (gindex == 5);
                    FxcShader shader      = new FxcShader();
                    if (!shader.Read(br, exbyteflag1, vsgsps))
                    {
                        LastError += shader.LastError;
                        //gindex = 6; //get outta the loop?
                        //break;
                    }
                    shaders.Add(shader);
                    shadergrp.Add(shader);
                }
            }

            Shaders         = shaders.ToArray();
            VertexShaders   = shadergrps[0]?.ToArray();
            PixelShaders    = shadergrps[1]?.ToArray();
            ComputeShaders  = shadergrps[2]?.ToArray();
            DomainShaders   = shadergrps[3]?.ToArray();
            GeometryShaders = shadergrps[4]?.ToArray();
            HullShaders     = shadergrps[5]?.ToArray();


            Chunks = chunks.ToArray();

            //ms.Dispose();
            //return;

            List <FxcVariable> globalVars = new List <FxcVariable>();

            CBufferDict = new Dictionary <uint, FxcCBuffer>();
            FxcCBuffer cbtmp = null;

            try //things can be uncertain after this...
            {
                byte cbCount1 = br.ReadByte();
                if (cbCount1 > 0)
                {
                    var cbuffers1 = new List <FxcCBuffer>();
                    for (int i = 0; i < cbCount1; i++) //cbuffers? includes?
                    {
                        FxcCBuffer cbuf = new FxcCBuffer();
                        cbuf.Read(br);
                        cbuffers1.Add(cbuf);
                        CBufferDict[cbuf.NameHash] = cbuf;
                    }
                    CBuffers1 = cbuffers1.ToArray();
                }

                byte varCount1 = br.ReadByte();
                if (varCount1 > 0)
                {
                    var vars1 = new List <FxcVariable>(); //cbuffer contents/vars
                    for (int i = 0; i < varCount1; i++)
                    {
                        FxcVariable vari = new FxcVariable();
                        vari.Read(br);
                        vars1.Add(vari);
                        if (CBufferDict.TryGetValue(vari.CBufferName, out cbtmp))
                        {
                            cbtmp.AddVariable(vari);
                        }
                        else
                        {
                            globalVars.Add(vari);
                        }
                    }
                    Variables1 = vars1.ToArray();
                }


                byte cbCount2 = br.ReadByte(); //0,1, +?
                if (cbCount2 > 0)
                {
                    var cbuffers2 = new List <FxcCBuffer>(); //more cbuffers..
                    for (int i = 0; i < cbCount2; i++)
                    {
                        FxcCBuffer cbuf = new FxcCBuffer();
                        cbuf.Read(br);
                        cbuffers2.Add(cbuf);
                        CBufferDict[cbuf.NameHash] = cbuf;
                    }
                    CBuffers2 = cbuffers2.ToArray();
                }


                byte varCount2 = br.ReadByte();
                if (varCount2 > 0)
                {
                    var vars2 = new List <FxcVariable>();
                    for (int i = 0; i < varCount2; i++) //textures/samplers
                    {
                        FxcVariable vari = new FxcVariable();
                        vari.Read(br);
                        vars2.Add(vari);
                        if (CBufferDict.TryGetValue(vari.CBufferName, out cbtmp))
                        {
                            cbtmp.AddVariable(vari);
                        }
                        else
                        {
                            globalVars.Add(vari);
                        }
                    }
                    Variables2 = vars2.ToArray();
                }


                byte techCount = br.ReadByte();
                if (techCount > 0)
                {
                    var techniques = new List <FxcTechnique>();
                    for (int i = 0; i < techCount; i++)
                    {
                        FxcTechnique tech = new FxcTechnique();
                        tech.Read(br);
                        techniques.Add(tech);
                    }
                    Techniques = techniques.ToArray();
                }


                foreach (var cbuf in CBufferDict.Values)
                {
                    cbuf.ConsolidateVariables();
                }
                GlobalVariables = globalVars.ToArray();


                if (ms.Position != ms.Length)
                {
                }
            }
            catch (Exception ex)
            {
                LastError = ex.ToString();
            }

            ms.Dispose();
        }
 public uint Jenkins_string_hash()
 {
     return(Jenkins.Hash(testString));
 }
Пример #15
0
        static void Main(string[] args)
        {
            EnsurePath();
            EnsureKeys();
            EnsureCache();

            CommandLine.Parse <GenPropDefsOptions>(args, opts =>
            {
                if (opts.InputFiles != null)
                {
                    var inputFiles = Utils.Expand(opts.InputFiles);
                    var ytyp       = new YtypFile();

                    for (int i = 0; i < inputFiles.Length; i++)
                    {
                        var fileInfo = inputFiles[i];

                        string name = "";
                        var split   = fileInfo.Name.Split('.');

                        for (int j = 0; j < split.Length; j++)
                        {
                            if (j < split.Length - 1)
                            {
                                if (j > 0)
                                {
                                    name += ".";
                                }

                                name += split[j];
                            }
                        }

                        Console.WriteLine(name);

                        try
                        {
                            switch (fileInfo.Extension)
                            {
                            case ".ydr":
                                {
                                    var ydr      = new YdrFile();
                                    var arch     = new RageLib.GTA5.ResourceWrappers.PC.Meta.Structures.CBaseArchetypeDef();
                                    var nameHash = (MetaName)Jenkins.Hash(name);

                                    ydr.Load(fileInfo.FullName);

                                    arch.Name              = nameHash;
                                    arch.AssetName         = nameHash;
                                    arch.TextureDictionary = nameHash;
                                    arch.PhysicsDictionary = (MetaName)Jenkins.Hash("prop_" + name);
                                    arch.Flags             = 32;
                                    arch.AssetType         = Unk_1991964615.ASSET_TYPE_DRAWABLE;
                                    arch.BbMin             = (Vector3)(Vector4)ydr.Drawable.BoundingBoxMin;
                                    arch.BbMax             = (Vector3)(Vector4)ydr.Drawable.BoundingBoxMax;
                                    arch.BsCentre          = (Vector3)ydr.Drawable.BoundingCenter;
                                    arch.BsRadius          = ydr.Drawable.BoundingSphereRadius;
                                    arch.LodDist           = 500f;
                                    arch.HdTextureDist     = 5;

                                    ytyp.CMapTypes.Archetypes.Add(arch);

                                    break;
                                }

                            case ".ydd":     // TODO
                                {
                                    break;
                                }

                            default: break;
                            }
                        }
                        catch (Exception e)
                        {
                            Console.Error.WriteLine("ERROR => " + e.Message);
                        }
                    }

                    string path = (opts.Directory == null) ? @".\props.ytyp" : opts.Directory + @"\props.ytyp";

                    ytyp.Save(path);
                }
            });

            CommandLine.Parse <ImportMetaOptions>(args, opts =>
            {
                if (opts.InputFiles != null && opts.Directory != null)
                {
                    var inputFiles = Utils.Expand(opts.InputFiles);

                    for (int i = 0; i < inputFiles.Length; i++)
                    {
                        var fileInfo = inputFiles[i];

                        Console.WriteLine(fileInfo.FullName);

                        var doc = new XmlDocument();

                        doc.Load(fileInfo.FullName);

                        var res          = new ResourceFile_GTA5_pc <MetaFile>();
                        res.Version      = 2;
                        res.ResourceData = XmlMeta.GetMeta(doc);;

                        string fileName = fileInfo.FullName.Replace(".xml", "");

                        res.Save(fileName);
                    }
                }
            });

            CommandLine.Parse <ExportMetaOptions>(args, opts =>
            {
                if (opts.InputFiles != null && opts.Directory != null)
                {
                    var inputFiles = Utils.Expand(opts.InputFiles);

                    for (int i = 0; i < inputFiles.Length; i++)
                    {
                        var fileInfo = inputFiles[i];

                        Console.WriteLine(fileInfo.FullName);

                        var res = new ResourceFile_GTA5_pc <MetaFile>();
                        res.Load(fileInfo.FullName);

                        var xml = MetaXml.GetXml(res.ResourceData);

                        File.WriteAllText(opts.Directory + "\\" + fileInfo.Name + ".xml", xml);
                    }
                }
            });

            CommandLine.Parse <InjectEntitiesOptions>(args, opts =>
            {
                if (opts.Ymap == null)
                {
                    Console.WriteLine("Please provide source ymap file with --ymap");
                    return;
                }

                if (opts.Ytyp == null)
                {
                    Console.WriteLine("Please provide source ytyp file with --ytyp");
                    return;
                }

                if (opts.Room == null)
                {
                    Console.WriteLine("Please provide mlo room name with --room");
                    return;
                }

                if (opts.Position == null || opts.Position.Count() != 3)
                {
                    Console.WriteLine("Please provide a correct position ex: --position 120.5,1370.312,769.2");
                    return;
                }

                if (opts.Rotation == null || opts.Rotation.Count() != 4)
                {
                    Console.WriteLine("Plase provide a correct rotation ex: --rotation 0,0,0,1");
                    return;
                }

                if (opts.Name == null)
                {
                    Console.WriteLine("Plase provide new generated ytyp name with --name");
                    return;
                }

                var position = new Vector3(opts.Position.ElementAt(0), opts.Position.ElementAt(1), opts.Position.ElementAt(2));
                var rotation = new Quaternion(opts.Rotation.ElementAt(0), opts.Rotation.ElementAt(1), opts.Rotation.ElementAt(2), opts.Rotation.ElementAt(3));

                var ymap = new YmapFile();
                var ytyp = new YtypFile();

                ymap.Load(opts.Ymap);
                ytyp.Load(opts.Ytyp);

                RageLib.GTA5.ResourceWrappers.PC.Meta.Structures.CMloArchetypeDef mlo = null;

                for (int i = 0; i < ytyp.CMapTypes.MloArchetypes.Count; i++)
                {
                    mlo = ytyp.CMapTypes.MloArchetypes[i];
                    break;
                }

                if (mlo == null)
                {
                    Console.WriteLine("MLO archetype not found");
                    return;
                }

                RageLib.GTA5.ResourceWrappers.PC.Meta.Structures.CMloRoomDef room = null;

                for (int i = 0; i < mlo.Rooms.Count; i++)
                {
                    if (mlo.Rooms[i].Name == opts.Room)
                    {
                        room = mlo.Rooms[i];
                        break;
                    }
                }

                if (room == null)
                {
                    Console.WriteLine("MLO room not found");
                    return;
                }

                var mloEntities     = new List <RageLib.GTA5.ResourceWrappers.PC.Meta.Structures.CEntityDef>();
                var attachedObjects = new List <uint>();

                mloEntities.AddRange(mlo.Entities);
                attachedObjects.AddRange(room.AttachedObjects);

                for (int i = 0; i < ymap.CMapData.Entities.Count; i++)
                {
                    var entity       = ymap.CMapData.Entities[i];
                    var mloRot       = rotation;
                    var objRot       = new Quaternion(entity.Rotation.X, entity.Rotation.Y, entity.Rotation.Z, entity.Rotation.W);
                    var rotationDiff = objRot * mloRot;                                                                    // Multiply initial entity rotation by mlo rotation

                    entity.Position -= position;                                                                           // Substract mlo world coords from entity world coords
                    entity.Position  = Utils.RotateTransform(Quaternion.Conjugate(mloRot), entity.Position, Vector3.Zero); // Rotate entity around center of mlo instance (mlo entities rotations in space are inverted)
                    entity.Rotation  = new Vector4(rotationDiff.X, rotationDiff.Y, rotationDiff.Z, rotationDiff.W);

                    mloEntities.Add(entity);
                    attachedObjects.Add((uint)mloEntities.IndexOf(entity));
                }

                mlo.Entities         = mloEntities;
                room.AttachedObjects = attachedObjects;

                ytyp.Save(opts.Name.EndsWith(".ytyp") ? opts.Name : opts.Name + ".ytyp");
            });

            CommandLine.Parse <FindOptions>(args, opts =>
            {
                if (opts.Position == null || opts.Position.Count != 3)
                {
                    Console.Error.WriteLine("Please specify position with -p --position");
                    return;
                }

                if (Cache == null)
                {
                    Console.Error.WriteLine("Please build cache first with buildcache");
                    return;
                }

                var c = CultureInfo.InvariantCulture;

                for (int i = 0; i < Cache["ymap"].Count; i++)
                {
                    var cYmap = Cache["ymap"][i];

                    var entitiesExtentsMin = new Vector3((float)cYmap["entitiesExtentsMin"]["x"], (float)cYmap["entitiesExtentsMin"]["y"], (float)cYmap["entitiesExtentsMin"]["z"]);
                    var entitiesExtentsMax = new Vector3((float)cYmap["entitiesExtentsMax"]["x"], (float)cYmap["entitiesExtentsMax"]["y"], (float)cYmap["entitiesExtentsMax"]["z"]);

                    if (
                        opts.Position[0] >= entitiesExtentsMin.X && opts.Position[0] <= entitiesExtentsMax.X &&
                        opts.Position[1] >= entitiesExtentsMin.Y && opts.Position[1] <= entitiesExtentsMax.Y &&
                        opts.Position[2] >= entitiesExtentsMin.Z && opts.Position[2] <= entitiesExtentsMax.Z
                        )
                    {
                        Console.WriteLine("ymap: " + ((string)cYmap["path"]).Split('\\').Last());

                        for (int j = 0; j < cYmap["mloInstances"].Count; j++)
                        {
                            var cMloInstance     = cYmap["mloInstances"][j];
                            var cMloInstanceHash = (uint)cMloInstance["name"];

                            var instancePos = new Vector3((float)cMloInstance["position"]["x"], (float)cMloInstance["position"]["y"], (float)cMloInstance["position"]["z"]);
                            var instanceRot = new Quaternion((float)cMloInstance["rotation"]["x"], (float)cMloInstance["rotation"]["y"], (float)cMloInstance["rotation"]["z"], (float)cMloInstance["rotation"]["w"]);

                            for (int k = 0; k < Cache["ytyp"].Count; k++)
                            {
                                var cYtyp     = Cache["ytyp"][k];
                                var cYtypHash = (uint)cYtyp["hash"];

                                for (int l = 0; l < cYtyp["mloArchetypes"].Count; l++)
                                {
                                    var cMloArch     = cYtyp["mloArchetypes"][l];
                                    var cMloArchHash = (uint)cMloArch["name"];

                                    if (cMloInstanceHash == cMloArchHash)
                                    {
                                        Console.WriteLine("  ytyp => " + ((string)cYtyp["path"]).Split('\\').Last());
                                        Console.WriteLine("    mlo => " + Jenkins.GetString(cMloArchHash));
                                        Console.WriteLine("    position => " + instancePos.X.ToString(c) + "," + instancePos.Y.ToString(c) + "," + instancePos.Z.ToString(c));
                                        Console.WriteLine("    rotation => " + instanceRot.X.ToString(c) + "," + instanceRot.Y.ToString(c) + "," + instanceRot.Z.ToString(c) + "," + instanceRot.W.ToString(c));

                                        for (int m = 0; m < cMloArch["rooms"].Count; m++)
                                        {
                                            var cMloRoom = cMloArch["rooms"][m];

                                            var roomBbMin = new Vector3((float)cMloRoom["bbMin"]["x"], (float)cMloRoom["bbMin"]["y"], (float)cMloRoom["bbMin"]["z"]);
                                            var roomBbMax = new Vector3((float)cMloRoom["bbMax"]["x"], (float)cMloRoom["bbMax"]["y"], (float)cMloRoom["bbMax"]["z"]);

                                            var roomBbMinWorld = instancePos + roomBbMin;
                                            var roomBbMaxWorld = instancePos + roomBbMax;

                                            roomBbMinWorld = Utils.RotateTransform(Quaternion.Conjugate(instanceRot), roomBbMinWorld, Vector3.Zero);
                                            roomBbMaxWorld = Utils.RotateTransform(Quaternion.Conjugate(instanceRot), roomBbMaxWorld, Vector3.Zero);

                                            if (
                                                opts.Position[0] >= roomBbMinWorld.X && opts.Position[0] <= roomBbMaxWorld.X &&
                                                opts.Position[1] >= roomBbMinWorld.Y && opts.Position[1] <= roomBbMaxWorld.Y &&
                                                opts.Position[2] >= roomBbMinWorld.Z && opts.Position[2] <= roomBbMaxWorld.Z
                                                )
                                            {
                                                Console.WriteLine("      room => " + cMloRoom["name"]);
                                            }
                                        }
                                    }
                                }
                            }
                        }

                        Console.WriteLine("");
                    }
                }
            });

            CommandLine.Parse <BuildCacheOptions>(args, opts =>
            {
                dynamic cache = new JObject();

                cache["ymap"] = new JArray();
                cache["ytyp"] = new JArray();

                ArchiveUtilities.ForEachFile(Settings.Default.GTAFolder, (fullFileName, file, encryption) =>
                {
                    Console.WriteLine(fullFileName);

                    string fileNameWithoutExtension = file.Name.Split('.').First();

                    Jenkins.Ensure(fileNameWithoutExtension);

                    if (file.Name.EndsWith(".ymap"))
                    {
                        var ymap = new YmapFile();

                        using (MemoryStream ms = new MemoryStream())
                        {
                            file.Export(ms);
                            ymap.Load(ms);
                        }

                        dynamic entry = new JObject()
                        {
                            ["name"] = fileNameWithoutExtension,
                            ["path"] = fullFileName,
                            ["hash"] = Jenkins.Hash(fileNameWithoutExtension),
                            ["entitiesExtentsMin"] = new JObject()
                            {
                                ["x"] = ymap.CMapData.EntitiesExtentsMin.X,
                                ["y"] = ymap.CMapData.EntitiesExtentsMin.Y,
                                ["z"] = ymap.CMapData.EntitiesExtentsMin.Z,
                            },
                            ["entitiesExtentsMax"] = new JObject()
                            {
                                ["x"] = ymap.CMapData.EntitiesExtentsMax.X,
                                ["y"] = ymap.CMapData.EntitiesExtentsMax.Y,
                                ["z"] = ymap.CMapData.EntitiesExtentsMax.Z,
                            },
                            ["mloInstances"] = new JArray(),
                        };

                        if (ymap.CMapData.MloInstances != null)
                        {
                            for (int i = 0; i < ymap.CMapData.MloInstances.Count; i++)
                            {
                                var mloInstance = ymap.CMapData.MloInstances[i];

                                var mloInstanceEntry = new JObject()
                                {
                                    ["name"]     = ymap.CMapData.MloInstances[i].ArchetypeName,
                                    ["position"] = new JObject()
                                    {
                                        ["x"] = mloInstance.Position.X,
                                        ["y"] = mloInstance.Position.Y,
                                        ["z"] = mloInstance.Position.Z,
                                    },
                                    ["rotation"] = new JObject()
                                    {
                                        ["x"] = mloInstance.Rotation.X,
                                        ["y"] = mloInstance.Rotation.Y,
                                        ["z"] = mloInstance.Rotation.Z,
                                        ["w"] = mloInstance.Rotation.W,
                                    }
                                };

                                entry["mloInstances"].Add(mloInstanceEntry);
                            }
                        }

                        cache["ymap"].Add(entry);
                    }
                    else if (file.Name.EndsWith(".ytyp"))
                    {
                        var ytyp = new YtypFile();

                        using (MemoryStream ms = new MemoryStream())
                        {
                            file.Export(ms);
                            ytyp.Load(ms);
                        }

                        dynamic entry = new JObject()
                        {
                            ["name"]          = fileNameWithoutExtension,
                            ["path"]          = fullFileName,
                            ["hash"]          = Jenkins.Hash(fileNameWithoutExtension),
                            ["mloArchetypes"] = new JArray(),
                        };

                        if (ytyp.CMapTypes.MloArchetypes != null)
                        {
                            for (int i = 0; i < ytyp.CMapTypes.MloArchetypes.Count; i++)
                            {
                                var archetype = ytyp.CMapTypes.MloArchetypes[i];
                                var mloEntry  = new JObject
                                {
                                    ["name"]  = archetype.Name,
                                    ["rooms"] = new JArray(),
                                };

                                if (archetype.Rooms != null)
                                {
                                    for (int j = 0; j < archetype.Rooms.Count; j++)
                                    {
                                        var room      = archetype.Rooms[j];
                                        var roomEntry = new JObject
                                        {
                                            ["name"]  = room.Name,
                                            ["bbMin"] = new JObject()
                                            {
                                                ["x"] = room.BbMin.X,
                                                ["y"] = room.BbMin.Y,
                                                ["z"] = room.BbMin.Z,
                                            },
                                            ["bbMax"] = new JObject()
                                            {
                                                ["x"] = room.BbMax.X,
                                                ["y"] = room.BbMax.Y,
                                                ["z"] = room.BbMax.Z,
                                            }
                                        };

                                        ((JArray)mloEntry["rooms"]).Add(roomEntry);
                                    }
                                }

                                entry["mloArchetypes"].Add(mloEntry);
                            }
                        }

                        cache["ytyp"].Add(entry);
                    }
                });

                var jsonString = JsonConvert.SerializeObject(cache, new JsonSerializerSettings()
                {
                    Formatting = Newtonsoft.Json.Formatting.None
                });

                File.WriteAllText(AssemblyDirectory + "\\cache.json", jsonString);

                using (StreamWriter writer = new StreamWriter(AssemblyDirectory + "\\strings.txt"))
                {
                    foreach (var kvp in Jenkins.Index)
                    {
                        writer.Write(kvp.Value + "\n");
                    }
                }
            });

            if (args.Length == 0 || args[0] == "help")
            {
                Console.Error.Write(CommandLine.GenHelp());
                return;
            }
        }
Пример #16
0
 public uint Jenkins_string_hash() => Jenkins.Hash(testString);
Пример #17
0
 public uint Jenkins_binary_hash() => Jenkins.Hash(testBinary);
Пример #18
0
        static void HandleBuildCacheOptions(string[] args)
        {
            CommandLine.Parse <BuildCacheOptions>(args, (opts, gOpts) =>
            {
                Init(args);

                dynamic cache = new JObject();

                cache["ymap"] = new JArray();
                cache["ytyp"] = new JArray();

                Console.WriteLine("Building strings");

                var names = FileUtilities.GetAllFileNamesWithoutExtension(Settings.Default.GTAFolder);

                foreach (var name in names)
                {
                    Utils.Hash(name.ToLowerInvariant().Replace("_children", ""));
                }

                using (StreamWriter writer = new StreamWriter(AssemblyDirectory + "\\strings.txt"))
                {
                    foreach (var kvp in Jenkins.Index)
                    {
                        writer.Write(kvp.Value + "\n");
                    }
                }

                Console.WriteLine("Bulding cache");

                ArchiveUtilities.ForEachFile(Settings.Default.GTAFolder, (fullFileName, file, encryption) =>
                {
                    string fileNameWithoutExtension = FileUtilities.RemoveExtension(file.Name);

                    try
                    {
                        if (file.Name.EndsWith(".ymap"))
                        {
                            Console.WriteLine(fullFileName);

                            var ymap = new YmapFile();

                            using (MemoryStream ms = new MemoryStream())
                            {
                                file.Export(ms);
                                ymap.Load(ms, new object[] { true });
                            }

                            dynamic entry = new JObject()
                            {
                                ["name"]               = fileNameWithoutExtension,
                                ["path"]               = fullFileName,
                                ["hash"]               = Jenkins.Hash(fileNameWithoutExtension),
                                ["parent"]             = (uint)ymap.CMapData.Parent,
                                ["entitiesExtentsMin"] = new JObject()
                                {
                                    ["x"] = ymap.CMapData.EntitiesExtentsMin.X,
                                    ["y"] = ymap.CMapData.EntitiesExtentsMin.Y,
                                    ["z"] = ymap.CMapData.EntitiesExtentsMin.Z,
                                },
                                ["entitiesExtentsMax"] = new JObject()
                                {
                                    ["x"] = ymap.CMapData.EntitiesExtentsMax.X,
                                    ["y"] = ymap.CMapData.EntitiesExtentsMax.Y,
                                    ["z"] = ymap.CMapData.EntitiesExtentsMax.Z,
                                },
                                ["mloInstances"] = new JArray(),
                            };

                            if (ymap.CMapData.MloInstances != null)
                            {
                                for (int i = 0; i < ymap.CMapData.MloInstances.Count; i++)
                                {
                                    var mloInstance = ymap.CMapData.MloInstances[i];

                                    var mloInstanceEntry = new JObject()
                                    {
                                        ["name"]     = ymap.CMapData.MloInstances[i].ArchetypeName,
                                        ["position"] = new JObject()
                                        {
                                            ["x"] = mloInstance.Position.X,
                                            ["y"] = mloInstance.Position.Y,
                                            ["z"] = mloInstance.Position.Z,
                                        },
                                        ["rotation"] = new JObject()
                                        {
                                            ["x"] = mloInstance.Rotation.X,
                                            ["y"] = mloInstance.Rotation.Y,
                                            ["z"] = mloInstance.Rotation.Z,
                                            ["w"] = mloInstance.Rotation.W,
                                        }
                                    };

                                    entry["mloInstances"].Add(mloInstanceEntry);
                                }
                            }

                            cache["ymap"].Add(entry);
                        }
                        else if (file.Name.EndsWith(".ytyp"))
                        {
                            Console.WriteLine(fullFileName);

                            var ytyp = new YtypFile();

                            using (MemoryStream ms = new MemoryStream())
                            {
                                file.Export(ms);
                                ytyp.Load(ms);
                            }

                            dynamic entry = new JObject()
                            {
                                ["name"]          = fileNameWithoutExtension,
                                ["path"]          = fullFileName,
                                ["hash"]          = Jenkins.Hash(fileNameWithoutExtension),
                                ["mloArchetypes"] = new JArray(),
                            };

                            if (ytyp.CMapTypes.MloArchetypes != null)
                            {
                                for (int i = 0; i < ytyp.CMapTypes.MloArchetypes.Count; i++)
                                {
                                    var archetype = ytyp.CMapTypes.MloArchetypes[i];
                                    var mloEntry  = new JObject
                                    {
                                        ["name"]  = archetype.Name,
                                        ["rooms"] = new JArray(),
                                    };

                                    if (archetype.Rooms != null)
                                    {
                                        for (int j = 0; j < archetype.Rooms.Count; j++)
                                        {
                                            var room      = archetype.Rooms[j];
                                            var roomEntry = new JObject
                                            {
                                                ["name"]  = room.Name,
                                                ["bbMin"] = new JObject()
                                                {
                                                    ["x"] = room.BbMin.X,
                                                    ["y"] = room.BbMin.Y,
                                                    ["z"] = room.BbMin.Z,
                                                },
                                                ["bbMax"] = new JObject()
                                                {
                                                    ["x"] = room.BbMax.X,
                                                    ["y"] = room.BbMax.Y,
                                                    ["z"] = room.BbMax.Z,
                                                }
                                            };

                                            ((JArray)mloEntry["rooms"]).Add(roomEntry);
                                        }
                                    }

                                    entry["mloArchetypes"].Add(mloEntry);
                                }
                            }

                            cache["ytyp"].Add(entry);
                        }
                    }
                    catch (Exception e)
                    {
                        Console.WriteLine(e.Message);
                    }
                });

                var jsonString = JsonConvert.SerializeObject(cache, new JsonSerializerSettings()
                {
                    Formatting = Newtonsoft.Json.Formatting.None
                });

                File.WriteAllText(AssemblyDirectory + "\\cache.json", jsonString);
            });
        }
 public uint Jenkins_binary_hash()
 {
     return(Jenkins.Hash(testBinary));
 }
Пример #20
0
        public static JObject Deamon_GetDrawableJSON(GtaDrawable drawable, string drawablePath)
        {
            Console.WriteLine("Requested drawable : " + drawable.Name.Value);

            var txds = Deamon_LoadExternalTextures(drawablePath);

            var data = new JObject()
            {
                ["shaderGroup"] = new JObject()
                {
                    ["shaders"]  = new JArray(),
                    ["textures"] = new JArray()
                },
                ["models"] = new JObject()
                {
                    ["high"]    = new JArray(),
                    ["medium"]  = new JArray(),
                    ["low"]     = new JArray(),
                    ["verylow"] = new JArray(),
                    ["x"]       = new JArray(),
                }
            };

            var jShaders  = (JArray)data["shaderGroup"]["shaders"];
            var jTextures = (JArray)data["shaderGroup"]["textures"];

            for (int i = 0; i < drawable.ShaderGroup.Shaders.Count; i++)
            {
                var shader = drawable.ShaderGroup.Shaders[i];

                var jShader = new JObject()
                {
                    ["textures"] = new JObject()
                };

                for (int j = 0; j < shader.ParametersList.Parameters.Count; j++)
                {
                    var param = shader.ParametersList.Parameters[j];

                    if (param.Data is TextureDX11)
                    {
                        var tx     = param.Data as TextureDX11;
                        var txName = tx.Name.Value.ToLowerInvariant();

                        switch (param.Unknown_1h)
                        {
                        case 0: jShader["textures"]["diffuse"] = txName; break;

                        case 2: jShader["textures"]["specular"] = txName; break;

                        case 3: jShader["textures"]["bump"] = txName; break;
                        }
                    }
                    else if (param.Data is Texture)
                    {
                        var txName = (param.Data as Texture).Name.Value.ToLowerInvariant();

                        for (int k = 0; k < txds.Length; k++)
                        {
                            var txd = txds[k];

                            for (int l = 0; l < txd.TextureDictionary.Textures.Entries.Count; l++)
                            {
                                var tx      = txd.TextureDictionary.Textures.Entries[l];
                                var txName2 = tx.Name.Value.ToLowerInvariant();

                                if (txName == txName2)
                                {
                                    switch (param.Unknown_1h)
                                    {
                                    case 0: jShader["textures"]["diffuse"] = txName; break;

                                    case 2: jShader["textures"]["specular"] = txName; break;

                                    case 3: jShader["textures"]["bump"] = txName; break;
                                    }

                                    break;
                                }
                            }
                        }
                    }
                }

                jShaders.Add(jShader);
            }

            for (int i = 0; i < txds.Length; i++)
            {
                var txd = txds[i];

                for (int j = 0; j < txd.TextureDictionary.Textures.Entries.Count; j++)
                {
                    var tx        = txd.TextureDictionary.Textures.Entries[j];
                    var txWrapper = new TextureWrapper_GTA5_pc(tx);
                    var txName    = tx.Name.Value.ToLowerInvariant();
                    var path      = Path.GetTempPath() + "\\gtautil_texture_" + txName + ".dds";

                    for (int m = 0; m < jShaders.Count; m++)
                    {
                        var jShader = (JObject)jShaders[m];

                        if ((string)jShader["textures"]["diffuse"] == txName || (string)jShader["textures"]["specular"] == txName || (string)jShader["textures"]["bump"] == txName)
                        {
                            Console.WriteLine("Reusing external texture " + txName);

                            DDSIO.SaveTextureData(txWrapper, path);

                            Utils.Hash(txName);

                            var jTx        = new JObject();
                            var txNameHash = Jenkins.Hash(txName);

                            jTx["hash"]   = txNameHash;
                            jTx["name"]   = txName;
                            jTx["path"]   = path;
                            jTx["width"]  = tx.Width;
                            jTx["height"] = tx.Height;

                            jTextures.Add(jTx);
                        }
                    }
                }
            }

            for (int i = 0; i < drawable.ShaderGroup.TextureDictionary.Textures.Entries.Count; i++)
            {
                var tx        = drawable.ShaderGroup.TextureDictionary.Textures.Entries[i];
                var txWrapper = new TextureWrapper_GTA5_pc(tx);
                var txName    = tx.Name.Value.ToLowerInvariant();
                var path      = Path.GetTempPath() + "\\gtautil_texture_" + txName + ".dds";

                DDSIO.SaveTextureData(txWrapper, path);

                Utils.Hash(txName);

                var jTx        = new JObject();
                var txNameHash = drawable.ShaderGroup.TextureDictionary.TextureNameHashes.Entries[i].Value;

                jTx["hash"]   = txNameHash;
                jTx["name"]   = txName;
                jTx["path"]   = path;
                jTx["width"]  = tx.Width;
                jTx["height"] = tx.Height;

                jTextures.Add(jTx);
            }

            for (int i = 0; i < drawable.DrawableModelsHigh.Entries.Count; i++)
            {
                var jModel = Deamon_GetModelData(drawable.DrawableModelsHigh?.Entries[i]);
                ((JArray)data["models"]["high"]).Add(jModel);
            }

            for (int i = 0; i < drawable.DrawableModelsMedium?.Entries.Count; i++)
            {
                var jModel = Deamon_GetModelData(drawable.DrawableModelsMedium.Entries[i]);
                ((JArray)data["models"]["medium"]).Add(jModel);
            }

            for (int i = 0; i < drawable.DrawableModelsLow?.Entries.Count; i++)
            {
                var jModel = Deamon_GetModelData(drawable.DrawableModelsLow.Entries[i]);
                ((JArray)data["models"]["low"]).Add(jModel);
            }

            for (int i = 0; i < drawable.DrawableModelsVeryLow?.Entries.Count; i++)
            {
                var jModel = Deamon_GetModelData(drawable.DrawableModelsVeryLow.Entries[i]);
                ((JArray)data["models"]["verylow"]).Add(jModel);
            }

            for (int i = 0; i < drawable.DrawableModelsX?.Entries.Count; i++)
            {
                var jModel = Deamon_GetModelData(drawable.DrawableModelsX.Entries[i]);
                ((JArray)data["models"]["x"]).Add(jModel);
            }

            return(data);
        }
Пример #21
0
        static void HandleCompileDrawableShadersOptions(string[] args)
        {
            CommandLine.Parse <CompileDrawableShadersOptions>(args, (opts, gOpts) =>
            {
                EnsurePath();
                EnsureKeys();

                var shaderNames             = new Dictionary <uint, string>();
                var shaderParameterSetNames = new Dictionary <uint, string>();
                var fxcShaders = new Dictionary <uint, FxcFile>();

                ArchiveUtilities.ForEachBinaryFile(Settings.Default.GTAFolder, (fullFileName, binaryFile, encryption) =>
                {
                    if (fullFileName.EndsWith(".fxc"))
                    {
                        string nameLower = binaryFile.Name.ToLowerInvariant().Replace(".fxc", "");
                        var hash         = Jenkins.Hash(nameLower);

                        if (!shaderNames.ContainsKey(hash))
                        {
                            shaderNames.Add(hash, nameLower);
                        }

                        byte[] data = Utils.GetBinaryFileData((IArchiveBinaryFile)binaryFile, encryption);
                        var fxc     = new FxcFile();

                        fxc.Load(data, nameLower);

                        if (!fxcShaders.ContainsKey(hash))
                        {
                            fxcShaders.Add(hash, fxc);
                        }
                    }
                    else if (fullFileName.EndsWith(".sps"))
                    {
                        string nameLower = binaryFile.Name.ToLowerInvariant();
                        var hash         = Jenkins.Hash(nameLower);

                        if (!shaderParameterSetNames.ContainsKey(hash))
                        {
                            shaderParameterSetNames.Add(hash, nameLower);
                        }
                    }
                });

                ArchiveUtilities.ForEachResourceFile(Settings.Default.GTAFolder, (fullFileName, resourceFile, encryption) =>
                {
                    if (fullFileName.EndsWith(".ydr"))
                    {
                        var ms = new MemoryStream();

                        resourceFile.Export(ms);

                        var ydr = new YdrFile();

                        ydr.Load(ms);

                        Console.WriteLine(fullFileName.Replace(Settings.Default.GTAFolder, ""));

                        CompileDrawableShaders_ProcessDrawable(ydr.Drawable, shaderNames, fxcShaders);

                        Console.WriteLine("");
                    }
                    else if (fullFileName.EndsWith(".ydd"))
                    {
                        var ms = new MemoryStream();

                        resourceFile.Export(ms);

                        var ydd = new YddFile();

                        ydd.Load(ms);

                        Console.WriteLine(fullFileName.Replace(Settings.Default.GTAFolder, ""));

                        var drawables = ydd.DrawableDictionary.Drawables;

                        for (int d = 0; d < drawables.Count; d++)
                        {
                            var drawable = drawables[d];

                            Console.WriteLine("  " + drawable.Name.Value);

                            CompileDrawableShaders_ProcessDrawable(drawable, shaderNames, fxcShaders);
                        }

                        Console.WriteLine("");
                    }
                });
            });
        }
Пример #22
0
 public bool TryAdd(string data)
 {
     return(this.TryAdd(Jenkins.Hash(data), data));
 }
Пример #23
0
        static void HandleExtractEntitiesOptions(string[] args)
        {
            CommandLine.Parse <ExtractEntitiesOptions>(args, (opts, gOpts) =>
            {
                if (opts.Ytyp == null)
                {
                    Console.WriteLine("Please provide source ytyp file with --ytyp");
                    return;
                }

                if (opts.Position == null || opts.Position.Count() != 3)
                {
                    Console.WriteLine("Please provide a correct position ex: --position 120.5,1370.312,769.2");
                    return;
                }

                if (opts.Rotation == null || opts.Rotation.Count() != 4)
                {
                    Console.WriteLine("Plase provide a correct rotation ex: --rotation 0,0,0,1");
                    return;
                }

                if (opts.Name == null)
                {
                    Console.WriteLine("Plase output directory name with --name");
                    return;
                }

                Init(args);

                var position = new Vector3(opts.Position.ElementAt(0), opts.Position.ElementAt(1), opts.Position.ElementAt(2));
                var rotation = new Quaternion(opts.Rotation.ElementAt(0), opts.Rotation.ElementAt(1), opts.Rotation.ElementAt(2), opts.Rotation.ElementAt(3));

                var ytyp = new YtypFile();

                ytyp.Load(opts.Ytyp);

                if (!File.Exists(opts.Name + ".original.ytyp"))
                {
                    File.Copy(opts.Ytyp, opts.Name + ".original.ytyp");
                }

                MCMloArchetypeDef mlo = null;

                for (int i = 0; i < ytyp.CMapTypes.MloArchetypes.Count; i++)
                {
                    if (opts.MloName == null)
                    {
                        mlo = ytyp.CMapTypes.MloArchetypes[i];
                        break;
                    }
                    else
                    {
                        uint mloNameHash = Jenkins.Hash(opts.MloName.ToLowerInvariant());

                        if (mloNameHash == ytyp.CMapTypes.MloArchetypes[i].Name)
                        {
                            Console.Error.WriteLine("Found MLO => " + opts.MloName);
                            mlo = ytyp.CMapTypes.MloArchetypes[i];
                            break;
                        }
                    }
                }

                if (mlo == null)
                {
                    Console.WriteLine("MLO archetype not found");
                    return;
                }

                for (int roomId = 0; roomId < mlo.Rooms.Count; roomId++)
                {
                    var room         = mlo.Rooms[roomId];
                    var ymap         = new YmapFile();
                    var ymapEntities = new List <MCEntityDef>();

                    Console.WriteLine("Room => " + room.Name + " (" + room.AttachedObjects.Count + " entities)");

                    for (int i = 0; i < room.AttachedObjects.Count; i++)
                    {
                        int idx = (int)room.AttachedObjects[i];

                        if (idx >= mlo.Entities.Count)
                        {
                            continue;
                        }

                        var entity         = mlo.Entities[idx];
                        var entityRotation = new Quaternion(entity.Rotation.X, entity.Rotation.Y, entity.Rotation.Z, entity.Rotation.W);

                        Utils.Mlo2World(entity, mlo, position, rotation);

                        entity.LodLevel = Unk_1264241711.LODTYPES_DEPTH_HD;

                        if (entity.Guid == 0)
                        {
                            var random = new Random();

                            do
                            {
                                entity.Guid = (uint)random.Next(1000000, Int32.MaxValue);
                            }while (mlo.Entities.Count(e => e.Guid == entity.Guid) == 1);

                            Console.WriteLine("[" + i + "] Setting random GUID => " + entity.Guid);
                        }

                        ymapEntities.Add(entity);
                    }

                    ymap.CMapData.Entities = ymapEntities;

                    var extents = Utils.CalcExtents(ymap.CMapData.Entities);

                    ymap.CMapData.EntitiesExtentsMin  = extents[0][0];
                    ymap.CMapData.EntitiesExtentsMax  = extents[0][1];
                    ymap.CMapData.StreamingExtentsMin = extents[1][0];
                    ymap.CMapData.StreamingExtentsMax = extents[1][1];

                    Console.WriteLine(extents[0][0].X + " " + extents[0][0].Y + " " + extents[0][0].Z);
                    Console.WriteLine(extents[0][1].X + " " + extents[0][1].Y + " " + extents[0][1].Z);

                    Directory.CreateDirectory(opts.Name);

                    ymap.Save(opts.Name + "\\" + room.Name + ".ymap");
                }

                if (mlo.EntitySets != null)
                {
                    for (int i = 0; i < mlo.EntitySets.Count; i++)
                    {
                        var entitySet = mlo.EntitySets[i];

                        Directory.CreateDirectory(opts.Name + "\\entitysets\\" + entitySet.Name);

                        for (int roomId = 0; roomId < mlo.Rooms.Count; roomId++)
                        {
                            var room         = mlo.Rooms[roomId];
                            var ymap         = new YmapFile();
                            var ymapEntities = new List <MCEntityDef>();

                            Console.WriteLine("EntitySet => " + entitySet.Name + " [" + room.Name + "] (" + entitySet.Entities.Count + " entities)");

                            for (int j = 0; j < entitySet.Entities.Count; j++)
                            {
                                int targetRoom = (int)entitySet.Locations[j];

                                if (targetRoom != roomId)
                                {
                                    continue;
                                }

                                var entity         = entitySet.Entities[j];
                                var entityRotation = new Quaternion(entity.Rotation.X, entity.Rotation.Y, entity.Rotation.Z, entity.Rotation.W);

                                Utils.Mlo2World(entity, mlo, position, rotation);

                                entity.LodLevel = Unk_1264241711.LODTYPES_DEPTH_HD;

                                if (entity.Guid == 0)
                                {
                                    var random = new Random();

                                    do
                                    {
                                        entity.Guid = (uint)random.Next(1000000, Int32.MaxValue);
                                    }while (mlo.Entities.Count(e => e.Guid == entity.Guid) == 1);

                                    Console.WriteLine("[" + i + "] Setting random GUID => " + entity.Guid);
                                }

                                ymapEntities.Add(entity);
                            }

                            ymap.CMapData.Entities = ymapEntities;

                            var extents = Utils.CalcExtents(ymap.CMapData.Entities);

                            ymap.CMapData.EntitiesExtentsMin  = extents[0][0];
                            ymap.CMapData.EntitiesExtentsMax  = extents[0][1];
                            ymap.CMapData.StreamingExtentsMin = extents[1][0];
                            ymap.CMapData.StreamingExtentsMax = extents[1][1];

                            Console.WriteLine(extents[0][0].X + " " + extents[0][0].Y + " " + extents[0][0].Z);
                            Console.WriteLine(extents[0][1].X + " " + extents[0][1].Y + " " + extents[0][1].Z);

                            ymap.Save(opts.Name + "\\entitysets\\" + entitySet.Name + "\\entityset_" + entitySet.Name + "_" + room.Name + ".ymap");
                        }
                    }
                }

                /*
                 * for(int portalId=0; portalId < mlo.Portals.Count; portalId++)
                 * {
                 *  var portal = mlo.Portals[portalId];
                 *  var ymap = new YmapFile();
                 *  var ymapEntities = new List<MCEntityDef>();
                 *  var entitiesExtents = new List<Tuple<Vector3, Vector3>>();
                 *  var streamingExtents = new List<Tuple<Vector3, Vector3>>();
                 *
                 *  Console.WriteLine("Portal => " + portalId + " (" + portal.AttachedObjects.Count + " entities)");
                 *
                 *  for (int i = 0; i < portal.AttachedObjects.Count; i++)
                 *  {
                 *      int idx = (int)portal.AttachedObjects[i];
                 *
                 *      if (idx >= mlo.Entities.Count)
                 *          continue;
                 *
                 *      var entity = mlo.Entities[idx];
                 *      var entityRotation = new Quaternion(entity.Rotation.X, entity.Rotation.Y, entity.Rotation.Z, entity.Rotation.W);
                 *
                 *      Utils.Mlo2World(entity, mlo, position, rotation);
                 *
                 *      entity.LodLevel = Unk_1264241711.LODTYPES_DEPTH_HD;
                 *
                 *      if (entity.Guid == 0)
                 *      {
                 *          var random = new Random();
                 *
                 *          do
                 *          {
                 *              entity.Guid = (uint)random.Next(1000000, Int32.MaxValue);
                 *          }
                 *          while (mlo.Entities.Count(e => e.Guid == entity.Guid) == 1);
                 *
                 *          Console.WriteLine("[" + i + "] Setting random GUID => " + entity.Guid);
                 *      }
                 *
                 *      ymapEntities.Add(entity);
                 *  }
                 *
                 *  ymap.CMapData.Entities = ymapEntities;
                 *
                 *  var extents = Utils.CalcExtents(ymap.CMapData.Entities);
                 *
                 *  ymap.CMapData.EntitiesExtentsMin = extents[0][0];
                 *  ymap.CMapData.EntitiesExtentsMax = extents[0][1];
                 *  ymap.CMapData.StreamingExtentsMin = extents[1][0];
                 *  ymap.CMapData.StreamingExtentsMax = extents[1][1];
                 *
                 *  Console.WriteLine(extents[0][0].X + " " + extents[0][0].Y + " " + extents[0][0].Z);
                 *  Console.WriteLine(extents[0][1].X + " " + extents[0][1].Y + " " + extents[0][1].Z);
                 *
                 *  Directory.CreateDirectory(opts.Name);
                 *
                 *  ymap.Save(opts.Name + "\\portal_" + portalId.ToString().PadLeft(3, '0') + ".ymap");
                 *
                 *  var data = new JObject()
                 *  {
                 *      ["corners"] = new JArray()
                 *      {
                 *          new JObject() { ["x"] = portal.Corners[0][0], ["y"] = portal.Corners[0][1], ["z"] = portal.Corners[0][2] },
                 *          new JObject() { ["x"] = portal.Corners[1][0], ["y"] = portal.Corners[1][1], ["z"] = portal.Corners[1][2] },
                 *          new JObject() { ["x"] = portal.Corners[2][0], ["y"] = portal.Corners[2][1], ["z"] = portal.Corners[2][2] },
                 *          new JObject() { ["x"] = portal.Corners[3][0], ["y"] = portal.Corners[3][1], ["z"] = portal.Corners[3][2] },
                 *      },
                 *      ["flags"] = portal.Flags,
                 *      ["mirrorPriority"] = portal.MirrorPriority,
                 *      ["opacity"] = portal.Opacity,
                 *      ["roomFrom"] = portal.RoomFrom,
                 *      ["roomTo"] = portal.RoomTo,
                 *  };
                 *
                 *  var jsonString = JsonConvert.SerializeObject(data, new JsonSerializerSettings() { Formatting = Newtonsoft.Json.Formatting.Indented });
                 *
                 *  File.WriteAllText(opts.Name + "\\portal_" + portalId.ToString().PadLeft(3, '0') + ".json", jsonString);
                 * }
                 */
            });
        }
Пример #24
0
        static void HandleInjectEntitiesOptions(string[] args)
        {
            CommandLine.Parse <InjectEntitiesOptions>(args, (opts, gOpts) =>
            {
                if (opts.Ymap == null)
                {
                    Console.WriteLine("Please provide source ymap file with --ymap");
                    return;
                }

                if (opts.Ytyp == null)
                {
                    Console.WriteLine("Please provide source ytyp file with --ytyp");
                    return;
                }

                if (opts.Position == null || opts.Position.Count() != 3)
                {
                    Console.WriteLine("Please provide a correct position ex: --position 120.5,1370.312,769.2");
                    return;
                }

                if (opts.Rotation == null || opts.Rotation.Count() != 4)
                {
                    Console.WriteLine("Plase provide a correct rotation ex: --rotation 0,0,0,1");
                    return;
                }

                if (opts.Name == null)
                {
                    Console.WriteLine("Plase provide new generated ytyp name with --name");
                    return;
                }

                Init(args);

                var ymapInfos = Utils.Expand(opts.Ymap);
                var ymapNames = ymapInfos.Select(e => Path.GetFileNameWithoutExtension(e.Name)).ToArray();

                var position = new Vector3(opts.Position.ElementAt(0), opts.Position.ElementAt(1), opts.Position.ElementAt(2));
                var rotation = new Quaternion(opts.Rotation.ElementAt(0), opts.Rotation.ElementAt(1), opts.Rotation.ElementAt(2), opts.Rotation.ElementAt(3));

                var ytyp = new YtypFile();

                ytyp.Load(opts.Ytyp);

                MCMloArchetypeDef mlo = null;

                for (int i = 0; i < ytyp.CMapTypes.MloArchetypes.Count; i++)
                {
                    if (opts.MloName == null)
                    {
                        mlo = ytyp.CMapTypes.MloArchetypes[i];
                        break;
                    }
                    else
                    {
                        uint mloNameHash = Jenkins.Hash(opts.MloName.ToLowerInvariant());

                        if (mloNameHash == ytyp.CMapTypes.MloArchetypes[i].Name)
                        {
                            Console.Error.WriteLine("Found MLO => " + opts.MloName);
                            mlo = ytyp.CMapTypes.MloArchetypes[i];
                            break;
                        }
                    }
                }

                if (mlo == null)
                {
                    Console.WriteLine("MLO archetype not found");
                    return;
                }

                var ymaps = new List <YmapFile>();

                for (int i = 0; i < ymapInfos.Length; i++)
                {
                    var ymap = new YmapFile();

                    ymap.Load(ymapInfos[i].FullName);

                    ymaps.Add(ymap);
                }

                var missingYmap  = new YmapFile();
                int missingCount = 0;

                Console.WriteLine("Calculating rooms extents");

                var roomExtents = new Vector3[mlo.Rooms.Count][];

                for (int i = 0; i < mlo.Rooms.Count; i++)
                {
                    var room     = mlo.Rooms[i];
                    var entities = new List <MCEntityDef>();

                    for (int j = 0; j < room.AttachedObjects.Count; j++)
                    {
                        int idx = (int)room.AttachedObjects[j];

                        if (idx >= mlo.Entities.Count)
                        {
                            continue;
                        }

                        entities.Add(mlo.Entities[idx]);
                    }

                    var extents = Utils.CalcExtents(entities);

                    roomExtents[i] = extents[0];
                }

                for (int i = 0; i < ymaps.Count; i++)
                {
                    var ymap = ymaps[i];
                    var name = ymapNames[i];

                    if (name.StartsWith("portal_") || name.StartsWith("entityset_"))
                    {
                        continue;
                    }

                    var roomIdx           = mlo.Rooms.FindIndex(e => e.Name == name);
                    MCMloRoomDef currRoom = null;

                    if (roomIdx != -1)
                    {
                        currRoom = mlo.Rooms[roomIdx];
                    }

                    for (int j = 0; j < ymap.CMapData.Entities.Count; j++)
                    {
                        var entity           = ymap.CMapData.Entities[j];
                        var idx              = mlo.Entities.FindIndex(e => e.Guid == entity.Guid);
                        var room             = currRoom;
                        var originalPosition = entity.Position;
                        var originalRotation = entity.Rotation;

                        Console.WriteLine(name + " => " + j + " (" + idx + "|" + mlo.Entities.Count + ") => " + Utils.HashString((MetaName)entity.ArchetypeName));

                        Utils.World2Mlo(entity, mlo, position, rotation);

                        if (opts.Static && idx == -1)
                        {
                            if ((entity.Flags & 32) == 0)
                            {
                                Console.WriteLine("  Setting static flag (32)");
                                entity.Flags = entity.Flags | 32;
                            }
                        }

                        entity.LodLevel = Unk_1264241711.LODTYPES_DEPTH_ORPHANHD;

                        if (entity.Guid == 0)
                        {
                            var random = new Random();

                            do
                            {
                                entity.Guid = (uint)random.Next(1000000, Int32.MaxValue);
                            }while (mlo.Entities.Count(e => e.Guid == entity.Guid) > 0);

                            Console.WriteLine("  Setting random GUID => " + entity.Guid);
                        }

                        if (idx == -1)
                        {
                            idx = mlo.AddEntity(entity);
                        }
                        else
                        {
                            Console.WriteLine("  Found matching GUID => Overriding " + idx);
                            mlo.Entities[idx] = entity;
                        }


                        Console.WriteLine(j + " " + Utils.HashString((MetaName)entity.ArchetypeName));

                        if (room == null)
                        {
                            room = GetRoomForEntity(mlo, roomExtents, entity);
                        }

                        if (room == null)
                        {
                            entity.Position = originalPosition;
                            entity.Rotation = originalRotation;
                            entity.LodLevel = Unk_1264241711.LODTYPES_DEPTH_HD;

                            missingYmap.CMapData.Entities.Add(entity);

                            missingCount++;

                            continue;
                        }

                        uint id = (uint)idx;

                        if (room.AttachedObjects.IndexOf(id) == -1)
                        {
                            room.AttachedObjects.Add(id);
                        }

                        Console.WriteLine("  Room => " + room.Name);
                    }
                }

                if (opts.DeleteMissing)
                {
                    for (int i = mlo.Entities.Count - 1; i >= 0; i--)
                    {
                        bool found = false;

                        for (int j = 0; j < ymaps.Count; j++)
                        {
                            var ymap = ymaps[j];

                            if (ymap.CMapData.Entities.FindIndex(e => e.Guid == mlo.Entities[i].Guid) != -1)
                            {
                                found = true;
                                break;
                            }
                        }

                        if (!found)
                        {
                            Console.WriteLine("DELETE " + i);

                            for (int j = 0; j < mlo.Rooms.Count; j++)
                            {
                                for (int k = mlo.Rooms[j].AttachedObjects.Count - 1; k >= 0; k--)
                                {
                                    if (mlo.Rooms[j].AttachedObjects[k] == (uint)i)
                                    {
                                        mlo.Rooms[j].AttachedObjects.RemoveAt(k);
                                    }
                                }
                            }
                        }
                    }
                }

                var foundEntities = new Dictionary <uint, List <MCEntityDef> >();

                for (int i = 0; i < ymaps.Count; i++)
                {
                    var ymap = ymaps[i];
                    var name = ymapNames[i];

                    if (!name.StartsWith("entityset_"))
                    {
                        continue;
                    }

                    string[] split  = name.Split('_');
                    uint nameHash   = uint.Parse(split[1]);
                    string roomName = split[2];

                    if (!foundEntities.TryGetValue(nameHash, out List <MCEntityDef> fEntities))
                    {
                        fEntities = new List <MCEntityDef>();
                    }

                    int entitySetIdx = mlo.EntitySets.FindIndex(e => e.Name == nameHash);
                    int roomIdx      = mlo.Rooms.FindIndex(e => e.Name == roomName);

                    MCMloEntitySet currEntitySet = null;

                    if (entitySetIdx != -1)
                    {
                        currEntitySet = mlo.EntitySets[entitySetIdx];
                    }

                    for (int j = 0; j < ymap.CMapData.Entities.Count; j++)
                    {
                        var entity           = ymap.CMapData.Entities[j];
                        var idx              = currEntitySet.Entities.FindIndex(e => e.Guid == entity.Guid);
                        var entitySet        = currEntitySet;
                        var originalPosition = entity.Position;
                        var originalRotation = entity.Rotation;

                        Console.WriteLine(name + " => " + j + " (" + idx + "|" + currEntitySet.Entities.Count + ") => " + Utils.HashString((MetaName)entity.ArchetypeName));

                        Utils.World2Mlo(entity, mlo, position, rotation);

                        if (opts.Static && idx == -1)
                        {
                            if ((entity.Flags & 32) == 0)
                            {
                                Console.WriteLine("  Setting static flag (32)");
                                entity.Flags = entity.Flags | 32;
                            }
                        }

                        entity.LodLevel = Unk_1264241711.LODTYPES_DEPTH_ORPHANHD;

                        if (entity.Guid == 0)
                        {
                            var random = new Random();

                            do
                            {
                                entity.Guid = (uint)random.Next(1000000, Int32.MaxValue);
                            }while (currEntitySet.Entities.Count(e => e.Guid == entity.Guid) > 0);

                            Console.WriteLine("  Setting random GUID => " + entity.Guid);
                        }

                        if (idx == -1)
                        {
                            idx = currEntitySet.AddEntity(entity, roomIdx);
                        }
                        else
                        {
                            Console.WriteLine("  Found matching GUID => Overriding " + idx);
                            currEntitySet.Entities[idx] = entity;
                        }


                        Console.WriteLine(j + " " + Utils.HashString((MetaName)entity.ArchetypeName));

                        fEntities.Add(entity);
                    }

                    foundEntities[nameHash] = fEntities;
                }

                if (opts.DeleteMissing)
                {
                    foreach (var entry in foundEntities)
                    {
                        var entitySet = mlo.EntitySets.Find(e => e.Name == entry.Key);

                        for (int i = entitySet.Entities.Count - 1; i >= 0; i--)
                        {
                            bool found = false;

                            if (entry.Value.FindIndex(e => e.Guid == entitySet.Entities[i].Guid) != -1)
                            {
                                found = true;
                            }

                            if (!found)
                            {
                                Console.WriteLine("DELETE " + i);
                                entitySet.RemoveEntity(entitySet.Entities[i]);
                            }
                        }
                    }
                }

                ytyp.Save(opts.Name + ".ytyp");

                if (missingCount > 0)
                {
                    var extents = Utils.CalcExtents(missingYmap.CMapData.Entities);

                    missingYmap.CMapData.EntitiesExtentsMin  = extents[0][0];
                    missingYmap.CMapData.EntitiesExtentsMax  = extents[0][1];
                    missingYmap.CMapData.StreamingExtentsMin = extents[1][0];
                    missingYmap.CMapData.StreamingExtentsMax = extents[1][1];

                    missingYmap.Save(opts.Name + "_exterior.ymap");
                }
            });
        }
Пример #25
0
        static void HandleGenPropDefsOptions(string[] args)
        {
            CommandLine.Parse <GenPropDefsOptions>(args, (opts, gOpts) =>
            {
                if (opts.InputFiles != null)
                {
                    var inputFiles = Utils.Expand(opts.InputFiles);
                    var ytyp       = new YtypFile();

                    if (opts.Ytyp != null)
                    {
                        var inputYtyps = Utils.Expand(opts.Ytyp);

                        for (int i = 0; i < inputYtyps.Length; i++)
                        {
                            var ytyp2 = new YtypFile();
                            ytyp2.Load(inputYtyps[i].FullName);

                            for (int j = 0; j < ytyp2.CMapTypes.Archetypes.Count; j++)
                            {
                                var archetype = ytyp2.CMapTypes.Archetypes[j];

                                if (Archetypes.TryGetValue(archetype.Name, out MCBaseArchetypeDef arch))
                                {
                                    Archetypes[archetype.Name] = archetype;
                                }
                                else
                                {
                                    Archetypes.Add(archetype.Name, archetype);
                                }
                            }
                        }
                    }

                    for (int i = 0; i < inputFiles.Length; i++)
                    {
                        var fileInfo = inputFiles[i];

                        string name = "";
                        var split   = fileInfo.Name.Split('.');

                        for (int j = 0; j < split.Length; j++)
                        {
                            if (j < split.Length - 1)
                            {
                                if (j > 0)
                                {
                                    name += ".";
                                }

                                name += split[j];
                            }
                        }

                        Console.WriteLine(name);

                        try
                        {
                            switch (fileInfo.Extension)
                            {
                            case ".ydr":
                                {
                                    var nameHash = (MetaName)Jenkins.Hash(name);

                                    var ydr = new YdrFile();
                                    ydr.Load(fileInfo.FullName);

                                    if (Archetypes.TryGetValue(nameHash, out MCBaseArchetypeDef arch))
                                    {
                                        arch.BbMin    = (Vector3)(Vector4)ydr.Drawable.BoundingBoxMin;
                                        arch.BbMax    = (Vector3)(Vector4)ydr.Drawable.BoundingBoxMax;
                                        arch.BsCentre = (Vector3)ydr.Drawable.BoundingCenter;
                                        arch.BsRadius = ydr.Drawable.BoundingSphereRadius;
                                    }
                                    else
                                    {
                                        arch = new MCBaseArchetypeDef();

                                        arch.Name              = nameHash;
                                        arch.AssetName         = nameHash;
                                        arch.TextureDictionary = nameHash;
                                        arch.PhysicsDictionary = (MetaName)Jenkins.Hash("prop_" + name);
                                        arch.Flags             = 32;
                                        arch.AssetType         = Unk_1991964615.ASSET_TYPE_DRAWABLE;
                                        arch.BbMin             = (Vector3)(Vector4)ydr.Drawable.BoundingBoxMin;
                                        arch.BbMax             = (Vector3)(Vector4)ydr.Drawable.BoundingBoxMax;
                                        arch.BsCentre          = (Vector3)ydr.Drawable.BoundingCenter;
                                        arch.BsRadius          = ydr.Drawable.BoundingSphereRadius;
                                        arch.LodDist           = 500f;
                                        arch.HdTextureDist     = 5;
                                    }

                                    ytyp.CMapTypes.Archetypes.Add(arch);

                                    break;
                                }

                            case ".ydd":     // TODO
                                {
                                    break;
                                }

                            default: break;
                            }
                        }
                        catch (Exception e)
                        {
                            Console.Error.WriteLine("ERROR => " + e.Message);
                        }
                    }

                    string path = (opts.OutputDirectory == null) ? @".\props.ytyp" : opts.OutputDirectory + @"\props.ytyp";

                    ytyp.Save(path);
                }
            });
        }