예제 #1
0
        public void GenerateWonderCardJob(uint year, List<int> months, int hourMin, int hourMax,
                                          Profile profile, uint shinyOffset, bool fastSearch, int listIndex, int shiny)
        {
            uint minAdvances = generators[listIndex].InitialFrame;

            var array = new uint[80];
            array[6] = (uint) (profile.MAC_Address & 0xFFFF);

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

            var upperMAC = (uint) (profile.MAC_Address >> 16);
            array[7] = (upperMAC ^ (profile.VFrame*0x1000000) ^ profile.GxStat);

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

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

            List<List<ButtonComboType>> keypressList = 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;

            // necessary to keep track of fast searching
            // for frames 1-6

            var included = new bool[6];

            for (int i = 0; i < 6; i++)
            {
                if (i >= (generators[listIndex].InitialFrame - 1) &&
                    i < (generators[listIndex].InitialFrame + generators[listIndex].MaxResults - 1))
                    included[i] = true;
                else
                    included[i] = false;
            }

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

                var dayMin = (int) (interval*listIndex + 1);
                var dayMax = (int) (interval*(listIndex + 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 = profile.Timer0Min; timer0 <= profile.Timer0Max; timer0++)
                    {
                        array[5] = (profile.VCount << 16) + timer0;
                        array[5] = Functions.Reorder(array[5]);

                        for (int day = dayMin; day <= dayMax; day++)
                        {
                            var searchTime = new DateTime((int) 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, 8);

                            // 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 = hourMin; hour <= hourMax; 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, profile.DSType);

                                        ulong seed = Functions.EncryptSeed(array, alpha, 9);

                                        // Set this to our seed here
                                        generators[listIndex].InitialSeed = seed;
                                        generators[listIndex].InitialFrame = Functions.initialPIDRNG(seed, profile) +
                                                                             minAdvances + (profile.IsBW2() ? 2u : 0);

                                        if (iframes.Count > 1000000)
                                            break;

                                        //  This is where we actually go ahead and call our
                                        //  generator for a list of IVs based on parameters
                                        //  that have been passed in.
                                        List<Frame> frames = generators[listIndex].GenerateWonderCard(frameCompare,
                                                                                                      profile.ID,
                                                                                                      profile.SID, shiny);

                                        progressSearched += searchRange;
                                        progressFound += (ulong) frames.Count;

                                        //  Now we need to iterate through each result here
                                        //  and create a collection of the information that
                                        //  we are going to place into our grid.
                                        foreach (Frame frame in frames)
                                        {
                                            var iframe = new IFrameCapture();

                                            frame.DisplayPrep();
                                            iframe.Offset = frame.Number;
                                            iframe.Seed = seed;
                                            iframe.Frame = frame;
                                            iframe.Advances = iframe.Offset -
                                                              (generators[listIndex].InitialFrame - minAdvances);

                                            iframe.TimeDate =
                                                searchTime.AddHours(hour).AddMinutes(minute).AddSeconds(second);
                                            iframe.KeyPresses = buttons[buttonCount];
                                            iframe.Timer0 = timer0;

                                            lock (threadLock)
                                            {
                                                iframes.Add(iframe);
                                            }
                                        }

                                        if (frames.Count > 0)
                                        {
                                            refreshQueue = true;
                                        }
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }
        private void Generate(FrameGenerator generator, IEnumerable<DateTime> possibleDates, uint minFrame,
                              uint maxFrame, Profile profile, uint groupSize, uint calibratedDelay)
        {
            const uint incrementFound = 1;
            List<List<ButtonComboType>> keypresses = profile.GetKeypresses();

            foreach (DateTime seedTime in possibleDates)
            {
                waitHandle.WaitOne();
                foreach (var combo in keypresses)
                {
                    for (uint timer0 = profile.Timer0Min; timer0 <= profile.Timer0Max; timer0++)
                    {
                        ulong seed = Functions.EncryptSeed(seedTime, profile, timer0, Functions.buttonMashed(combo));

                        generator.InitialSeed = seed;
                        generator.InitialFrame = Functions.initialPIDRNG(seed, profile) + minFrame;
                        generator.MaxResults = maxFrame - minFrame + 1;

                        List<Frame> frames = generator.Generate(frameCompare, 0, 0);

                        IFrameCapture previous = null;
                        bool previouslyAdded = false;

                        var frameGroup = new List<IFrameCapture>();
                        // quick check and if it's impossible that this is a match don't waste our time loop
                        // breaks search progress so that needs to get fixed
                        if (frames.Count < groupSize) continue;
                        foreach (Frame frame in frames)
                        {
                            var iframe = new IFrameCapture
                                {
                                    Offset = frame.Number,
                                    Seed = seed,
                                    Frame = frame,
                                    TimeDate = seedTime,
                                    Timer0 = timer0,
                                    Delay = calibratedDelay,
                                    KeyPresses = combo
                                };

                            //  Calibrated delay instead of the real delay for correct CGear Times

                            if (previous != null &&
                                (iframe.Offset == previous.Offset + 1 || iframe.Offset == previous.Offset + 2))
                            {
                                if (!previouslyAdded)
                                    frameGroup.Add(previous);

                                frameGroup.Add(iframe);
                                previouslyAdded = true;
                            }
                            else
                            {
                                if (frameGroup.Count >= groupSize)
                                {
                                    lock (threadLock)
                                    {
                                        foreach (IFrameCapture t in frameGroup)
                                            t.Frame.Synchable = grey;
                                        iframes.AddRange(frameGroup);
                                        grey = !grey;
                                    }
                                    refreshQueue = true;
                                    progressFound += incrementFound;
                                }

                                frameGroup = new List<IFrameCapture>();
                                previouslyAdded = false;
                            }
                            previous = iframe;
                        }
                        progressSearched += (uint) frames.Count;

                        if (frameGroup.Count >= groupSize)
                        {
                            lock (threadLock)
                            {
                                for (int i = 0; i < frameGroup.Count; ++i)
                                    frameGroup[i].Frame.Synchable = grey;
                                iframes.AddRange(frameGroup);
                                grey = !grey;
                            }
                            refreshQueue = true;
                            progressFound += incrementFound;
                        }
                    }
                }
            }
        }