Exemplo n.º 1
0
 // Checksums
 protected override void setChecksums()
 {
     for (int i = 0; i < 14; i++)
     {
         byte[] chunk = Data.Skip(ABO + i * 0x1000).Take(chunkLength[BlockOrder[i]]).ToArray();
         ushort chk   = SaveUtil.check32(chunk);
         BitConverter.GetBytes(chk).CopyTo(Data, ABO + i * 0x1000 + 0xFF6);
     }
 }
Exemplo n.º 2
0
        public override string getBoxName(int box)
        {
            int offset = getBoxOffset(BoxCount);

            if (Version == GameVersion.HGSS)
            {
                offset += 0x8;
            }
            return(PKX.array2strG4(Data.Skip(offset + box * 0x28).Take(0x28).ToArray()));
        }
Exemplo n.º 3
0
        public override string getDaycareRNGSeed(int loc)
        {
            if (loc != 0)
                return null;
            if (Daycare < 0)
                return null;

            var data = Data.Skip(Daycare + 0x1DC).Take(DaycareSeedSize / 2).Reverse().ToArray();
            return BitConverter.ToString(data).Replace("-", "");
        }
Exemplo n.º 4
0
        public override string getDaycareRNGSeed(int loc)
        {
            if (Version != GameVersion.B2W2)
            {
                return(null);
            }
            var data = Data.Skip(Daycare + 0x1CC).Take(DaycareSeedSize / 2).Reverse().ToArray();

            return(BitConverter.ToString(data).Replace("-", ""));
        }
Exemplo n.º 5
0
 public WC6(byte[] data = null)
 {
     Data = (byte[])(data?.Clone() ?? new byte[Size]);
     if (Data.Length == SizeFull)
     {
         Data = Data.Skip(SizeFull - Size).ToArray();
         DateTime now = DateTime.Now;
         Year  = (uint)now.Year;
         Month = (uint)now.Month;
         Day   = (uint)now.Day;
     }
 }
Exemplo n.º 6
0
        public override string getDaycareRNGSeed(int loc)
        {
            int ofs = loc == 0 ? Daycare : Daycare2;

            if (ofs <= 0)
            {
                return(null);
            }

            var data = Data.Skip(Daycare + 0x1E8).Take(DaycareSeedSize / 2).Reverse().ToArray();

            return(BitConverter.ToString(data).Replace("-", ""));
        }
Exemplo n.º 7
0
        private WC7 getWC7(int index)
        {
            if (WondercardData < 0)
            {
                return(null);
            }
            if (index < 0 || index > GiftCountMax)
            {
                return(null);
            }

            return(new WC7(Data.Skip(WondercardData + index * WC7.Size).Take(WC7.Size).ToArray()));
        }
Exemplo n.º 8
0
        public override byte[] Write(bool DSV)
        {
            StrategyMemo.FinalData.CopyTo(Data, Memo);
            setChecksums();

            // Get updated save slot data
            byte[] digest = Data.Skip(Data.Length - 20).Take(20).ToArray();
            byte[] newSAV = EncryptColosseum(Data, digest);

            // Put save slot back in original save data
            byte[] newFile = (byte[])OriginalData.Clone();
            Array.Copy(newSAV, 0, newFile, SLOT_START + SaveIndex * SLOT_SIZE, newSAV.Length);
            return(Header.Concat(newFile).ToArray());
        }
Exemplo n.º 9
0
 protected override void setChecksums()
 {
     // Check for invalid block lengths
     if (Blocks.Length < 3) // arbitrary...
     {
         Console.WriteLine("Not enough blocks ({0}), aborting setChecksums", Blocks.Length);
         return;
     }
     // Apply checksums
     for (int i = 0; i < Blocks.Length; i++)
     {
         byte[] array = Data.Skip(Blocks[i].Offset).Take(Blocks[i].Length).ToArray();
         BitConverter.GetBytes(SaveUtil.ccitt16(array)).CopyTo(Data, BlockInfoOffset + 6 + i * 8);
     }
 }
