示例#1
0
        private void CheckNazos()
        {
            Profile p = GetProfile();

            if (p != null && Nazos.Nazo(p) == null)
            {
                if (MessageBox.Show(
                        "We currently do not have information to be able to support this version of the game. Would you like to help out with adding support?",
                        "Warning", MessageBoxButtons.YesNo) == DialogResult.Yes)
                {
                    Process.Start("http://www.smogon.com/forums/showpost.php?p=4432994&postcount=977");
                }
            }
        }
示例#2
0
        public Profile GetProfile()
        {
            ushort id, sid;
            uint   vcount, vframe, timer0min, timer0max, gxstat;
            ulong  mac;

            //validation
            if (!FormsFunctions.ParseInputD(maskedTextBoxID, out id) ||
                !FormsFunctions.ParseInputD(maskedTextBoxSID, out sid) ||
                !FormsFunctions.ParseInputH(textBoxMAC, out mac) ||
                !FormsFunctions.ParseInputH(textBoxVCount, out vcount) ||
                !FormsFunctions.ParseInputH(textBoxVFrame, out vframe) ||
                !FormsFunctions.ParseInputH(textBoxTimer0Min, out timer0min) ||
                !FormsFunctions.ParseInputH(textBoxTimer0Max, out timer0max) ||
                !FormsFunctions.ParseInputH(textBoxGxStat, out gxstat))
            {
                return(null);
            }
            var profile = new Profile
            {
                Name        = textBoxName.Text,
                ID          = id,
                SID         = sid,
                MAC_Address = mac,
                Version     = (Version)comboBoxVersion.SelectedIndex,
                Language    = (Language)comboBoxLanguage.SelectedIndex,
                DSType      = (DSType)comboBoxDSType.SelectedIndex,
                VCount      = vcount,
                VFrame      = vframe,
                Timer0Min   = timer0min,
                Timer0Max   = timer0max,
                GxStat      = gxstat,
                Keypresses  = GetKeypresses(),
                SoftReset   = checkBoxSoftReset.Checked,
                SkipLR      = checkBoxSkipLR.Checked,
                MemoryLink  = checkBoxMemoryLink.Checked
            };

            if (Nazos.Nazo(profile) == null)
            {
                MessageBox.Show("Warning: this version of the game is currently unsupported.",
                                "Unsupported game: " + profile.Version + " " + profile.Language + " " + profile.DSType,
                                MessageBoxButtons.OK, MessageBoxIcon.Warning);
            }
            return(profile);
        }
        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;
                            }
                        }
                    }
                }
            }
        }
示例#4
0
        // needs to be threaded
        // optimal to use buttons, look into that
        // todo: abstract this, make a gen5searcher
        private void Search()
        {
            const int minHour     = 0;
            const int maxHour     = 24;
            const int threadIndex = 0;
            // todo: move this outside the search and only do it once
            var array = new uint[80];

            array[6] = (uint)(searchParams.Profile.MAC_Address & 0xFFFF);

            if (searchParams.Profile.SoftReset)
            {
                array[6] = array[6] ^ 0x01000000;
            }

            var upperMAC = (uint)(searchParams.Profile.MAC_Address >> 16);

            array[7] = (upperMAC ^ (searchParams.Profile.VFrame * 0x1000000) ^ searchParams.Profile.GxStat);

            // Get the version-unique part of the message
            Array.Copy(
                Nazos.Nazo(searchParams.Profile.Version, searchParams.Profile.Language, searchParams.Profile.DSType),
                array, 5);

            array[10] = 0x00000000;
            array[11] = 0x00000000;
            array[13] = 0x80000000;
            array[14] = 0x00000000;
            array[15] = 0x000001A0;
            List <List <ButtonComboType> > keypressList = searchParams.Profile.GetKeypresses();

            List <ButtonComboType>[] buttons = keypressList.ToArray();
            var buttonMashValue = new uint[keypressList.Count];

            for (int i = 0; i < buttons.Length; i++)
            {
                buttonMashValue[i] = Functions.buttonMashed(buttons[i]);
            }

            //uint searchRange = generator.MaxResults;

            foreach (int month in months)
            {
                float interval = ((float)DateTime.DaysInMonth(year, month) / numThreads + (float)0.05);

                var dayMin = (int)(interval * threadIndex + 1);
                var dayMax = (int)(interval * (threadIndex + 1));

                string yearMonth = String.Format("{0:00}", year % 2000) + String.Format("{0:00}", month);
                for (int buttonCount = 0; buttonCount < keypressList.Count; buttonCount++)
                {
                    array[12] = buttonMashValue[buttonCount];
                    for (uint timer0 = searchParams.Profile.Timer0Min;
                         timer0 <= searchParams.Profile.Timer0Max;
                         timer0++)
                    {
                        array[5] = (searchParams.Profile.VCount << 16) + timer0;
                        array[5] = Functions.Reorder(array[5]);

                        for (int day = dayMin; day <= dayMax; day++)
                        {
                            var searchTime = new DateTime(year, month, day);

                            string dateString = String.Format("{0:00}", (int)searchTime.DayOfWeek);
                            dateString = String.Format("{0:00}", searchTime.Day) + dateString;
                            dateString = yearMonth + dateString;
                            array[8]   = uint.Parse(dateString, NumberStyles.HexNumber);
                            array[9]   = 0x0;

                            // For seeds with the same date, the contents of the SHA-1 array will be the same for the first 8 steps
                            // We are precomputing those 8 steps to save time
                            // Trying to precompute beyond 8 steps is complicated and does not save much time, also runs the risk of errors

                            uint[] alpha = Functions.alphaSHA1(array);

                            // We are also precomputing select portions of the SHA-1 array during the expansion process
                            // As they are also the same

                            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 hour = minHour; hour <= maxHour; hour++)
                            {
                                //int seedHour = hour;
                                for (int minute = 0; minute <= 59; minute++)
                                {
                                    waitHandle.WaitOne();
                                    for (int second = 0; second <= 59; second++)
                                    {
                                        array[9] = Functions.seedSecond(second) | Functions.seedMinute(minute) |
                                                   Functions.seedHour(hour, searchParams.Profile.DSType);

                                        ulong seed = Functions.EncryptSeed(array, alpha, 9);
                                        List <DreamRadarFrame> frames = generator.Generate(seed, searchParams.Profile);
                                        // todo: remove the need to use a loop like this

                                        /*foreach (DreamRadarFrame t in frames)
                                         * {
                                         *  t.DateTime =
                                         *      searchTime.AddHours(hour).AddMinutes(minute).AddSeconds(second);
                                         *  t.Timer0 = timer0;
                                         *  t.Keypresses = keypressList[buttonCount];
                                         * }*/
                                        lock (threadLock)
                                        {
                                            drFrames.AddRange(frames);
                                        }

                                        /* progressSearched += generator.OpenHollows * generator.MaxAdvances;
                                         * progressFound += (ulong)hollows.Count;
                                         * progressTotal += (ulong)hollows.Count * generator.OpenHollows *
                                         *               generator.MaxAdvances;
                                         * refreshQueue = true;
                                         */
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }
示例#5
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);
            }
        }