Beispiel #1
0
        public static string GetFormattedShowdownText(PKM pkm)
        {
            var newShowdown = new List <string>();
            var showdown    = ShowdownParsing.GetShowdownText(pkm);

            foreach (var line in showdown.Split('\n'))
            {
                newShowdown.Add(line);
            }

            if (pkm.IsEgg)
            {
                newShowdown.Add("\nPokémon is an egg");
            }
            if (pkm.Ball > (int)Ball.None)
            {
                newShowdown.Insert(newShowdown.FindIndex(z => z.Contains("Nature")), $"Ball: {(Ball)pkm.Ball} Ball");
            }
            if (pkm.IsShiny)
            {
                var index = newShowdown.FindIndex(x => x.Contains("Shiny: Yes"));
                if (pkm.ShinyXor == 0 || pkm.FatefulEncounter)
                {
                    newShowdown[index] = "Shiny: Square\r";
                }
                else
                {
                    newShowdown[index] = "Shiny: Star\r";
                }
            }

            newShowdown.InsertRange(1, new string[] { $"OT: {pkm.OT_Name}", $"TID: {pkm.DisplayTID}", $"SID: {pkm.DisplaySID}", $"OTGender: {(Gender)pkm.OT_Gender}", $"Language: {(LanguageID)pkm.Language}" });
            return(Format.Code(string.Join("\n", newShowdown).TrimEnd()));
        }
Beispiel #2
0
        private async Task <bool> HandleEncounter(PK8 pk, bool legends, CancellationToken token)
        {
            encounterCount++;
            Log($"Encounter: {encounterCount}{Environment.NewLine}{ShowdownParsing.GetShowdownText(pk)}{Environment.NewLine}");
            if (legends)
            {
                Counts.AddCompletedLegends();
            }
            else
            {
                Counts.AddCompletedEncounters();
            }

            if (DumpSetting.Dump && !string.IsNullOrEmpty(DumpSetting.DumpFolder))
            {
                DumpPokemon(DumpSetting.DumpFolder, legends ? "legends" : "encounters", pk);
            }

            if (StopConditionSettings.EncounterFound(pk, DesiredMinIVs, DesiredMaxIVs, Hub.Config.StopConditions))
            {
                Log("Result found! Stopping routine execution; restart the bot(s) to search again.");
                if (Hub.Config.StopConditions.CaptureVideoClip)
                {
                    await Task.Delay(Hub.Config.StopConditions.ExtraTimeWaitCaptureVideo, token).ConfigureAwait(false);
                    await PressAndHold(CAPTURE, 2_000, 1_000, token).ConfigureAwait(false);
                }
                return(true);
            }

            return(false);
        }
        public static string GetFormattedShowdownText(PKM pkm)
        {
            var newShowdown = new List <string>();
            var showdown    = ShowdownParsing.GetShowdownText(pkm);

            foreach (var line in showdown.Split('\n'))
            {
                newShowdown.Add($"\n{line}");
            }

            int index = newShowdown.FindIndex(z => z.Contains("Nature"));

            if (pkm.Ball > (int)Ball.None && index != -1)
            {
                newShowdown.Insert(newShowdown.FindIndex(z => z.Contains("Nature")), $"\nBall: {(Ball)pkm.Ball} Ball");
            }

            index = newShowdown.FindIndex(x => x.Contains("Shiny: Yes"));
            if (pkm is PK8 && pkm.IsShiny && index != -1)
            {
                if (pkm.ShinyXor == 0 || pkm.FatefulEncounter)
                {
                    newShowdown[index] = "\nShiny: Square\r";
                }
                else
                {
                    newShowdown[index] = "\nShiny: Star\r";
                }
            }

            var extra = new string[] { $"\nOT: {pkm.OT_Name}", $"\nTID: {pkm.DisplayTID}", $"\nSID: {pkm.DisplaySID}", $"\nOTGender: {(Gender)pkm.OT_Gender}", $"\nLanguage: {(LanguageID)pkm.Language}", $"{(pkm.IsEgg ? "\nIsEgg: Yes" : "")}" };

            newShowdown.InsertRange(1, extra);
            return(Format.Code(string.Join("", newShowdown).Trim()));
        }
        private async Task <bool> LogPKMs(PK8 pk, bool legends, CancellationToken token)
        {
            encounterCount++;
            string text = "";

            if (Hub.Config.StopConditions.StopOnSpecies != 0 && pk.Species == (int)Hub.Config.StopConditions.StopOnSpecies)
            {
                _ = $"Scan {encounterCount}:\n{ShowdownParsing.GetShowdownText(pk)}";
                if (pk.IsShiny && pk.ShinyXor == 0)
                {
                    _ = text.Replace("Shiny: Yes", "Shiny: Square");
                }
                else if (pk.IsShiny)
                {
                    _ = text.Replace("Shiny: Yes", "Shiny: Star");
                }
                _ = $"{text}\n{GetRibbonsList(pk)}";
            }
            else
            {
                _ = $"Scan {encounterCount}: {(pk.IsShiny ? "Shiny " : "")}{pk.Nickname}.";
            }

            Log($"Scan: {text}");
            if (legends)
            {
                Counts.AddSWSHLegendaryScans();
            }
            else
            {
                Counts.AddSWSHOverworldScans();
            }

            if (DumpSetting.Dump && !string.IsNullOrEmpty(DumpSetting.DumpFolder))
            {
                DumpPokemon(DumpSetting.DumpFolder, legends ? "OverworldLegends" : "OverworldEncounters", pk);
            }

            if (StopConditionSettings.EncounterFound(pk, DesiredMinIVs, DesiredMaxIVs, Hub.Config.StopConditions))
            {
                if (!String.IsNullOrEmpty(Hub.Config.Discord.UserTag))
                {
                    Log($"<@{Hub.Config.Discord.UserTag}> result found! Stopping routine execution; restart the bot(s) to search again.");
                }
                else
                {
                    Log("Result found! Stopping routine execution; restart the bot(s) to search again.");
                }
                if (Hub.Config.StopConditions.CaptureVideoClip)
                {
                    await Task.Delay(Hub.Config.StopConditions.ExtraTimeWaitCaptureVideo, token).ConfigureAwait(false);
                    await PressAndHold(CAPTURE, 2_000, 1_000, token).ConfigureAwait(false);
                }
                return(true);
            }
            return(false);
        }
