Esempio n. 1
0
        public dynamic CheckLegality([FromForm][Required] IFormFile pokemon, [FromForm] string generation, bool bot)
        {
            using var memoryStream = new MemoryStream();
            pokemon.CopyTo(memoryStream);
            PKM pkm;

            byte[] data = memoryStream.ToArray();
            try
            {
                if (string.IsNullOrEmpty(generation))
                {
                    pkm = PKMConverter.GetPKMfromBytes(data);
                    if (pkm == null)
                    {
                        throw new System.ArgumentException("Bad data!");
                    }
                    generation = Utils.GetGeneration(pkm);
                }
                else
                {
                    pkm = Utils.GetPKMwithGen(generation, data);
                    if (pkm == null)
                    {
                        throw new System.ArgumentException("Bad generation!");
                    }
                }
            }
            catch
            {
                Response.StatusCode = 400;
                return("Bad Data Was Provided");
            }

            if (!Utils.PokemonExistsInGeneration(generation, pkm.Species))
            {
                Response.StatusCode = 400;
                return("Pokemon not in generation!");
            }

            var la = new LegalityAnalysis(pkm);

            if (bot)
            {
                return(la.Report());
            }

            return(new { report = la.Report().Replace("\r", string.Empty).Split('\n'), legal = la.Valid });
        }
Esempio n. 2
0
        /// <summary>
        /// Main function that auto legalizes based on the legality
        /// </summary>
        /// <remarks>Leverages <see cref="Core"/>'s <see cref="EncounterMovesetGenerator"/> to create a <see cref="PKM"/> from a <see cref="ShowdownSet"/>.</remarks>
        /// <param name="dest">Destination for the generated pkm</param>
        /// <param name="template">rough pkm that has all the <see cref="set"/> values entered</param>
        /// <param name="set">Showdown set object</param>
        /// <param name="satisfied">If the final result is satisfactory, otherwise use deprecated bruteforce auto legality functionality</param>
        public static PKM GetLegalFromTemplate(this ITrainerInfo dest, PKM template, ShowdownSet set, out bool satisfied)
        {
            set = set.PreProcessShowdownSet();
            var Form = SanityCheckForm(template, ref set);

            template.ApplySetDetails(set);
            template.SetRecordFlags(); // Validate TR moves for the encounter
            var destType = template.GetType();
            var destVer  = (GameVersion)dest.Game;

            if (destVer <= 0 && dest is SaveFile s)
            {
                destVer = s.Version;
            }

            var gamelist = GameUtil.GetVersionsWithinRange(template, template.Format).OrderByDescending(c => c.GetGeneration()).ToArray();

            EncounterMovesetGenerator.PriorityList = new[] { EncounterOrder.Egg, EncounterOrder.Static, EncounterOrder.Trade, EncounterOrder.Slot, EncounterOrder.Mystery };
            var encounters = EncounterMovesetGenerator.GenerateEncounters(pk: template, moves: set.Moves, gamelist);

            if (template.Species <= 721)
            {
                encounters = encounters.Concat(GetFriendSafariEncounters(template));
            }
            foreach (var enc in encounters)
            {
                var ver = enc is IVersion v ? v.Version : destVer;
                var gen = enc is IGeneration g ? g.Generation : dest.Generation;
                var tr  = UseTrainerData ? TrainerSettings.GetSavedTrainerData(ver, gen) : TrainerSettings.DefaultFallback(gen);
                var raw = SanityCheckEncounters(enc).ConvertToPKM(tr);
                if (raw.IsEgg) // PGF events are sometimes eggs. Force hatch them before proceeding
                {
                    raw.HandleEggEncounters(enc, tr);
                }
                var pk = PKMConverter.ConvertToType(raw, destType, out _);
                if (pk == null)
                {
                    continue;
                }

                ApplySetDetails(pk, set, Form, raw, dest, enc);
                if (set.CanGigantamax && pk is IGigantamax gmax)
                {
                    if (!gmax.CanGigantamax)
                    {
                        continue;
                    }
                }

                var la = new LegalityAnalysis(pk);
                if (la.Valid)
                {
                    satisfied = true;
                    return(pk);
                }
                Debug.WriteLine(la.Report());
            }
            satisfied = false;
            return(template);
        }
Esempio n. 3
0
        /// <summary>
        /// Set a valid Pokeball based on a legality check's suggestions.
        /// </summary>
        /// <param name="pk">Pokémon to modify</param>
        /// <param name="matching">Set matching ball</param>
        public static void SetSuggestedBall(this PKM pk, bool matching = true)
        {
            if (matching)
            {
                if (!pk.IsShiny)
                {
                    pk.SetMatchingBall();
                }
                else
                {
                    Aesthetics.ApplyShinyBall(pk);
                }
            }
            var la     = new LegalityAnalysis(pk);
            var report = la.Report();

            if (!report.Contains(LegalityCheckStrings.LBallEncMismatch))
            {
                return;
            }
            if (pk.GenNumber == 5 && pk.Met_Location == 75)
            {
                pk.Ball = (int)Ball.Dream;
            }
            else
            {
                pk.Ball = 4;
            }
        }
Esempio n. 4
0
        private async Task LegalityCheck(IAttachment att, bool verbose)
        {
            var download = await NetUtil.DownloadPKMAsync(att).ConfigureAwait(false);

            if (!download.Success)
            {
                await ReplyAsync(download.ErrorMessage).ConfigureAwait(false);

                return;
            }

            var pkm     = download.Data !;
            var la      = new LegalityAnalysis(pkm);
            var builder = new EmbedBuilder
            {
                Color       = la.Valid ? Color.Green : Color.Red,
                Description = $"Legality Report for {download.SanitizedFileName}:"
            };

            builder.AddField(x =>
            {
                x.Name     = la.Valid ? "Valid" : "Invalid";
                x.Value    = la.Report(verbose);
                x.IsInline = false;
            });

            await ReplyAsync("Here's the legality report!", false, builder.Build()).ConfigureAwait(false);
        }
