private void Search(DateTime date, uint vcountMin, uint vcountMax,
                            uint timer0Min, uint timer0Max, uint vframeMin, uint vframeMax, uint gxstatMin,
                            uint gxstatMax, bool minmaxgxstat, int secondsMin, int secondsMax, bool softreset,
                            Version version, Language language,
                            DSType dstype, bool memorylink, ulong macaddress, uint buttons, uint[] pattern)
        {
            var array = new uint[80];

            array[6] = (uint)(macaddress & 0xFFFF);
            if (softreset)
            {
                array[6] = array[6] ^ 0x01000000;
            }
            Array.Copy(Nazos.Nazo(version, language, dstype), array, 5);

            array[10] = 0x00000000;
            array[11] = 0x00000000;
            array[13] = 0x80000000;
            array[14] = 0x00000000;
            array[15] = 0x000001A0;

            array[12] = buttons;

            string yearMonth  = String.Format("{0:00}", date.Year % 2000) + String.Format("{0:00}", date.Month);
            string dateString = String.Format("{0:00}", (int)date.DayOfWeek);

            dateString = String.Format("{0:00}", date.Day) + dateString;
            dateString = yearMonth + dateString;
            array[8]   = uint.Parse(dateString, NumberStyles.HexNumber);
            array[9]   = 0x0;
            //uint[] alpha = Functions.alphaSHA1(array, 8);

            var upperMAC = (uint)(macaddress >> 16);

            for (uint vcount = vcountMin; vcount <= vcountMax; ++vcount)
            {
                for (uint timer0 = timer0Min; timer0 <= timer0Max; ++timer0)
                {
                    array[5] = (vcount << 16) + timer0;
                    array[5] = Functions.Reorder(array[5]);

                    for (uint vframe = vframeMin; vframe <= vframeMax; ++vframe)
                    {
                        for (uint gxstat = gxstatMin; gxstat <= gxstatMax; ++gxstat)
                        {
                            array[7] = (upperMAC ^ (vframe * 0x1000000) ^ gxstat);
                            uint[] alpha = Functions.alphaSHA1(array);

                            array[16] = Functions.RotateLeft(array[13] ^ array[8] ^ array[2] ^ array[0], 1);
                            array[18] = Functions.RotateLeft(array[15] ^ array[10] ^ array[4] ^ array[2], 1);
                            array[19] = Functions.RotateLeft(array[16] ^ array[11] ^ array[5] ^ array[3], 1);
                            array[21] = Functions.RotateLeft(array[18] ^ array[13] ^ array[7] ^ array[5], 1);
                            array[22] = Functions.RotateLeft(array[19] ^ array[14] ^ array[8] ^ array[6], 1);
                            array[24] = Functions.RotateLeft(array[21] ^ array[16] ^ array[10] ^ array[8], 1);
                            array[27] = Functions.RotateLeft(array[24] ^ array[19] ^ array[13] ^ array[11], 1);

                            for (int second = secondsMin; second <= secondsMax; ++second)
                            {
                                array[9] = Functions.seedSecond(second) | Functions.seedMinute(date.Minute) |
                                           Functions.seedHour(date.Hour, dstype);
                                ulong seed = Functions.EncryptSeed(array, alpha, 9);
                                // it appears to have the same initial seed as in the main game
                                // pressing Unova link does the same probability table calls
                                uint initial = Functions.initialPIDRNG(seed, version, memorylink);
                                var  rng     = new BWRng(seed);
                                for (uint i = 0; i < initial; ++i)
                                {
                                    rng.GetNext64BitNumber();
                                }
                                bool found = true;
                                for (uint i = 0; i < pattern.Length; ++i)
                                {
                                    if (pattern[i] != rng.GetNext32BitNumber(8))
                                    {
                                        found = false;
                                        break;
                                    }
                                    // there's another RNG call here unreleated to the spinner
                                    rng.GetNext64BitNumber();
                                }
                                progressSearched++;
                                if (found)
                                {
                                    var parameter = new DSParameterCapture
                                    {
                                        ActualSeconds = second,
                                        GxStat        = gxstat,
                                        Seed          = seed,
                                        Timer0        = timer0,
                                        VCount        = vcount,
                                        VFrame        = vframe
                                    };
                                    dsParameters.Add(parameter);
                                    refreshQueue = true;
                                    progressFound++;
                                }
                            }


                            if (minmaxgxstat && gxstatMax > gxstatMin)
                            {
                                gxstat = gxstatMax - 1;
                            }
                        }
                    }
                }
            }
        }
