private static void LoadGMDKeys(ref cGMD gmd) { gmd.gKeys?.Clear(); gmd.gKeys = new Dictionary <string, int>(gmd.gkeysCount); char[] chars = Kernel.ReadStructure <char>(gmd.gKeysBaseAddress, gmd.gKeysChunkSize); StringBuilder sb = new StringBuilder(); int idx = 0; for (int i = 0; i < chars.Length; i++) { if (chars[i] != '\x00') { sb.Append(chars[i]); } else { gmd.gKeys.Add(sb.ToString(), idx); idx++; sb.Clear(); continue; } } }
/// <summary> /// Gets raw string from a GMD file /// </summary> /// <param name="gmd">the GMD that will be searched for</param> /// <param name="idx">Index in the value</param> /// <returns>Raw string read from memory</returns> public static string GetRawValueString(cGMD gmd, int idx) { if (idx >= gmd.gValuesOffsets.Length || idx < 0) { return("Unknown"); } if (idx >= gmd.gValuesOffsets.Length || idx < 0) { return(""); } long length; if ((idx + 1) >= gmd.gValuesOffsets.Length) { length = gmd.gValuesChunkSize - gmd.gValuesOffsets[idx]; } else { length = gmd.gValuesOffsets[idx + 1] - gmd.gValuesOffsets[idx]; } long stringAddress = gmd.gValuesBaseAddress + gmd.gValuesOffsets[idx]; return(Kernel.ReadString(stringAddress, (int)length)); }
private static bool LoadGMD(ref cGMD gmd, long addr) { if (addr == Kernel.NULLPTR) { return(false); } long addrBase = Kernel.Read <long>(addr); // GMD Metadata | TODO: Turn this into a structure string gmdName = Kernel.ReadString(addr - 0xEC, 32); int nElements = Kernel.Read <int>(addr - 0x40); gmd.gValuesChunkSize = Kernel.Read <int>(addr - 0x10); gmd.gKeysChunkSize = Kernel.Read <int>(addr - 0x30); gmd.gKeysBaseAddress = Kernel.Read <long>(addr - 0x28); gmd.gkeysCount = Kernel.Read <int>(addr - 0x20); // An array of pointers to the strings, this way we can index each element without // calculating the string length first long[] gValueStringsPtrs = Kernel.ReadStructure <long>(addrBase, nElements); // Calculates the offset of each string, this way we can just get the string lenght // and also where they start gmd.gValuesOffsets = gValueStringsPtrs .Where(ptr => ((ptr & Address.GetAddress("BASE")) != Address.GetAddress("BASE"))) .Select(ptr => (int)(ptr - gValueStringsPtrs[0])) .ToArray(); gmd.gValuesBaseAddress = Kernel.Read <long>(addrBase); Debugger.Write($"[GMD] Indexed {gmdName} (Strings: {nElements} | Chunk Size: {gmd.gValuesChunkSize} Bytes)", "#FFC88DF2"); return(true); }