Exemplo n.º 10
0
 protected override void setChecksums()
 {
     // Check for invalid block lengths
     if (Blocks.Length < 3) // arbitrary...
     {
         Console.WriteLine("Not enough blocks ({0}), aborting setChecksums", Blocks.Length);
         return;
     }
     // Apply checksums
     foreach (BlockInfo b in Blocks)
     {
         byte[] array = Data.Skip(b.Offset).Take(b.Length).ToArray();
         ushort chk   = SaveUtil.ccitt16(array);
         BitConverter.GetBytes(chk).CopyTo(Data, b.ChecksumOffset);
         BitConverter.GetBytes(chk).CopyTo(Data, b.ChecksumMirror);
     }
 }
Exemplo n.º 11
0
        public SAV3RSBox(byte[] data = null)
        {
            Data       = data == null ? new byte[SaveUtil.SIZE_G3BOX] : (byte[])data.Clone();
            BAK        = (byte[])Data.Clone();
            Exportable = !Data.SequenceEqual(new byte[Data.Length]);

            if (SaveUtil.getIsG3BOXSAV(Data) != GameVersion.RSBOX)
            {
                return;
            }

            Blocks = new RSBOX_Block[2 * BLOCK_COUNT];
            for (int i = 0; i < Blocks.Length; i++)
            {
                int offset = BLOCK_SIZE + i * BLOCK_SIZE;
                Blocks[i] = new RSBOX_Block(Data.Skip(offset).Take(BLOCK_SIZE).ToArray(), offset);
            }

            // Detect active save
            int[] SaveCounts = Blocks.Select(block => (int)block.SaveCount).ToArray();
            SaveCount = SaveCounts.Max();
            int ActiveSAV = Array.IndexOf(SaveCounts, SaveCount) / BLOCK_COUNT;

            Blocks = Blocks.Skip(ActiveSAV * BLOCK_COUNT).Take(BLOCK_COUNT).OrderBy(b => b.BlockNumber).ToArray();

            // Set up PC data buffer beyond end of save file.
            Box = Data.Length;
            Array.Resize(ref Data, Data.Length + SIZE_RESERVED); // More than enough empty space.

            // Copy block to the allocated location
            foreach (RSBOX_Block b in Blocks)
            {
                Array.Copy(b.Data, 0xC, Data, Box + b.BlockNumber * (BLOCK_SIZE - 0x10), b.Data.Length - 0x10);
            }

            Personal  = PersonalTable.RS;
            HeldItems = Legal.HeldItems_RS;

            if (!Exportable)
            {
                resetBoxes();
            }
        }
Exemplo n.º 12
0
        public override string getBoxName(int box)
        {
            // Tweaked for the 1-30/31-60 box showing
            string lo      = (30 * (box % 2) + 1).ToString("00");
            string hi      = (30 * (box % 2 + 1)).ToString("00");
            string boxName = $"[{lo}-{hi}] ";

            box = box / 2;

            int offset = Box + 0x1EC38 + 9 * box;

            if (Data[offset] == 0 || Data[offset] == 0xFF)
            {
                boxName += $"BOX {box + 1}";
            }
            boxName += PKX.getG3Str(Data.Skip(offset).Take(9).ToArray(), Japanese);

            return(boxName);
        }
Exemplo n.º 13
0
 public WC6(byte[] data = null)
 {
     Data = (byte[])(data?.Clone() ?? new byte[Size]);
     if (Data.Length == SizeFull)
     {
         if (Data[0x205] == 0)
         {
             Data = new byte[Data.Length]; // Invalidate
         }
         Data = Data.Skip(SizeFull - Size).ToArray();
         DateTime now = DateTime.Now;
         Year  = (uint)now.Year;
         Month = (uint)now.Month;
         Day   = (uint)now.Day;
     }
     if (Year < 2000)
     {
         Data = new byte[Data.Length]; // Invalidate
     }
 }
Exemplo n.º 14
0
        // Writeback Validity
        public override string MiscSaveChecks()
        {
            string r = "";
            byte[] FFFF = Enumerable.Repeat((byte)0xFF, 0x200).ToArray();
            for (int i = 0; i < Data.Length / 0x200; i++)
            {
                if (!FFFF.SequenceEqual(Data.Skip(i * 0x200).Take(0x200))) continue;
                r = $"0x200 chunk @ 0x{(i*0x200).ToString("X5")} is FF'd."
                    + Environment.NewLine + "Cyber will screw up (as of August 31st 2014)." + Environment.NewLine + Environment.NewLine;

                // Check to see if it is in the Pokedex
                if (i * 0x200 > PokeDex && i * 0x200 < PokeDex + 0x900)
                {
                    r += "Problem lies in the Pokedex. ";
                    if (i * 0x200 == PokeDex + 0x400)
                        r += "Remove a language flag for a species < 585, ie Petilil";
                }
                break;
            }
            return r;
        }