Esempio n. 5
0
        private static void Main(string[] args)
        {
            var pk = CreatePKMfromArgs(args);

            if (args.Contains(RequestLegalityCheck))
            {
                var lc      = new LegalityAnalysis(pk);
                var verbose = args.Contains("--verbose");
                Console.WriteLine(lc.Report(verbose));
            }

            if (!args.Contains(RequestLegalization))
            {
                return;
            }

            if (!args.Contains("--version"))
            {
                Console.WriteLine("Specify version with the [--version] tag");
                return;
            }

            var ver = GetArgVal(args, "--version");

            pk = ConsoleLegalizer.GetLegalPKM(pk, ver);
            var outPath = GetOutputPath(args, pk);

            File.WriteAllBytes(outPath, pk.DecryptedBoxData);
        }
Esempio n. 6
0
        /// <summary>
        /// Main function that auto legalizes based on the legality
        /// </summary>
        /// <remarks>Leverages <see cref="Core"/>'s <see cref="EncounterMovesetGenerator"/> to create a <see cref="PKM"/> from a <see cref="ShowdownSet"/>.</remarks>
        /// <param name="dest">Destination for the generated pkm</param>
        /// <param name="template">rough pkm that has all the <see cref="set"/> values entered</param>
        /// <param name="set">Showdown set object</param>
        /// <param name="satisfied">If the final result is satisfactory, otherwise use current auto legality functionality</param>
        public static PKM GetLegalFromTemplate(this ITrainerInfo dest, PKM template, ShowdownSet set, out bool satisfied)
        {
            var Form = SanityCheckForm(template, ref set);

            template.ApplySetDetails(set);
            var destType = template.GetType();
            var destVer  = (GameVersion)dest.Game;

            if (destVer <= 0 && dest is SaveFile s)
            {
                destVer = s.Version;
            }

            var encounters = EncounterMovesetGenerator.GenerateEncounters(pk: template, moves: set.Moves);

            foreach (var enc in encounters)
            {
                var ver = enc is IVersion v ? v.Version : destVer;
                var gen = enc is IGeneration g ? g.Generation : dest.Generation;
                var tr  = TrainerSettings.GetSavedTrainerData(ver, gen);
                var raw = enc.ConvertToPKM(tr);
                var pk  = PKMConverter.ConvertToType(raw, destType, out _);
                ApplySetDetails(pk, set, Form, raw, dest);

                var la = new LegalityAnalysis(pk);
                if (la.Valid)
                {
                    satisfied = true;
                    return(pk);
                }
                Debug.WriteLine(la.Report());
            }
            satisfied = false;
            return(template);
        }
Esempio n. 7
0
        public string Post()
        {
            if (Request.ContentType != "application/octet-stream")
            {
                return(string.Empty);
            }
            if (Request.Body.Length == 0)
            {
                return(string.Empty);
            }

            var ver = Request.Headers["Version"];

            if (string.IsNullOrWhiteSpace(ver))
            {
                return(string.Empty);
            }

            var data = new byte[Request.Body.Length];

            using (var ms = new MemoryStream(data))
                Request.Body.CopyTo(ms);

            try
            {
                var pk = PKMConverter.GetPKMfromBytes(data);
                var la = new LegalityAnalysis(pk);
                return(la.Report());
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.Message);
                return(string.Empty);
            }
        }
Esempio n. 8
0
        private async Task <PokeTradeResult> ProcessGiveawayUploadAsync(PokeTradeDetail <PK8> detail, CancellationToken token)
        {
            int ctr       = 0;
            var time      = TimeSpan.FromSeconds(Hub.Config.Trade.MaxDumpTradeTime);
            var start     = DateTime.Now;
            var pkprev    = new PK8();
            var poolEntry = detail.PoolEntry;

            while (ctr < 1 && DateTime.Now - start < time)
            {
                var pk = await ReadUntilPresent(LinkTradePartnerPokemonOffset, 3_000, 1_000, token).ConfigureAwait(false);

                if (pk == null || pk.Species < 1 || !pk.ChecksumValid || SearchUtil.HashByDetails(pk) == SearchUtil.HashByDetails(pkprev))
                {
                    continue;
                }

                // Save the new Pokémon for comparison next round.
                pkprev            = pk;
                poolEntry.PK8     = pk;
                poolEntry.Pokemon = SpeciesName.GetSpeciesName(pk.Species, 2);

                if (Hub.Config.Legality.VerifyLegality)
                {
                    LogUtil.LogInfo($"Performing legality check on {poolEntry.Pokemon}", "PokeTradeBot.GiveawayUpload");
                    var la      = new LegalityAnalysis(poolEntry.PK8);
                    var verbose = la.Report(true);
                    LogUtil.LogInfo($"Shown Pokémon is {(la.Valid ? "Valid" : "Invalid")}.", "PokeTradeBot.GiveawayUpload");
                    detail.SendNotification(this, pk, $"Pokémon sent is {(la.Valid ? "Valid" : "Invalid")}.");
                    detail.SendNotification(this, pk, verbose);
                    if (!la.Valid)
                    {
                        detail.SendNotification(this, pk, $"Show a different pokemon to continue or exit the trade to end.");
                        continue;
                    }
                }
                LogUtil.LogInfo("Creating new database entry", "PokeTradeBot.GiveawayUpload");
                Hub.GiveawayPoolDatabase.NewEntry(poolEntry);
                if (Hub.Config.Discord.ReturnPK8s)
                {
                    detail.SendNotification(this, pk, "Here's what you showed me!");
                }

                ctr++;
            }

            LogUtil.LogInfo($"Ended Giveaway pool upload", "PokeTradeBot.GiveawayUpload");
            await ExitSeedCheckTrade(Hub.Config, token).ConfigureAwait(false);

            if (ctr == 0)
            {
                return(PokeTradeResult.TrainerTooSlow);
            }

            detail.Notifier.SendNotification(this, detail, $"Finished uploading Pokémon to the Giveaway Pool.");
            detail.Notifier.TradeFinished(this, detail, detail.TradeData); // blank pk8
            return(PokeTradeResult.Success);
        }