Beispiel #5
0
        public static List <ShowdownTeamSet> GetTeams(string paste)
        {
            string[] lines  = paste.Split(new[] { "\n" }, StringSplitOptions.None);
            var      result = new List <ShowdownTeamSet>();

            for (int i = 0; i < lines.Length; i++)
            {
                var line = lines[i].Trim();
                if (string.IsNullOrWhiteSpace(line))
                {
                    continue;
                }

                if (!IsLineShowdownTeam(line))
                {
                    continue;
                }

                var split = line.Split(new[] { "===" }, 0);
                if (split.Length != 3)
                {
                    continue;
                }

                var split2 = split[1].Trim().Split(']');
                if (split2.Length != 2)
                {
                    continue;
                }

                var format = split2[0].Substring(1);
                var name   = split2[1].TrimStart();
                // find end

                int end = i + 1;
                while (end < lines.Length)
                {
                    if (IsLineShowdownTeam(lines[end]))
                    {
                        break;
                    }
                    end++;
                }

                var teamlines = lines.Skip(i + 1).Take(end - i - 1);
                var sets      = ShowdownParsing.GetShowdownSets(teamlines).ToList();
                if (sets.Count == 0)
                {
                    continue;
                }
                result.Add(new ShowdownTeamSet(name, sets, format));

                i = end - 1;
            }
            return(result);
        }
Beispiel #6
0
        public string GetPrintName(PKM pk)
        {
            var set = ShowdownParsing.GetShowdownText(pk);

            if (pk is IRibbonIndex r)
            {
                set += GetMarkName(r);
            }
            return(set);
        }
        /// <summary>
        /// A method to get a list of ShowdownSet(s) from a string paste
        /// Needs to be extended to hold several teams
        /// </summary>
        /// <param name="paste"></param>
        public static List <ShowdownSet> ShowdownSets(string paste)
        {
            paste = paste.Trim(); // Remove White Spaces
            if (IsTeamBackup(paste))
            {
                return(ShowdownTeamSet.GetTeams(paste).SelectMany(z => z.Team).ToList());
            }
            var lines = paste.Split(new[] { "\n" }, StringSplitOptions.None);

            return(ShowdownParsing.GetShowdownSets(lines).ToList());
        }
        private async Task <bool> HandleEncounter(PK8 pk, bool legends, CancellationToken token)
        {
            encounterCount++;

            //Star/Square Shiny Recognition
            var showdowntext = ShowdownParsing.GetShowdownText(pk);

            if (pk.IsShiny && pk.ShinyXor == 0)
            {
                showdowntext = showdowntext.Replace("Shiny: Yes", "Shiny: Square");
            }
            else if (pk.IsShiny)
            {
                showdowntext = showdowntext.Replace("Shiny: Yes", "Shiny: Star");
            }

            Log($"Encounter: {encounterCount}{Environment.NewLine}{Environment.NewLine}{showdowntext}{Environment.NewLine}{GetRibbonsList(pk)}{Environment.NewLine}");
            if (legends)
            {
                Counts.AddCompletedLegends();
            }
            else
            {
                Counts.AddCompletedEncounters();
            }

            if (DumpSetting.Dump && !string.IsNullOrEmpty(DumpSetting.DumpFolder))
            {
                DumpPokemon(DumpSetting.DumpFolder, legends ? "legends" : "encounters", pk);
                Counts.AddCompletedDumps();
            }

            if (StopConditionSettings.EncounterFound(pk, DesiredMinIVs, DesiredMaxIVs, Hub.Config.StopConditions))
            {
                if (!String.IsNullOrEmpty(Hub.Config.Discord.UserTag) && Hub.Config.SWSH_Encounter.EncounteringType != EncounterMode.LiveStatsChecking)
                {
                    Log($"<@{Hub.Config.Discord.UserTag}> result found! Stopping routine execution; restart the bot(s) to search again.");
                }
                else if (Hub.Config.SWSH_Encounter.EncounteringType != EncounterMode.LiveStatsChecking)
                {
                    Log("Result found!");
                }
                if (Hub.Config.StopConditions.CaptureVideoClip)
                {
                    await Task.Delay(Hub.Config.StopConditions.ExtraTimeWaitCaptureVideo, token).ConfigureAwait(false);
                    await PressAndHold(CAPTURE, 2_000, 1_000, token).ConfigureAwait(false);
                }
                return(true);
            }
            return(false);
        }
Beispiel #9
0
        public string GetPrintName(PKM pk)
        {
            var set = ShowdownParsing.GetShowdownText(pk);

            if (pk is IRibbonIndex r)
            {
                var rstring = GetMarkName(r);
                if (!string.IsNullOrEmpty(rstring))
                {
                    set += $"\nPokémon found to have **{GetMarkName(r)}**!";
                }
            }
            return(set);
        }
Beispiel #10
0
        public void SimulatorParseMultiple()
        {
            var text  = string.Join("\r\n\r\n", Sets);
            var lines = text.Split(new[] { "\r\n", "\n" }, StringSplitOptions.None);
            var sets  = ShowdownParsing.GetShowdownSets(lines);

            Assert.True(sets.Count() == Sets.Length);

            sets = ShowdownParsing.GetShowdownSets(Enumerable.Empty <string>());
            Assert.True(!sets.Any());

            sets = ShowdownParsing.GetShowdownSets(new [] { "", "   ", " " });
            Assert.True(!sets.Any());
        }
Beispiel #11
0
        private async void B_ExportShowdownPKM_Click(object sender, EventArgs e)
        {
            try
            {
                await Clipboard.SetTextAsync(ShowdownParsing.GetShowdownText(VM.Pane)).ConfigureAwait(false);

                await UserDialogs.Instance
                .AlertAsync("Set the exported Showdown Set to the device clipboard!")
                .ConfigureAwait(false);
            }
            catch
            {
                await UserDialogs.Instance
                .AlertAsync("Failed to set Showdown Set to Clipboard.")
                .ConfigureAwait(false);
            }
        }