示例#2
0
        private void GenerateSearchJob(DateTime testTime, int[] minIVs, int[] maxIVs,
                                       uint VCountMin, uint VCountMax, uint Timer0Min, uint Timer0Max,
                                       uint GxStatMin, uint GxStatMax, uint VFrameMin, uint VFrameMax,
                                       int secondsMin, int secondsMax, Version version, Language language, DSType dstype,
                                       int[] button,
                                       bool softReset, bool roamer, bool minMaxGxStat)
        {
            // offset the start by 2 for BW2
            int offset = version == Version.Black2 || version == Version.White2 ? 2 : 0;
            uint buttonMashed = Functions.buttonMashed(button);

            var array = new uint[80];
            uint[] h = {0x67452301, 0xEFCDAB89, 0x98BADCFE, 0x10325476, 0xC3D2E1F0};

            array[6] = (uint) (MAC_address & 0xFFFF);
            if (softReset)
            {
                array[6] = array[6] ^ 0x01000000;
            }
            var upperMAC = (uint) (MAC_address >> 16);

            // Get the version-unique part of the message
            Array.Copy(Nazos.Nazo(version, language, dstype), array, 5);

            array[10] = 0x00000000;
            array[11] = 0x00000000;
            array[12] = buttonMashed;
            array[13] = 0x80000000;
            array[14] = 0x00000000;
            array[15] = 0x000001A0;

            array[8] = Functions.seedDate(testTime);
            var GxStatList = new List<uint> {GxStatMin};

            // build the GxStat ranges
            if (GxStatMin != GxStatMax)
                if (!minMaxGxStat)
                    GxStatList.Add(GxStatMax);
                else
                    for (uint i = GxStatMin + 1; i <= GxStatMax; ++i)
                        GxStatList.Add(i);

            for (int cntSeconds = secondsMin; cntSeconds <= secondsMax; cntSeconds++)
            {
                array[9] = Functions.seedTime(testTime, dstype);

                for (uint cntVCount = VCountMin; cntVCount <= VCountMax; cntVCount++)
                {
                    for (uint cntTimer0 = Timer0Min; cntTimer0 <= Timer0Max; cntTimer0++)
                    {
                        array[5] = cntVCount*0x10000 + cntTimer0;
                        array[5] = Functions.Reorder(array[5]);
                        foreach (uint GxStat in GxStatList)
                        {
                            for (uint cntVFrame = VFrameMin; cntVFrame <= VFrameMax; cntVFrame++)
                            {
                                uint a = h[0];
                                uint b = h[1];
                                uint c = h[2];
                                uint d = h[3];
                                uint e = h[4];
                                uint f = 0;
                                uint k = 0;

                                array[7] = (upperMAC ^ (cntVFrame*0x1000000) ^ GxStat);

                                for (int i = 0; i < 80; i++)
                                {
                                    if (i < 20)
                                    {
                                        f = (b & c) | ((~b) & d);
                                        k = 0x5A827999;
                                    }
                                    if (i < 40 && i >= 20)
                                    {
                                        f = b ^ c ^ d;
                                        k = 0x6ED9EBA1;
                                    }
                                    if (i < 60 && i >= 40)
                                    {
                                        f = (b & c) | (b & d) | (c & d);
                                        k = 0x8F1BBCDC;
                                    }
                                    if (i >= 60)
                                    {
                                        f = b ^ c ^ d;
                                        k = 0xCA62C1D6;
                                    }

                                    if (i > 15)
                                    {
                                        array[i] =
                                            Functions.RotateLeft(
                                                array[i - 3] ^ array[i - 8] ^ array[i - 14] ^ array[i - 16], 1);
                                    }

                                    uint temp = Functions.RotateLeft(a, 5) + f + e + k + array[i];
                                    e = d;
                                    d = c;
                                    c = Functions.RotateRight(b, 2);
                                    b = a;
                                    a = temp;
                                }

                                uint part1 = Functions.Reorder(h[0] + a);
                                uint part2 = Functions.Reorder(h[1] + b);

                                ulong seed2 = (ulong) part1*0x6C078965;
                                uint seed1 = part2*0x6C078965 + (uint) (seed2 >> 32);
                                seed1 = seed1 + (part1*0x5D588B65);
                                seed2 = (uint) (seed2 & 0xFFFFFFFF) + 0x269EC3;

                                ulong seed = (ulong) (seed1*0x100000000) + seed2;
                                var tempSeed = (uint) (seed >> 32);

                                progressSearched++;
                                if (!findDirectSeed)
                                {
                                    var IVArray = new int[6];
                                    MersenneTwisterFast mt;
                                    if (roamer)
                                    {
                                        mt = new MersenneTwisterFast(tempSeed, 7);
                                        mt.Nextuint();
                                        IVArray[0] = (int) (mt.Nextuint() >> 27);
                                        IVArray[1] = (int) (mt.Nextuint() >> 27);
                                        IVArray[2] = (int) (mt.Nextuint() >> 27);
                                        IVArray[4] = (int) (mt.Nextuint() >> 27);
                                        IVArray[5] = (int) (mt.Nextuint() >> 27);
                                        IVArray[3] = (int) (mt.Nextuint() >> 27);
                                    }
                                    else
                                    {
                                        //advance for BW2
                                        mt = new MersenneTwisterFast(tempSeed, 6 + offset);
                                        for (int i = 0; i < offset; ++i) mt.Nextuint();

                                        IVArray[0] = (int) (mt.Nextuint() >> 27);
                                        IVArray[1] = (int) (mt.Nextuint() >> 27);
                                        IVArray[2] = (int) (mt.Nextuint() >> 27);
                                        IVArray[3] = (int) (mt.Nextuint() >> 27);
                                        IVArray[4] = (int) (mt.Nextuint() >> 27);
                                        IVArray[5] = (int) (mt.Nextuint() >> 27);
                                    }
                                    if ((IVArray[0] >= minIVs[0] && IVArray[0] <= maxIVs[0]) &&
                                        (IVArray[1] >= minIVs[1] && IVArray[1] <= maxIVs[1]) &&
                                        (IVArray[2] >= minIVs[2] && IVArray[2] <= maxIVs[2]) &&
                                        (IVArray[3] >= minIVs[3] && IVArray[3] <= maxIVs[3]) &&
                                        (IVArray[4] >= minIVs[4] && IVArray[4] <= maxIVs[4]) &&
                                        (IVArray[5] >= minIVs[5] && IVArray[5] <= maxIVs[5]))
                                    {
                                        var dsParameterFound =
                                            new DSParameterCapture
                                                {
                                                    ActualSeconds = testTime.Second,
                                                    VCount = cntVCount,
                                                    Timer0 = cntTimer0,
                                                    GxStat = GxStat,
                                                    VFrame = cntVFrame,
                                                    Seed = seed
                                                };
                                        dsParameters.Add(dsParameterFound);
                                        refreshQueue = true;
                                        progressFound++;
                                    }
                                }
                                else
                                {
                                    if (checkBoxHalfSeed.Checked)
                                    {
                                        if (tempSeed == (int) directSeed)
                                        {
                                            var dsParameterFound =
                                                new DSParameterCapture
                                                    {
                                                        ActualSeconds = testTime.Second,
                                                        VCount = cntVCount,
                                                        Timer0 = cntTimer0,
                                                        GxStat = GxStat,
                                                        VFrame = cntVFrame,
                                                        Seed = seed
                                                    };
                                            dsParameters.Add(dsParameterFound);
                                            refreshQueue = true;
                                            progressFound++;
                                        }
                                    }
                                    else
                                    {
                                        if (seed == directSeed)
                                        {
                                            var dsParameterFound =
                                                new DSParameterCapture
                                                    {
                                                        ActualSeconds = testTime.Second,
                                                        VCount = cntVCount,
                                                        Timer0 = cntTimer0,
                                                        GxStat = GxStat,
                                                        VFrame = cntVFrame,
                                                        Seed = seed
                                                    };
                                            dsParameters.Add(dsParameterFound);
                                            refreshQueue = true;
                                            progressFound++;
                                        }
                                    }
                                }
                            }
                        }
                    }
                }
                testTime = testTime.AddSeconds(1);
            }
        }