Exemplo n.º 15
0
        public SAV7(byte[] data = null)
        {
            Data       = data == null ? new byte[SaveUtil.SIZE_G7SM] : (byte[])data.Clone();
            BAK        = (byte[])Data.Clone();
            Exportable = !Data.SequenceEqual(new byte[Data.Length]);

            // Load Info
            getBlockInfo();
            getSAVOffsets();

            HeldItems = Legal.HeldItems_SM;
            Personal  = PersonalTable.SM;
            if (!Exportable)
            {
                resetBoxes();
            }

            var demo = new byte[0x4C4].SequenceEqual(Data.Skip(PCLayout).Take(0x4C4)); // up to Battle Box values

            if (demo || !Exportable)
            {
                PokeDex     = -1; // Disabled
                LockedSlots = new int[0];
            }
            else // Valid slot locking info present
            {
                int lockedCount = 0;
                for (int i = 0; i < LockedSlots.Length; i++)
                {
                    short val = BitConverter.ToInt16(Data, BattleBoxFlags + i * 2);
                    if (val >= 0)
                    {
                        LockedSlots[lockedCount++] = (BoxSlotCount * (val >> 8) + (val & 0xFF)) & 0xFFFF;
                    }
                }
                Array.Resize(ref LockedSlots, lockedCount);
            }
        }
Exemplo n.º 16
0
        // Writeback Validity
        public override string MiscSaveChecks()
        {
            var r = new StringBuilder();

            // MemeCrypto check
            if (RequiresMemeCrypto && !MemeCrypto.CanUseMemeCrypto())
            {
                r.AppendLine("Platform does not support required cryptography providers.");
                r.AppendLine("Checksum will be broken until the file is saved using an OS without FIPS compliance enabled or a newer OS.");
                r.AppendLine();
            }

            // FFFF checks
            byte[] FFFF = Enumerable.Repeat((byte)0xFF, 0x200).ToArray();
            for (int i = 0; i < Data.Length / 0x200; i++)
            {
                if (!FFFF.SequenceEqual(Data.Skip(i * 0x200).Take(0x200)))
                {
                    continue;
                }
                r.AppendLine($"0x200 chunk @ 0x{(i * 0x200).ToString("X5")} is FF'd.");
                r.AppendLine("Cyber will screw up (as of August 31st 2014).");
                r.AppendLine();

                // Check to see if it is in the Pokedex
                if (i * 0x200 > PokeDex && i * 0x200 < PokeDex + 0x900)
                {
                    r.Append("Problem lies in the Pokedex. ");
                    if (i * 0x200 == PokeDex + 0x400)
                    {
                        r.Append("Remove a language flag for a species < 585, ie Petilil");
                    }
                }
                break;
            }
            return(r.ToString());
        }
Exemplo n.º 17
0
        public SAV7(byte[] data = null)
        {
            Data       = data == null ? new byte[SaveUtil.SIZE_G7SM] : (byte[])data.Clone();
            BAK        = (byte[])Data.Clone();
            Exportable = !Data.SequenceEqual(new byte[Data.Length]);

            // Load Info
            getBlockInfo();
            getSAVOffsets();

            HeldItems = Legal.HeldItems_SM;
            Personal  = PersonalTable.SM;
            if (!Exportable)
            {
                resetBoxes();
            }

            var demo = new byte[0x4C4].SequenceEqual(Data.Skip(PCLayout).Take(0x4C4));

            if (demo)
            {
                PokeDex = -1; // Disabled
            }
        }
