private bool AddToTradeQueue(PK8 pk8, int code, OnWhisperReceivedArgs e, bool sudo, PokeRoutineType type, out string msg) { // var user = e.WhisperMessage.UserId; var userID = ulong.Parse(e.WhisperMessage.UserId); var name = e.WhisperMessage.DisplayName; var trainer = new PokeTradeTrainerInfo(name); var notifier = new TwitchTradeNotifier <PK8>(pk8, trainer, code, e.WhisperMessage.Username, client, Channel); var detail = type == PokeRoutineType.DuduBot ? new PokeTradeDetail <PK8>(pk8, trainer, notifier, PokeTradeType.Dudu, code: code) : new PokeTradeDetail <PK8>(pk8, trainer, notifier, PokeTradeType.Specific, code: code); var trade = new TradeEntry <PK8>(detail, userID, type, name); var added = Info.AddToTradeQueue(trade, userID, sudo); if (added == QueueResultAdd.AlreadyInQueue) { msg = "Sorry, you are already in the queue."; return(false); } msg = $"Added {name} to the queue. Your current position is: {Info.CheckPosition(userID, type).Position}"; return(true); }
/// <summary> /// Method to find the PID and IV associated with a nest. Shinies are just allowed /// since there is no way GameFreak actually brute-forces top half of the PID to flag illegals. /// </summary> /// <param name="pk">Passed PKM</param> /// <param name="enc">Nest encounter object</param> /// <param name="shiny">Shiny boolean</param> private static void FindNestPIDIV <T>(PK8 pk, T enc, bool shiny) where T : EncounterStatic8Nest <T> { // Preserve Nature, Altform, Ability (only if HA) // Nest encounter RNG generation var iterPKM = pk.Clone(); if (enc.Ability != -1 && (pk.AbilityNumber == 4) != (enc.Ability == 4)) { return; } if (pk.Species == (int)Species.Toxtricity && pk.AltForm != EvolutionMethod.GetAmpLowKeyResult(pk.Nature)) { enc.ApplyDetailsTo(pk, GetRandomULong()); pk.RefreshAbility(iterPKM.AbilityNumber >> 1); pk.StatNature = iterPKM.StatNature; return; } if (shiny || !UseXOROSHIRO) { return; } var count = 0; do { ulong seed = GetRandomULong(); enc.ApplyDetailsTo(pk, seed); if (IsMatchCriteria <T>(pk, iterPKM)) { break; } } while (++count < 10_000); // can be ability capsuled pk.RefreshAbility(iterPKM.AbilityNumber >> 1); pk.StatNature = iterPKM.StatNature; }
private async Task <bool> HandleEncounter(PK8 pk, bool legends, CancellationToken token) { encounterCount++; Log($"Encounter: {encounterCount}{Environment.NewLine}{ShowdownParsing.GetShowdownText(pk)}{Environment.NewLine}{(StopConditionSettings.HasMark(pk, out RibbonIndex mark) ? $"Mark: {mark.ToString().Replace("Mark", "")}{Environment.NewLine}" : "")}"); TradeExtensions.EncounterLogs(pk); 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, DesiredIVs, Hub.Config.StopConditions)) { Log(Hub.Config.StopConditions.CatchEncounter && (Hub.Config.Encounter.EncounteringType == EncounterMode.VerticalLine || Hub.Config.Encounter.EncounteringType == EncounterMode.HorizontalLine) ? "Result found! Attempting to catch..." : $"{(!Hub.Config.StopConditions.PingOnMatch.Equals(string.Empty) ? $"<@{Hub.Config.StopConditions.PingOnMatch}>\n" : "")}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); } if (Hub.Config.StopConditions.CatchEncounter && (Hub.Config.Encounter.EncounteringType == EncounterMode.VerticalLine || Hub.Config.Encounter.EncounteringType == EncounterMode.HorizontalLine)) { await CatchWildPokemon(pk, token).ConfigureAwait(false); } return(true); } return(false); }
private bool AddToTradeQueue(PK8 pk8, int code, string trainerName, bool sudo, PokeRoutineType type, out string msg) { var user = Context.User; var userID = user.Id; var name = user.Username; var trainer = new PokeTradeTrainerInfo(trainerName); var notifier = new DiscordTradeNotifier <PK8>(pk8, trainer, code, Context); var detail = new PokeTradeDetail <PK8>(pk8, trainer, notifier, PokeTradeType.Dudu, code: code); var trade = new TradeEntry <PK8>(detail, userID, type, name); var added = Info.AddToTradeQueue(trade, userID, sudo); if (added == QueueResultAdd.AlreadyInQueue) { msg = "Sorry, you are already in the queue."; return(false); } msg = $"Added {user.Mention} to the queue. Your current position is: {Info.CheckPosition(userID, type).Position}"; return(true); }
private void ReplyWithZ3Results(PokeTradeDetail <PK8> detail, PK8 result) { detail.SendNotification(this, "Calculating your seed(s)..."); if (result.IsShiny) { Connection.Log("The Pokémon is already shiny!"); // Do not bother checking for next shiny frame detail.SendNotification(this, "This Pokémon is already shiny! Raid seed calculation was not done."); if (DumpSetting.Dump && !string.IsNullOrEmpty(DumpSetting.DumpFolder)) { DumpPokemon(DumpSetting.DumpFolder, "seed", result); } detail.TradeFinished(this, result); return; } var ec = result.EncryptionConstant; var pid = result.PID; var IVs = result.IVs.Length == 0 ? GetBlankIVTemplate() : PKX.ReorderSpeedLast((int[])result.IVs.Clone()); if (Hub.Config.Dudu.ShowAllZ3Results) { var matches = Z3Search.GetAllSeeds(ec, pid, IVs); foreach (var match in matches) { var lump = new PokeTradeSummary("Calculated Seed:", match); detail.SendNotification(this, lump); } } else { var match = Z3Search.GetFirstSeed(ec, pid, IVs); var lump = new PokeTradeSummary("Calculated Seed:", match); detail.SendNotification(this, lump); } Connection.Log("Seed calculation completed."); }
private static bool IsMatchCriteria <T>(PK8 pk, PKM template) where T : EncounterStatic8Nest <T> { if (template.Nature != pk.Nature) // match nature { return(false); } if (template.Gender != pk.Gender) // match gender { return(false); } if (template.AbilityNumber == 4 && !(template.Ability == pk.Ability && template.AbilityNumber == pk.AbilityNumber)) { return(false); } if (template.AbilityNumber != 4 && pk.AbilityNumber == 4) // cannot ability capsule HA to non HA { return(false); } // if (template.AltForm != pk.AltForm) // match form -- no variable forms // return false; return(true); }
private async Task <bool> HandleEncounter(PK8 pk, bool legends, CancellationToken token) { encounterCount++; Log($"Encounter: {encounterCount}{Environment.NewLine}{ShowdownSet.GetShowdownText(pk)}{Environment.NewLine}"); Counts.AddEncounteredSpecies(pk); 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, DesiredIVs, Hub.Config.StopConditions)) { Log(!Hub.Config.StopConditions.CatchEncounter || Hub.Config.Encounter.EncounteringType == EncounterMode.StrongSpawn ? $"{Ping}Result found! Stopping routine execution; restart the bot(s) to search again." : "Result found! Attempting to catch..."); if (Hub.Config.StopConditions.CaptureVideoClip) { await Task.Delay(Hub.Config.StopConditions.ExtraTimeWaitCaptureVideo).ConfigureAwait(false); await PressAndHold(CAPTURE, 2_000, 1_000, token).ConfigureAwait(false); } if (Hub.Config.StopConditions.CatchEncounter && (Hub.Config.Encounter.EncounteringType == EncounterMode.VerticalLine || Hub.Config.Encounter.EncounteringType == EncounterMode.HorizontalLine)) { await CatchWildPokemon(pk, token).ConfigureAwait(false); } return(true); } return(false); }
private async Task AddTradeToQueueAsync(int code, string trainerName, PK8 pk8, bool sudo) { if ((uint)code > MaxTradeCode) { await ReplyAsync("Trade code should be 0000-9999!").ConfigureAwait(false); return; } var la = new LegalityAnalysis(pk8); if (!la.Valid && SysCordInstance.Self.Hub.Config.VerifyLegality) { await ReplyAsync("PK8 attachment is not legal, and cannot be traded!").ConfigureAwait(false); return; } try { await Context.User.SendMessageAsync("I've added you to the queue! I'll message you here when your trade is starting.").ConfigureAwait(false); } catch (HttpException ex) { await ReplyAsync($"{ex.HttpCode}: {ex.Reason}!").ConfigureAwait(false); await ReplyAsync("You must enable private messages in order to be queued!").ConfigureAwait(false); return; } var result = AddToTradeQueue(pk8, code, trainerName, sudo, PokeRoutineType.LinkTrade, out var msg); await ReplyAsync(msg).ConfigureAwait(false); if (result) { await Context.Message.DeleteAsync(RequestOptions.Default).ConfigureAwait(false); } }
public void TestHub() { var cfg = new PokeTradeHubConfig { Distribution = { DistributeWhileIdle = true } }; var hub = new PokeTradeHub <PK8>(cfg); var pool = hub.Ledy.Pool; var a = new PK8 { Species = 5 }; pool.Add(a); var trade = hub.Queues.TryDequeue(PokeRoutineType.FlexTrade, out _, out _); trade.Should().BeFalse(); var ledy = hub.Queues.TryDequeueLedy(out var detail); ledy.Should().BeTrue(); detail.TradeData.Should().Be(a); }
private async void loopTrades(ulong toAdd = ulong.MaxValue) { var trainerDetail = "Berichan" + (toAdd == ulong.MaxValue ? "" : toAdd.ToString()); var userID = toAdd == ulong.MaxValue ? 0ul : toAdd; var trainer = new PokeTradeTrainerInfo(trainerDetail); var pk = new PK8(); while (true) { if (!Hub.Queues.GetQueue(PokeRoutineType.SeedCheck).Contains(trainerDetail)) { await Task.Delay(100).ConfigureAwait(false); var notifier = new WebTradeNotifier <PK8>(pk, trainer, Code, WebNotifierInstance); var detail = new PokeTradeDetail <PK8>(pk, trainer, notifier, PokeTradeType.Seed, Code, true); var trade = new TradeEntry <PK8>(detail, userID, PokeRoutineType.SeedCheck, ""); Info.AddToTradeQueue(trade, userID, false); } await Task.Delay(1_000).ConfigureAwait(false); } }
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); } }
static void Main(string[] args) { if (args.Length != 1) { Console.WriteLine("input path please"); return; } var path = args[0]; var fi = new FileInfo(path); if (!fi.Exists) { return; } if (FileUtil.IsFileTooBig(fi.Length)) { Console.WriteLine("File too big"); return; } if (FileUtil.IsFileTooSmall(fi.Length)) { Console.WriteLine("File too small"); return; } byte[] input; try { input = File.ReadAllBytes(path); } catch (Exception e) { Console.WriteLine("Read error"); return; } if (input == null) { return; } PK8 pk8 = new PK8(input); PK7 pk7 = convert(pk8); var data = pk7.DecryptedPartyData; File.WriteAllBytes(Path.GetFileNameWithoutExtension(path) + ".pk7", data); }
protected override async Task MainLoop(CancellationToken token) { Log("Identifying trainer data of the host console."); await IdentifyTrainer(token).ConfigureAwait(false); var originalTextSpeed = await EnsureTextSpeedFast(token).ConfigureAwait(false); await SetCurrentBox(0, token).ConfigureAwait(false); Log("Checking destination slot..."); var existing = await GetBoxSlotQuality(InjectBox, InjectSlot, token).ConfigureAwait(false); if (existing.Quality != SlotQuality.Overwritable) { PrintBadSlotMessage(existing); return; } Log("Starting main EggBot loop."); Config.IterateNextRoutine(); var blank = new PK8(); while (!token.IsCancellationRequested && Config.NextRoutineType == PokeRoutineType.EggFetch) { // Walk a step left, then right => check if egg was generated on this attempt. // Repeat until an egg is generated. var attempts = await StepUntilEgg(token).ConfigureAwait(false); if (attempts < 0) // aborted { continue; } Log($"Egg available after {attempts} attempts! Clearing destination slot."); await SetBoxPokemon(blank, InjectBox, InjectSlot, token).ConfigureAwait(false); for (int i = 0; i < 4; i++) { await Click(A, 0_400, token).ConfigureAwait(false); } // Safe to mash B from here until we get out of all menus. Currentscreen becomes 0xFFFFFFFF. while (!await IsOnOverworldFossil(token).ConfigureAwait(false)) { await Click(B, 0_400, token).ConfigureAwait(false); } Log("Egg received. Checking details."); var pk = await ReadBoxPokemon(InjectBox, InjectSlot, token).ConfigureAwait(false); if (pk.Species == 0) { Log("Invalid data detected in destination slot. Restarting loop."); continue; } encounterCount++; Log($"Encounter: {encounterCount}:{Environment.NewLine}{ShowdownSet.GetShowdownText(pk)}{Environment.NewLine}{Environment.NewLine}"); Counts.AddCompletedEggs(); if (DumpSetting.Dump && !string.IsNullOrEmpty(DumpSetting.DumpFolder)) { DumpPokemon(DumpSetting.DumpFolder, "egg", pk); } if (StopCondition(pk)) { if (ContinueGettingEggs) { Log("Result found! Continuing to collect more eggs."); continue; } Log("Result found! Stopping routine execution; restart the bot(s) to search again."); return; } } // If aborting the sequence, we might have the stick set at some position. Clear it just in case. await SetStick(LEFT, 0, 0, 0, CancellationToken.None).ConfigureAwait(false); // reset await SetTextSpeed(originalTextSpeed, token).ConfigureAwait(false); }
private static bool DisallowSurpriseTrade(PK8 pk8) { // Surprise Trade currently bans Mythicals and Legendaries, not Sub-Legendaries. return(Legal.Legends.Contains(pk8.Species)); }
public static async Task AddToQueueAsync(this SocketCommandContext Context, int code, string trainer, RequestSignificance sig, PK8 trade, PokeRoutineType routine, PokeTradeType type) { await AddToQueueAsync(Context, code, trainer, sig, trade, routine, type, Context.User).ConfigureAwait(false); }
private static void LanRollTrade(PK8 pkm) { int[] regional = { 26, 27, 28, 37, 38, 50, 51, 52, 53, 77, 78, 79, 80, 83, 103, 105, 110, 122, 144, 145, 146, 199, 222, 263, 264, 554, 555, 562, 618 }; int[] shinyOdds = { 3, 3, 3, 3, 3, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 6, 6, 6, 6, 6 }; int[] formIndex1 = { 0, 1 }; int[] formIndex2 = { 0, 1, 2 }; var rng = new System.Random(); int shinyRng = rng.Next(0, shinyOdds.Length); if (regional.ToList().Contains(pkm.Species)) // Randomize Regional Form { int formRng = rng.Next(0, formIndex1.Length); int formRng2 = rng.Next(0, formIndex2.Length); if (pkm.Species != 52) // Checks for Meowth because he's got 2 regional forms { pkm.SetAltForm(formIndex1[formRng]); } else { pkm.SetAltForm(formIndex2[formRng2]); } } pkm.Nature = rng.Next(0, 24); pkm.StatNature = pkm.Nature; pkm.IVs = pkm.SetRandomIVs(4); int randomBall = rng.Next(0, pkm.MaxBallID); pkm.Ball = randomBall; // Source: https://bulbapedia.bulbagarden.net/wiki/Ability#List_of_Abilities // https://game8.co/games/pokemon-sword-shield/archives/271828 to see if it exists in the game. int[] vaildAbilities = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 75, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 91, 92, 93, 94, 95, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, 165, 166, 167, 169, 170, 171, 172, 173, 174, 175, 176, 177, 178, 180, 181, 182, 183, 186, 187, 188, 192, 193, 194, 195, 196, 198, 199, 200, 201, 202, 203, 204, 205, 207, 208, 209, 211, 212, 214, 215, 217, 218, 220, 221, 222, 224, 225, 226, 227, 228, 229, 230, 231, 232, 234, 235, 236, 237, 238, 239, 240, 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, 254, 255, 256, 257, 258, 259, 260, 261, 262, 263, 264, 265 }; // 266/267 (As One) is not on here because it's meh... int abilityNum = rng.Next(0, vaildAbilities.Length); pkm.Ability = vaildAbilities[abilityNum]; // Source: https://bulbapedia.bulbagarden.net/wiki/List_of_moves int[] invalidMoves = { 2, 3, 4, 13, 26, 27, 41, 49, 82, 96, 99, 112, 117, 119, 121, 125, 128, 131, 132, 134, 140, 145, 146, 148, 149, 159, 169, 171, 185, 193, 216, 218, 222, 228, 237, 265, 274, 287, 289, 290, 293, 300, 301, 302, 316, 318, 320, 324, 327, 346, 357, 358, 363, 373, 376, 377, 378, 381, 382, 386, 426, 429, 431, 443, 445, 456, 466, 477, 481, 485, 498, 507, 516, 531, 537, 563, 569, 622, 623, 624, 625, 626, 627, 628, 629, 630, 631, 632, 633, 634, 635, 636, 637, 638, 639, 640, 641, 642, 643, 644, 645, 646, 647, 648, 649, 650, 651, 652, 653, 654, 655, 656, 657, 658, 695, 696, 697, 698, 699, 700, 701, 702, 703, 717, 718, 719, 720, 721, 722, 723, 724, 725, 726, 727, 728, 729, 730, 731, 732, 733, 734, 735, 736, 737, 738, 739, 740, 741, 742, 743, 757, 758, 759, 760, 761, 762, 763, 764, 765, 766, 767, 768, 769, 770, 771, 772, 773, 774 }; int moveRng1 = rng.Next(0, pkm.MaxMoveID); int moveRng2 = rng.Next(0, pkm.MaxMoveID); int moveRng3 = rng.Next(0, pkm.MaxMoveID); int moveRng4 = rng.Next(0, pkm.MaxMoveID); while (invalidMoves.ToList().Contains(moveRng1)) // Keeps selecting moves until it picks one that exists in Sword and Shield { moveRng1 = rng.Next(0, pkm.MaxMoveID); } while (invalidMoves.ToList().Contains(moveRng2) || moveRng1 == moveRng2) // the OR operand is for duplicate moves { moveRng2 = rng.Next(0, pkm.MaxMoveID); } while (invalidMoves.ToList().Contains(moveRng3) || moveRng1 == moveRng3 || moveRng2 == moveRng3) { moveRng3 = rng.Next(0, pkm.MaxMoveID); } while (invalidMoves.ToList().Contains(moveRng4) || moveRng1 == moveRng4 || moveRng2 == moveRng4 || moveRng3 == moveRng4) { moveRng4 = rng.Next(0, pkm.MaxMoveID); } pkm.Move1 = moveRng1; pkm.Move2 = moveRng2; pkm.Move3 = moveRng3; pkm.Move4 = moveRng4; MoveApplicator.SetMaximumPPCurrent(pkm); pkm.HeldItem = rng.Next(1, pkm.MaxItemID); // random held item while (!ItemRestrictions.IsHeldItemAllowed(pkm)) // checks for non-existing items { pkm.HeldItem = rng.Next(1, pkm.MaxItemID); } pkm.CurrentLevel = rng.Next(1, 101); pkm.IsEgg = true; pkm.Egg_Location = 60002; pkm.EggMetDate = System.DateTime.Now.Date; pkm.DynamaxLevel = 0; pkm.Met_Level = 1; pkm.Met_Location = 0; pkm.MetDate = System.DateTime.Now.Date; pkm.CurrentHandler = 0; pkm.OT_Friendship = 1; pkm.HT_Name = ""; pkm.HT_Friendship = 0; pkm.HT_Language = 0; pkm.HT_Gender = 0; pkm.HT_Memory = 0; pkm.HT_Feeling = 0; pkm.HT_Intensity = 0; pkm.EVs = new int[] { 0, 0, 0, 0, 0, 0 }; pkm.Markings = new int[] { 0, 0, 0, 0, 0, 0, 0, 0 }; pkm.SetRibbon(rng.Next(53, 98), true); //ribbons 53-97 are marks switch (shinyOdds[shinyRng]) { case 3: pkm.SetUnshiny(); break; case 5: CommonEdits.SetShiny(pkm, Shiny.AlwaysStar); break; case 6: CommonEdits.SetShiny(pkm, Shiny.AlwaysSquare); break; } }
protected override async Task MainLoop(CancellationToken token) { Connection.Log("Identifying trainer data of the host console."); await IdentifyTrainer(token).ConfigureAwait(false); Connection.Log("Checking destination slot for eggs to see if anything is in the slot..."); var existing = await GetBoxSlotQuality(InjectBox, InjectSlot, token).ConfigureAwait(false); if (existing.Quality != SlotQuality.Overwritable) { PrintBadSlotMessage(existing); return; } Connection.Log("Starting main EggBot loop."); var blank = new PK8(); while (!token.IsCancellationRequested && Config.NextRoutineType == PokeRoutineType.EggFetch) { // Walk a step left, then right => check if egg was generated on this attempt. // Repeat until an egg is generated. var attempts = await StepUntilEgg(token).ConfigureAwait(false); if (attempts < 0) // aborted { continue; } Connection.Log($"Egg available after {attempts} attempts! Clearing destination slot."); await SetBoxPokemon(blank, InjectBox, InjectSlot, token).ConfigureAwait(false); for (int i = 0; i < 4; i++) { await Click(A, 500, token).ConfigureAwait(false); } await Task.Delay(4000, token).ConfigureAwait(false); await Click(A, 1850, token).ConfigureAwait(false); await Click(A, 1850, token).ConfigureAwait(false); await Click(A, 450, token).ConfigureAwait(false); Connection.Log("Egg received. Checking details."); var pk = await ReadBoxPokemon(InjectBox, InjectSlot, token).ConfigureAwait(false); if (pk.Species == 0) { Connection.Log("Invalid data detected in destination slot. Restarting loop."); continue; } Connection.Log($"Encounter: {encounterCount}:{Environment.NewLine}{ShowdownSet.GetShowdownText(pk)}{Environment.NewLine}{Environment.NewLine}"); Counts.AddCompletedEggs(); if (DumpSetting.Dump && !string.IsNullOrEmpty(DumpSetting.DumpFolder)) { DumpPokemon(DumpSetting.DumpFolder, pk); } encounterCount++; if (!StopCondition(pk)) { continue; } Connection.Log("Result found! Stopping routine execution; re-start the bot(s) to search again."); break; } // If aborting the sequence, we might have the stick set at some position. Clear it just in case. await SetStick(LEFT, 0, 0, 0, CancellationToken.None).ConfigureAwait(false); // reset }
private bool CheckForAdNickname(PK8 pkm) => System.Text.RegularExpressions.Regex.Match(pkm.Nickname, @"(YT$)|(YT\w*$)|(Lab$)|(\.\w*)|(TV$)|(PKHeX)|(FB:)|(SysBot)|(AuSLove)").Value != "";
public static async Task AddToQueueAsync(this SocketCommandContext Context, int code, string trainer, bool sudo, PK8 trade, PokeRoutineType routine, PokeTradeType type) { if ((uint)code > MaxTradeCode) { await Context.Channel.SendMessageAsync("Trade code should be 00000000-99999999!").ConfigureAwait(false); return; } IUserMessage test; try { const string helper = "I've added you to the queue! I'll message you here when your trade is starting."; test = await Context.User.SendMessageAsync(helper).ConfigureAwait(false); } catch (HttpException ex) { await Context.Channel.SendMessageAsync($"{ex.HttpCode}: {ex.Reason}!").ConfigureAwait(false); await Context.Channel.SendMessageAsync("You must enable private messages in order to be queued!").ConfigureAwait(false); return; } // Try adding var result = Context.AddToTradeQueue(trade, code, trainer, sudo, routine, type, out var msg); // Notify in channel await Context.Channel.SendMessageAsync(msg).ConfigureAwait(false); // Notify in PM to mirror what is said in the channel. await Context.User.SendMessageAsync(msg).ConfigureAwait(false); // Clean Up if (result) { // Delete the user's join message for privacy if (!Context.IsPrivate) { await Context.Message.DeleteAsync(RequestOptions.Default).ConfigureAwait(false); } } else { // Delete our "I'm adding you!", and send the same message that we sent to the general channel. await test.DeleteAsync().ConfigureAwait(false); } }
public async Task <PK8?> ReadOwPokemon(uint offset, SAV8 TrainerData, CancellationToken token) { byte[] data = await Connection.ReadBytesAsync(offset, 56, token).ConfigureAwait(false); Log("RAM data: " + BitConverter.ToString(data)); if (data[20] == 1) { PK8?pk = new PK8 { Species = BitConverter.ToUInt16(data.Slice(0, 2), 0), Form = data[2], CurrentLevel = data[4], Met_Level = data[4], Gender = (data[10] == 1) ? 0 : 1, OT_Name = TrainerData.OT, TID = TrainerData.TID, SID = TrainerData.SID, TrainerID7 = TrainerData.TrainerID7, TrainerSID7 = TrainerData.TrainerSID7, OT_Gender = TrainerData.Gender, HT_Name = TrainerData.OT, HT_Gender = TrainerData.Gender, Move1 = BitConverter.ToUInt16(data.Slice(48, 2), 0), Move2 = BitConverter.ToUInt16(data.Slice(50, 2), 0), Move3 = BitConverter.ToUInt16(data.Slice(52, 2), 0), Move4 = BitConverter.ToUInt16(data.Slice(54, 2), 0), }; pk.SetNature(data[8]); pk.SetAbility(data[12] - 1); if (data[22] != 255) { pk.SetRibbonIndex((RibbonIndex)data[22]); } if (!pk.IsGenderValid()) { pk.Gender = 2; } if (data[14] == 1) { pk.HeldItem = data[16]; } Shiny shinyness = (Shiny)(data[6] + 1); int ivs = data[18]; uint seed = BitConverter.ToUInt32(data.Slice(24, 4), 0); Log($"Stats in RAM: Shinyness {shinyness}, IVs {ivs}, Seed: {String.Format("{0:X}", seed)}"); pk = Overworld8RNG.CalculateFromSeed(pk, shinyness, ivs, seed); if (pk != null) { return(pk); } else { return(null); } } else { return(null); } }
private async Task <PokeTradeResult> PerformSurpriseTrade(SAV8SWSH sav, PK8 pkm, CancellationToken token) { // General Bot Strategy: // 1. Inject to b1s1 // 2. Send out Trade // 3. Clear received PKM to skip the trade animation // 4. Repeat // Inject to b1s1 Connection.Log("Starting next Surprise Trade. Getting data..."); await SetBoxPokemon(pkm, InjectBox, InjectSlot, token, sav).ConfigureAwait(false); if (!await IsCorrectScreen(CurrentScreen_Overworld, token).ConfigureAwait(false)) { await ExitTrade(true, token).ConfigureAwait(false); return(PokeTradeResult.Recover); } Connection.Log("Open Y-Comm Menu"); await Click(Y, 2_000, token).ConfigureAwait(false); if (token.IsCancellationRequested) { return(PokeTradeResult.Aborted); } Connection.Log("Select Surprise Trade"); await Click(DDOWN, 0_500, token).ConfigureAwait(false); await Click(A, 4_000, token).ConfigureAwait(false); if (token.IsCancellationRequested) { return(PokeTradeResult.Aborted); } await Task.Delay(2_000, token).ConfigureAwait(false); if (!await IsCorrectScreen(CurrentScreen_Box, token).ConfigureAwait(false)) { await ExitTrade(true, token).ConfigureAwait(false); return(PokeTradeResult.Recover); } Connection.Log("Select Pokemon"); // Box 1 Slot 1; no movement required. await Click(A, 0_700, token).ConfigureAwait(false); if (token.IsCancellationRequested) { return(PokeTradeResult.Aborted); } Connection.Log("Confirming..."); await Click(A, 5_000, token).ConfigureAwait(false); for (int i = 0; i < 3; i++) { await Click(A, 0_700, token).ConfigureAwait(false); } if (token.IsCancellationRequested) { return(PokeTradeResult.Aborted); } // Let Surprise Trade be sent out before checking if we're back to the Overworld. await Task.Delay(3_000, token).ConfigureAwait(false); if (!await IsCorrectScreen(CurrentScreen_Overworld, token).ConfigureAwait(false)) { await ExitTrade(true, token).ConfigureAwait(false); return(PokeTradeResult.Recover); } Connection.Log("Waiting for Surprise Trade Partner..."); // Time we wait for a trade var partnerFound = await ReadUntilChanged(SupriseTradePartnerPokemonOffset, PokeTradeBotUtil.EMPTY_SLOT, 90_000, 50, token).ConfigureAwait(false); if (token.IsCancellationRequested) { return(PokeTradeResult.Aborted); } if (!partnerFound) { await ResetTradePosition(token).ConfigureAwait(false); return(PokeTradeResult.NoTrainerFound); } // Let the game flush the results and de-register from the online surprise trade queue. await Task.Delay(7_000, token).ConfigureAwait(false); var TrainerName = await GetTradePartnerName(TradeMethod.SupriseTrade, token).ConfigureAwait(false); var SuprisePoke = await ReadSupriseTradePokemon(token).ConfigureAwait(false); Connection.Log($"Found Surprise Trade Partner: {TrainerName} , Pokemon: {(Species)SuprisePoke.Species}"); // Clear out the received trade data; we want to skip the trade animation. // The box slot locks have been removed prior to searching. await Connection.WriteBytesAsync(BitConverter.GetBytes(SupriseTradeSearch_Empty), SupriseTradeSearchOffset, token).ConfigureAwait(false); await Connection.WriteBytesAsync(PokeTradeBotUtil.EMPTY_SLOT, SupriseTradePartnerPokemonOffset, token).ConfigureAwait(false); // Let the game recognize our modifications before finishing this loop. await Task.Delay(5_000, token).ConfigureAwait(false); // Clear the Surprise Trade slot locks! We'll skip the trade animation and reuse the slot on later loops. // Write 8 bytes of FF to set both Int32's to -1. Regular locks are [Box32][Slot32] await Connection.WriteBytesAsync(BitConverter.GetBytes(ulong.MaxValue), SupriseTradeLockBox, token).ConfigureAwait(false); if (token.IsCancellationRequested) { return(PokeTradeResult.Aborted); } if (await IsCorrectScreen(CurrentScreen_Overworld, token).ConfigureAwait(false)) { Connection.Log("Trade complete!"); } else { await ExitTrade(true, token).ConfigureAwait(false); } if (DumpSetting.Dump && !string.IsNullOrEmpty(DumpSetting.DumpFolder)) { DumpPokemon(DumpSetting.DumpFolder, SuprisePoke); } Hub.Counts.AddCompletedSurprise(); return(PokeTradeResult.Success); }
// return true if breaking loop protected async Task <bool> HandleEncounter(PK8 pk, CancellationToken token) { encounterCount++; var print = Hub.Config.StopConditions.GetPrintName(pk); Log($"Encounter: {encounterCount}{Environment.NewLine}{print}{Environment.NewLine}"); var legendary = Legal.Legends.Contains(pk.Species) || Legal.SubLegends.Contains(pk.Species); if (legendary) { Settings.AddCompletedLegends(); } else { Settings.AddCompletedEncounters(); } if (DumpSetting.Dump && !string.IsNullOrEmpty(DumpSetting.DumpFolder)) { DumpPokemon(DumpSetting.DumpFolder, legendary ? "legends" : "encounters", pk); } if (!StopConditionSettings.EncounterFound(pk, DesiredMinIVs, DesiredMaxIVs, Hub.Config.StopConditions, UnwantedMarks)) { return(false); } if (Hub.Config.StopConditions.CaptureVideoClip) { await Task.Delay(Hub.Config.StopConditions.ExtraTimeWaitCaptureVideo, token).ConfigureAwait(false); await PressAndHold(CAPTURE, 2_000, 0, token).ConfigureAwait(false); } var mode = Settings.ContinueAfterMatch; var msg = $"Result found!\n{print}\n" + mode switch { ContinueAfterMatch.Continue => "Continuing...", ContinueAfterMatch.PauseWaitAcknowledge => "Waiting for instructions to continue.", ContinueAfterMatch.StopExit => "Stopping routine execution; restart the bot to search again.", _ => throw new ArgumentOutOfRangeException(), }; if (!string.IsNullOrWhiteSpace(Hub.Config.StopConditions.MatchFoundEchoMention)) { msg = $"{Hub.Config.StopConditions.MatchFoundEchoMention} {msg}"; } EchoUtil.Echo(msg); Log(msg); if (mode == ContinueAfterMatch.StopExit) { return(true); } if (mode == ContinueAfterMatch.Continue) { return(false); } IsWaiting = true; while (IsWaiting) { await Task.Delay(1_000, token).ConfigureAwait(false); } return(false); }
private static PKM SetToEgg(PKM pkm, int origin, GameVersion gameVersion) { int dayCare = origin <= 4 ? Locations.Daycare4 : Locations.Daycare5; int metLevel = origin <= 4 ? 0 : 1; int currentLevel = origin <= 4 ? 5 : 1; // 非初级形态 PKM tmp = pkm.Clone(); tmp.IsEgg = true; tmp.Egg_Location = dayCare; tmp.Data[0xA8] = tmp.Data[0xA8 + 1] = 0; //Milotic List <CheckResult> checkResult = EncounterFinder.FindVerifiedEncounter(tmp).Parse; if (checkResult.IsPropStrInEleList("Comment", LegalityCheckStrings.LEvoInvalid)) { return(null); } int language = pkm.Language; pkm.Nickname = SpeciesName.GetSpeciesNameGeneration((int)Species.None, language, pkm.Format); pkm.IsNicknamed = true; pkm.IsEgg = true; pkm.HeldItem = 0; pkm.CurrentLevel = currentLevel; pkm.StatNature = pkm.Nature; pkm.RefreshAbility(new Random().Next(0, 3)); pkm.SetIVs(); pkm.EVs = new int[6]; pkm.Ball = (int)Ball.Poke; pkm.Met_Location = 0; pkm.Met_Level = metLevel; pkm.Egg_Location = dayCare; ReflectUtils.methods.TryGetValue("GetEggMoves", out MethodInfo method); int[] result = (int[])method.Invoke(null, new object[] { pkm, pkm.Species, pkm.AltForm, gameVersion }); pkm.SetMoves(new List <int>()); if (result.Length == 0) { pkm.SetRelearnMoves(pkm.GetSuggestedRelearnMoves()); } else { pkm.SetRelearnMoves(GetEggMovesRandom(pkm, result)); } pkm.SetMoves(pkm.RelearnMoves); pkm.SetMovesPPUpsToZero(); pkm.SetMaximumPPCurrent(); pkm.FixMoves(); // 8代独有数据 if (pkm.Format == 8) { PK8 pk8 = (PK8)pkm; pk8.DynamaxLevel = 0; pk8.CanGigantamax = false; } pkm.ClearAllRibbon(); pkm.ClearCurrentHandler(); pkm.ClearMemories(); pkm.ClearRecordFlags(); pkm.CurrentFriendship = 4; return(pkm); }
private async Task <PokeTradeResult> PerformSurpriseTrade(SAV8SWSH sav, PK8 pkm, CancellationToken token) { // General Bot Strategy: // 1. Inject to b1s1 // 2. Send out Trade // 3. Clear received PKM to skip the trade animation // 4. Repeat // Inject to b1s1 if (await CheckIfSoftBanned(token).ConfigureAwait(false)) { await Unban(token).ConfigureAwait(false); } Log("Starting next Surprise Trade. Getting data..."); 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); } if (await CheckIfSearchingForSurprisePartner(token).ConfigureAwait(false)) { Log("Still searching, reset."); await ResetTradePosition(Hub.Config, token).ConfigureAwait(false); } Log("Opening Y-Comm Menu"); await Click(Y, 1_500, token).ConfigureAwait(false); if (token.IsCancellationRequested) { return(PokeTradeResult.Aborted); } Log("Selecting Surprise Trade"); await Click(DDOWN, 0_500, token).ConfigureAwait(false); await Click(A, 2_000, token).ConfigureAwait(false); if (token.IsCancellationRequested) { return(PokeTradeResult.Aborted); } await Task.Delay(0_750, token).ConfigureAwait(false); if (!await IsInBox(token).ConfigureAwait(false)) { await ExitTrade(Hub.Config, true, token).ConfigureAwait(false); return(PokeTradeResult.RecoverPostLinkCode); } Log("Selecting Pokémon"); // Box 1 Slot 1; no movement required. await Click(A, 0_700, token).ConfigureAwait(false); if (token.IsCancellationRequested) { return(PokeTradeResult.Aborted); } Log("Confirming..."); while (!await IsOnOverworld(Hub.Config, token).ConfigureAwait(false)) { await Click(A, 0_800, token).ConfigureAwait(false); } if (token.IsCancellationRequested) { return(PokeTradeResult.Aborted); } // Let Surprise Trade be sent out before checking if we're back to the Overworld. await Task.Delay(3_000, token).ConfigureAwait(false); if (!await IsOnOverworld(Hub.Config, token).ConfigureAwait(false)) { await ExitTrade(Hub.Config, true, token).ConfigureAwait(false); return(PokeTradeResult.RecoverReturnOverworld); } // Wait 30 Seconds for Trainer... Log("Waiting for Surprise Trade Partner..."); // Wait for an offer... var oldEC = await Connection.ReadBytesAsync(SurpriseTradeSearchOffset, 4, Config.ConnectionType, token).ConfigureAwait(false); var partnerFound = Hub.Config.Trade.SpinTrade && Config.ConnectionType == ConnectionType.USB ? await SpinTrade(SurpriseTradeSearchOffset, oldEC, Hub.Config.Trade.TradeWaitTime * 1_000, 0_200, false, token).ConfigureAwait(false) : await ReadUntilChanged(SurpriseTradeSearchOffset, oldEC, Hub.Config.Trade.TradeWaitTime * 1_000, 0_200, false, token).ConfigureAwait(false); if (token.IsCancellationRequested) { return(PokeTradeResult.Aborted); } if (!partnerFound) { await ResetTradePosition(Hub.Config, token).ConfigureAwait(false); return(PokeTradeResult.NoTrainerFound); } // Let the game flush the results and de-register from the online surprise trade queue. await Task.Delay(7_000, token).ConfigureAwait(false); var TrainerName = await GetTradePartnerName(TradeMethod.SupriseTrade, token).ConfigureAwait(false); var SurprisePoke = await ReadSurpriseTradePokemon(token).ConfigureAwait(false); Log($"Found Surprise Trade Partner: {TrainerName}, Pokémon: {(Species)SurprisePoke.Species}"); // Clear out the received trade data; we want to skip the trade animation. // The box slot locks have been removed prior to searching. await Connection.WriteBytesAsync(BitConverter.GetBytes(SurpriseTradeSearch_Empty), SurpriseTradeSearchOffset, Config.ConnectionType, token).ConfigureAwait(false); await Connection.WriteBytesAsync(PokeTradeBotUtil.EMPTY_SLOT, SurpriseTradePartnerPokemonOffset, Config.ConnectionType, token).ConfigureAwait(false); // Let the game recognize our modifications before finishing this loop. await Task.Delay(5_000, token).ConfigureAwait(false); // Clear the Surprise Trade slot locks! We'll skip the trade animation and reuse the slot on later loops. // Write 8 bytes of FF to set both Int32's to -1. Regular locks are [Box32][Slot32] await Connection.WriteBytesAsync(BitConverter.GetBytes(ulong.MaxValue), SurpriseTradeLockBox, Config.ConnectionType, token).ConfigureAwait(false); if (token.IsCancellationRequested) { return(PokeTradeResult.Aborted); } if (await IsOnOverworld(Hub.Config, token).ConfigureAwait(false)) { if (Hub.Config.Trade.SpinTrade) { await SpinCorrection(token).ConfigureAwait(false); } Log("Trade complete!"); } else { await ExitTrade(Hub.Config, true, token).ConfigureAwait(false); } if (DumpSetting.Dump && !string.IsNullOrEmpty(DumpSetting.DumpFolder)) { DumpPokemon(DumpSetting.DumpFolder, "surprise", SurprisePoke); } Hub.Counts.AddCompletedSurprise(); return(PokeTradeResult.Success); }
private async Task <PokeTradeResult> EndSeedCheckTradeAsync(PokeTradeDetail <PK8> detail, PK8 pk, CancellationToken token) { await ExitSeedCheckTrade(Hub.Config, token).ConfigureAwait(false); detail.TradeFinished(this, pk); if (DumpSetting.Dump && !string.IsNullOrEmpty(DumpSetting.DumpFolder)) { DumpPokemon(DumpSetting.DumpFolder, "seed", pk); } // Send results from separate thread; the bot doesn't need to wait for things to be calculated. #pragma warning disable 4014 Task.Run(() => { try { ReplyWithSeedCheckResults(detail, pk); } catch (Exception ex) { detail.SendNotification(this, $"Unable to calculate seeds: {ex.Message}\r\n{ex.StackTrace}"); } }, token); #pragma warning restore 4014 Hub.Counts.AddCompletedSeedCheck(); return(PokeTradeResult.Success); }
public async Task <PK8?> ReadOwPokemon(Species target, uint startoffset, byte[]?mondata, SAV8 TrainerData, CancellationToken token) { byte[]? data = null; Species species = 0; uint offset = startoffset; int i = 0; if (target != (Species)0) { do { data = await Connection.ReadBytesAsync(offset, 56, token).ConfigureAwait(false); species = (Species)BitConverter.ToUInt16(data.Slice(0, 2), 0); offset += 192; i++; } while (target != 0 && species != 0 && target != species && i <= 40); if (i > 40) { data = null; } } else if (mondata != null) { data = mondata; species = (Species)BitConverter.ToUInt16(data.Slice(0, 2), 0); } if (data != null && data[20] == 1) { PK8 pk = new PK8 { Species = (int)species, Form = data[2], CurrentLevel = data[4], Met_Level = data[4], Gender = (data[10] == 1) ? 0 : 1, OT_Name = TrainerData.OT, TID = TrainerData.TID, SID = TrainerData.SID, OT_Gender = TrainerData.Gender, HT_Name = TrainerData.OT, HT_Gender = TrainerData.Gender, Move1 = BitConverter.ToUInt16(data.Slice(48, 2), 0), Move2 = BitConverter.ToUInt16(data.Slice(50, 2), 0), Move3 = BitConverter.ToUInt16(data.Slice(52, 2), 0), Move4 = BitConverter.ToUInt16(data.Slice(54, 2), 0), Version = 44, }; pk.SetNature(data[8]); pk.SetAbility(data[12] - 1); if (data[22] != 255) { pk.SetRibbonIndex((RibbonIndex)data[22]); } if (!pk.IsGenderValid()) { pk.Gender = 2; } if (data[14] == 1) { pk.HeldItem = data[16]; } Shiny shinyness = (Shiny)(data[6] + 1); int ivs = data[18]; uint seed = BitConverter.ToUInt32(data.Slice(24, 4), 0); pk = OverworldSWSHRNG.CalculateFromSeed(pk, shinyness, ivs, seed); return(pk); } else { return(null); } }
// Created when looking up an entry from the database public GiveawayPoolEntry(int id, string pool, string name, string tag, string uploader, PK8 pkm, string description, string status, string speciesName) { Id = id; Pool = pool; Name = name; Description = description; Status = status; Tag = tag; Uploader = uploader; PK8 = pkm; Pokemon = speciesName; Count = 1; }
private static bool DisallowSurpriseTrade(PK8 pk8) { return(pk8.RibbonClassic || pk8.RibbonPremier || pk8.RibbonBirthday); }
private async Task <PokeTradeResult> EndDuduTradeAsync(PokeTradeDetail <PK8> detail, PK8 pk, CancellationToken token) { await ExitDuduTrade(token).ConfigureAwait(false); detail.TradeFinished(this, pk); // Send results from separate thread; the bot doesn't need to wait for things to be calculated. #pragma warning disable 4014 Task.Run(() => ReplyWithZ3Results(detail, pk), token); #pragma warning restore 4014 Hub.Counts.AddCompletedDudu(); await Task.Delay(5_000, token).ConfigureAwait(false); return(PokeTradeResult.Success); }
public YouTubeQueue(PK8 pkm, PokeTradeTrainerInfo trainer, string username) { Pokemon = pkm; Trainer = trainer; UserName = username; }