示例#1
0
        /// <summary>
        /// Convert to bytes.
        /// </summary>
        /// <returns>Bytes</returns>
        public byte[] ToBytes()
        {
            using (var memStream = new MemoryStream())
                using (var writer = new BeBinaryWriter(memStream))
                {
                    writer.WriteUInt32(this.Version);

                    // Version 0
                    writer.WriteBytes(this.Hash);
                    writer.WriteUInt32(this.Flags);

                    // Version 1
                    if (this.Version >= 1)
                    {
                        writer.WriteUInt32(this.InternalFlags);
                    }

                    // Version 3
                    if (this.Version >= 3)
                    {
                        writer.WriteUInt32(this.Speedups);
                        writer.WriteUInt32(this.Shorts);
                    }

                    return(memStream.ToArray());
                }
        }
示例#2
0
        /// <summary>
        /// Patch app file to map D-Pad directions. This assumes the app file is decompressed.
        /// </summary>
        /// <param name="config">D-Pad configuration</param>
        /// <param name="VCDir">VC directory</param>
        private static void PatchApp1(DPadConfig config, string VCDir)
        {
            using (var app1 = new BeBinaryWriter(File.OpenWrite(Path.Combine(VCDir, "00000001.app"))))
            {
                var used    = config.InUse;
                var buttons = new VCControllerButton[]
                {
                    VCControllerButton.DPadUp,
                    VCControllerButton.DPadDown,
                    VCControllerButton.DPadLeft,
                    VCControllerButton.DPadRight,
                };

                // Fix array for ordering of the fields in app file: Up, Down, Left, Right
                used = new bool[] { used[0], used[2], used[3], used[1] };

                for (int i = 0; i < used.Length; i++)
                {
                    int offset = DPAD_MAPPING_OFFSET + (i * 4);
                    app1.Seek(offset, SeekOrigin.Begin);

                    if (used[i])
                    {
                        // If using this D-Pad direction, write its button flag
                        app1.WriteUInt32((uint)buttons[i]);
                    }
                    else
                    {
                        // Otherwise write the button flag for the L button
                        app1.WriteUInt32((uint)VCControllerButton.L);
                    }
                }
            }
        }
示例#3
0
        /// <summary>
        /// Create patch data from current ROM state and write to <see cref="Stream"/>.
        /// </summary>
        /// <param name="outStream">Output stream.</param>
        /// <param name="originalMMFiles">Original <see cref="MMFile"/> collection.</param>
        /// <returns><see cref="SHA256"/> hash of the patch.</returns>
        public static byte[] CreatePatch(Stream outStream, List <MMFile> originalMMFiles)
        {
            var aes     = Aes.Create();
            var hashAlg = new SHA256Managed();

            using (var cryptoStream = new CryptoStream(outStream, aes.CreateEncryptor(key, iv), CryptoStreamMode.Write))
                using (var hashStream = new CryptoStream(cryptoStream, hashAlg, CryptoStreamMode.Write))
                    using (var compressStream = new GZipStream(hashStream, CompressionMode.Compress))
                        using (var writer = new BeBinaryWriter(compressStream))
                        {
                            // Write magic value.
                            writer.WriteUInt32(PatchMagic);

                            Span <byte> headerBytes = stackalloc byte[PatchHeader.Size];
                            for (var fileIndex = 0; fileIndex < RomData.MMFileList.Count; fileIndex++)
                            {
                                var file = RomData.MMFileList[fileIndex];

                                // Check whether file should be included in the patch.
                                if (file.Data == null || (file.IsCompressed && !file.WasEdited))
                                {
                                    continue;
                                }

                                if (fileIndex >= originalMMFiles.Count)
                                {
                                    var index   = (uint)fileIndex;
                                    var address = (uint)file.Addr;

                                    // Create header for appending new file.
                                    var header = PatchHeader.CreateNew(index, address, file.Data.Length, file.IsStatic);
                                    header.Write(headerBytes);

                                    // Write header bytes and file contents.
                                    writer.Write(headerBytes);
                                    writer.Write(file.Data);
                                }
                                else
                                {
                                    RomUtils.CheckCompressed(fileIndex, originalMMFiles);
                                    var originalFile = originalMMFiles[fileIndex];

                                    var index   = (uint)fileIndex;
                                    var address = (uint)file.Addr;
                                    var diff    = VcDiffEncodeManaged(originalFile.Data, file.Data);

                                    // Create header for patching existing file.
                                    var header = PatchHeader.CreateExisting(index, address, diff.Length, file.IsStatic);
                                    header.Write(headerBytes);

                                    // Write header bytes and diff bytes.
                                    writer.Write(headerBytes);
                                    writer.Write(diff);
                                }
                            }
                        }
            return(hashAlg.Hash);
        }
