commit c950db4dfe28b2073a06f7cdfb717fdb225a36c2
parent 178f2f4ac6b2065147fa415da2093e41101c806a
Author: w451 <115924828+w451@users.noreply.github.com>
Date:   Sat, 27 Apr 2024 08:00:20 -0400

feat: Random walking around in spoofed location (#805)

Co-authored-by: w451 <cheb>
Co-authored-by: auth <64337177+authorisation@users.noreply.github.com>
Diffstat:
MREADME.md | 1+
Mcommon/src/main/assets/lang/en_US.json | 4++++
Mcommon/src/main/kotlin/me/rhunk/snapenhance/common/config/impl/Global.kt | 1+
Mcore/src/main/kotlin/me/rhunk/snapenhance/core/features/impl/experiments/BetterLocation.kt | 78+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++-----
Mcore/src/main/kotlin/me/rhunk/snapenhance/core/ui/menu/impl/ChatActionMenu.kt | 3++-
5 files changed, 81 insertions(+), 6 deletions(-)

diff --git a/README.md b/README.md @@ -249,6 +249,7 @@ Thanks to everyone involved including the [third-party libraries](https://github - [TheVisual](https://github.com/TheVisual) - [CanerKaraca23](https://github.com/CanerKaraca23) - [bocajthomas](https://github.com/bocajthomas) +- [w451](https://github.com/w451) ## Donate - LTC: LbBnT9GxgnFhwy891EdDKqGmpn7XtduBdE diff --git a/common/src/main/assets/lang/en_US.json b/common/src/main/assets/lang/en_US.json @@ -636,6 +636,10 @@ "name": "Coordinates", "description": "Set the coordinates of the spoofed location" }, + "walk_radius": { + "name": "Walk Radius", + "description": "Randomly walk around within this radius (ft)" + }, "always_update_location": { "name": "Always Update Location", "description": "Force Snapchat to update location even if no GPS data is received" diff --git a/common/src/main/kotlin/me/rhunk/snapenhance/common/config/impl/Global.kt b/common/src/main/kotlin/me/rhunk/snapenhance/common/config/impl/Global.kt @@ -21,6 +21,7 @@ class Global : ConfigContainer() { inner class BetterLocation : ConfigContainer(hasGlobalState = true) { val spoofLocation = boolean("spoof_location") { requireRestart() } val coordinates = mapCoordinates("coordinates", 0.0 to 0.0) // lat, long + val walkRadius = string("walk_radius") { requireRestart(); inputCheck = { it.toDoubleOrNull()?.isFinite() == true && it.toDouble() >= 0.0 } } val alwaysUpdateLocation = boolean("always_update_location") { requireRestart() } val suspendLocationUpdates = boolean("suspend_location_updates") { requireRestart() } val spoofBatteryLevel = string("spoof_battery_level") { requireRestart(); inputCheck = { it.isEmpty() || it.toIntOrNull() in 0..100 } } diff --git a/core/src/main/kotlin/me/rhunk/snapenhance/core/features/impl/experiments/BetterLocation.kt b/core/src/main/kotlin/me/rhunk/snapenhance/core/features/impl/experiments/BetterLocation.kt @@ -11,9 +11,78 @@ import me.rhunk.snapenhance.core.features.impl.global.SuspendLocationUpdates import me.rhunk.snapenhance.core.util.hook.HookStage import me.rhunk.snapenhance.core.util.hook.hook import java.nio.ByteBuffer +import kotlin.math.cos +import kotlin.math.hypot +import kotlin.math.pow +import kotlin.math.sin +import kotlin.math.sqrt import kotlin.time.Duration.Companion.days class BetterLocation : Feature("Better Location", loadParams = FeatureLoadParams.INIT_SYNC) { + //Latitude ft / deg /Longitude ft /deg = 1.26301179736 + // 4ft/s * 1 degree/364000ft (latitude) * 1s/1000ms = .000000010989011 degrees/ms + val max_speed = 4.0 / 364000.0 / 1000.0 + val pause_chance = .0023 // .23% chance to pause every second = after 5 minutes 50% chance of pause + val pause_duration = 60000L //ms + val pause_random = 30000L //ms + + var pause_expire = 0L + var current_x = 0.0 + var current_y = 0.0 + var target_x = 0.0 + var target_y = 0.0 + var last_update_time = 0L + private fun updatePosition(){ + val now = System.currentTimeMillis() + + if(current_x == target_x && current_y == target_y) { + val config = context.config.global.betterLocation + val walk_rad = if (config.walkRadius.get() + .toDoubleOrNull() == null + ) 0.0 else (config.walkRadius.get().toDouble() / 364000.0) //Lat deg + + if(last_update_time == 0L){ //Start at random position + val radius1 = sqrt(Math.random()) * walk_rad + val theta1 = Math.PI * 2.0 * Math.random() + current_x = cos(theta1) * radius1 * 1.26301179736 + current_y = sin(theta1) * radius1 + } + + val radius2 = sqrt(Math.random()) * walk_rad + val theta2 = Math.PI * 2.0 * Math.random() + target_x = cos(theta2) * radius2 * 1.26301179736 + target_y = sin(theta2) * radius2 + } else if (pause_expire < now) { + val deltat = now - last_update_time + if(Math.random() > (1.0 - pause_chance).pow(deltat / 1000.0)){ + pause_expire = now + pause_duration + (pause_random * Math.random()).toLong() + } else { + val max_dist = max_speed * deltat + val dist = hypot(target_x - current_x, target_y - current_y) + + if (dist <= max_dist) { + current_x = target_x + current_y = target_y + } else { + val norm_x = (target_x - current_x) / dist * max_dist + val norm_y = (target_y - current_y) / dist * max_dist + current_x += norm_x + current_y += norm_y + } + } + } + last_update_time = now + } + + private fun getLat() : Double { + updatePosition() + return (context.config.global.betterLocation.coordinates.get().first + current_x) + } + + private fun getLong() : Double { + updatePosition() + return (context.config.global.betterLocation.coordinates.get().second + current_y) + } private fun editClientUpdate(editor: EditorContext) { val config = context.config.global.betterLocation @@ -22,11 +91,10 @@ class BetterLocation : Feature("Better Location", loadParams = FeatureLoadParams edit(1) { context.log.verbose("SCVSLocationUpdate ${this@apply}") if (config.spoofLocation.get()) { - val coordinates by config.coordinates remove(1) remove(2) - addFixed32(1, coordinates.first.toFloat()) // lat - addFixed32(2, coordinates.second.toFloat()) // lng + addFixed32(1, getLat().toFloat()) // lat + addFixed32(2, getLong().toFloat()) // lng } if (config.alwaysUpdateLocation.get()) { @@ -79,9 +147,9 @@ class BetterLocation : Feature("Better Location", loadParams = FeatureLoadParams } Location::class.java.apply { hook("getLatitude", HookStage.BEFORE) { - it.setResult(context.config.global.betterLocation.coordinates.get().first) } + it.setResult(getLat()) } hook("getLongitude", HookStage.BEFORE) { - it.setResult(context.config.global.betterLocation.coordinates.get().second) + it.setResult(getLong()) } } } diff --git a/core/src/main/kotlin/me/rhunk/snapenhance/core/ui/menu/impl/ChatActionMenu.kt b/core/src/main/kotlin/me/rhunk/snapenhance/core/ui/menu/impl/ChatActionMenu.kt @@ -172,4 +172,4 @@ class ChatActionMenu : AbstractMenu() { viewGroup.addView(buttonContainer) } -} +}+ \ No newline at end of file