private async Task <bool> SkipCorrection(int skips, CancellationToken token) { var currentSeed = new RaidSpawnDetail(await DenData(Hub, token).ConfigureAwait(false), 0).Seed; if (currentSeed == InitialSeed) { Log("No frames were skipped. Ensure \"Synchronize Clock via Internet\" is enabled, are using sys-botbase that allows time change, and haven't used anything that shifts RAM. \"SkipDelay\" may also need to be increased."); return(false); } while (currentSeed != DestinationSeed) { skips = DenUtil.GetSkipsToTargetSeed(currentSeed, DestinationSeed, skips); if (skips > 0) { Log($"Fell short by {skips} skips! Resuming skipping until destination seed is reached."); await PerformDaySkip(skips, token).ConfigureAwait(false); currentSeed = new RaidSpawnDetail(await DenData(Hub, token).ConfigureAwait(false), 0).Seed; } else if (skips < 0) { Log($"Date must have rolled while skipping. We have overskipped our target."); return(false); } else { return(true); } } return(true); }
private async Task <int> SkipCheck(int skips, int skipsDone, CancellationToken token) { var currentSeed = new RaidSpawnDetail(await DenData(Hub, token).ConfigureAwait(false), 0).Seed; var remaining = DenUtil.GetSkipsToTargetSeed(currentSeed, DestinationSeed, skips); bool dateRolled = remaining < skips - skipsDone; if (dateRolled) { return(remaining + skipsDone); } else { return(skips); } }
public static string GetCurrentFrameInfo(DenUtil.RaidData raidInfo, uint flawlessIVs, ulong seed, out uint shinyType, bool raid = true) { var rng = new Xoroshiro128Plus(seed); _ = (uint)rng.NextInt(0xFFFFFFFF); uint SIDTID = (uint)rng.NextInt(0xFFFFFFFF); uint PID = (uint)rng.NextInt(0xFFFFFFFF); shinyType = GetShinyType(PID, SIDTID); var IVs = new uint[] { 255, 255, 255, 255, 255, 255 }; GetIVs(rng, IVs, flawlessIVs, out uint[,] allIVs, out _); uint[] ivs = new uint[6]; for (int i = 0; i < 6; i++) { ivs[i] = allIVs[flawlessIVs - 1, i]; } return(DenUtil.IVSpreadByStar(GetIVSpread(allIVs), raidInfo, ivs, seed, raid)); }
public static void SpecificSeedSearch(DenUtil.RaidData raidInfo, out long frames, out ulong seedRes, out ulong threeDay, out string ivSpread) { threeDay = seedRes = 0; frames = 0; ivSpread = string.Empty; ulong seed = raidInfo.Den.Seed; var rng = new Xoroshiro128Plus(seed); for (long i = 0; i < raidInfo.SearchRange; i++) { if (i > 0) { rng = new Xoroshiro128Plus(seed); seed = rng.Next(); rng = new Xoroshiro128Plus(seed); } uint EC = (uint)rng.NextInt(0xFFFFFFFF); uint SIDTID = (uint)rng.NextInt(0xFFFFFFFF); uint PID = (uint)rng.NextInt(0xFFFFFFFF); uint shinytype = GetShinyType(PID, SIDTID); if (shinytype == (uint)raidInfo.Shiny) { rng = GetIVs(rng, raidInfo.IVs, raidInfo.GuaranteedIVs, out uint[,] allIVs, out bool IVMatch); if (!IVMatch) { continue; } GetCharacteristic(EC, allIVs, raidInfo.GuaranteedIVs - 1, out bool charMatch, raidInfo.Characteristic); if (!charMatch) { continue; } rng = GetAbility(rng, raidInfo.Den.IsEvent ? raidInfo.RaidDistributionEncounter.Ability : (uint)raidInfo.RaidEncounter.Ability, out uint abilityT); bool abilityMatch = raidInfo.Ability == AbilityType.Any ? abilityT != (uint)raidInfo.Ability : abilityT == (uint)raidInfo.Ability; if (!abilityMatch) { continue; } rng = GetGender(rng, raidInfo.Ratio, raidInfo.Den.IsEvent ? raidInfo.RaidDistributionEncounter.Gender : (uint)raidInfo.RaidEncounter.Gender, out uint genderT); bool genderMatch = raidInfo.Gender == GenderType.Any ? genderT != (uint)raidInfo.Gender : genderT == (uint)raidInfo.Gender; if (!genderMatch) { continue; } GetNature(rng, raidInfo.Den.IsEvent ? raidInfo.RaidDistributionEncounter.Species : raidInfo.RaidEncounter.Species, raidInfo.Den.IsEvent ? raidInfo.RaidDistributionEncounter.AltForm : raidInfo.RaidEncounter.AltForm, out uint natureT); bool natureMatch = raidInfo.Nature == Nature.Random ? natureT != (uint)raidInfo.Nature : natureT == (uint)raidInfo.Nature; if (!natureMatch) { continue; } ivSpread = DenUtil.IVSpreadByStar(GetIVSpread(allIVs), raidInfo, seed); frames = i; seedRes = seed; for (int d = 3; d > 0; d--) { seed -= 0x82A2B175229D6A5B; } threeDay = seed; return; } if (i >= raidInfo.SearchRange) { return; } } }
private async Task DoDenBot(CancellationToken token) { if (Settings.Star < 0 || Settings.Star > 4) { Log("Please enter a valid star count."); return; } else if (Settings.Randroll < 1 || Settings.Randroll > 100) { Log("Please enter a valid randroll"); return; } else if (Settings.SkipCount < 0) { Log("Please enter a valid skip count."); return; } RaidInfo.Settings = Settings; var denData = await DenData(Hub, token).ConfigureAwait(false); RaidInfo = DenUtil.GetRaid(RaidInfo, denData); Log("Starting main DenBot loop."); while (!token.IsCancellationRequested && Config.NextRoutineType == PokeRoutineType.DenBot) { Config.IterateNextRoutine(); if (Settings.DenMode == DenMode.Skip) { var skips = Settings.SkipCount; InitialSeed = RaidInfo.Den.Seed; DestinationSeed = DenUtil.GetTargetSeed(RaidInfo.Den.Seed, skips); Log($"\nInitial seed: {InitialSeed:X16}.\nDestination seed: {DestinationSeed:X16}."); await PerformDaySkip(skips, token).ConfigureAwait(false); if (!await SkipCorrection(skips, token).ConfigureAwait(false)) { return; } EchoUtil.Echo($"{(!Hub.Config.StopConditions.PingOnMatch.Equals(string.Empty) ? $"<@{Hub.Config.StopConditions.PingOnMatch}> " : "")}Skipping complete\n"); } else { PerformSeedSearch(); EchoUtil.Echo($"{(!Hub.Config.StopConditions.PingOnMatch.Equals(string.Empty) ? $"<@{Hub.Config.StopConditions.PingOnMatch}> " : "")}Seed search complete, stopping the bot.\n"); return; } if (Settings.HostAfterSkip && Settings.DenMode != DenMode.SeedSearch) { Config.Initialize(PokeRoutineType.RaidBot); await SaveGame(Hub.Config, token).ConfigureAwait(false); Log("\nInitializing RaidBot..."); } else { return; } } }
private async Task <byte[]> DenData(PokeTradeHub <PK8> hub, CancellationToken token) => await Connection.ReadBytesAsync(DenUtil.GetDenOffset(hub), 0x18, token).ConfigureAwait(false);