Exemple #1
0
 /// <summary>Creates and loads a WZ file from a path. The Stream created will be disposed when the WZ file is disposed.</summary>
 /// <param name="path"> The path where the WZ file is located. </param>
 /// <param name="variant"> The variant of this WZ file. </param>
 /// <param name="encrypted"> Whether the WZ file is encrypted outside a WZ image. </param>
 /// <param name="flag"> WZ parsing flags. </param>
 public unsafe WZFile(string path, WZVariant variant, bool encrypted, WZReadSelection flag = WZReadSelection.None)
 {
     _variant   = variant;
     _encrypted = encrypted;
     _flag      = flag;
     _aes       = new WZAES(_variant);
     _bpo       = new MemoryMappedFile(path);
     _r         = new WZBinaryReader(_bpo.Pointer, _bpo.Length, _aes, 0);
     Parse();
 }
Exemple #2
0
        private static void Run(string inWz, string outPath, WZVariant wzVar, bool initialEnc)
        {
            Console.WriteLine("Input .wz: {0}{1}Output .nx: {2}", Path.GetFullPath(inWz),
                              Environment.NewLine, Path.GetFullPath(outPath));

            Stopwatch swOperation = new Stopwatch();
            Stopwatch fullTimer   = new Stopwatch();

            Action <string> reportDone = str => {
                Console.WriteLine("done. E{0} T{1}", swOperation.Elapsed,
                                  fullTimer.Elapsed);
                swOperation.Restart();
                Console.Write(str);
            };

            fullTimer.Start();
            swOperation.Start();
            Console.Write("Parsing input WZ... ".PadRight(31));

            WZReadSelection rFlags = WZReadSelection.EagerParseImage |
                                     WZReadSelection.EagerParseStrings;

            if (!dumpImg)
            {
                rFlags |= WZReadSelection.NeverParseCanvas;
            }

            using (WZFile wzf = new WZFile(inWz, wzVar, initialEnc, rFlags))
                using (
                    FileStream outFs = new FileStream(outPath, FileMode.Create, FileAccess.ReadWrite,
                                                      FileShare.None))
                    using (BinaryWriter bw = new BinaryWriter(outFs)) {
                        DumpState state = new DumpState();

                        reportDone("Writing header... ".PadRight(31));
                        bw.Write(PKG4);
                        bw.Write(new byte[(4 + 8) * 4]);

                        reportDone("Writing nodes... ".PadRight(31));
                        outFs.EnsureMultiple(4);
                        ulong           nodeOffset = (ulong)bw.BaseStream.Position;
                        List <WZObject> nodeLevel  = new List <WZObject> {
                            wzf.MainDirectory
                        };
                        while (nodeLevel.Count > 0)
                        {
                            WriteNodeLevel(ref nodeLevel, state, bw);
                        }

                        ulong stringOffset;
                        uint  stringCount = (uint)state.Strings.Count;
                        {
                            reportDone("Writing string data...".PadRight(31));
                            Dictionary <uint, string> strings = state.Strings.ToDictionary(kvp => kvp.Value,
                                                                                           kvp => kvp.Key);
                            ulong[] offsets = new ulong[stringCount];
                            for (uint idx = 0; idx < stringCount; ++idx)
                            {
                                outFs.EnsureMultiple(2);
                                offsets[idx] = (ulong)bw.BaseStream.Position;
                                WriteString(strings[idx], bw);
                            }

                            outFs.EnsureMultiple(8);
                            stringOffset = (ulong)bw.BaseStream.Position;
                            for (uint idx = 0; idx < stringCount; ++idx)
                            {
                                bw.Write(offsets[idx]);
                            }
                        }

                        ulong bitmapOffset = 0UL;
                        uint  bitmapCount  = 0U;
                        if (dumpImg)
                        {
                            reportDone("Writing canvas data...".PadRight(31));
                            bitmapCount = (uint)state.Canvases.Count;
                            ulong[] offsets = new ulong[bitmapCount];
                            long    cId     = 0;
                            foreach (WZCanvasProperty cNode in state.Canvases)
                            {
                                outFs.EnsureMultiple(8);
                                offsets[cId++] = (ulong)bw.BaseStream.Position;
                                WriteBitmap(cNode, bw);
                            }
                            outFs.EnsureMultiple(8);
                            bitmapOffset = (ulong)bw.BaseStream.Position;
                            for (uint idx = 0; idx < bitmapCount; ++idx)
                            {
                                bw.Write(offsets[idx]);
                            }
                        }

                        ulong soundOffset = 0UL;
                        uint  soundCount  = 0U;
                        if (dumpSnd)
                        {
                            reportDone("Writing MP3 data... ".PadRight(31));
                            soundCount = (uint)state.MP3s.Count;
                            ulong[] offsets = new ulong[soundCount];
                            long    cId     = 0;
                            foreach (WZAudioProperty mNode in state.MP3s)
                            {
                                outFs.EnsureMultiple(8);
                                offsets[cId++] = (ulong)bw.BaseStream.Position;
                                WriteMP3(mNode, bw);
                            }
                            outFs.EnsureMultiple(8);
                            soundOffset = (ulong)bw.BaseStream.Position;
                            for (uint idx = 0; idx < soundCount; ++idx)
                            {
                                bw.Write(offsets[idx]);
                            }
                        }

                        reportDone("Writing linked node data... ".PadRight(31));
                        byte[] uolReplace = new byte[16];
                        foreach (KeyValuePair <WZUOLProperty, Action <BinaryWriter, byte[]> > pair in state.UOLs)
                        {
                            WZObject result = pair.Key.FinalTarget;
                            if (result == null)
                            {
                                continue;
                            }
                            bw.BaseStream.Position = (long)(nodeOffset + state.GetNodeID(result) * 20 + 4);
                            bw.BaseStream.Read(uolReplace, 0, 16);
                            pair.Value(bw, uolReplace);
                        }

                        reportDone("Finalising... ".PadRight(31));

                        bw.Seek(4, SeekOrigin.Begin);
                        bw.Write((uint)state.Nodes.Count);
                        bw.Write(nodeOffset);
                        bw.Write(stringCount);
                        bw.Write(stringOffset);
                        bw.Write(bitmapCount);
                        bw.Write(bitmapOffset);
                        bw.Write(soundCount);
                        bw.Write(soundOffset);

                        reportDone("Completed!");
                    }
        }