Exemplo n.º 18
0
        public SAV3XD(byte[] data = null)
        {
            Data       = data == null ? new byte[SaveUtil.SIZE_G3XD] : (byte[])data.Clone();
            BAK        = (byte[])Data.Clone();
            Exportable = !Data.SequenceEqual(new byte[Data.Length]);

            if (SaveUtil.getIsG3XDSAV(Data) != GameVersion.XD)
            {
                return;
            }

            OriginalData = (byte[])Data.Clone();

            // Scan all 3 save slots for the highest counter
            for (int i = 0; i < SLOT_COUNT; i++)
            {
                int slotOffset  = SLOT_START + i * SLOT_SIZE;
                int SaveCounter = BigEndian.ToInt32(Data, slotOffset + 4);
                if (SaveCounter <= SaveCount)
                {
                    continue;
                }

                SaveCount = SaveCounter;
                SaveIndex = i;
            }

            // Decrypt most recent save slot
            {
                byte[] slot       = new byte[SLOT_SIZE];
                int    slotOffset = SLOT_START + SaveIndex * SLOT_SIZE;
                Array.Copy(Data, slotOffset, slot, 0, slot.Length);

                ushort[] keys = new ushort[4];
                for (int i = 0; i < keys.Length; i++)
                {
                    keys[i] = BigEndian.ToUInt16(slot, 8 + i * 2);
                }

                // Decrypt Slot
                Data = SaveUtil.DecryptGC(slot, 0x00010, 0x27FD8, keys);
            }

            // Get Offset Info
            ushort[] subLength = new ushort[16];
            for (int i = 0; i < 16; i++)
            {
                subLength[i]  = BigEndian.ToUInt16(Data, 0x20 + 2 * i);
                subOffsets[i] = BigEndian.ToUInt16(Data, 0x40 + 4 * i) | BigEndian.ToUInt16(Data, 0x40 + 4 * i + 2) << 16;
            }
            // Offsets are displaced by the 0xA8 savedata region
            Trainer1 = subOffsets[1] + 0xA8;
            Party    = Trainer1 + 0x30;
            Box      = subOffsets[2] + 0xA8;
            Daycare  = subOffsets[4] + 0xA8;
            Memo     = subOffsets[5] + 0xA8;
            Shadow   = subOffsets[7] + 0xA8;
            // Purifier = subOffsets[14] + 0xA8;

            StrategyMemo = new StrategyMemo(Data, Memo, xd: true);
            ShadowInfo   = new ShadowInfoTableXD(Data.Skip(Shadow).Take(subLength[7]).ToArray());

            OFS_PouchHeldItem = Trainer1 + 0x4C8;
            OFS_PouchKeyItem  = Trainer1 + 0x540;
            OFS_PouchBalls    = Trainer1 + 0x5EC;
            OFS_PouchTMHM     = Trainer1 + 0x62C;
            OFS_PouchBerry    = Trainer1 + 0x72C;
            OFS_PouchCologne  = Trainer1 + 0x7E4;
            OFS_PouchDisc     = Trainer1 + 0x7F0;

            LegalItems    = Legal.Pouch_Items_XD;
            LegalKeyItems = Legal.Pouch_Key_XD;
            LegalBalls    = Legal.Pouch_Ball_RS;
            LegalTMHMs    = Legal.Pouch_TM_RS; // not HMs
            LegalBerries  = Legal.Pouch_Berries_RS;
            LegalCologne  = Legal.Pouch_Cologne_CXD;
            LegalDisc     = Legal.Pouch_Disc_XD;

            Personal  = PersonalTable.RS;
            HeldItems = Legal.HeldItems_XD;

            if (!Exportable)
            {
                resetBoxes();
            }

            // Since PartyCount is not stored in the save file,
            // Count up how many party slots are active.
            for (int i = 0; i < 6; i++)
            {
                if (getPartySlot(getPartyOffset(i)).Species != 0)
                {
                    PartyCount++;
                }
            }
        }
Exemplo n.º 19
0
        public override string getBoxName(int box)
        {
            int offset = getBoxOffset(BoxCount);

            return(PKX.getG3Str(Data.Skip(offset + box * 9).Take(9).ToArray(), Japanese));
        }
Exemplo n.º 20
0
 public override string getBoxName(int box)
 {
     return(PKX.getG1Str(Data.Skip(BoxNamesOffset + box * 9).Take(9).ToArray(), Japanese));
 }