// Checks if player is in overworld (outside of a building). protected async Task <bool> IsOverworld(CancellationToken token) { var state = await Connection.ReadBytesAbsoluteAsync(CoordinateAddressIsland + 0x1E, 0x4, token).ConfigureAwait(false); var value = BitConverter.ToUInt32(state, 0); return(GetOverworldState(value) == OverworldState.Overworld); }
public async Task <ulong> FollowMainPointer(long[] jumps, bool canSolveOnSysmodule, CancellationToken token) //include the last jump here { // 1.7+ sys-botbase can solve entire pointer if (canSolveOnSysmodule) { var jumpsWithoutLast = jumps.Take(jumps.Length - 1); byte[] command = Encoding.UTF8.GetBytes($"pointer{string.Concat(jumpsWithoutLast.Select(z => $" {z}"))}\r\n"); byte[] socketReturn = await Connection.ReadRaw(command, sizeof(ulong) * 2 + 1, token).ConfigureAwait(false); var bytes = Base.Decoder.ConvertHexByteStringToBytes(socketReturn); bytes = bytes.Reverse().ToArray(); var offset = (ulong)((long)BitConverter.ToUInt64(bytes, 0) + jumps[jumps.Length - 1]); return(offset); } // solve pointer manually var ofs = (ulong)jumps[0]; // won't work with negative first jump var address = BitConverter.ToUInt64(await Connection.ReadBytesMainAsync(ofs, 0x8, token).ConfigureAwait(false), 0); for (int i = 1; i < jumps.Length - 1; ++i) { await Task.Delay(0_008, token).ConfigureAwait(false); // 1/4 frame var jump = jumps[i]; if (jump > 0) { address += (ulong)jump; } else { address -= (ulong)Math.Abs(jump); } byte[] bytes = await Connection.ReadBytesAbsoluteAsync(address, 0x8, token).ConfigureAwait(false); address = BitConverter.ToUInt64(bytes, 0); } return(address + (ulong)jumps[jumps.Length - 1]); }
public static async Task <ulong> GetPointerAddressFromExpression(ISwitchConnectionAsync sw, string pointerExpression, CancellationToken token) { // Regex pattern to get operators and offsets from pointer expression. const string pattern = @"(\+|\-)([A-Fa-f0-9]+)"; Regex regex = new(pattern); Match match = regex.Match(pointerExpression); // Get first offset from pointer expression and read address at that offset from main start. var ofs = Convert.ToUInt64(match.Groups[2].Value, 16); var address = BitConverter.ToUInt64(await sw.ReadBytesMainAsync(ofs, 0x8, token).ConfigureAwait(false), 0); match = match.NextMatch(); // Matches the rest of the operators and offsets in the pointer expression. while (match.Success) { // Get operator and offset from match. string opp = match.Groups[1].Value; ofs = Convert.ToUInt64(match.Groups[2].Value, 16); // Add or subtract the offset from the current stored address based on operator in front of offset. switch (opp) { case "+": address += ofs; break; case "-": address -= ofs; break; } // Attempt another match and if successful read bytes at address and store the new address. match = match.NextMatch(); if (!match.Success) { continue; } byte[] bytes = await sw.ReadBytesAbsoluteAsync(address, 0x8, token).ConfigureAwait(false); address = BitConverter.ToUInt64(bytes, 0); } return(address); }
/// <summary> /// Reads an offset until it changes to either match or differ from the comparison value. /// </summary> /// <returns>If <see cref="match"/> is set to true, then the function returns true when the offset matches the given value.<br>Otherwise, it returns true when the offset no longer matches the given value.</br></returns> public async Task <bool> ReadUntilChanged(ulong offset, byte[] comparison, int waitms, int waitInterval, bool match, bool absolute, CancellationToken token) { var sw = new Stopwatch(); sw.Start(); do { var task = absolute ? SwitchConnection.ReadBytesAbsoluteAsync(offset, comparison.Length, token) : SwitchConnection.ReadBytesAsync((uint)offset, comparison.Length, token); var result = await task.ConfigureAwait(false); if (match == result.SequenceEqual(comparison)) { return(true); } await Task.Delay(waitInterval, token).ConfigureAwait(false); } while (sw.ElapsedMilliseconds < waitms); return(false); }