Esempio n. 9
0
        /// <summary>
        /// Main function that auto legalizes based on the legality
        /// </summary>
        /// <remarks>Leverages <see cref="Core"/>'s <see cref="EncounterMovesetGenerator"/> to create a <see cref="PKM"/> from a <see cref="IBattleTemplate"/>.</remarks>
        /// <param name="dest">Destination for the generated pkm</param>
        /// <param name="template">rough pkm that has all the <see cref="set"/> values entered</param>
        /// <param name="set">Showdown set object</param>
        /// <param name="satisfied">If the final result is satisfactory, otherwise use deprecated bruteforce auto legality functionality</param>
        public static PKM GetLegalFromTemplate(this ITrainerInfo dest, PKM template, IBattleTemplate set, out bool satisfied)
        {
            if (set is RegenTemplate t)
            {
                t.FixGender(template.PersonalInfo);
            }
            template.ApplySetDetails(set);
            template.SetRecordFlags(); // Validate TR moves for the encounter
            var isHidden = template.AbilityNumber == 4;
            var destType = template.GetType();
            var destVer  = (GameVersion)dest.Game;

            if (destVer <= 0 && dest is SaveFile s)
            {
                destVer = s.Version;
            }

            var gamelist   = GameUtil.GetVersionsWithinRange(template, template.Format).OrderByDescending(c => c.GetGeneration()).ToArray();
            var encounters = EncounterMovesetGenerator.GenerateEncounters(pk: template, moves: set.Moves, gamelist);

            encounters = encounters.Concat(GetFriendSafariEncounters(template));
            foreach (var enc in encounters)
            {
                if (!IsEncounterValid(set, enc, isHidden, destVer, out var ver))
                {
                    continue;
                }
                var tr  = UseTrainerData ? TrainerSettings.GetSavedTrainerData(ver, enc.Generation) : TrainerSettings.DefaultFallback(enc.Generation);
                var raw = SanityCheckEncounters(enc).ConvertToPKM(tr);
                if (raw.IsEgg) // PGF events are sometimes eggs. Force hatch them before proceeding
                {
                    raw.HandleEggEncounters(enc, tr);
                }
                var pk = PKMConverter.ConvertToType(raw, destType, out _);
                if (pk == null)
                {
                    continue;
                }

                ApplySetDetails(pk, set, raw, dest, enc);
                if (pk is IGigantamax gmax && gmax.CanGigantamax != set.CanGigantamax)
                {
                    continue;
                }

                var la = new LegalityAnalysis(pk);
                if (la.Valid)
                {
                    satisfied = true;
                    return(pk);
                }
                Debug.WriteLine($"{la.Report()}\n");
            }
            satisfied = false;
            return(template);
        }
Esempio n. 10
0
        private async Task <PokeTradeResult> ProcessDumpTradeAsync(PokeTradeDetail <PB8> detail, CancellationToken token)
        {
            int ctr   = 0;
            var time  = TimeSpan.FromSeconds(Hub.Config.Trade.MaxDumpTradeTime);
            var start = DateTime.Now;

            while (ctr < Hub.Config.Trade.MaxDumpsPerTrade && DateTime.Now - start < time)
            {
                // Wait for user input... Needs to be different from the previously offered Pokémon.
                var tradeOffered = await ReadUntilChanged(LinkTradePokemonOffset, lastOffered, 3_000, 1_000, false, true, token).ConfigureAwait(false);

                if (!tradeOffered)
                {
                    continue;
                }

                // If we detected a change, they offered something.
                var pk = await ReadPokemon(LinkTradePokemonOffset, BoxFormatSlotSize, token).ConfigureAwait(false);

                var newEC = await SwitchConnection.ReadBytesAbsoluteAsync(LinkTradePokemonOffset, 8, token).ConfigureAwait(false);

                if (pk == null || pk.Species < 1 || !pk.ChecksumValid || lastOffered == newEC)
                {
                    continue;
                }
                lastOffered = newEC;

                // Send results from separate thread; the bot doesn't need to wait for things to be calculated.
                if (DumpSetting.Dump)
                {
                    var subfolder = detail.Type.ToString().ToLower();
                    DumpPokemon(DumpSetting.DumpFolder, subfolder, pk); // received
                }

                var la      = new LegalityAnalysis(pk);
                var verbose = la.Report(true);
                Log($"Shown Pokémon is: {(la.Valid ? "Valid" : "Invalid")}.");

                detail.SendNotification(this, pk, verbose);
                ctr++;
            }

            Log($"Ended Dump loop after processing {ctr} Pokémon.");
            if (ctr == 0)
            {
                return(PokeTradeResult.TrainerTooSlow);
            }

            TradeSettings.AddCompletedDumps();
            detail.Notifier.SendNotification(this, detail, $"Dumped {ctr} Pokémon.");
            detail.Notifier.TradeFinished(this, detail, detail.TradeData); // blank pk8
            return(PokeTradeResult.Success);
        }