Beispiel #12
0
        public QRView(PKM pkm)
        {
            InitializeComponent();

            Header.Text    = "PKHeX Mobile!" + Environment.NewLine + $"Data Format: {pkm.GetType().Name}";
            Preview.Source = (SKBitmapImageSource)pkm.Sprite();

            // get high resolution QR with dimensions best suited to the device's dimensions
            // we don't overlay the pkm sprite in this QR since we do it above
            var di    = DeviceDisplay.MainDisplayInfo;
            var width = Math.Min(di.Height, di.Width);
            var img   = QRBuilder.GetQR(pkm, (int)(width * 0.8));

            QR.Source = (SKBitmapImageSource)img;

            Desc.Text = ShowdownParsing.GetShowdownText(pkm);
        }
        public static string GetFormattedShowdownText(PKM pkm)
        {
            int    TID          = (pkm.Gen7 || pkm.Gen8) ? pkm.TrainerID7 : pkm.TID;
            int    SID          = (pkm.Gen7 || pkm.Gen8) ? pkm.TrainerSID7 : pkm.SID;
            string showdowntext = ShowdownParsing.GetShowdownText(pkm);

            if (pkm.IsShiny && pkm.ShinyXor == 0)
            {
                showdowntext = showdowntext.Replace("Shiny: Yes", "Shiny: Square");
            }
            else if (pkm.IsShiny)
            {
                showdowntext = showdowntext.Replace("Shiny: Yes", "Shiny: Star");
            }
            string showdown = $"{showdowntext}\nOT: {pkm.OT_Name}\nTID: {TID}\nSID: {SID}";

            return(Format.Code(showdown));
        }
        private bool HandleEncounter(PK8 pk, bool legends)
        {
            encounterCount++;

            //Star/Square Shiny Recognition
            var showdowntext = ShowdownParsing.GetShowdownText(pk);

            if (pk.IsShiny && pk.ShinyXor == 0)
            {
                showdowntext = showdowntext.Replace("Shiny: Yes", "Shiny: Square");
            }
            else if (pk.IsShiny)
            {
                showdowntext = showdowntext.Replace("Shiny: Yes", "Shiny: Star");
            }

            Log($"Encounter: {encounterCount}{Environment.NewLine}{Environment.NewLine}{showdowntext}{Environment.NewLine}");
            if (legends)
            {
                Counts.AddCompletedLegends();
            }
            else
            {
                Counts.AddCompletedEncounters();
            }

            if (DumpSetting.Dump && !string.IsNullOrEmpty(DumpSetting.DumpFolder))
            {
                DumpPokemon(DumpSetting.DumpFolder, legends ? "legends" : "encounters", pk);
                Counts.AddCompletedDumps();
            }

            if (StopConditionSettings.EncounterFound(pk, DesiredMinIVs, DesiredMaxIVs, Hub.Config.StopConditions))
            {
                if (legends)
                {
                    Log("Result found! Stopping routine execution; restart the bot(s) to search again.");
                }
                return(true);
            }
            return(false);
        }
Beispiel #15
0
        private static bool AddToTradeQueue(this SocketCommandContext Context, PK8 pk8, int code, string trainerName, RequestSignificance sig, PokeRoutineType type, PokeTradeType t, SocketUser trader, out string msg)
        {
            var user   = trader;
            var userID = user.Id;
            var name   = user.Username;

            var trainer  = new PokeTradeTrainerInfo(trainerName);
            var notifier = new DiscordTradeNotifier <PK8>(pk8, trainer, code, user, Context);
            var detail   = new PokeTradeDetail <PK8>(pk8, trainer, notifier, t, code: code, sig == RequestSignificance.Favored);
            var trade    = new TradeEntry <PK8>(detail, userID, type, name);

            var hub   = SysCordInstance.Self.Hub;
            var Info  = hub.Queues.Info;
            var added = Info.AddToTradeQueue(trade, userID, sig == RequestSignificance.Sudo);

            if (added == QueueResultAdd.AlreadyInQueue)
            {
                msg = "Sorry, you are already in the queue.";
                return(false);
            }

            var position = Info.CheckPosition(userID, type);

            var ticketID = "";

            if (TradeStartModule.IsStartChannel(Context.Channel.Id))
            {
                ticketID = $", unique ID: {detail.ID}";
            }

            var pokeName = "";

            if (t == PokeTradeType.Specific || t == PokeTradeType.TradeCord && pk8.Species != 0)
            {
                pokeName = $" Receiving: {(hub.Config.Trade.ItemMuleSpecies == (Species)pk8.Species && pk8.HeldItem != 0 ? $"{(Species)pk8.Species} ({ShowdownParsing.GetShowdownText(pk8).Split('@','\n')[1].Trim()})" : $"{(Species)pk8.Species}")}.";
            }
            msg = $"{user.Mention} - Added to the {type} queue{ticketID}. Current Position: {position.Position}.{pokeName}";

            var botct = Info.Hub.Bots.Count;

            if (position.Position > botct)
            {
                var eta = Info.Hub.Config.Queues.EstimateDelay(position.Position, botct);
                msg += $" Estimated: {eta:F1} minutes.";
            }
            return(true);
        }