示例#3
0
        private void GenerateSearchJob(DateTime testTime, int[] minIVs, int[] maxIVs,
                                       uint VCountMin, uint VCountMax, uint Timer0Min, uint Timer0Max,
                                       uint GxStatMin, uint GxStatMax, uint VFrameMin, uint VFrameMax,
                                       int secondsMin, int secondsMax, Version version, Language language, DSType dstype,
                                       int[] button,
                                       bool softReset, bool roamer, bool minMaxGxStat)
        {
            // offset the start by 2 for BW2
            int  offset       = version == Version.Black2 || version == Version.White2 ? 2 : 0;
            uint buttonMashed = Functions.buttonMashed(button);

            var array = new uint[80];

            uint[] h = { 0x67452301, 0xEFCDAB89, 0x98BADCFE, 0x10325476, 0xC3D2E1F0 };

            array[6] = (uint)(MAC_address & 0xFFFF);
            if (softReset)
            {
                array[6] = array[6] ^ 0x01000000;
            }
            var upperMAC = (uint)(MAC_address >> 16);

            // Get the version-unique part of the message
            Array.Copy(Nazos.Nazo(version, language, dstype), array, 5);

            array[10] = 0x00000000;
            array[11] = 0x00000000;
            array[12] = buttonMashed;
            array[13] = 0x80000000;
            array[14] = 0x00000000;
            array[15] = 0x000001A0;


            array[8] = Functions.seedDate(testTime);
            var GxStatList = new List <uint> {
                GxStatMin
            };

            // build the GxStat ranges
            if (GxStatMin != GxStatMax)
            {
                if (!minMaxGxStat)
                {
                    GxStatList.Add(GxStatMax);
                }
                else
                {
                    for (uint i = GxStatMin + 1; i <= GxStatMax; ++i)
                    {
                        GxStatList.Add(i);
                    }
                }
            }

            for (int cntSeconds = secondsMin; cntSeconds <= secondsMax; cntSeconds++)
            {
                array[9] = Functions.seedTime(testTime, dstype);

                for (uint cntVCount = VCountMin; cntVCount <= VCountMax; cntVCount++)
                {
                    for (uint cntTimer0 = Timer0Min; cntTimer0 <= Timer0Max; cntTimer0++)
                    {
                        array[5] = cntVCount * 0x10000 + cntTimer0;
                        array[5] = Functions.Reorder(array[5]);
                        foreach (uint GxStat in GxStatList)
                        {
                            for (uint cntVFrame = VFrameMin; cntVFrame <= VFrameMax; cntVFrame++)
                            {
                                uint a = h[0];
                                uint b = h[1];
                                uint c = h[2];
                                uint d = h[3];
                                uint e = h[4];
                                uint f = 0;
                                uint k = 0;

                                array[7] = (upperMAC ^ (cntVFrame * 0x1000000) ^ GxStat);

                                for (int i = 0; i < 80; i++)
                                {
                                    if (i < 20)
                                    {
                                        f = (b & c) | ((~b) & d);
                                        k = 0x5A827999;
                                    }
                                    if (i < 40 && i >= 20)
                                    {
                                        f = b ^ c ^ d;
                                        k = 0x6ED9EBA1;
                                    }
                                    if (i < 60 && i >= 40)
                                    {
                                        f = (b & c) | (b & d) | (c & d);
                                        k = 0x8F1BBCDC;
                                    }
                                    if (i >= 60)
                                    {
                                        f = b ^ c ^ d;
                                        k = 0xCA62C1D6;
                                    }

                                    if (i > 15)
                                    {
                                        array[i] =
                                            Functions.RotateLeft(
                                                array[i - 3] ^ array[i - 8] ^ array[i - 14] ^ array[i - 16], 1);
                                    }

                                    uint temp = Functions.RotateLeft(a, 5) + f + e + k + array[i];
                                    e = d;
                                    d = c;
                                    c = Functions.RotateRight(b, 2);
                                    b = a;
                                    a = temp;
                                }

                                uint part1 = Functions.Reorder(h[0] + a);
                                uint part2 = Functions.Reorder(h[1] + b);

                                ulong seed2 = (ulong)part1 * 0x6C078965;
                                uint  seed1 = part2 * 0x6C078965 + (uint)(seed2 >> 32);
                                seed1 = seed1 + (part1 * 0x5D588B65);
                                seed2 = (uint)(seed2 & 0xFFFFFFFF) + 0x269EC3;

                                ulong seed     = (ulong)(seed1 * 0x100000000) + seed2;
                                var   tempSeed = (uint)(seed >> 32);

                                progressSearched++;
                                if (!findDirectSeed)
                                {
                                    var IVArray = new int[6];
                                    MersenneTwisterFast mt;
                                    if (roamer)
                                    {
                                        mt = new MersenneTwisterFast(tempSeed, 7);
                                        mt.Nextuint();
                                        IVArray[0] = (int)(mt.Nextuint() >> 27);
                                        IVArray[1] = (int)(mt.Nextuint() >> 27);
                                        IVArray[2] = (int)(mt.Nextuint() >> 27);
                                        IVArray[4] = (int)(mt.Nextuint() >> 27);
                                        IVArray[5] = (int)(mt.Nextuint() >> 27);
                                        IVArray[3] = (int)(mt.Nextuint() >> 27);
                                    }
                                    else
                                    {
                                        //advance for BW2
                                        mt = new MersenneTwisterFast(tempSeed, 6 + offset);
                                        for (int i = 0; i < offset; ++i)
                                        {
                                            mt.Nextuint();
                                        }

                                        IVArray[0] = (int)(mt.Nextuint() >> 27);
                                        IVArray[1] = (int)(mt.Nextuint() >> 27);
                                        IVArray[2] = (int)(mt.Nextuint() >> 27);
                                        IVArray[3] = (int)(mt.Nextuint() >> 27);
                                        IVArray[4] = (int)(mt.Nextuint() >> 27);
                                        IVArray[5] = (int)(mt.Nextuint() >> 27);
                                    }
                                    if ((IVArray[0] >= minIVs[0] && IVArray[0] <= maxIVs[0]) &&
                                        (IVArray[1] >= minIVs[1] && IVArray[1] <= maxIVs[1]) &&
                                        (IVArray[2] >= minIVs[2] && IVArray[2] <= maxIVs[2]) &&
                                        (IVArray[3] >= minIVs[3] && IVArray[3] <= maxIVs[3]) &&
                                        (IVArray[4] >= minIVs[4] && IVArray[4] <= maxIVs[4]) &&
                                        (IVArray[5] >= minIVs[5] && IVArray[5] <= maxIVs[5]))
                                    {
                                        var dsParameterFound =
                                            new DSParameterCapture
                                        {
                                            ActualSeconds = testTime.Second,
                                            VCount        = cntVCount,
                                            Timer0        = cntTimer0,
                                            GxStat        = GxStat,
                                            VFrame        = cntVFrame,
                                            Seed          = seed
                                        };
                                        dsParameters.Add(dsParameterFound);
                                        refreshQueue = true;
                                        progressFound++;
                                    }
                                }
                                else
                                {
                                    if (checkBoxHalfSeed.Checked)
                                    {
                                        if (tempSeed == (int)directSeed)
                                        {
                                            var dsParameterFound =
                                                new DSParameterCapture
                                            {
                                                ActualSeconds = testTime.Second,
                                                VCount        = cntVCount,
                                                Timer0        = cntTimer0,
                                                GxStat        = GxStat,
                                                VFrame        = cntVFrame,
                                                Seed          = seed
                                            };
                                            dsParameters.Add(dsParameterFound);
                                            refreshQueue = true;
                                            progressFound++;
                                        }
                                    }
                                    else
                                    {
                                        if (seed == directSeed)
                                        {
                                            var dsParameterFound =
                                                new DSParameterCapture
                                            {
                                                ActualSeconds = testTime.Second,
                                                VCount        = cntVCount,
                                                Timer0        = cntTimer0,
                                                GxStat        = GxStat,
                                                VFrame        = cntVFrame,
                                                Seed          = seed
                                            };
                                            dsParameters.Add(dsParameterFound);
                                            refreshQueue = true;
                                            progressFound++;
                                        }
                                    }
                                }
                            }
                        }
                    }
                }
                testTime = testTime.AddSeconds(1);
            }
        }
