예제 #1
0
        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"));
        }
예제 #2
0
        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);
        }