Beispiel #16
0
        public override async Task MainLoop(CancellationToken token)
        {
            Log("Identifying trainer data of the host console.");
            await IdentifyTrainer(token).ConfigureAwait(false);

            Log("Checking item counts...");
            var pouchData = await Connection.ReadBytesAsync(ItemTreasureAddress, 80, token).ConfigureAwait(false);

            var counts      = FossilCount.GetFossilCounts(pouchData);
            int reviveCount = counts.PossibleRevives(Hub.Config.SWSH_Fossil.Species);

            if (reviveCount == 0)
            {
                Log("Insufficient fossil pieces. Please obtain at least one of each required fossil piece first.");
                return;
            }

            Log("Starting main FossilBot loop.");
            Config.IterateNextRoutine();
            while (!token.IsCancellationRequested && Config.NextRoutineType == PokeRoutineType.SWSH_FossilBot)
            {
                if (encounterCount != 0 && encounterCount % reviveCount == 0)
                {
                    Log($"Ran out of fossils to revive {Hub.Config.SWSH_Fossil.Species}.");
                    Log("Restarting the game to restore the puch data.");
                    await CloseGame(Hub.Config, token).ConfigureAwait(false);
                    await StartGame(Hub.Config, token).ConfigureAwait(false);
                }

                await ReviveFossil(counts, token).ConfigureAwait(false);

                Log("Fossil revived. Checking details...");

                var pk = await ReadUntilPresent(await ParsePointer(PokeGift, token), 2_000, 0_200, token).ConfigureAwait(false);

                if (pk == null)
                {
                    Log("RAM may be shifted, please restart the game and the bot.");
                }
                else
                {
                    encounterCount++;
                    Log($"Encounter: {encounterCount}:{Environment.NewLine}{ShowdownParsing.GetShowdownText(pk)}{Environment.NewLine}");
                    if (DumpSetting.Dump)
                    {
                        DumpPokemon(DumpSetting.DumpFolder, "fossil", pk);
                    }

                    Counts.AddCompletedFossils();

                    if (StopConditionSettings.EncounterFound(pk, DesiredMinIVs, DesiredMaxIVs, Hub.Config.StopConditions))
                    {
                        if (Hub.Config.StopConditions.CaptureVideoClip)
                        {
                            await Task.Delay(Hub.Config.StopConditions.ExtraTimeWaitCaptureVideo, token).ConfigureAwait(false);
                            await PressAndHold(CAPTURE, 2_000, 1_000, token).ConfigureAwait(false);
                        }

                        Log("Result found! Stopping routine execution; restart the bot(s) to search again.");
                        await DetachController(token).ConfigureAwait(false);

                        return;
                    }

                    while (!await IsOnOverworld(Hub.Config, token).ConfigureAwait(false))
                    {
                        await Click(B, 0_200, token).ConfigureAwait(false);
                    }
                }
            }
        }