示例#4
0
        private void searchGenVHit(DateTime date, int hour, int minute, int minSec, int maxSec, int minframe,
                                   int maxframe, uint id, ulong mAC, Version version, Language language, DSType dstype,
                                   bool softReset,
                                   uint vCount, uint timer0, uint gxStat, uint vFrame)
        {
            var rng = new BWRng(0);
            int[] buttons = {0};

            isSearching = true;

            for (int sec = minSec; sec <= maxSec; sec++)
            {
                var dTime = new DateTime(date.Year, date.Month, date.Day, hour, minute, sec);

                for (int button = 0; button < 13; button++)
                {
                    buttons[0] = button;
                    ulong seed = Functions.EncryptSeed(dTime, mAC, version, language, dstype, softReset, vCount, timer0,
                                                       gxStat,
                                                       vFrame,
                                                       Functions.buttonMashed(buttons));

                    rng.Seed = seed;
                    ulong oSeed = seed;

                    for (int frame = 0; frame < minframe; frame++)
                    {
                        rng.Next();
                    }

                    for (int frame = minframe; frame <= maxframe; frame++)
                    {
                        rng.Next();
                        seed = rng.Seed;

                        var upper = (uint) (((seed >> 32)*0xFFFFFFFF) >> 32);
                        uint tid = (upper & 0xFFFF);
                        uint sid = (upper >> 16);

                        if (tid == id)
                        {
                            var iDSeed = new IDListBW
                                {
                                    Seed = oSeed,
                                    Date = dTime.ToShortDateString(),
                                    Time = dTime.ToString("HH:mm:ss"),
                                    Frame = frame,
                                    InitialFrame = (int) Functions.initialPIDRNG_ID(oSeed, false, version),
                                    ID = tid,
                                    SID = sid,
                                    Starter = "N/A",
                                    Button = Functions.buttonStrings[button]
                                };

                            resultsListBW.Add(iDSeed);

                            refresh = true;
                        }
                    }
                }
            }
            isSearching = false;

            lblAction.Text = "Done. - Awaiting Command";
        }