Esempio n. 11
0
        /// <summary>
        /// Main function that auto legalizes based on the legality
        /// </summary>
        /// <remarks>Leverages <see cref="Core"/>'s <see cref="EncounterMovesetGenerator"/> to create a <see cref="PKM"/> from a <see cref="ShowdownSet"/>.</remarks>
        /// <param name="dest">Destination for the generated pkm</param>
        /// <param name="template">rough pkm that has all the <see cref="set"/> values entered</param>
        /// <param name="set">Showdown set object</param>
        /// <param name="satisfied">If the final result is satisfactory, otherwise use deprecated bruteforce auto legality functionality</param>
        public static PKM GetLegalFromTemplate(this ITrainerInfo dest, PKM template, ShowdownSet set, out bool satisfied)
        {
            var Form = SanityCheckForm(template, ref set);

            template.ApplySetDetails(set);
            template.SetRecordFlags(); // Validate TR moves for the encounter
            var destType = template.GetType();
            var destVer  = (GameVersion)dest.Game;

            if (destVer <= 0 && dest is SaveFile s)
            {
                destVer = s.Version;
            }

            var gamelist   = GameUtil.GetVersionsWithinRange(template, template.Format).OrderByDescending(c => c.GetGeneration()).ToArray();
            var encounters = EncounterMovesetGenerator.GenerateEncounters(pk: template, moves: set.Moves, gamelist);

            foreach (var enc in encounters)
            {
                var          ver = enc is IVersion v ? v.Version : destVer;
                var          gen = enc is IGeneration g ? g.Generation : dest.Generation;
                ITrainerInfo tr  = new SimpleTrainerInfo(ver);
                if (UseTrainerData)
                {
                    tr = TrainerSettings.GetSavedTrainerData(ver, gen, new SimpleTrainerInfo(ver));
                }
                var raw = SanityCheckEncounters(enc).ConvertToPKM(tr);
                var pk  = PKMConverter.ConvertToType(raw, destType, out _);
                if (pk == null)
                {
                    continue;
                }

                ApplySetDetails(pk, set, Form, raw, dest, enc);
                if (set.CanGigantamax && pk is IGigantamax gmax)
                {
                    if (!gmax.CanGigantamax)
                    {
                        continue;
                    }
                }

                var la = new LegalityAnalysis(pk);
                if (la.Valid)
                {
                    satisfied = true;
                    return(pk);
                }
                Debug.WriteLine(la.Report());
            }
            satisfied = false;
            return(template);
        }
        public static void CheckAndSetFateful(PKM pk)
        {
            LegalityAnalysis la     = new LegalityAnalysis(pk);
            string           Report = la.Report();

            if (Report.Contains(LFatefulMysteryMissing) || Report.Contains(LFatefulMissing))
            {
                pk.FatefulEncounter = true;
            }
            if (Report.Contains(LFatefulInvalid))
            {
                pk.FatefulEncounter = false;
            }
        }
Esempio n. 13
0
        private async Task <PokeTradeResult> ProcessDumpTradeAsync(PokeTradeDetail <PK8> detail, CancellationToken token)
        {
            int ctr   = 0;
            var time  = TimeSpan.FromSeconds(Hub.Config.Trade.MaxDumpTradeTime);
            var start = DateTime.Now;

            while (ctr < Hub.Config.Trade.MaxDumpsPerTrade && DateTime.Now - start < time)
            {
                bool found = await WaitForPokemonChanged(LinkTradePartnerPokemonOffset, 15_000, 1_000, token);

                if (!found)
                {
                    continue;
                }

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

                if (pk == null || pk.Species < 1 || !pk.ChecksumValid)
                {
                    continue;
                }

                // Send results from separate thread; the bot doesn't need to wait for things to be calculated.
                if (DumpSetting.Dump)
                {
                    var subfolder = detail.Type.ToString().ToLower();
                    DumpPokemon(DumpSetting.DumpFolder, subfolder, pk); // received
                }

                var la      = new LegalityAnalysis(pk);
                var verbose = la.Report(true);
                Log($"Shown Pokémon is {(la.Valid ? "Valid" : "Invalid")}.");

                detail.SendNotification(this, pk, verbose);
                ctr++;
            }

            Log($"Ended Dump loop after processing {ctr} Pokémon");
            await ExitSeedCheckTrade(Hub.Config, token).ConfigureAwait(false);

            if (ctr == 0)
            {
                return(PokeTradeResult.TrainerTooSlow);
            }

            Hub.Counts.AddCompletedDumps();
            detail.Notifier.SendNotification(this, detail, $"Dumped {ctr} Pokémon.");
            detail.Notifier.TradeFinished(this, detail, detail.TradeData); // blank pk8
            return(PokeTradeResult.Success);
        }
Esempio n. 14
0
        public static void CheckAndSetFateful(PKM pk)
        {
            LegalityAnalysis la     = new LegalityAnalysis(pk);
            string           Report = la.Report();

            if (Report.Contains(V322) || Report.Contains(V324))
            {
                pk.FatefulEncounter = true;
            }
            if (Report.Contains(V325))
            {
                pk.FatefulEncounter = false;
            }
        }
Esempio n. 15
0
        /// <summary>
        /// Quick Gender Toggle
        /// </summary>
        /// <param name="pk">PKM whose gender needs to be toggled</param>
        /// <param name="set">Showdown Set for Gender reference</param>
        public static void FixGender(this PKM pk, ShowdownSet set)
        {
            pk.SetGender(set.Gender);
            var    la     = new LegalityAnalysis(pk);
            string Report = la.Report();

            if (Report.Contains(LegalityCheckStrings.LPIDGenderMismatch))
            {
                pk.Gender = pk.Gender == 0 ? 1 : 0;
            }

            if (pk.Gender != 0 && pk.Gender != 1)
            {
                pk.Gender = pk.GetSaneGender();
            }
        }
        public void SendNotification(PokeRoutineExecutor routine, PokeTradeDetail <T> info, LegalityAnalysis la)
        {
            var builder = new EmbedBuilder
            {
                Color       = la.Valid ? Color.Green : Color.Red,
                Description = $"Legality Report for {info.TradeData.Species}:"
            };

            builder.AddField(x =>
            {
                x.Name     = la.Valid ? "Valid" : "Invalid";
                x.Value    = la.Report(true);
                x.IsInline = false;
            });
            LogUtil.LogInfo("We're running the LC!", "Discord");
            Trader.SendMessageAsync(embed: builder.Build()).ConfigureAwait(false);
        }