Beispiel #17
0
        private async Task <PokeTradeResult> PerformLinkCodeTrade(SAV8SWSH sav, PokeTradeDetail <PK8> poke, CancellationToken token)
        {
            // Update Barrier Settings
            UpdateBarrier(poke.IsSynchronized);
            poke.TradeInitialize(this);
            Hub.Config.Stream.EndEnterCode(this);

            if (await CheckIfSoftBanned(token).ConfigureAwait(false))
            {
                await Unban(token).ConfigureAwait(false);
            }

            var pkm = poke.TradeData;

            if (pkm.Species != 0)
            {
                await SetBoxPokemon(pkm, InjectBox, InjectSlot, token, sav).ConfigureAwait(false);
            }

            if (!await IsOnOverworld(Hub.Config, token).ConfigureAwait(false))
            {
                await ExitTrade(Hub.Config, true, token).ConfigureAwait(false);

                return(PokeTradeResult.RecoverStart);
            }

            while (await CheckIfSearchingForLinkTradePartner(token).ConfigureAwait(false))
            {
                Log("Still searching, reset bot position.");
                await ResetTradePosition(Hub.Config, token).ConfigureAwait(false);
            }

            Log("Opening Y-Comm Menu");
            await Click(Y, 2_000, token).ConfigureAwait(false);

            Log("Selecting Link Trade");
            await Click(A, 1_500, token).ConfigureAwait(false);

            Log("Selecting Link Trade Code");
            await Click(DDOWN, 500, token).ConfigureAwait(false);

            for (int i = 0; i < 2; i++)
            {
                await Click(A, 1_500, token).ConfigureAwait(false);
            }

            // All other languages require an extra A press at this menu.
            if (GameLang != LanguageID.English && GameLang != LanguageID.Spanish)
            {
                await Click(A, 1_500, token).ConfigureAwait(false);
            }

            // Loading Screen
            if (poke.Type != PokeTradeType.Random)
            {
                Hub.Config.Stream.StartEnterCode(this);
            }
            await Task.Delay(Hub.Config.Timings.ExtraTimeOpenCodeEntry, token).ConfigureAwait(false);

            var code = poke.Code;

            Log($"Entering Link Trade Code: {code:0000 0000}...");
            await EnterTradeCode(code, Hub.Config, token).ConfigureAwait(false);

            // Wait for Barrier to trigger all bots simultaneously.
            WaitAtBarrierIfApplicable(token);
            await Click(PLUS, 1_000, token).ConfigureAwait(false);

            Hub.Config.Stream.EndEnterCode(this);

            // Confirming and return to overworld.
            var delay_count = 0;

            while (!await IsOnOverworld(Hub.Config, token).ConfigureAwait(false))
            {
                if (delay_count >= 5)
                {
                    await ExitTrade(Hub.Config, true, token).ConfigureAwait(false);

                    return(PokeTradeResult.RecoverPostLinkCode);
                }

                for (int i = 0; i < 5; i++)
                {
                    await Click(A, 0_800, token).ConfigureAwait(false);
                }
                delay_count++;
            }

            poke.TradeSearching(this);
            await Task.Delay(0_500, token).ConfigureAwait(false);

            // Wait for a Trainer...
            Log("Waiting for trainer...");
            bool partnerFound = await WaitForPokemonChanged(LinkTradePartnerPokemonOffset, Hub.Config.Trade.TradeWaitTime * 1_000, 0_200, token).ConfigureAwait(false);

            if (token.IsCancellationRequested)
            {
                return(PokeTradeResult.Aborted);
            }
            if (!partnerFound)
            {
                await ResetTradePosition(Hub.Config, token).ConfigureAwait(false);

                return(PokeTradeResult.NoTrainerFound);
            }

            // Select Pokemon
            // pkm already injected to b1s1
            await Task.Delay(5_500, token).ConfigureAwait(false); // necessary delay to get to the box properly

            var TrainerName = await GetTradePartnerName(TradeMethod.LinkTrade, token).ConfigureAwait(false);

            Log($"Found Trading Partner: {TrainerName}...");

            if (!await IsInBox(token).ConfigureAwait(false))
            {
                await ExitTrade(Hub.Config, true, token).ConfigureAwait(false);

                return(PokeTradeResult.RecoverOpenBox);
            }

            // Confirm Box 1 Slot 1
            if (poke.Type == PokeTradeType.Specific || poke.Type == PokeTradeType.TradeCord || poke.Type == PokeTradeType.Giveaway)
            {
                for (int i = 0; i < 5; i++)
                {
                    await Click(A, 0_500, token).ConfigureAwait(false);
                }
            }

            poke.SendNotification(this, $"Found Trading Partner: {TrainerName}. Waiting for a Pokémon...");

            if (poke.Type == PokeTradeType.Dump)
            {
                return(await ProcessDumpTradeAsync(poke, token).ConfigureAwait(false));
            }

            // Wait for User Input...
            var pk = await ReadUntilPresent(LinkTradePartnerPokemonOffset, 25_000, 1_000, token).ConfigureAwait(false);

            var oldEC = await Connection.ReadBytesAsync(LinkTradePartnerPokemonOffset, 4, token).ConfigureAwait(false);

            if (pk == null)
            {
                if (poke.Type == PokeTradeType.Seed)
                {
                    await ExitSeedCheckTrade(Hub.Config, token).ConfigureAwait(false);
                }
                else
                {
                    await ExitTrade(Hub.Config, true, token).ConfigureAwait(false);
                }
                return(PokeTradeResult.TrainerTooSlow);
            }

            if (poke.Type == PokeTradeType.Seed)
            {
                // Immediately exit, we aren't trading anything.
                return(await EndSeedCheckTradeAsync(poke, pk, token).ConfigureAwait(false));
            }

            SpecialTradeType itemReq = SpecialTradeType.None;

            if (poke.Type == PokeTradeType.SpecialRequest)
            {
                itemReq = CheckItemRequest(ref pk, this, poke, TrainerName, sav);
            }
            if (itemReq == SpecialTradeType.FailReturn)
            {
                await ExitTrade(Hub.Config, false, token).ConfigureAwait(false);

                return(PokeTradeResult.IllegalTrade);
            }

            if (poke.Type == PokeTradeType.SpecialRequest && itemReq == SpecialTradeType.None)
            {
                // Immediately exit, we aren't trading anything.
                poke.SendNotification(this, "Held item was outside the bounds of the Array, or nothing was held.");
                await ResetTradePosition(Hub.Config, token).ConfigureAwait(false);

                return(PokeTradeResult.IncorrectHeldItem);
            }

            if (poke.Type == PokeTradeType.Random) // distribution
            {
                // Allow the trade partner to do a Ledy swap.
                var trade = Hub.Ledy.GetLedyTrade(pk, Hub.Config.Distribution.LedySpecies);
                if (trade != null)
                {
                    pkm            = trade.Receive;
                    poke.TradeData = pkm;

                    poke.SendNotification(this, "Injecting the requested Pokémon.");
                    await Click(A, 0_800, token).ConfigureAwait(false);
                    await SetBoxPokemon(pkm, InjectBox, InjectSlot, token, sav).ConfigureAwait(false);

                    await Task.Delay(2_500, token).ConfigureAwait(false);
                }

                for (int i = 0; i < 5; i++)
                {
                    await Click(A, 0_500, token).ConfigureAwait(false);
                }
            }
            else if (poke.Type == PokeTradeType.Clone || itemReq != SpecialTradeType.None)
            {
                // Inject the shown Pokémon.
                var clone = (PK8)pk.Clone();
                if (itemReq != SpecialTradeType.WonderCard)
                {
                    if (Hub.Config.Discord.ReturnPK8s)
                    {
                        poke.SendNotification(this, clone, "Here's what you showed me!");
                    }

                    var la = new LegalityAnalysis(clone);
                    if (!la.Valid)
                    {
                        Log($"Clone request has detected an invalid Pokémon: {(Species)clone.Species}");
                        if (DumpSetting.Dump)
                        {
                            DumpPokemon(DumpSetting.DumpFolder, "hacked", pk);
                        }

                        var report = la.Report();
                        Log(report);
                        poke.SendNotification(this, "This Pokémon is not legal per PKHeX's legality checks. I am forbidden from cloning this. Exiting trade.");
                        if (itemReq != SpecialTradeType.None)
                        {
                            poke.SendNotification(this, "SSRYour request isn't legal. Please try a different Pokémon or request.");
                            if (!string.IsNullOrWhiteSpace(Hub.Config.Web.URIEndpoint))
                            {
                                SpecialRequests.AddToPlayerLimit(TrainerName, -1);
                            }
                        }

                        poke.SendNotification(this, report);

                        await ExitTrade(Hub.Config, true, token).ConfigureAwait(false);

                        return(PokeTradeResult.IllegalTrade);
                    }

                    if (Hub.Config.Legality.ResetHOMETracker)
                    {
                        clone.Tracker = 0;
                    }


                    poke.SendNotification(this, $"**Cloned your {(Species)clone.Species}!**\nNow press B to cancel your offer and trade me a Pokémon you don't want.");
                    Log($"Cloned a {(Species)clone.Species}. Waiting for user to change their Pokémon...");
                }

                if (itemReq != SpecialTradeType.WonderCard)
                {
                    // Separate this out from WaitForPokemonChanged since we compare to old EC from original read.
                    partnerFound = await ReadUntilChanged(LinkTradePartnerPokemonOffset, oldEC, 15_000, 0_200, false, token).ConfigureAwait(false);

                    if (!partnerFound)
                    {
                        poke.SendNotification(this, "__**Change It Now Or I Am Leaving!**__");
                        // They get one more chance.
                        partnerFound = await ReadUntilChanged(LinkTradePartnerPokemonOffset, oldEC, 15_000, 0_200, false, token).ConfigureAwait(false);
                    }

                    var pk2 = await ReadUntilPresent(LinkTradePartnerPokemonOffset, 3_000, 1_000, token).ConfigureAwait(false);

                    if (!partnerFound || pk2 == null || SearchUtil.HashByDetails(pk2) == SearchUtil.HashByDetails(pk))
                    {
                        Log("Trading partner did not change their Pokémon.");
                        await ExitTrade(Hub.Config, true, token).ConfigureAwait(false);

                        return(PokeTradeResult.TrainerTooSlow);
                    }
                }

                await Click(A, 0_800, token).ConfigureAwait(false);
                await SetBoxPokemon(clone, InjectBox, InjectSlot, token, sav).ConfigureAwait(false);

                pkm = pk;

                if (itemReq == SpecialTradeType.WonderCard)
                {
                    poke.SendNotification(this, "SSRDistribution success!");
                    Log($"{(Species)clone.Species} Distribution Success!");
                }
                else if (itemReq != SpecialTradeType.None && itemReq != SpecialTradeType.Shinify)
                {
                    poke.SendNotification(this, "SSRSpecial request successful!");
                    Log($"{(Species)clone.Species} modification successful!");
                }
                else if (itemReq == SpecialTradeType.Shinify)
                {
                    poke.SendNotification(this, "Shinify success!");
                    Log($"Successfully Shinified a {(Species)clone.Species}!");


                    for (int i = 0; i < 5; i++)
                    {
                        await Click(A, 0_500, token).ConfigureAwait(false);
                    }
                }
            }
            else if (poke.Type == PokeTradeType.FixOT)
            {
                var clone = (PK8)pk.Clone();
                var adOT  = System.Text.RegularExpressions.Regex.Match(clone.OT_Name, @"(YT$)|(YT\w*$)|(Lab$)|(\.\w*)|(TV$)|(PKHeX)|(FB:)|(SysBot)|(AuSLove)|(ShinyMart)|(Blainette)").Value != "" ||
                            System.Text.RegularExpressions.Regex.Match(clone.Nickname, @"(YT$)|(YT\w*$)|(Lab$)|(\.\w*)|(TV$)|(PKHeX)|(FB:)|(SysBot)|(AuSLove)|(ShinyMart)|(Blainette)").Value != "";

                var extraInfo = $"\nBall: {(Ball)clone.Ball}\nShiny: {(clone.ShinyXor == 0 ? "Square" : clone.ShinyXor <= 16 ? "Star" : "No")}{(clone.FatefulEncounter ? "" : $"\nOT: {TrainerName}")}";
                var laInit    = new LegalityAnalysis(clone);
                if (laInit.Valid && adOT)
                {
                    clone.OT_Name       = clone.FatefulEncounter ? clone.OT_Name : $"{TrainerName}";
                    clone.PKRS_Infected = false;
                    clone.PKRS_Cured    = false;
                    clone.PKRS_Days     = 0;
                    clone.PKRS_Strain   = 0;
                }
                else if (!laInit.Valid)
                {
                    Log($"FixOT request has detected an invalid Pokémon from {poke.Trainer.TrainerName}: {(Species)clone.Species}");
                    if (DumpSetting.Dump)
                    {
                        DumpPokemon(DumpSetting.DumpFolder, "hacked", clone);
                    }

                    poke.SendNotification(this, $"```fix\nShown Pokémon is invalid. Attempting to regenerate... \n{laInit.Report()}```");
                    if (clone.FatefulEncounter)
                    {
                        clone.SetDefaultNickname(laInit);
                        var info = new SimpleTrainerInfo {
                            Gender = clone.OT_Gender, Language = clone.Language, OT = TrainerName, TID = clone.TID, SID = clone.SID
                        };
                        var mg = EncounterEvent.GetAllEvents().Where(x => x.Species == clone.Species && x.Form == clone.Form && x.IsShiny == clone.IsShiny && x.OT_Name == clone.OT_Name).ToList();
                        if (mg.Count > 0)
                        {
                            clone = TradeExtensions.CherishHandler(mg.First(), info);
                        }
                        else
                        {
                            clone = (PK8)AutoLegalityWrapper.GetTrainerInfo(8).GetLegal(AutoLegalityWrapper.GetTemplate(new ShowdownSet(ShowdownParsing.GetShowdownText(clone) + extraInfo)), out _);
                        }
                    }
                    else
                    {
                        clone = (PK8)AutoLegalityWrapper.GetTrainerInfo(8).GetLegal(AutoLegalityWrapper.GetTemplate(new ShowdownSet(ShowdownParsing.GetShowdownText(clone) + extraInfo)), out _);
                    }
                    var laRegen = new LegalityAnalysis(clone);
                    if (laRegen.Valid)
                    {
                        poke.SendNotification(this, $"```fix\nRegenerated and legalized your {(Species)clone.Species}!```");
                    }
                }
                else if (!adOT && laInit.Valid)
                {
                    poke.SendNotification(this, "```fix\nNo ad detected in Nickname or OT, and the Pokémon is legal. Exiting trade.```");
                    await ExitTrade(Hub.Config, true, token).ConfigureAwait(false);

                    return(PokeTradeResult.Aborted);
                }

                clone = (PK8)TradeExtensions.TrashBytes(clone, new LegalityAnalysis(clone));
                var la = new LegalityAnalysis(clone);
                if (!la.Valid)
                {
                    var report = la.Report();
                    Log(report);
                    poke.SendNotification(this, "This Pokémon is not legal per PKHeX's legality checks. I was unable to fix this. Exiting trade.");
                    poke.SendNotification(this, report);
                    await ExitTrade(Hub.Config, true, token).ConfigureAwait(false);

                    return(PokeTradeResult.IllegalTrade);
                }

                if (Hub.Config.Legality.ResetHOMETracker)
                {
                    clone.Tracker = 0;
                }

                poke.SendNotification(this, $"```fix\nNow confirm the trade!```");
                Log($"{(!laInit.Valid ? "Legalized" : "Fixed Nickname/OT for")} {(Species)clone.Species}!");

                bool changed = await ReadUntilChanged(LinkTradePartnerPokemonOffset, oldEC, 10_000, 0_200, false, token).ConfigureAwait(false);

                if (changed)
                {
                    Log($"{poke.Trainer.TrainerName} changed the shown Pokémon ({(Species)clone.Species})");
                    poke.SendNotification(this, $"```fix\nSend away the originally shown Pokémon, please.```");
                    changed = !await ReadUntilChanged(LinkTradePartnerPokemonOffset, oldEC, 15_000, 0_200, true, token).ConfigureAwait(false);
                }

                var pk2 = await ReadUntilPresent(LinkTradePartnerPokemonOffset, 3_000, 1_000, token).ConfigureAwait(false);

                if (changed || pk2 == null || SearchUtil.HashByDetails(pk2) != SearchUtil.HashByDetails(pk))
                {
                    Log("Trading partner did not wish to send away their ad-mon.");
                    await ExitTrade(Hub.Config, true, token).ConfigureAwait(false);

                    return(PokeTradeResult.TrainerTooSlow);
                }

                await Click(A, 0_800, token).ConfigureAwait(false);
                await SetBoxPokemon(clone, InjectBox, InjectSlot, token, sav).ConfigureAwait(false);

                pkm = clone;

                for (int i = 0; i < 5; i++)
                {
                    await Click(A, 0_500, token).ConfigureAwait(false);
                }
            }
            else if (poke.Type == PokeTradeType.Clone)
            {
                // Inject the shown Pokémon.
                var clone = (PK8)pk.Clone();

                if (Hub.Config.Discord.ReturnPK8s)
                {
                    poke.SendNotification(this, clone, "Here's what you showed me!");
                }

                var la = new LegalityAnalysis(clone);
                if (!la.Valid)
                {
                    Log($"Clone request (from {poke.Trainer.TrainerName}) has detected an invalid Pokémon: {(Species)clone.Species}.");
                    if (DumpSetting.Dump)
                    {
                        DumpPokemon(DumpSetting.DumpFolder, "hacked", clone);
                    }

                    var report = la.Report();
                    Log(report);
                    poke.SendNotification(this, "This Pokémon is not legal per PKHeX's legality checks. I am forbidden from cloning this. Exiting trade.");
                    poke.SendNotification(this, report);

                    await ExitTrade(Hub.Config, true, token).ConfigureAwait(false);

                    return(PokeTradeResult.IllegalTrade);
                }

                if (Hub.Config.Legality.ResetHOMETracker)
                {
                    clone.Tracker = 0;
                }

                poke.SendNotification(this, $"**Cloned your {(Species)clone.Species}!**\nNow press B to cancel your offer and trade me a Pokémon you don't want.");
                Log($"Cloned a {(Species)clone.Species}. Waiting for user to change their Pokémon...");

                // Separate this out from WaitForPokemonChanged since we compare to old EC from original read.
                partnerFound = await ReadUntilChanged(LinkTradePartnerPokemonOffset, oldEC, 15_000, 0_200, false, token).ConfigureAwait(false);

                if (!partnerFound)
                {
                    poke.SendNotification(this, "**HEY CHANGE IT NOW OR I AM LEAVING!!!**");
                    // They get one more chance.
                    partnerFound = await ReadUntilChanged(LinkTradePartnerPokemonOffset, oldEC, 15_000, 0_200, false, token).ConfigureAwait(false);
                }

                var pk2 = await ReadUntilPresent(LinkTradePartnerPokemonOffset, 3_000, 1_000, token).ConfigureAwait(false);

                if (!partnerFound || pk2 == null || SearchUtil.HashByDetails(pk2) == SearchUtil.HashByDetails(pk))
                {
                    Log("Trading partner did not change their Pokémon.");
                    await ExitTrade(Hub.Config, true, token).ConfigureAwait(false);

                    return(PokeTradeResult.TrainerTooSlow);
                }

                await Click(A, 0_800, token).ConfigureAwait(false);
                await SetBoxPokemon(clone, InjectBox, InjectSlot, token, sav).ConfigureAwait(false);

                pkm = clone;

                for (int i = 0; i < 5; i++)
                {
                    await Click(A, 0_500, token).ConfigureAwait(false);
                }
            }

            await Click(A, 3_000, token).ConfigureAwait(false);

            for (int i = 0; i < 5; i++)
            {
                await Click(A, 1_500, token).ConfigureAwait(false);
            }

            delay_count = 0;
            while (!await IsInBox(token).ConfigureAwait(false))
            {
                await Click(A, 3_000, token).ConfigureAwait(false);

                delay_count++;
                if (delay_count >= 50)
                {
                    break;
                }
                if (await IsOnOverworld(Hub.Config, token).ConfigureAwait(false)) // In case we are in a Trade Evolution/PokeDex Entry and the Trade Partner quits we land on the Overworld
                {
                    break;
                }
            }

            await Task.Delay(1_000 + Util.Rand.Next(0_700, 1_000), token).ConfigureAwait(false);

            await ExitTrade(Hub.Config, false, token).ConfigureAwait(false);

            Log("Exited Trade!");

            if (token.IsCancellationRequested)
            {
                return(PokeTradeResult.Aborted);
            }

            // Trade was Successful!
            var traded = await ReadBoxPokemon(InjectBox, InjectSlot, token).ConfigureAwait(false);

            // Pokémon in b1s1 is same as the one they were supposed to receive (was never sent).
            if (poke.Type != PokeTradeType.FixOT && SearchUtil.HashByDetails(traded) == SearchUtil.HashByDetails(pkm))
            {
                Log("User did not complete the trade.");
                return(PokeTradeResult.TrainerTooSlow);
            }
            else
            {
                // As long as we got rid of our inject in b1s1, assume the trade went through.
                Log("User completed the trade.");
                poke.TradeFinished(this, traded);

                // Only log if we completed the trade.
                var counts = Hub.Counts;
                if (poke.Type == PokeTradeType.Random)
                {
                    counts.AddCompletedDistribution();
                }
                else if (poke.Type == PokeTradeType.Clone)
                {
                    counts.AddCompletedClones();
                }
                else if (poke.Type == PokeTradeType.FixOT)
                {
                    counts.AddCompletedFixOTs();
                }
                else if (poke.Type == PokeTradeType.SpecialRequest)
                {
                    counts.AddCompletedSpecialRequests();
                }
                else if (poke.Type == PokeTradeType.TradeCord)
                {
                    counts.AddCompletedTradeCords();
                }
                else if (poke.Type == PokeTradeType.Giveaway)
                {
                    counts.AddCompletedGiveaways();
                }
                else
                {
                    Hub.Counts.AddCompletedTrade();
                }

                if (DumpSetting.Dump && !string.IsNullOrEmpty(DumpSetting.DumpFolder))
                {
                    var subfolder = poke.Type.ToString().ToLower();
                    DumpPokemon(DumpSetting.DumpFolder, subfolder, traded); // received
                    if (poke.Type == PokeTradeType.Specific || poke.Type == PokeTradeType.Clone || poke.Type == PokeTradeType.FixOT || poke.Type == PokeTradeType.TradeCord || poke.Type == PokeTradeType.Giveaway)
                    {
                        DumpPokemon(DumpSetting.DumpFolder, "traded", pkm); // sent to partner
                    }
                }
            }

            return(PokeTradeResult.Success);
        }
        public override async Task MainLoop(CancellationToken token)
        {
            Log("Identifying trainer data of the host console.");
            await IdentifyTrainer(token).ConfigureAwait(false);

            Log("Checking item counts...");
            var pouchData = await Connection.ReadBytesAsync(ItemTreasureAddress, 80, token).ConfigureAwait(false);

            var counts      = FossilCount.GetFossilCounts(pouchData);
            int reviveCount = counts.PossibleRevives(Hub.Config.Fossil.Species);

            if (reviveCount == 0)
            {
                Log("Insufficient fossil pieces. Please obtain at least one of each required fossil piece first.");
                return;
            }

            Config.IterateNextRoutine();

            while (!token.IsCancellationRequested && Config.NextRoutineType == PokeRoutineType.FossilBot)
            {
                await ReviveFossil(counts, token).ConfigureAwait(false);

                Log("Fossil revived. Checking details...");

                var pk = await ReadUntilPresent(await ParsePointer(giftpoke, token), 2_000, 0_200, token).ConfigureAwait(false);

                if (pk == null)
                {
                    Log("RAM probably shifted.");
                    continue;
                }

                encounterCount++;

                string showdowntext = ShowdownParsing.GetShowdownText(pk);
                if (pk.IsShiny && pk.ShinyXor == 0)
                {
                    showdowntext = showdowntext.Replace("Shiny: Yes", "Shiny: Square");
                }
                else if (pk.IsShiny)
                {
                    showdowntext = showdowntext.Replace("Shiny: Yes", "Shiny: Star");
                }

                Log($"Encounter: {encounterCount}:{Environment.NewLine}{Environment.NewLine}{showdowntext}{Environment.NewLine}{Environment.NewLine}");
                if (DumpSetting.Dump)
                {
                    DumpPokemon(DumpSetting.DumpFolder, "fossil", pk);
                }

                Counts.AddCompletedFossils();

                if (StopConditionSettings.EncounterFound(pk, DesiredIVs, Hub.Config.StopConditions))
                {
                    if (Hub.Config.StopConditions.CaptureVideoClip)
                    {
                        await Task.Delay(Hub.Config.StopConditions.ExtraTimeWaitCaptureVideo, token).ConfigureAwait(false);
                        await PressAndHold(CAPTURE, 2_000, 1_000, token).ConfigureAwait(false);
                    }

                    if (!String.IsNullOrEmpty(Hub.Config.Discord.UserTag))
                    {
                        Log($"<@{Hub.Config.Discord.UserTag}> Result found! Stopping routine execution; restart the bot(s) to search again.");
                    }
                    else
                    {
                        Log("Result found! Stopping routine execution; restart the bot(s) to search again.");
                    }

                    await DetachController(token).ConfigureAwait(false);

                    return;
                }
                else
                {
                    await CloseGame(Hub.Config, token).ConfigureAwait(false);
                    await StartGame(Hub.Config, token).ConfigureAwait(false);
                }
            }
        }
