コード例 #1
0
 public WZDataDirectoryCollection(string path, WZVariant variant, bool encrypted)
 {
     _files = Directory.GetFiles(path, "*.nx").ToImmutableDictionary(
         Path.GetFileNameWithoutExtension,
         d => new WZFile(d, variant, encrypted)
         );
 }
コード例 #2
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();
 }
コード例 #3
0
        private static byte[] GetWZKey(WZVariant version)
        {
            switch ((int)version)
            {
            case 0:
                return(GenerateKey(KMSIV, AESKey));

            case 1:
                return(GenerateKey(GMSIV, AESKey));

            case 2:
                return(new byte[0x10000]);

            default:
                throw new ArgumentException("Invalid WZ variant passed.", "version");
            }
        }
コード例 #4
0
ファイル: WZAES.cs プロジェクト: gxrald/reWZ
        private static byte[] GetWZKey(WZVariant version, int length)
        {
            length = (length & ~15) + ((length & 15) > 0 ? 16 : 0);
            switch ((int)version)
            {
            case 0:
                return(GenerateKey(KMSIV, AESKey, length));

            case 1:
                return(GenerateKey(GMSIV, AESKey, length));

            case 2:
                return(new byte[length]);

            default:
                throw new ArgumentException("Invalid WZ variant passed.", nameof(version));
            }
        }
コード例 #5
0
        private static void Main(string[] args)
        {
            #region Option parsing

            string    inWz = null, outPath = null;
            WZVariant wzVar      = (WZVariant)255;
            bool      initialEnc = true;
            OptionSet oSet       = new OptionSet {
                { "in=", "Path to input WZ; required.", a => inWz = a }, {
                    "out=", "Path to output NX; optional, defaults to <WZ file name>.nx in this directory",
                    a => outPath = a
                }, {
                    "wzv=", "WZ encryption key; required.",
                    a => wzVar = (WZVariant)Enum.Parse(typeof(WZVariant), a, true)
                },
                { "Ds|dumpsound", "Set to include sound properties in the NX file.", a => dumpSnd = true },
                { "Di|dumpimage", "Set to include canvas properties in the NX file.", a => dumpImg = true },
                { "wzn", "Set if the input WZ is not encrypted.", a => initialEnc = false }
            };
            oSet.Parse(args);

            if (inWz == null || wzVar == (WZVariant)255)
            {
                oSet.WriteOptionDescriptions(Console.Out);
                return;
            }
            if (outPath == null)
            {
                outPath = Path.GetFileNameWithoutExtension(inWz) + ".nx";
            }

            #endregion

            try {
                Run(inWz, outPath, wzVar, initialEnc);
            } catch (Exception e) {
                Console.WriteLine(e);
                Console.WriteLine("Exception; toggling /wzn and retrying.");
                initialEnc = !initialEnc;
                Run(inWz, outPath, wzVar, initialEnc);
            }
        }
コード例 #6
0
ファイル: WZAES.cs プロジェクト: jeremistadler/WzExporter
 internal WZAES(WZVariant version)
 {
     _wzKey         = GetWZKey(version);
     _asciiKey      = new byte[_wzKey.Length];
     _unicodeKey    = new byte[_wzKey.Length];
     _asciiEncKey   = new byte[_wzKey.Length];
     _unicodeEncKey = new byte[_wzKey.Length];
     unchecked {
         byte mask = 0xAA;
         for (int i = 0; i < _wzKey.Length; ++i, ++mask)
         {
             _asciiKey[i]    = mask;
             _asciiEncKey[i] = (byte)(_wzKey[i] ^ mask);
         }
         ushort umask = 0xAAAA;
         for (int i = 0; i < _wzKey.Length / 2; i += 2, ++umask)
         {
             _unicodeKey[i]        = (byte)(umask & 0xFF);
             _unicodeKey[i + 1]    = (byte)((umask & 0xFF00) >> 8);
             _unicodeEncKey[i]     = (byte)(_wzKey[i] ^ _unicodeKey[i]);
             _unicodeEncKey[i + 1] = (byte)(_wzKey[i + 1] ^ _unicodeKey[i + 1]);
         }
     }
 }
コード例 #7
0
ファイル: WZAES.cs プロジェクト: gxrald/reWZ
 internal WZAES(WZVariant version)
 {
     _version = version;
     GenerateKeys(0x10000);
 }
コード例 #8
0
ファイル: Program.cs プロジェクト: mspencer92/ms-wz2nx
        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!");
            }
        }