Esempio n. 17
0
        /// <summary>
        /// Set a valid Pokeball based on a legality check's suggestions.
        /// </summary>
        /// <param name="pk">Pokémon to modify</param>
        public static void SetSuggestedBall(this PKM pk)
        {
            var la     = new LegalityAnalysis(pk);
            var report = la.Report();

            if (!report.Contains(LegalityCheckStrings.LBallEncMismatch))
            {
                return;
            }
            if (pk.GenNumber == 5 && pk.Met_Location == 75)
            {
                pk.Ball = (int)Ball.Dream;
            }
            else
            {
                pk.Ball = 4;
            }
        }
Esempio n. 18
0
        private static PKM M2EventFix(PKM pk, bool shiny)
        {
            int  eggloc = pk.Egg_Location;
            bool feFlag = pk.FatefulEncounter;

            pk.Egg_Location     = 0;
            pk.FatefulEncounter = true;
            string[] NatureHPIVs = IVtoPIDGenerator.GetIVPID((uint)pk.Nature, pk.HPType, false, IVPIDMethod.M2);
            pk.PID = Util.GetHexValue(NatureHPIVs[0]);
            if (pk.GenNumber < 5)
            {
                pk.EncryptionConstant = pk.PID;
            }
            pk.IV_HP  = Convert.ToInt32(NatureHPIVs[1]);
            pk.IV_ATK = Convert.ToInt32(NatureHPIVs[2]);
            pk.IV_DEF = Convert.ToInt32(NatureHPIVs[3]);
            pk.IV_SPA = Convert.ToInt32(NatureHPIVs[4]);
            pk.IV_SPD = Convert.ToInt32(NatureHPIVs[5]);
            pk.IV_SPE = Convert.ToInt32(NatureHPIVs[6]);
            if (shiny)
            {
                pk.SetShinySID();
            }
            var    recheckLA     = new LegalityAnalysis(pk);
            string updatedReport = recheckLA.Report();

            if (updatedReport.Contains(LPIDGenderMismatch))
            {
                pk.Gender = pk.Gender == 0 ? 1 : 0;
                var recheckLA2 = new LegalityAnalysis(pk);
                updatedReport = recheckLA2.Report();
            }

            if (!updatedReport.Contains(LPIDTypeMismatch) || UsesEventBasedMethod(pk.Species, pk.Moves, PIDType.Method_2))
            {
                return(pk);
            }
            Debug.WriteLine(GetReport(pk));
            pk.FatefulEncounter = feFlag;
            pk.Egg_Location     = eggloc;
            return(pk);
        }
Esempio n. 19
0
        private PKM Legalize(PKM pk, GameVersion ver)
        {
            Report = la.Report();
            var sav = SaveUtil.GetBlankSAV(ver, pk.OT_Name);

            sav.TID      = pk.TID;
            sav.SID      = pk.SID;
            sav.Language = pk.Language;
            PKM upd = sav.Legalize(pk.Clone());

            upd.SetTrainerData(GetTrainerInfo(pk, ver));
            la = new LegalityAnalysis(upd);
            if (la.Valid)
            {
                legalpk    = upd;
                Successful = true;
                return(legalpk);
            }
            return(null);
        }
Esempio n. 20
0
 private PKM ProcessALM(PKM pkm, CancellationTokenSource cts, GameVersion ver = GameVersion.GP)
 {
     la = new LegalityAnalysis(pkm);
     if (la.Valid)
     {
         legalpk = pkm;
         Ran     = false;
         Report  = la.Report();
         cts.Cancel();
         return(legalpk);
     }
     Task.Run(() =>
     {
         var thread = Thread.CurrentThread.ManagedThreadId;
         Console.WriteLine($"Legalization on Thread ({thread}) has started at: {DateTime.Now:F}");
         legalpk = Legalize(pkm, ver);
         Console.WriteLine($"Legalization on Thread ({thread}) has finished at: {DateTime.Now:F}");
         cts.Cancel();
     }, cts.Token);
     return(legalpk);
 }
        /// <summary>
        /// Quick Gender Toggle
        /// </summary>
        /// <param name="pk">PKM whose gender needs to be toggled</param>
        /// <param name="set">Showdown Set for Gender reference</param>
        public static void FixGender(this PKM pk, IBattleTemplate set)
        {
            pk.ApplySetGender(set);
            var la = new LegalityAnalysis(pk);

            if (la.Valid)
            {
                return;
            }
            string Report = la.Report();

            if (Report.Contains(LegalityCheckStrings.LPIDGenderMismatch))
            {
                pk.Gender = pk.Gender == 0 ? 1 : 0;
            }

            if (pk.Gender != 0 && pk.Gender != 1)
            {
                pk.Gender = pk.GetSaneGender();
            }
        }