Beispiel #19
0
        private static bool AddToTradeQueue(SocketCommandContext context, T pk, int code, string trainerName, RequestSignificance sig, PokeRoutineType type, PokeTradeType t, SocketUser trader, out string msg, int catchID = 0)
        {
            var user   = trader;
            var userID = user.Id;
            var name   = user.Username;

            var trainer  = new PokeTradeTrainerInfo(trainerName, userID);
            var notifier = new DiscordTradeNotifier <T>(pk, trainer, code, user);
            var detail   = new PokeTradeDetail <T>(pk, trainer, notifier, t, code, sig == RequestSignificance.Favored);
            var trade    = new TradeEntry <T>(detail, userID, type, name);

            var hub   = SysCord <T> .Runner.Hub;
            var Info  = hub.Queues.Info;
            var added = Info.AddToTradeQueue(trade, userID, sig == RequestSignificance.Owner);

            if (added == QueueResultAdd.AlreadyInQueue)
            {
                msg = "Sorry, you are already in the queue.";
                return(false);
            }

            if (detail.Type == PokeTradeType.TradeCord)
            {
                TradeCordHelper <T> .TradeCordTrades.Add(trader.Id, catchID);
            }

            var position = Info.CheckPosition(userID, type);

            var ticketID = "";

            if (TradeStartModule <T> .IsStartChannel(context.Channel.Id))
            {
                ticketID = $", unique ID: {detail.ID}";
            }

            var pokeName = "";

            if ((t == PokeTradeType.Specific || t == PokeTradeType.TradeCord || t == PokeTradeType.SupportTrade || t == PokeTradeType.Giveaway) && pk.Species != 0)
            {
                pokeName = $" Receiving: {(t == PokeTradeType.SupportTrade && pk.Species != (int)Species.Ditto && pk.HeldItem != 0 ? $"{(Species)pk.Species} ({ShowdownParsing.GetShowdownText(pk).Split('@','\n')[1].Trim()})" : $"{(Species)pk.Species}")}.";
            }
            msg = $"{user.Mention} - Added to the {type} queue{ticketID}. Current Position: {position.Position}.{pokeName}";

            var botct = Info.Hub.Bots.Count;

            if (position.Position > botct)
            {
                var eta = Info.Hub.Config.Queues.EstimateDelay(position.Position, botct);
                msg += $" Estimated: {eta:F1} minutes.";
            }
            return(true);
        }
Beispiel #20
0
        public static string GetFormattedShowdownText(PKM pkm)
        {
            var showdown = ShowdownParsing.GetShowdownText(pkm);

            return(Format.Code(showdown));
        }