示例#4
0
        /// <summary>
        /// Convert to bytes.
        /// </summary>
        /// <returns>Bytes</returns>
        public byte[] ToBytes()
        {
            using (var memoryStream = new MemoryStream())
                using (var writer = new BeBinaryWriter(memoryStream))
                {
                    writer.WriteUInt32(this.Version);
                    writer.Write(this.SequenceMaskFileIndex ?? 0);

                    return(memoryStream.ToArray());
                }
        }
示例#5
0
        /// <summary>
        /// Convert to bytes.
        /// </summary>
        /// <returns>Bytes</returns>
        public byte[] ToBytes()
        {
            using (var memStream = new MemoryStream())
                using (var writer = new BeBinaryWriter(memStream))
                {
                    writer.WriteUInt32(this.Version);

                    foreach (var val in this.RupeeRepeatableLocations)
                    {
                        writer.WriteUInt16(val);
                    }

                    writer.WriteUInt16(RupeeRepeatableLocationsLength);

                    writer.WriteUInt16(this.LocationBottleRedPotion);
                    writer.WriteUInt16(this.LocationBottleGoldDust);
                    writer.WriteUInt16(this.LocationBottleMilk);
                    writer.WriteUInt16(this.LocationBottleChateau);

                    writer.WriteUInt16(this.LocationSwordKokiri);
                    writer.WriteUInt16(this.LocationSwordRazor);
                    writer.WriteUInt16(this.LocationSwordGilded);

                    writer.WriteUInt16(this.LocationMagicSmall);
                    writer.WriteUInt16(this.LocationMagicLarge);

                    writer.WriteUInt16(this.LocationWalletAdult);
                    writer.WriteUInt16(this.LocationWalletGiant);
                    writer.WriteUInt16(this.LocationWalletRoyal);

                    writer.WriteUInt16(this.LocationBombBagSmall);
                    writer.WriteUInt16(this.LocationBombBagBig);
                    writer.WriteUInt16(this.LocationBombBagBiggest);

                    writer.WriteUInt16(this.LocationQuiverSmall);
                    writer.WriteUInt16(this.LocationQuiverLarge);
                    writer.WriteUInt16(this.LocationQuiverLargest);

                    writer.WriteByte(this.ExtraStartingMaps);
                    writer.WriteByte(0); // padding
                    writer.WriteBytes(this.ExtraStartingItemIds);
                    writer.WriteUInt16(this.ExtraStartingItemIdsLength);
                    foreach (var val in this.ItemsToReturnIds)
                    {
                        writer.WriteUInt16(val);
                    }
                    writer.WriteUInt16(this.ItemsToReturnIdsLength);

                    return(memStream.ToArray());
                }
        }
示例#6
0
        /// <summary>
        /// Convert to bytes.
        /// </summary>
        /// <returns>Bytes</returns>
        public byte[] ToBytes()
        {
            using (var memStream = new MemoryStream())
                using (var writer = new BeBinaryWriter(memStream))
                {
                    writer.WriteUInt32(this.Version);

                    foreach (var color in this.Colors)
                    {
                        writer.WriteBytes(color.ToBytesRGB(0));
                    }
                    return(memStream.ToArray());
                }
        }
示例#7
0
        /// <summary>
        /// Convert to bytes.
        /// </summary>
        /// <returns>Bytes</returns>
        public byte[] ToBytes()
        {
            using (var memStream = new MemoryStream())
                using (var writer = new BeBinaryWriter(memStream))
                {
                    writer.WriteUInt32(this.Version);

                    // Version 0
                    writer.WriteBytes(this.Items);
                    writer.WriteByte(this.State);
                    writer.WriteByte(this.Display);

                    return(memStream.ToArray());
                }
        }