Esempio n. 22
0
        private void UpdateLegality(PKM pkm, bool skipMoveRepop = false)
        {
            LegalityAnalysis Legality = new LegalityAnalysis(pkm);

            if (debug)
            {
                Console.WriteLine(Legality.Report(true));
            }
            // Refresh Move Legality
            bool[] validmoves = new bool[] { false, false, false, false };
            for (int i = 0; i < 4; i++)
            {
                validmoves[i] = !Legality.Info?.Moves[i].Valid ?? false;
            }

            bool[] validrelearn = new bool[] { false, false, false, false };
            if (pkm.Format >= 6)
            {
                for (int i = 0; i < 4; i++)
                {
                    validrelearn[i] = !Legality.Info?.Relearn[i].Valid ?? false;
                }
            }

            if (skipMoveRepop)
            {
                return;
            }
            // Resort moves
            bool fieldsLoaded = true;
            bool tmp          = fieldsLoaded;

            fieldsLoaded = false;
            var cb       = new[] { pkm.Move1, pkm.Move2, pkm.Move3, pkm.Move4 };
            var moves    = Legality.AllSuggestedMovesAndRelearn;
            var moveList = GameInfo.MoveDataSource.OrderByDescending(m => moves.Contains(m.Value)).ToArray();

            fieldsLoaded |= tmp;
            LegalityChanged?.Invoke(Legality.Valid, null);
        }
Esempio n. 23
0
        private async Task LegalityCheck(IAttachment att, bool verbose)
        {
            if (!PKX.IsPKM(att.Size))
            {
                await ReplyAsync($"{att.Filename}: Invalid size.").ConfigureAwait(false);

                return;
            }

            string url = att.Url;

            // Download the resource and load the bytes into a buffer.
            byte[] buffer = await webClient.DownloadDataTaskAsync(url).ConfigureAwait(false);

            var pkm = PKMConverter.GetPKMfromBytes(buffer);

            if (pkm == null)
            {
                await ReplyAsync($"{att.Filename}: Invalid pkm attachment.").ConfigureAwait(false);

                return;
            }

            var la      = new LegalityAnalysis(pkm);
            var builder = new EmbedBuilder
            {
                Color       = la.Valid ? Color.Green : Color.Red,
                Description = $"Legality Report for {att.Filename}:"
            };

            builder.AddField(x =>
            {
                x.Name     = la.Valid ? "Valid" : "Invalid";
                x.Value    = la.Report(verbose);
                x.IsInline = false;
            });

            await ReplyAsync("Here's the legality report!", false, builder.Build()).ConfigureAwait(false);
        }
Esempio n. 24
0
        public static PKM Legalize(PKM pk, GameVersion ver, LegalityAnalysis old = null)
        {
            if (old != null)
            {
                Debug.WriteLine(old.Report());
            }

            var sav     = SaveUtil.GetBlankSAV(ver, "PKHeX");
            var updated = sav.Legalize(pk);
            var la      = new LegalityAnalysis(updated);

            if (!la.Valid)
            {
                return(pk);
            }

            Console.WriteLine("====================================");
            Console.WriteLine("= Legalized with Auto Legality Mod =");
            Console.WriteLine("====================================");
            Console.WriteLine(la.Report(true));
            return(updated);
        }
Esempio n. 25
0
        /// <summary>
        /// Quick Gender Toggle
        /// </summary>
        /// <param name="pk">PKM whose gender needs to be toggled</param>
        /// <param name="SSet">Showdown Set for Gender reference</param>
        public static void FixGender(PKM pk, ShowdownSet SSet)
        {
            pk.SetGender(SSet.Gender);
            LegalityAnalysis la     = new LegalityAnalysis(pk);
            string           Report = la.Report();

            if (Report.Contains(V255))
            {
                if (pk.Gender == 0)
                {
                    pk.Gender = 1;
                }
                else
                {
                    pk.Gender = 0;
                }
            }
            if (pk.Gender != 0 && pk.Gender != 1)
            {
                pk.Gender = pk.GetSaneGender();
            }
        }
Esempio n. 26
0
        /// <summary>
        /// Set a valid Pokeball based on a legality check's suggestions.
        /// </summary>
        /// <param name="pk">Pokémon to modify</param>
        /// <param name="matching">Set matching ball</param>
        /// <param name="force"></param>
        /// <param name="ball"></param>
        public static void SetSuggestedBall(this PKM pk, bool matching = true, bool force = false, Ball ball = Ball.None)
        {
            if (ball != Ball.None)
            {
                var orig = pk.Ball;
                pk.Ball = (int)ball;
                if (!force && !pk.ValidBall())
                {
                    pk.Ball = orig;
                }
            }
            else if (matching)
            {
                if (!pk.IsShiny)
                {
                    pk.SetMatchingBall();
                }
                else
                {
                    Aesthetics.ApplyShinyBall(pk);
                }
            }
            var la     = new LegalityAnalysis(pk);
            var report = la.Report();

            if (!report.Contains(LegalityCheckStrings.LBallEncMismatch) || force)
            {
                return;
            }
            if (pk.Generation == 5 && pk.Met_Location == 75)
            {
                pk.Ball = (int)Ball.Dream;
            }
            else
            {
                pk.Ball = 4;
            }
        }
Esempio n. 27
0
        private bool IsLegal(PK8 pk, PokeTradeDetail <PK8> poke)
        {
            var la = new LegalityAnalysis(pk);

            if (!la.Valid && Hub.Config.Legality.VerifyLegality)
            {
                Log($"Clone request has detected an invalid Pokémon: {(Species)pk.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.");
                poke.SendNotification(this, report);
                return(false);
            }
            else
            {
                return(true);
            }
        }