示例#5
0
        private void searchGenV(DateTime date, bool entireMonth, bool useSeed, ulong shinySeed, int seedFrame,
                                bool usePID, uint pid, bool useID,
                                uint id, bool useSID, uint sid, bool calcMinFrame, bool existingFile, ulong mAC,
                                Version version, Language language, DSType dstype, bool softRest, uint vCount,
                                uint timer0, uint gxStat,
                                uint vFrame)
        {
            int dayMin, dayMax;
            uint shinyUpper = 0;
            bool xOR2 = false, starter = false;
            var rng = new BWRng(0);
            resultsCount = 0;
            int[] buttons = {0};

            isSearching = true;

            if (useSeed)
            {
                rng.Seed = shinySeed;
                for (int i = 0; i < seedFrame; i++)
                {
                    rng.Next();
                }

                shinyUpper = (uint) (rng.Seed >> 32);

                xOR2 = Convert.ToBoolean((shinyUpper >> 31) ^ (shinyUpper & 1));
            }

            if (entireMonth)
            {
                dayMin = 1;
                dayMax = DateTime.DaysInMonth(date.Year, date.Month);
            }
            else
                dayMin = dayMax = date.Day;

            long total = 86400*(dayMax - dayMin + 1);

            for (int day = dayMin; day <= dayMax; day++)
            {
                for (int hour = 0; hour < 24; hour++)
                {
                    for (int minute = 0; minute < 60; minute++)
                    {
                        for (int second = 0; second < 60; second++)
                        {
                            var dTime = new DateTime(date.Year, date.Month, day, hour, minute, second);

                            for (int button = 0; button < 13; button++)
                            {
                                buttons[0] = button;
                                ulong seed = Functions.EncryptSeed(dTime, mAC, version, language, dstype, softRest,
                                                                   vCount, timer0,
                                                                   gxStat,
                                                                   vFrame, Functions.buttonMashed(buttons));

                                rng.Seed = seed;
                                ulong oSeed = seed;

                                if (calcMinFrame)
                                {
                                    minFrame = (int) Functions.initialPIDRNG_ID(seed, existingFile, version);
                                }

                                for (int frame = 0; frame < minFrame; frame++)
                                {
                                    rng.Next();
                                }

                                for (int frame = minFrame; frame <= maxFrame; frame++)
                                {
                                    rng.Next();
                                    seed = rng.Seed;

                                    var upper = (uint) (((seed >> 32)*0xFFFFFFFF) >> 32);
                                    uint tid = (upper & 0xFFFF);
                                    uint tsid = (upper >> 16);

                                    if (useSeed)
                                    {
                                        bool xOR1 = Convert.ToBoolean((tid + tsid) & 1);

                                        if (xOR1 ^ xOR2)
                                        {
                                            pid = shinyUpper ^ 0x80010000;
                                            starter = false;
                                        }
                                        else
                                        {
                                            pid = shinyUpper ^ 0x00010000;
                                            starter = true;
                                        }

                                        pid = ((pid >> 16) ^ (pid << 16 >> 16));
                                    }

                                    if ((!useID || (tid == id)) && (!useSID || (tsid == sid)))
                                    {
                                        if (useSeed && (tid ^ tsid ^ pid) >= 8) continue;
                                        if (usePID && !Functions.Shiny(pid, (ushort) tid, (ushort) tsid)) continue;
                                        var iDSeed = new IDListBW
                                            {
                                                Seed = oSeed,
                                                Date = dTime.ToShortDateString(),
                                                Time = dTime.ToString("HH:mm:ss"),
                                                InitialFrame = minFrame,
                                                Frame = frame,
                                                ID = tid,
                                                SID = tsid,
                                                Starter = starter.ToString(),
                                                Button = Functions.buttonStrings[button]
                                            };

                                        resultsListBW.Add(iDSeed);
                                        refresh = true;

                                        if (resultsCount++ >= MAX_RESULTS)
                                        {
                                            lblAction.Text =
                                                "Search stopped - results max reached. Narrow your search for better results.";

                                            isSearching = false;
                                            return;
                                        }
                                    }
                                }
                            }
                        }
                    }
                    lblAction.Text = ((((day - dayMin)*24 + hour + 1)*3600)/(float) total*100) + "%";
                }
            }
            isSearching = false;

            lblAction.Text = "Done. - Awaiting Command";
        }
        private void Search(DateTime date, uint vcountMin, uint vcountMax,
                            uint timer0Min, uint timer0Max, uint vframeMin, uint vframeMax, uint gxstatMin,
                            uint gxstatMax, bool minmaxgxstat, int secondsMin, int secondsMax, bool softreset,
                            Version version, Language language,
                            DSType dstype, bool memorylink, ulong macaddress, uint buttons, uint[] pattern)
        {
            var array = new uint[80];
            array[6] = (uint) (macaddress & 0xFFFF);
            if (softreset)
            {
                array[6] = array[6] ^ 0x01000000;
            }
            Array.Copy(Nazos.Nazo(version, language, dstype), array, 5);

            array[10] = 0x00000000;
            array[11] = 0x00000000;
            array[13] = 0x80000000;
            array[14] = 0x00000000;
            array[15] = 0x000001A0;

            array[12] = buttons;

            string yearMonth = String.Format("{0:00}", date.Year%2000) + String.Format("{0:00}", date.Month);
            string dateString = String.Format("{0:00}", (int) date.DayOfWeek);
            dateString = String.Format("{0:00}", date.Day) + dateString;
            dateString = yearMonth + dateString;
            array[8] = uint.Parse(dateString, NumberStyles.HexNumber);
            array[9] = 0x0;
            //uint[] alpha = Functions.alphaSHA1(array, 8);

            var upperMAC = (uint) (macaddress >> 16);

            for (uint vcount = vcountMin; vcount <= vcountMax; ++vcount)
            {
                for (uint timer0 = timer0Min; timer0 <= timer0Max; ++timer0)
                {
                    array[5] = (vcount << 16) + timer0;
                    array[5] = Functions.Reorder(array[5]);

                    for (uint vframe = vframeMin; vframe <= vframeMax; ++vframe)
                    {
                        for (uint gxstat = gxstatMin; gxstat <= gxstatMax; ++gxstat)
                        {
                            array[7] = (upperMAC ^ (vframe*0x1000000) ^ gxstat);
                            uint[] alpha = Functions.alphaSHA1(array, 8);

                            array[16] = Functions.RotateLeft(array[13] ^ array[8] ^ array[2] ^ array[0], 1);
                            array[18] = Functions.RotateLeft(array[15] ^ array[10] ^ array[4] ^ array[2], 1);
                            array[19] = Functions.RotateLeft(array[16] ^ array[11] ^ array[5] ^ array[3], 1);
                            array[21] = Functions.RotateLeft(array[18] ^ array[13] ^ array[7] ^ array[5], 1);
                            array[22] = Functions.RotateLeft(array[19] ^ array[14] ^ array[8] ^ array[6], 1);
                            array[24] = Functions.RotateLeft(array[21] ^ array[16] ^ array[10] ^ array[8], 1);
                            array[27] = Functions.RotateLeft(array[24] ^ array[19] ^ array[13] ^ array[11], 1);

                            for (int second = secondsMin; second <= secondsMax; ++second)
                            {
                                array[9] = Functions.seedSecond(second) | Functions.seedMinute(date.Minute) |
                                           Functions.seedHour(date.Hour, dstype);
                                ulong seed = Functions.EncryptSeed(array, alpha, 9);
                                // it appears to have the same initial seed as in the main game
                                // pressing Unova link does the same probability table calls
                                uint initial = Functions.initialPIDRNG(seed, version, memorylink);
                                var rng = new BWRng(seed);
                                for (uint i = 0; i < initial; ++i) rng.GetNext64BitNumber();
                                bool found = true;
                                for (uint i = 0; i < pattern.Length; ++i)
                                {
                                    if (pattern[i] != rng.GetNext32BitNumber(8))
                                    {
                                        found = false;
                                        break;
                                    }
                                    // there's another RNG call here unreleated to the spinner
                                    rng.GetNext64BitNumber();
                                }
                                progressSearched++;
                                if (found)
                                {
                                    var parameter = new DSParameterCapture
                                        {
                                            ActualSeconds = second,
                                            GxStat = gxstat,
                                            Seed = seed,
                                            Timer0 = timer0,
                                            VCount = vcount,
                                            VFrame = vframe
                                        };
                                    dsParameters.Add(parameter);
                                    refreshQueue = true;
                                    progressFound++;
                                }
                            }

                            if (minmaxgxstat && gxstatMax > gxstatMin) gxstat = gxstatMax - 1;
                        }
                    }
                }
            }
        }