feat(cheststealer): add InvCleaner priority & distance randomization bypass#8428
feat(cheststealer): add InvCleaner priority & distance randomization bypass#8428m1trenv0 wants to merge 1 commit into
Conversation
There was a problem hiding this comment.
Pull request overview
Note
Copilot was unable to run its full agentic suite in this review.
This PR introduces randomized behavior for “edge distance” checks (Scaffold Eagle + SafeWalk) and enhances ChestStealer slot ordering by adding distance randomization and an InvCleaner-priority selection mode.
Changes:
- Replace fixed edge-distance thresholds with configurable ranges and randomized sampling.
- Add ChestStealer distance randomization factor and a new
INVCLEANER_PRIORITYselection mode. - Refactor distance-based slot ordering to incorporate randomized weighting.
Reviewed changes
Copilot reviewed 3 out of 3 changed files in this pull request and generated 9 comments.
| File | Description |
|---|---|
src/main/kotlin/net/ccbluex/liquidbounce/features/module/modules/world/scaffold/techniques/normal/ScaffoldEagleFeature.kt |
Changes Eagle edge distance from a fixed float to a randomized range sampled at runtime. |
src/main/kotlin/net/ccbluex/liquidbounce/features/module/modules/player/cheststealer/ModuleChestStealer.kt |
Adds distance randomization and a new selection mode that groups by InvCleaner-style priority, then sorts within groups. |
src/main/kotlin/net/ccbluex/liquidbounce/features/module/modules/movement/ModuleSafeWalk.kt |
Changes SafeWalk “OnEdge” distance from a fixed float to a randomized range sampled at runtime. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
|
|
||
| private val blocksToEagle = intRange("BlocksToEagle", 0..0, 0..10).asRefreshable() | ||
| private val edgeDistance by float("EdgeDistance", 0.01f, 0.01f..1.3f) | ||
| private val edgeDistance by floatRange("EdgeDistance", 0.01f..0.05f, 0.01f..1.3f) |
| val shouldBeActive = !player.abilities.flying && placedBlocks == 0 | ||
|
|
||
| return shouldBeActive && player.isCloseToEdge(input, edgeDistance.toDouble()) | ||
| return shouldBeActive && player.isCloseToEdge(input, edgeDistance.random().toDouble()) |
|
|
||
| private val blocksToEagle = intRange("BlocksToEagle", 0..0, 0..10).asRefreshable() | ||
| private val edgeDistance by float("EdgeDistance", 0.01f, 0.01f..1.3f) | ||
| private val edgeDistance by floatRange("EdgeDistance", 0.01f..0.05f, 0.01f..1.3f) |
| class OnEdge(override val parent: ModeValueGroup<Mode>) : Mode("OnEdge") { | ||
|
|
||
| private val edgeDistance by float("Distance", 0.1f, 0.1f..0.5f) | ||
| private val edgeDistance by floatRange("Distance", 0.1f..0.15f, 0.05f..0.5f) |
| val isOnEdge = player.isCloseToEdge( | ||
| event.directionalInput, | ||
| min(player.horizontalSpeed, edgeDistance.toDouble()) | ||
| min(player.horizontalSpeed, edgeDistance.random().toDouble()) |
| class OnEdge(override val parent: ModeValueGroup<Mode>) : Mode("OnEdge") { | ||
|
|
||
| private val edgeDistance by float("Distance", 0.1f, 0.1f..0.5f) | ||
| private val edgeDistance by floatRange("Distance", 0.1f..0.15f, 0.05f..0.5f) |
| val factorRange = ModuleChestStealer.distanceRandomFactor | ||
| val hasRandom = factorRange.start != factorRange.endInclusive | ||
|
|
||
| for (i in 0..<n - 1) { | ||
| var bestIdx = i + 1 | ||
| var bestDist = Int.MAX_VALUE | ||
| var bestDist = Double.MAX_VALUE |
| for (j in i + 1..<n) { | ||
| val d = current.distance(slots[j]) | ||
| val d = current.distance(slots[j]).toDouble() | ||
| val randomizedDist = if (hasRandom) d * factorRange.random() else d | ||
|
|
||
| if (d < bestDist) { | ||
| bestDist = d | ||
| if (randomizedDist < bestDist) { | ||
| bestDist = randomizedDist |
| for (priority in sortedPriorities) { | ||
| val groupSlots = grouped[priority]!!.toMutableList() |
635fca1 to
9ca3b35
Compare
|
Conflict |
9ca3b35 to
903abbb
Compare
dd8d436 to
d4bca4f
Compare
fixed. check it now |
| } | ||
|
|
||
| override fun deserialize(json: JsonElement, typeOfT: Type, context: JsonDeserializationContext?): ClosedRange<*> { | ||
| return when (typeOfT) { |
| private val autoClose by boolean("AutoClose", true) | ||
|
|
||
| private val selectionMode by enumChoice("SelectionMode", SelectionMode.DISTANCE) | ||
| private val distanceRandomFactor by floatRange( |
There was a problem hiding this comment.
I doubt any anticheat will detect this
There was a problem hiding this comment.
I doubt any anticheat will detect this
works as expected in Polar. I just checked it. It doesn't detect the randomness pattern instantly—it does so after 2-3 chests on MineBlaze. Besides, if the anti-cheat detects it, you can simply enable Random Factor 1-1, and it will work exactly the same as in previous versions.
There was a problem hiding this comment.
Moreover, without this option, ChestStealer only beats Polar with Delay 4 or higher, but with this option I can use Delay 2-2 and it bypass
| 1.0f..1.0f, | ||
| 0.0f..5.0f, | ||
| "factor" | ||
| ).doNotIncludeWhen { |
d4bca4f to
40b51c5
Compare
|
…tion Adds a SelectionMode.InvCleanerPriority that groups slots by InvCleaner item priority and orders each group by distance, plus a per-mode DistanceRandomFactor that multiplies slot distances by a random factor so the steal order is not perfectly distance-monotonic. Review fixes: - Use the Mode pattern (choices/Mode) instead of a Tagged enum for SelectionMode, as requested. Each mode owns its own settings, so DistanceRandomFactor only shows for Distance / InvCleanerPriority (the modes that sort by distance) and is hidden for Index / Random — this replaces the misused doNotIncludeWhen with native mode-scoped visibility. - Revert the unrelated RangeAdapter.kt change; it does not belong in this PR. - One random factor per slot (not per comparison), so ordering is stable and not O(n^2) RNG. - getValue instead of !! for the priority groups. Co-Authored-By: Claude <noreply@anthropic.com>
40b51c5 to
9af90ab
Compare
|
Please split 2 features and update PR description |
|
Well, I gonna add more features for Distance/Index mode, so you will need to resolve another conflict later. |
I have exams :(, so I'll resolve everything at the end of next week |
| val randomizedDist = if (randomFactors == null) { | ||
| baseDist | ||
| } else { | ||
| baseDist * randomFactors.get(candidate.slotInContainer) | ||
| } |
There was a problem hiding this comment.
Just use Elvis operator
| val randomizedDist = if (randomFactors == null) { | |
| baseDist | |
| } else { | |
| baseDist * randomFactors.get(candidate.slotInContainer) | |
| } | |
| val randomizedDist = baseDist * (randomFactors?.get(candidate.slotInContainer) ?: 1.0) |
| private fun primaryItemType(slot: ItemSlot): ItemType { | ||
| val facets = ItemCategorization.Default.getItemFacets(slot) | ||
| val nonWeaponFacets = facets.filterNot { it is WeaponItemFacet } | ||
| val facetsToCheck = if (nonWeaponFacets.isEmpty()) facets else nonWeaponFacets |
There was a problem hiding this comment.
simplify with takeIf
| val facetsToCheck = if (nonWeaponFacets.isEmpty()) facets else nonWeaponFacets | |
| val facetsToCheck = nonWeaponFacets.takeIf { it.isNotEmpty() } ?: facets |
| val grouped = slots.groupBy { invCleanerPriorityFor(it) } | ||
| val sortedPriorities = grouped.keys.sortedDescending() | ||
|
|
||
| slots.clear() | ||
| for (priority in sortedPriorities) { | ||
| val groupSlots = grouped.getValue(priority).toMutableList() | ||
| sortByDistance(groupSlots, distanceRandomFactor) | ||
| slots.addAll(groupSlots) | ||
| } |
There was a problem hiding this comment.
use flatMap
| val grouped = slots.groupBy { invCleanerPriorityFor(it) } | |
| val sortedPriorities = grouped.keys.sortedDescending() | |
| slots.clear() | |
| for (priority in sortedPriorities) { | |
| val groupSlots = grouped.getValue(priority).toMutableList() | |
| sortByDistance(groupSlots, distanceRandomFactor) | |
| slots.addAll(groupSlots) | |
| } | |
| val sortedPriorities = slots | |
| .groupBy { invCleanerPriorityFor(it) } | |
| .toSortedMap(compareByDescending { it }) | |
| .flatMap { (_, groupSlots) -> | |
| groupSlots.toMutableList().also { | |
| sortByDistance(this, distanceRandomFactor) | |
| } | |
| } | |
| slots.clear() | |
| slots.addAll(sortedPriorities) |
|
I refactored this to make the transformation more explicit and reduce intermediate variables. |
This pull request adds two key improvements to the
ChestStealermodule to improve combat-preparedness and bypass checks on strict anti-cheats (like Polar):1. InvCleaner Priority Selection Mode
ItemCategorizationfacets.DISTANCE), ensuring both logical priority and local slot efficiency.2. Distance Randomization Bypass
DistanceRandomFactorsetting group (hides automatically if selection mode is notDistanceorInvCleanerPriority).Предлагаемое изменение в документацию (Suggested changes to documentation):