Esempio n. 28
0
        public Pokemon CreatePKMN()
        {
            try
            {
                var country  = "N/A";
                var region   = "N/A";
                var dsregion = "N/A";
                if (CountryID != "N/A" && CountryID != "0")
                {
                    System.Tuple <string, string> cr = GeoLocation.GetCountryRegionText(int.Parse(CountryID), int.Parse(RegionID), "en");
                    country = cr.Item1;
                    region  = cr.Item2;
                }
                switch (DSRegionID)
                {
                case "N/A":
                    dsregion = "None";
                    break;

                case "0":
                    dsregion = "Japan";
                    break;

                case "1":
                    dsregion = "North America";
                    break;

                case "2":
                    dsregion = "Europe";
                    break;

                case "3":
                    dsregion = "China";
                    break;

                case "4":
                    dsregion = "Korea";
                    break;

                case "5":
                    dsregion = "Taiwan";
                    break;
                }
                var lc   = new LegalityAnalysis(pkm);
                var pkmn = new Pokemon
                {
                    ATK            = ATK,
                    ATK_EV         = ATK_EV,
                    ATK_IV         = ATK_IV,
                    Ability        = Ability,
                    AbilityNum     = AbilityNum,
                    AltForms       = AltForms,
                    Ball           = Ball,
                    Beauty         = Beauty,
                    Cool           = Cool,
                    Country        = country,
                    CountryID      = CountryID,
                    Cute           = Cute,
                    DEF            = DEF,
                    DEF_EV         = DEF_EV,
                    DEF_IV         = DEF_IV,
                    DSRegion       = dsregion,
                    DSRegionID     = DSRegionID,
                    EC             = EC,
                    ESV            = ESV,
                    EXP            = EXP,
                    EggLoc         = EggLoc,
                    Egg_Day        = Egg_Day,
                    Egg_Month      = Egg_Month,
                    Egg_Year       = Egg_Year,
                    Encounter      = Encounter,
                    FatefulFlag    = FatefulFlag,
                    Friendship     = Friendship,
                    Gender         = Gender,
                    GenderFlag     = GenderFlag,
                    Size           = pkm.SIZE_STORED,
                    HP             = HP,
                    HP_EV          = HP_EV,
                    HP_IV          = HP_IV,
                    HP_Type        = HP_Type,
                    HT             = pkm.HT_Name,
                    HeldItem       = HeldItem,
                    IsEgg          = IsEgg,
                    IsNicknamed    = IsNicknamed,
                    IsShiny        = IsShiny,
                    Legal          = Legal,
                    Level          = Level,
                    Markings       = Markings,
                    MetLevel       = MetLevel,
                    MetLoc         = MetLoc,
                    Met_Day        = Met_Day,
                    Met_Month      = Met_Month,
                    Met_Year       = Met_Year,
                    Move1          = Move1,
                    Move1_PP       = Move1_PP,
                    Move1_PPUp     = Move1_PPUp,
                    Move2          = Move2,
                    Move2_PP       = Move2_PP,
                    Move2_PPUp     = Move2_PPUp,
                    Move3          = Move3,
                    Move3_PP       = Move3_PP,
                    Move3_PPUp     = Move3_PPUp,
                    Move4          = Move4,
                    Move4_PP       = Move4_PP,
                    Move4_PPUp     = Move4_PPUp,
                    Nature         = Nature,
                    Nickname       = Nickname,
                    NotOT          = NotOT,
                    OT             = OT,
                    OTLang         = OTLang,
                    OT_Affection   = OT_Affection,
                    OT_Gender      = OT_Gender,
                    PID            = PID,
                    PKRS_Days      = PKRS_Days,
                    PKRS_Strain    = PKRS_Strain,
                    Position       = Position ?? "",
                    Region         = region,
                    RegionID       = RegionID,
                    Relearn1       = Relearn1,
                    Relearn2       = Relearn2,
                    Relearn3       = Relearn3,
                    Relearn4       = Relearn4,
                    SID            = SID,
                    SPA            = SPA,
                    SPA_EV         = SPA_EV,
                    SPA_IV         = SPA_IV,
                    SPD            = SPD,
                    SPD_EV         = SPD_EV,
                    SPD_IV         = SPD_IV,
                    SPE            = SPE,
                    SPE_EV         = SPE_EV,
                    SPE_IV         = SPE_IV,
                    Sheen          = Sheen,
                    Smart          = Smart,
                    Species        = Species,
                    SpecForm       = pkm.SpecForm,
                    TID            = TID,
                    TSV            = TSV,
                    Tough          = Tough,
                    Version        = Version,
                    IllegalReasons = lc.Report(),
                    Checksum       = Checksum,
                    ItemNum        = pkm.HeldItem
                };
                if (pkm.HT_Name == "")
                {
                    pkmn.HT = OT;
                }
                var ds = FormConverter.GetFormList(pkm.Species, GameInfo.Strings.types, GameInfo.Strings.forms, GameInfo.GenderSymbolUnicode, pkm.Format);
                if (ds.Count() > 1)
                {
                    pkmn.Form = ds[pkmn.AltForms];
                }
                else
                {
                    pkmn.Form = ds[0];
                }
                pkmn.HeldItemSpriteURL = "";
                pkmn.Move1_Type        = ConsoleIndex.mt[pkm.Move1].Type;
                pkmn.Move2_Type        = ConsoleIndex.mt[pkm.Move2].Type;
                pkmn.Move3_Type        = ConsoleIndex.mt[pkm.Move3].Type;
                pkmn.Move4_Type        = ConsoleIndex.mt[pkm.Move4].Type;
                if (pkm.GetType() == typeof(PK4))
                {
                    pkmn.Generation = "4";
                }
                else if (pkm.GetType() == typeof(PK5))
                {
                    pkmn.Generation = "5";
                }
                else if (pkm.GetType() == typeof(PK6))
                {
                    pkmn.Generation = "6";
                }
                else if (pkm.GetType() == typeof(PK7))
                {
                    pkmn.Generation = "7";
                }
                else if (pkm.GetType() == typeof(PB7))
                {
                    pkmn.Generation = "LGPE";
                }
                else if (pkm.GetType() == typeof(PK8))
                {
                    pkmn.Generation = "8";
                }
                else if (pkm.GetType() == typeof(PK3))
                {
                    pkmn.Generation = "3";
                }
                else if (pkm.GetType() == typeof(PK2))
                {
                    pkmn.Generation = "2";
                }
                else if (pkm.GetType() == typeof(PK1))
                {
                    pkmn.Generation = "1";
                }
                pkmn.SpeciesSpriteURL = GetPokeSprite(pkm.Species, pkmn.Species, pkmn.Gender, pkmn.Version, pkmn.Form, pkmn.Generation, pkmn.IsShiny);
                return(pkmn);
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.ToString());
                return(null);
            }
        }
