public async Task <long> LGCountMilliseconds(PokeTradeHubConfig config, CancellationToken token) { long WaitMS = config.LGPE_OverworldScan.MaxMs; bool stuck = false; Stopwatch stopwatch = new Stopwatch(); stopwatch.Start(); byte[] data = await SwitchConnection.ReadBytesMainAsync(FreezedValue, 1, token).ConfigureAwait(false); byte[] comparison = data; do { data = await SwitchConnection.ReadBytesMainAsync(FreezedValue, 1, token).ConfigureAwait(false); if (stopwatch.ElapsedMilliseconds > WaitMS) { stuck = true; } } while (data.SequenceEqual(comparison) && stuck == false && !token.IsCancellationRequested); if (!stuck) { stopwatch.Restart(); comparison = data; do { data = await SwitchConnection.ReadBytesMainAsync(FreezedValue, 1, token).ConfigureAwait(false); } while (data == comparison && !token.IsCancellationRequested); return(stopwatch.ElapsedMilliseconds); } else { return(0); } }
public async Task <PB7> LGReadPokemon(uint offset, CancellationToken token, int size = EncryptedSize, bool heap = true) { byte[] data; if (heap == true) { data = await Connection.ReadBytesAsync(offset, size, token).ConfigureAwait(false); } else { data = await SwitchConnection.ReadBytesMainAsync(offset, size, token).ConfigureAwait(false); } return(new PB7(data)); }
//Pointer parser, code from ALM public async Task <ulong> ParsePointer(String pointer, CancellationToken token) { var ptr = pointer; uint finadd = 0; if (!ptr.EndsWith("]")) { finadd = Util.GetHexValue(ptr.Split('+').Last()); } var jumps = ptr.Replace("main", "").Replace("[", "").Replace("]", "").Split(new[] { "+" }, StringSplitOptions.RemoveEmptyEntries); if (jumps.Length == 0) { Log("Invalid Pointer"); return(0); } var initaddress = Util.GetHexValue(jumps[0].Trim()); ulong address = BitConverter.ToUInt64(await SwitchConnection.ReadBytesMainAsync(initaddress, 0x8, token).ConfigureAwait(false), 0); foreach (var j in jumps) { var val = Util.GetHexValue(j.Trim()); if (val == initaddress) { continue; } if (val == finadd) { address += val; break; } address = BitConverter.ToUInt64(await SwitchConnection.ReadBytesAbsoluteAsync(address + val, 0x8, token).ConfigureAwait(false), 0); } return(address); }
public async Task <bool> LGIsGiftFound(CancellationToken token) => (await SwitchConnection.ReadBytesMainAsync(IsGiftFound, 1, token).ConfigureAwait(false))[0] > 0;
public async Task <bool> LGIsInTrade(CancellationToken token) => (await SwitchConnection.ReadBytesMainAsync(IsInTrade, 1, token).ConfigureAwait(false))[0] != 0;
public async Task <bool> LGIsInCatchScreen(CancellationToken token) => (await SwitchConnection.ReadBytesMainAsync(IsInOverworld, 1, token).ConfigureAwait(false))[0] != 0;
public async Task <bool> LGIsInBattle(CancellationToken token) => (await SwitchConnection.ReadBytesMainAsync(IsInBattleScenario, 1, token).ConfigureAwait(false))[0] > 0;
public async Task <bool> LGIsInTitleScreen(CancellationToken token) => !((await SwitchConnection.ReadBytesMainAsync(IsInTitleScreen, 1, token).ConfigureAwait(false))[0] == 1);
public async Task <bool> IsInLairEndList(CancellationToken token) => (await SwitchConnection.ReadBytesMainAsync(LairRewards, 1, token).ConfigureAwait(false))[0] != 0;
private async Task TestOffsets(CancellationToken token) { GameVersion version = await LGWhichGameVersion(token).ConfigureAwait(false); long waitms; long maxms = 0; int i = 0; Log("Testing Game Version..."); if (version == GameVersion.GP) { Log("OK: Let's Go Pikachu."); } else if (version == GameVersion.GE) { Log("OK: Let's Go Eevee."); } else { Log("FAILED: Incompatible game or update."); } Log("Testing Shiny Value..."); var data = await SwitchConnection.ReadBytesMainAsync(version == GameVersion.GP?PShinyValue : EShinyValue, 4, token).ConfigureAwait(false); byte[] compare = new byte[] { 0xE0, 0x02, 0x00, 0x54 }; if (data.SequenceEqual(compare)) { Log($"OK: {BitConverter.ToString(data)}"); } else { Log($"FAILED: {BitConverter.ToString(data)} should be {BitConverter.ToString(compare)}."); } Log("Testing generating function..."); data = await SwitchConnection.ReadBytesMainAsync(version == GameVersion.GP?PGeneratingFunction1 : EGeneratingFunction1, 4, token).ConfigureAwait(false); compare = new byte[] { 0xE8, 0x03, 0x00, 0x2A }; byte[] zak = new byte[] { 0xE9, 0x03, 0x00, 0x2A }; if (data.SequenceEqual(compare) || data.SequenceEqual(zak)) { Log($"OK: {BitConverter.ToString(data)}"); } else { Log($"FAILED: {BitConverter.ToString(data)} should be {BitConverter.ToString(compare)}."); } while (!token.IsCancellationRequested) { i++; Log($"Checking freezing value, attempt n.{i}..."); waitms = await LGCountMilliseconds(Hub.Config, token).ConfigureAwait(false); if (waitms > 0) { if (waitms > maxms) { maxms = waitms; } Log($"OK: 0x1610EE0 changed after {waitms}ms"); } else { Log("FAILED: 0x1610EE0 not changed."); } if (i >= Hub.Config.LGPE_OverworldScan.FreezingTestCount) { Log($"Test completed. MaxMS value: {maxms}"); return; } } }
private async Task DoDynamaxAdventure(CancellationToken token) { //Initialization int adventureCompleted = 0; LairSpecies mon = Hub.Config.SWSH_DynaAdventure.EditLairPath; byte[] demageStandardState = BitConverter.GetBytes(0x7900E808); byte[] demageAlteredState = BitConverter.GetBytes(0x7900E81F); byte[] demageTemporalState; bool wasVideoClipActive = Hub.Config.StopConditions.CaptureVideoClip; System.Diagnostics.Stopwatch stopwatch = new System.Diagnostics.Stopwatch(); //Check/set target parameters uint pathoffset = LairSpeciesSelector; bool caneditspecies = true; stopwatch.Start(); //Check what's the right offset for the first lair path byte[] current_try1 = await Connection.ReadBytesAsync(LairSpeciesSelector, 2, token).ConfigureAwait(false); byte[] current_try2 = await Connection.ReadBytesAsync(LairSpeciesSelector2, 2, token).ConfigureAwait(false); if (Enum.IsDefined(typeof(LairSpecies), (ushort)BitConverter.ToInt16(current_try1, 0))) { pathoffset = LairSpeciesSelector; } else if (Enum.IsDefined(typeof(LairSpecies), (ushort)BitConverter.ToInt16(current_try2, 0))) { pathoffset = LairSpeciesSelector2; } else { caneditspecies = false; } byte[] current = await Connection.ReadBytesAsync(pathoffset, 2, token).ConfigureAwait(false); byte[] wanted = BitConverter.GetBytes((ushort)mon); if ((ushort)mon != 0 && current != wanted && !Enum.IsDefined(typeof(LairSpecies), mon)) { Log($"{mon} is not an available Lair Boss species. Check your configurations and restart the bot."); return; } else if ((ushort)mon != 0 && current != wanted && Enum.IsDefined(typeof(LairSpecies), mon)) { if (caneditspecies) { await Connection.WriteBytesAsync(wanted, pathoffset, token); Log($"{mon} ready to be hunted."); } else { Log($"________________________________{Environment.NewLine}ATTENTION!" + $"{Environment.NewLine}{mon} may not be your first path pokemon. Ignore this message if the Pokémon on the Stop Condition matches the Pokémon on your current Lair Path." + $"{Environment.NewLine}________________________________"); } } else if ((ushort)mon == 0) { Log("(Any) Legendary ready to be hunted."); } //Check ShinyXOR if (Hub.Config.StopConditions.ShinyTarget.ToString() == "SquareOnly") { Log("Lair Pokémon cannot be Square Shiny! Forced XOR=1. Check your settings and restart the bot."); return; } while (!token.IsCancellationRequested) { //Capture video clip is menaged internally if (Hub.Config.StopConditions.CaptureVideoClip == true) { Hub.Config.StopConditions.CaptureVideoClip = false; } //Talk to the Lady while (!await IsInLairWait(token).ConfigureAwait(false)) { await Click(A, 0_200, token).ConfigureAwait(false); } //Select Solo Adventure await Click(DDOWN, 0_800, token).ConfigureAwait(false); await Click(A, 1_000, token).ConfigureAwait(false); //MAIN LOOP int raidCount = 1; bool inBattle = false; bool lost = false; //Allows 1HKO if (Hub.Config.SWSH_DynaAdventure.InstantKill) { demageTemporalState = await SwitchConnection.ReadBytesMainAsync(demageOutputOffset, 4, token).ConfigureAwait(false); if (demageStandardState.SequenceEqual(demageTemporalState)) { await SwitchConnection.WriteBytesMainAsync(demageAlteredState, demageOutputOffset, token).ConfigureAwait(false); } } while (!(await IsInLairEndList(token).ConfigureAwait(false) || lost || token.IsCancellationRequested)) { await Click(A, 0_200, token).ConfigureAwait(false); if (await IsOnOverworld(Hub.Config, token).ConfigureAwait(false)) { lost = true; Log("Lost at first raid. Starting again."); } else if (!await IsInBattle(token).ConfigureAwait(false) && inBattle) { inBattle = false; } else if (await IsInBattle(token).ConfigureAwait(false) && !inBattle) { var pk = await ReadUntilPresent(RaidPokemonOffset, 2_000, 0_200, token).ConfigureAwait(false); if (pk != null) { Log($"Raid Battle {raidCount}: {pk.Species} {pk.Nickname}"); } else { Log($"Raid Battle {raidCount}.{Environment.NewLine}RAM probably shifted. It is suggested to reboot the game or console."); } inBattle = true; raidCount++; stopwatch.Restart(); } else if (await IsInBattle(token).ConfigureAwait(false) && inBattle) { if (stopwatch.ElapsedMilliseconds > 120000) { Log("Stuck in a battle, trying to change move."); for (int j = 0; j < 10; j++) { await Click(B, 1_00, token).ConfigureAwait(false); } await Click(DDOWN, 1_000, token).ConfigureAwait(false); stopwatch.Restart(); } } } //Disable 1HKO if (Hub.Config.SWSH_DynaAdventure.InstantKill) { demageTemporalState = await SwitchConnection.ReadBytesMainAsync(demageOutputOffset, 4, token).ConfigureAwait(false); if (demageAlteredState.SequenceEqual(demageTemporalState)) { await SwitchConnection.WriteBytesMainAsync(demageStandardState, demageOutputOffset, token).ConfigureAwait(false); } } if (!lost) { //Check for shinies, check all the StopConditions for the Legendary int[] found = await IsAdventureHuntFound(token).ConfigureAwait(false); adventureCompleted++; if (raidCount < 5) { Log($"Lost at battle n. {(raidCount - 1)}, adventure n. {adventureCompleted}."); } else if (found[1] == 0) { Log($"Lost at battle n. 4, adventure n. {adventureCompleted}."); } else { Log($"Adventure n. {adventureCompleted} completed."); } //Ending routine if ((Hub.Config.SWSH_DynaAdventure.KeepShinies && found[0] > 0) || found[0] == 4) { await Task.Delay(1_500, token).ConfigureAwait(false); for (int i = 1; i < found[0]; i++) { await Click(DDOWN, 1_000, token).ConfigureAwait(false); } await Click(A, 0_900, token).ConfigureAwait(false); await Click(DDOWN, 0_800, token).ConfigureAwait(false); await Click(A, 2_300, token).ConfigureAwait(false); await PressAndHold(CAPTURE, 2_000, 10_000, token).ConfigureAwait(false); if (wasVideoClipActive == true) { Hub.Config.StopConditions.CaptureVideoClip = true; } //If legendary Pokémon is found, stop the routine, else keep the shiny pokemon and restart the routine if (found[0] == 4) { return; } else { await Task.Delay(1_500, token).ConfigureAwait(false); await Click(B, 1_500, token).ConfigureAwait(false); while (!await IsOnOverworld(Hub.Config, token).ConfigureAwait(false)) { await Click(A, 0_500, token).ConfigureAwait(false); await Task.Delay(2_000, token).ConfigureAwait(false); } } } else { Log("No result found, starting again"); await Task.Delay(1_500, token).ConfigureAwait(false); await Click(B, 1_000, token).ConfigureAwait(false); while (!await IsOnOverworld(Hub.Config, token).ConfigureAwait(false)) { await Click(A, 0_500, token).ConfigureAwait(false); await Task.Delay(2_000, token).ConfigureAwait(false); } } } } }