private static void UnpackStage() { var outputLocation = Path.Combine(Settings.Working, "STAGEDAT"); var source = Path.Combine(Settings.SourceUserFolder, "STAGEDAT.PDT.Original"); var file = StageDataFile.Read(source, outputLocation); SerializationHelper.Save(file, Path.Combine(Settings.Working, "STAGEDAT.PDT.xml")); }
public static StageDataFile Read(string path, string outputLocation) { var sd = new StageDataFile(); FileUtility.PrepareFolder(outputLocation); string combineKey = null; using (var fs = File.OpenRead(path)) { var raw = File.ReadAllBytes(path); sd.HashKey1 = fs.ReadInt32(); sd.HashKey2 = fs.ReadInt32(); sd.HashKey3 = fs.ReadInt32(); // +0xc 이놈은 뭔지모르겠다. 그냥 덮어써버린다. sd.Hash = new Hash(sd.HashKey1, sd.HashKey2, sd.HashKey3); var hash = sd.Hash; var header = fs.ReadBytes(20); DecryptionUtility.Decrypt(header, ref hash); sd.Unknown1 = BitConverter.ToUInt32(header, 0); sd.Unknown2 = BitConverter.ToUInt32(header, 4); sd.Unknown3 = BitConverter.ToUInt32(header, 8); sd.EntityCount = BitConverter.ToUInt16(header, 12); sd.LookupStart = BitConverter.ToInt32(header, 16); var listData = fs.ReadBytes(sd.EntityCount * ENTITY_ITEM_LENGTH); DecryptionUtility.Decrypt(listData, ref hash); Debug.Assert(fs.Position == sd.LookupStart); var lookupData = fs.ReadBytes(sd.EntityCount * LOOKUP_ITEM_LENGTH); DecryptionUtility.Decrypt(lookupData, ref hash); sd.Entities = new List <Entity>(); sd.LookupList = new List <LookupBlock>(); for (int i = 0; i < sd.EntityCount; i++) { var offset = i * ENTITY_ITEM_LENGTH; var entity = new Entity { Size = BitConverter.ToUInt32(listData, offset), Hash = BitConverter.ToUInt32(listData, offset + 4), Position = BitConverter.ToUInt32(listData, offset + 8), }; sd.Entities.Add(entity); offset = i * LOOKUP_ITEM_LENGTH; var lookup = new LookupBlock { Key = BitConverter.ToUInt32(lookupData, offset), Index = BitConverter.ToUInt32(lookupData, offset + 4), Unknown1 = BitConverter.ToUInt32(lookupData, offset + 8), Unknown2 = BitConverter.ToUInt32(lookupData, offset + 12) }; sd.LookupList.Add(lookup); var decompressed = Decompress(sd.Hash, raw, (int)entity.Position, (int)entity.Size); if (BitConverter.ToInt32(decompressed, 0) == 0x636F6E2E) // '.noc'ache { using (var sr = new StringReader(Encoding.ASCII.GetString(decompressed))) { string line = null; while ((line = sr.ReadLine()) != null) { if (line.EndsWith(".rlc")) { combineKey = line.Remove(line.IndexOf('.')); } } } } entity.Extension = ResolveExtension(HashString(combineKey), (int)lookup.Key); entity.CombineKey = combineKey; var extension = entity.Extension == EntityExtensions.Unknown ? "" : entity.Extension.ToString(); var fileName = Path.Combine(outputLocation, string.Format("{0:X8}.{1}", entity.Hash, extension)); File.WriteAllBytes(fileName, decompressed); } } return(sd); }