Esempio n. 29
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
            await Task.Delay(1_000, token).ConfigureAwait(false);

            if (poke.Type != PokeTradeType.Random)
            {
                Hub.Config.Stream.StartEnterCode(this);
            }
            await Task.Delay(1_000, token).ConfigureAwait(false);

            var code = poke.Code;

            Log($"Entering Link Trade Code: {code:0000 0000}...");
            await EnterTradeCode(code, 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);

            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)
            {
                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)
            {
                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));
            }

            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.FixAdOT)
            {
                var clone = (PK8)pk.Clone();
                var adOT  = System.Text.RegularExpressions.Regex.Match(clone.OT_Name, @"(YT$)|(YT\w*$)|(Lab$)|(\.\w*)|(TV$)|(PKHeX)|(FB:)|(SysBot)").Value != "" ||
                            System.Text.RegularExpressions.Regex.Match(clone.Nickname, @"(YT$)|(YT\w*$)|(Lab$)|(\.\w*)|(TV$)|(PKHeX)|(FB:)|(SysBot)").Value != "";

                if (adOT && clone.OT_Name != $"{TrainerName}")
                {
                    clone.OT_Name = $"{TrainerName}";
                    clone.ClearNickname();
                    clone.PKRS_Infected = false;
                    clone.PKRS_Cured    = false;
                    clone.PKRS_Days     = 0;
                    clone.PKRS_Strain   = 0;
                    poke.SendNotification(this, $"```fix\nDetected an ad OT/Nickname with your {(Species)clone.Species}! Fixed it for you!```");
                }
                else
                {
                    poke.SendNotification(this, "```fix\nNo website ad detected in Nickname or OT. Exiting trade...```");
                    await ExitTrade(Hub.Config, true, token).ConfigureAwait(false);

                    return(PokeTradeResult.IllegalTrade);
                }

                var la = new LegalityAnalysis(clone);
                if (!la.Valid && Hub.Config.Legality.VerifyLegality)
                {
                    Log($"FixAd request 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, $"```fix\nFixed your {(Species)clone.Species}!\nNow confirm the trade!```");
                Log($"Fixed Nickname/OT for {(Species)clone.Species}.");

                await ReadUntilPresent(LinkTradePartnerPokemonOffset, 3_000, 1_000, token).ConfigureAwait(false);
                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 && Hub.Config.Legality.VerifyLegality)
                {
                    Log($"Clone request 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.FixAdOT && 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
                {
                    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)
                    {
                        DumpPokemon(DumpSetting.DumpFolder, "traded", pkm); // sent to partner
                    }
                }
            }

            return(PokeTradeResult.Success);
        }
Esempio n. 30
0
        /// <summary>
        /// Main function that auto legalizes based on the legality
        /// </summary>
        /// <param name="roughPK">rough pkm that has all the SSet values entered</param>
        /// <param name="SSet">Showdown set object</param>
        /// <param name="satisfied">If the final result is satisfactory, otherwise use current auto legality functionality</param>
        /// <returns></returns>
        public static PKM APILegality(PKM roughPK, ShowdownSet SSet, out bool satisfied)
        {
            bool changedForm = false;

            if (SSet.Form != null)
            {
                changedForm = FixFormes(SSet, out SSet);
            }
            satisfied = false; // true when all features of the PKM are satisfied
            int Form = roughPK.AltForm;

            if (changedForm)
            {
                Form = SSet.FormIndex;
                roughPK.ApplySetDetails(SSet);
            }
            int HPType = roughPK.HPType;

            // List of candidate PKM files

            int[] moves = SSet.Moves;
            var   f     = GeneratePKMs(roughPK, SAV, moves);

            foreach (PKM pkmn in f)
            {
                if (pkmn != null)
                {
                    PKM       pk     = PKMConverter.ConvertToType(pkmn, SAV.PKMType, out _); // All Possible PKM files
                    LegalInfo info   = new LegalInfo(pk);
                    var       pidiv  = info.PIDIV ?? MethodFinder.Analyze(pk);
                    PIDType   Method = PIDType.None;
                    if (pidiv != null)
                    {
                        Method = pidiv.Type;
                    }
                    SetVersion(pk, pkmn); // PreEmptive Version setting
                    SetSpeciesLevel(pk, SSet, Form);
                    SetMovesEVsItems(pk, SSet);
                    SetTrainerDataAndMemories(pk);
                    SetNatureAbility(pk, SSet);
                    SetIVsPID(pk, SSet, Method, HPType, pkmn);
                    PrintLegality(pk);
                    ColosseumFixes(pk);
                    pk.SetSuggestedHyperTrainingData(pk.IVs); // Hypertrain
                    SetEncryptionConstant(pk);
                    SetShinyBoolean(pk, SSet.Shiny);
                    CheckAndSetFateful(pk);
                    FixGender(pk, SSet);
                    FixRibbons(pk);
                    FixMemoriesPKM(pk);
                    SetSpeciesBall(pk);
                    SetHappiness(pk);
                    LegalityAnalysis la = new LegalityAnalysis(pk);
                    if (la.Valid)
                    {
                        satisfied = true;
                    }
                    if (satisfied)
                    {
                        return(pk);
                    }
                    else
                    {
                        Console.WriteLine(la.Report());
                    }
                }
            }
            return(roughPK);
        }