コード例 #9
0
ファイル: Program.cs プロジェクト: angelsl/MSIT
        private static void MainMain(string[] args)
        {
            #region getopt

            bool      printHelp   = false;
            string    aWzInPath   = null;
            bool      aWzNamesEnc = true;
            bool      aPngOutput  = false;
            WZVariant aWzVer      = (WZVariant)int.MinValue;
            string    aOutputPath = null;
            Color     aBgColor    = Color.Black;
            LoopType  aLoop       = LoopType.NoLoop;
            int       aPadding    = 10;
            // input, input-wzfile, input-wzpath, input-wzver, output, output-path, background-color, padding
            OptionSet set = new OptionSet();
            set.Add("iwzp=|input-wzpath=", "The path of the animation or image. Required", s => aWzInPath = s);
            set.Add("iwzv=|input-wzver=", "The WZ key to use when decoding the WZ. Required", s => aWzVer = (WZVariant)Enum.Parse(typeof(WZVariant), s));
            set.Add("iwzne|input-wz-names-not-encrypted", "Flag if WZ image names are not encrypted. ", s => aWzNamesEnc = false);
            set.Add("o=|of=|output-format=", "The method of output: (a)png or gif", s => {
                switch (s.ToLower())
                {
                case "png":
                    aPngOutput = true;
                    break;

                case "gif":
                    aPngOutput = false;
                    break;

                default:
                    throw new ArgumentException("output must be either png or gif");
                }
            });
            set.Add("op=|output-path=", "The path to write the output, (A)PNG or GIF, to", s => aOutputPath = s);
            set.Add("abg=|a-background-color=", "The background color of the animated output. Default is black. Ignored if there is no animation.", s => aBgColor        = Color.FromArgb(int.Parse(s)));
            set.Add("ap=|a-padding=", "The amount of padding in pixels to pad the animated output with. Default is 10. Ignored if there is no animation.", s => aPadding = int.Parse(s));
            set.Add("al=|a-looping=", "The method to loop multi-animations with. Default is NoLoop. Ignored if there is no animation.", s => aLoop = (LoopType)Enum.Parse(typeof(LoopType), s, true));
            set.Add("?|h|help", "Shows help", s => printHelp = true);
            set.Parse(args);

            #endregion

            #region check params

            printHelp |= aWzInPath == null || aWzVer == (WZVariant)int.MinValue || aOutputPath == null;
            if (printHelp)
            {
                PrintHelp(set);
                return;
            }

            #endregion

            string[]             wzpaths = aWzInPath.Split('*');
            List <List <Frame> > framess = new List <List <Frame> >();
            string newPath = null, cWzPath = null;
            WZFile wz = null;
            foreach (string[] split in wzpaths.Select(wzpath => wzpath.Split('?')))
            {
                string inPath;
                if (newPath != null && split.Length == 1)
                {
                    inPath = split[0];
                }
                else
                {
                    newPath = split[0];
                    inPath  = split[1];
                }
                if (cWzPath != newPath && wz != null)
                {
                    wz.Dispose();
                }

                #region wz parsing

                if (cWzPath != newPath)
                {
                    wz = new WZFile(newPath, aWzVer, aWzNamesEnc);
                }
                cWzPath = newPath;
                #endregion

                #region getting single image

                WZCanvasProperty wzcp = wz.ResolvePath(inPath).ResolveUOL() as WZCanvasProperty;
                if (wzcp != null)
                {
                    Bitmap b = wzcp.Value;
                    if (aPngOutput)
                    {
                        OutputMethods.OutputPNG(b, aOutputPath);
                    }
                    else
                    {
                        OutputMethods.OutputGIF(b, aOutputPath);
                    }
                    return;
                }

                #endregion

                try {
                    List <Frame> data = InputMethods.InputWz(wz, inPath);
                    if (data.Count > 0)
                    {
                        framess.Add(data);
                    }
                } catch (Exception e) {
                    Console.WriteLine("An error occured while retrieving frames. Check your arguments.");
                    Console.WriteLine(e);
                    throw;
                }
            }
            IEnumerable <Frame> final = OffsetAnimator.Process(new Rectangle(aPadding, aPadding, aPadding, aPadding), aBgColor, aLoop, framess.ToArray());
            framess.ForEach(f => f.ForEach(g => g.Image.Dispose()));
            if (aPngOutput)
#if APNG
            { OutputMethods.OutputAPNG(final, aOutputPath); }
            else
#else
            { Console.WriteLine("APNG output not supported in this version; outputting GIF."); }
#endif
            { OutputMethods.OutputAGIF(final, aOutputPath); }
        }
コード例 #10
0
ファイル: WZAES.cs プロジェクト: angelsl/ms-reWZ
 private static byte[] GetWZKey(WZVariant version, int length)
 {
     length = (length & ~15) + ((length & 15) > 0 ? 16 : 0);
     switch ((int) version) {
         case 0:
             return GenerateKey(KMSIV, AESKey, length);
         case 1:
             return GenerateKey(GMSIV, AESKey, length);
         case 2:
             return new byte[length];
         default:
             throw new ArgumentException("Invalid WZ variant passed.", nameof(version));
     }
 }
コード例 #11
0
ファイル: WZAES.cs プロジェクト: angelsl/ms-reWZ
 internal WZAES(WZVariant version)
 {
     _version = version;
     GenerateKeys(0x10000);
 }
コード例 #12
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!");
                    }
        }
コード例 #13
0
 public static void AddWZParser(this IServiceCollection c, string directory, WZVariant variant, bool encrypted)
 {
     c.AddSingleton <IDataDirectoryCollection>(new WZDataDirectoryCollection(directory, variant, encrypted));
 }