Пример #1
0
        /// <summary>
        /// Creates an instance of <see cref="PKM"/> from the given data.
        /// </summary>
        /// <param name="data">Raw data of the Pokemon file.</param>
        /// <param name="prefer">Optional identifier for the preferred generation.  Usually the generation of the destination save file.</param>
        /// <returns>An instance of <see cref="PKM"/> created from the given <paramref name="data"/>, or null if <paramref name="data"/> is invalid.</returns>
        public static PKM?GetPKMfromBytes(byte[] data, int prefer = 7)
        {
            int format = GetPKMDataFormat(data);

            switch (format)
            {
            case 1:
                var list1 = new PokeList1(data);
                return(list1[0]);

            case 2:
                if (data.Length == PokeCrypto.SIZE_2STADIUM)
                {
                    return(new SK2(data));
                }

                var list2 = new PokeList2(data);
                return(list2[0]);

            case 3:
                return(data.Length switch
                {
                    PokeCrypto.SIZE_3CSTORED => new CK3(data),
                    PokeCrypto.SIZE_3XSTORED => new XK3(data),
                    _ => new PK3(data)
                });
Пример #2
0
        private const int SIZE_RESERVED = 0x8000; // unpacked box data

        protected override byte[] GetFinalData()
        {
            var capacity = Japanese ? PokeListType.StoredJP : PokeListType.Stored;

            for (int i = 0; i < BoxCount; i++)
            {
                var boxPL = new PokeList1(capacity, Japanese);
                int slot  = 0;
                for (int j = 0; j < boxPL.Pokemon.Length; j++)
                {
                    PK1 boxPK = (PK1)GetPKM(GetData(GetBoxOffset(i) + (j * SIZE_STORED), SIZE_STORED));
                    if (boxPK.Species > 0)
                    {
                        boxPL[slot++] = boxPK;
                    }
                }

                // copy to box location
                var boxdata = boxPL.Write();
                int ofs     = GetBoxRawDataOffset(i);
                SetData(boxdata, ofs);

                // copy to active loc if current box
                if (i == CurrentBox)
                {
                    SetData(boxdata, Offsets.CurrentBox);
                }
            }

            var partyPL = new PokeList1(PokeListType.Party, Japanese);
            int pSlot   = 0;

            for (int i = 0; i < 6; i++)
            {
                PK1 partyPK = (PK1)GetPKM(GetData(GetPartyOffset(i), SIZE_STORED));
                if (partyPK.Species > 0)
                {
                    partyPL[pSlot++] = partyPK;
                }
            }
            partyPL.Write().CopyTo(Data, Offsets.Party);

            // Daycare is read-only, but in case it ever becomes editable, copy it back in.
            byte[] rawDC = GetData(GetDaycareSlotOffset(loc: 0, slot: 0), SIZE_STORED);
            byte[] dc    = new byte[1 + (2 * StringLength) + PKX.SIZE_1STORED];
            dc[0] = rawDC[0];
            Array.Copy(rawDC, 2 + 1 + PKX.SIZE_1PARTY + StringLength, dc, 1, StringLength);
            Array.Copy(rawDC, 2 + 1 + PKX.SIZE_1PARTY, dc, 1 + StringLength, StringLength);
            Array.Copy(rawDC, 2 + 1, dc, 1 + (2 * StringLength), PKX.SIZE_1STORED);
            dc.CopyTo(Data, Offsets.Daycare);

            SetChecksums();
            byte[] outData = new byte[Data.Length - SIZE_RESERVED];
            Array.Copy(Data, outData, outData.Length);
            return(outData);
        }
Пример #3
0
        /// <summary>
        /// Creates an instance of <see cref="PKM"/> from the given data.
        /// </summary>
        /// <param name="data">Raw data of the Pokemon file.</param>
        /// <param name="ident">Optional identifier for the Pokemon.  Usually the full path of the source file.</param>
        /// <param name="prefer">Optional identifier for the preferred generation.  Usually the generation of the destination save file.</param>
        /// <returns>An instance of <see cref="PKM"/> created from the given <paramref name="data"/>, or null if <paramref name="data"/> is invalid.</returns>
        public static PKM GetPKMfromBytes(byte[] data, string ident = null, int prefer = 7)
        {
            int format = GetPKMDataFormat(data);

            switch (format)
            {
            case 1:
                var PL1 = new PokeList1(data);
                if (ident != null)
                {
                    PL1[0].Identifier = ident;
                }
                return(PL1[0]);

            case 2:
                var PL2 = new PokeList2(data);
                if (ident != null)
                {
                    PL2[0].Identifier = ident;
                }
                return(PL2[0]);

            case 3:
                switch (data.Length)
                {
                case PKX.SIZE_3CSTORED: return(new CK3(data, ident));

                case PKX.SIZE_3XSTORED: return(new XK3(data, ident));

                default: return(new PK3(data, ident));
                }

            case 4:
                var pk = new PK4(data, ident);
                if (!pk.Valid || pk.Sanity != 0)
                {
                    var bk = new BK4(data, ident);
                    if (bk.Valid)
                    {
                        return(bk);
                    }
                }
                return(pk);

            case 5:
                return(new PK5(data, ident));

            case 6:
                var pkx = new PK6(data, ident);
                return(CheckPKMFormat7(pkx, prefer));

            default:
                return(null);
            }
        }
Пример #4
0
        /// <summary>
        /// Creates an instance of <see cref="PKM"/> from the given data.
        /// </summary>
        /// <param name="data">Raw data of the Pokemon file.</param>
        /// <param name="prefer">Optional identifier for the preferred generation.  Usually the generation of the destination save file.</param>
        /// <returns>An instance of <see cref="PKM"/> created from the given <paramref name="data"/>, or null if <paramref name="data"/> is invalid.</returns>
        public static PKM?GetPKMfromBytes(byte[] data, int prefer = 7)
        {
            int format = GetPKMDataFormat(data);

            switch (format)
            {
            case 1:
                var PL1 = new PokeList1(data);
                return(PL1[0]);

            case 2:
                var PL2 = new PokeList2(data);
                return(PL2[0]);

            case 3:
                return(data.Length switch
                {
                    PokeCrypto.SIZE_3CSTORED => new CK3(data),
                    PokeCrypto.SIZE_3XSTORED => new XK3(data),
                    _ => new PK3(data)
                });
Пример #5
0
        private void Initialize(GameVersion versionOverride)
        {
            // see if RBY can be differentiated
            if (Starter != 0 && versionOverride != GameVersion.Any)
            {
                Version = Yellow ? GameVersion.YW : GameVersion.RB;
            }

            Box = Data.Length;
            Array.Resize(ref Data, Data.Length + SIZE_RESERVED);
            Party = GetPartyOffset(0);

            // Stash boxes after the save file's end.
            int stored   = SIZE_STOREDBOX;
            int baseDest = Data.Length - SIZE_RESERVED;
            var capacity = Japanese ? PokeListType.StoredJP : PokeListType.Stored;

            for (int i = 0; i < BoxCount; i++)
            {
                int ofs     = GetBoxRawDataOffset(i);
                var box     = GetData(ofs, stored);
                var boxDest = baseDest + (i * SIZE_BOX);
                var boxPL   = new PokeList1(box, capacity, Japanese);
                for (int j = 0; j < boxPL.Pokemon.Length; j++)
                {
                    var dest  = boxDest + (j * SIZE_STORED);
                    var pkDat = (j < boxPL.Count)
                        ? new PokeList1(boxPL[j]).Write()
                        : new byte[PokeList1.GetDataLength(PokeListType.Single, Japanese)];
                    pkDat.CopyTo(Data, dest);
                }
            }

            var current  = GetData(Offsets.CurrentBox, SIZE_STOREDBOX);
            var curBoxPL = new PokeList1(current, capacity, Japanese);

            for (int i = 0; i < curBoxPL.Pokemon.Length; i++)
            {
                var dest  = Data.Length - SIZE_RESERVED + (CurrentBox * SIZE_BOX) + (i * SIZE_STORED);
                var pkDat = i < curBoxPL.Count
                    ? new PokeList1(curBoxPL[i]).Write()
                    : new byte[PokeList1.GetDataLength(PokeListType.Single, Japanese)];
                pkDat.CopyTo(Data, dest);
            }

            var party   = GetData(Offsets.Party, SIZE_STOREDPARTY);
            var partyPL = new PokeList1(party, PokeListType.Party, Japanese);

            for (int i = 0; i < partyPL.Pokemon.Length; i++)
            {
                var dest  = GetPartyOffset(i);
                var pkDat = i < partyPL.Count
                    ? new PokeList1(partyPL[i]).Write()
                    : new byte[PokeList1.GetDataLength(PokeListType.Single, Japanese)];
                pkDat.CopyTo(Data, dest);
            }

            byte[] rawDC = new byte[0x38];
            Array.Copy(Data, Offsets.Daycare, rawDC, 0, rawDC.Length);
            byte[] TempDaycare = new byte[PokeList1.GetDataLength(PokeListType.Single, Japanese)];
            TempDaycare[0] = rawDC[0];
            Array.Copy(rawDC, 1, TempDaycare, 2 + 1 + PKX.SIZE_1PARTY + StringLength, StringLength);
            Array.Copy(rawDC, 1 + StringLength, TempDaycare, 2 + 1 + PKX.SIZE_1PARTY, StringLength);
            Array.Copy(rawDC, 1 + (2 * StringLength), TempDaycare, 2 + 1, PKX.SIZE_1STORED);
            PokeList1 daycareList = new PokeList1(TempDaycare, PokeListType.Single, Japanese);

            daycareList.Write().CopyTo(Data, GetPartyOffset(7));
            DaycareOffset = GetPartyOffset(7);

            EventFlag = Offsets.EventFlag;

            // Enable Pokedex editing
            PokeDex = 0;
        }
Пример #6
0
        public SAV1(byte[] data = null, GameVersion versionOverride = GameVersion.Any)
        {
            Data       = data ?? new byte[SaveUtil.SIZE_G1RAW];
            BAK        = (byte[])Data.Clone();
            Exportable = !IsRangeEmpty(0, Data.Length);

            if (versionOverride != GameVersion.Any)
            {
                Version = versionOverride;
            }
            else if (data == null)
            {
                Version = GameVersion.RBY;
            }
            else
            {
                Version = SaveUtil.GetIsG1SAV(Data);
            }
            if (Version == GameVersion.Invalid)
            {
                return;
            }

            Japanese = SaveUtil.GetIsG1SAVJ(Data);
            Offsets  = Japanese ? SAV1Offsets.JPN : SAV1Offsets.INT;

            // see if RBY can be differentiated
            if (Starter != 0 && versionOverride != GameVersion.Any)
            {
                Version = Yellow ? GameVersion.YW : GameVersion.RB;
            }

            Box = Data.Length;
            Array.Resize(ref Data, Data.Length + SIZE_RESERVED);
            Party = GetPartyOffset(0);

            Personal = Version == GameVersion.Y ? PersonalTable.Y : PersonalTable.RB;

            // Stash boxes after the save file's end.
            int stored   = SIZE_STOREDBOX;
            int baseDest = Data.Length - SIZE_RESERVED;
            var capacity = Japanese ? PokeListType.StoredJP : PokeListType.Stored;

            for (int i = 0; i < BoxCount; i++)
            {
                int ofs     = GetBoxRawDataOffset(i);
                var box     = GetData(ofs, stored);
                var boxDest = baseDest + (i * SIZE_BOX);
                var boxPL   = new PokeList1(box, capacity, Japanese);
                for (int j = 0; j < boxPL.Pokemon.Length; j++)
                {
                    var dest  = boxDest + (j * SIZE_STORED);
                    var pkDat = (j < boxPL.Count)
                        ? new PokeList1(boxPL[j]).Write()
                        : new byte[PokeList1.GetDataLength(PokeListType.Single, Japanese)];
                    pkDat.CopyTo(Data, dest);
                }
            }

            var current  = GetData(Offsets.CurrentBox, SIZE_STOREDBOX);
            var curBoxPL = new PokeList1(current, capacity, Japanese);

            for (int i = 0; i < curBoxPL.Pokemon.Length; i++)
            {
                var dest  = Data.Length - SIZE_RESERVED + (CurrentBox * SIZE_BOX) + (i * SIZE_STORED);
                var pkDat = i < curBoxPL.Count
                    ? new PokeList1(curBoxPL[i]).Write()
                    : new byte[PokeList1.GetDataLength(PokeListType.Single, Japanese)];
                pkDat.CopyTo(Data, dest);
            }

            var party   = GetData(Offsets.Party, SIZE_STOREDPARTY);
            var partyPL = new PokeList1(party, PokeListType.Party, Japanese);

            for (int i = 0; i < partyPL.Pokemon.Length; i++)
            {
                var dest  = GetPartyOffset(i);
                var pkDat = i < partyPL.Count
                    ? new PokeList1(partyPL[i]).Write()
                    : new byte[PokeList1.GetDataLength(PokeListType.Single, Japanese)];
                pkDat.CopyTo(Data, dest);
            }

            byte[] rawDC = new byte[0x38];
            Array.Copy(Data, Offsets.Daycare, rawDC, 0, rawDC.Length);
            byte[] TempDaycare = new byte[PokeList1.GetDataLength(PokeListType.Single, Japanese)];
            TempDaycare[0] = rawDC[0];
            Array.Copy(rawDC, 1, TempDaycare, 2 + 1 + PKX.SIZE_1PARTY + StringLength, StringLength);
            Array.Copy(rawDC, 1 + StringLength, TempDaycare, 2 + 1 + PKX.SIZE_1PARTY, StringLength);
            Array.Copy(rawDC, 1 + (2 * StringLength), TempDaycare, 2 + 1, PKX.SIZE_1STORED);
            PokeList1 daycareList = new PokeList1(TempDaycare, PokeListType.Single, Japanese);

            daycareList.Write().CopyTo(Data, GetPartyOffset(7));
            Daycare = GetPartyOffset(7);

            EventFlag = Offsets.EventFlag;

            // Enable Pokedex editing
            PokeDex = 0;

            if (!Exportable)
            {
                ClearBoxes();
            }
        }