Skip to content

feat(cheststealer): add InvCleaner priority & distance randomization bypass#8428

Open
m1trenv0 wants to merge 1 commit into
CCBlueX:nextgenfrom
m1trenv0:feat/cheststealer-bypass
Open

feat(cheststealer): add InvCleaner priority & distance randomization bypass#8428
m1trenv0 wants to merge 1 commit into
CCBlueX:nextgenfrom
m1trenv0:feat/cheststealer-bypass

Conversation

@m1trenv0

@m1trenv0 m1trenv0 commented Jun 1, 2026

Copy link
Copy Markdown
Contributor

This pull request adds two key improvements to the ChestStealer module to improve combat-preparedness and bypass checks on strict anti-cheats (like Polar):

1. InvCleaner Priority Selection Mode

  • Dynamically evaluates chest items using the standard ItemCategorization facets.
  • Prioritizes high-value combat and survival items (Armor, Swords, Weapons, Ender Pearls, Tools) before clearing lesser utility slots (blocks, food, etc.).
  • Within each priority tier, items are cleared using a proximity-based path (DISTANCE), ensuring both logical priority and local slot efficiency.

2. Distance Randomization Bypass

  • Adds a DistanceRandomFactor setting group (hides automatically if selection mode is not Distance or InvCleanerPriority).
  • Instead of following a perfectly linear, deterministic proximity path (which strict anti-cheats easily flag as automated), it perturbs slot distances using a random multiplier from your configured factor range.
  • This generates a slightly chaotic but highly efficient path (stealing nearby slots first, but occasionally choosing slightly further ones), defeating heuristic checks while maintaining maximum speed.

Предлагаемое изменение в документацию (Suggested changes to documentation):

### ChestStealer

Automatically steals all items from a chest.

Category: Player  
Enabled by default: No  

#### Settings

Below is the complete tree of all configurable settings for this module.

├── Constraints (Setting Group)
│   ├── StartDelay (Integer Range | default: 1..2 | range: 0..20 | ticks)
│   ├── ClickDelay (Integer Range | default: 2..4 | range: 0..20 | ticks)
│   ├── CloseDelay (Integer Range | default: 1..2 | range: 0..20 | ticks)
│   ├── MissChance (Integer Range | default: 0..0 | range: 0..100 | %)
│   └── Requires (Multi-Select | options: NoMovement, NoRotation)
├── AutoClose (Toggle | default: true)
├── SelectionMode (Choice | default: DISTANCE | options: Distance, Index, Random, InvCleanerPriority)
├── DistanceRandomFactor (Decimal Range | default: 1.0..1.0 | range: 0.0..5.0)
├── MoveMode (Choice | default: QUICK_MOVE | options: QuickMove, DragAndDrop)
...

#### Settings Details

* **SelectionMode** (Choice) — default: `DISTANCE`; options: `Distance`, `Index`, `Random`, `InvCleanerPriority`
  * `Distance`: Steals items starting from the closest slot in a proximity path.
  * `Index`: Steals items slot-by-slot from left to right.
  * `Random`: Steals items in a completely random order.
  * `InvCleanerPriority`: Dynamically analyzes item utility using Inventory Cleaner facets, prioritizing high-value combat items (Armor, Swords, Weapons, Ender Pearls, Tools) before stealing lesser items. Slots within each priority group are cleared using proximity-based distance.

* **DistanceRandomFactor** (Decimal Range) — default: `1.0..1.0`; range: `0.0..5.0`
  * Controls the randomization jitter applied to proximity-based stealing paths.
  * Setting this to a range like `0.8..1.3` adds natural, human-like variance to the path, completely bypassing heuristics while maintaining top-speed efficiency.

Copilot AI review requested due to automatic review settings June 1, 2026 11:29

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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_PRIORITY selection 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)
Comment on lines +343 to +348
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
Comment on lines +352 to +357
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
Comment on lines +381 to +382
for (priority in sortedPriorities) {
val groupSlots = grouped[priority]!!.toMutableList()
@m1trenv0 m1trenv0 force-pushed the feat/cheststealer-bypass branch 2 times, most recently from 635fca1 to 9ca3b35 Compare June 1, 2026 12:24
@MukjepScarlet

Copy link
Copy Markdown
Contributor

Conflict

@m1trenv0 m1trenv0 force-pushed the feat/cheststealer-bypass branch from 9ca3b35 to 903abbb Compare June 1, 2026 14:20
@m1trenv0 m1trenv0 force-pushed the feat/cheststealer-bypass branch 2 times, most recently from dd8d436 to d4bca4f Compare June 1, 2026 16:30
@m1trenv0

m1trenv0 commented Jun 1, 2026

Copy link
Copy Markdown
Contributor Author

Conflict

fixed. check it now

}

override fun deserialize(json: JsonElement, typeOfT: Type, context: JsonDeserializationContext?): ClosedRange<*> {
return when (typeOfT) {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why change this file

private val autoClose by boolean("AutoClose", true)

private val selectionMode by enumChoice("SelectionMode", SelectionMode.DISTANCE)
private val distanceRandomFactor by floatRange(

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I doubt any anticheat will detect this

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.

@m1trenv0 m1trenv0 Jun 3, 2026

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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 {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Incorrect usage

@m1trenv0 m1trenv0 force-pushed the feat/cheststealer-bypass branch from d4bca4f to 40b51c5 Compare June 3, 2026 10:07
@MukjepScarlet

Copy link
Copy Markdown
Contributor
  1. Update branch
  2. Use Mode pattern instead of Tagged for mode-specified settings

…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>
@m1trenv0 m1trenv0 force-pushed the feat/cheststealer-bypass branch from 40b51c5 to 9af90ab Compare June 8, 2026 15:43
@MukjepScarlet

Copy link
Copy Markdown
Contributor

Please split 2 features and update PR description

@MukjepScarlet

Copy link
Copy Markdown
Contributor

Well, I gonna add more features for Distance/Index mode, so you will need to resolve another conflict later.

@m1trenv0

Copy link
Copy Markdown
Contributor Author

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

Comment on lines +344 to +348
val randomizedDist = if (randomFactors == null) {
baseDist
} else {
baseDist * randomFactors.get(candidate.slotInContainer)
}

@minecrrrr minecrrrr Jun 19, 2026

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just use Elvis operator

Suggested change
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

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

simplify with takeIf

Suggested change
val facetsToCheck = if (nonWeaponFacets.isEmpty()) facets else nonWeaponFacets
val facetsToCheck = nonWeaponFacets.takeIf { it.isNotEmpty() } ?: facets

Comment on lines +423 to +431
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)
}

@minecrrrr minecrrrr Jun 19, 2026

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

use flatMap

Suggested change
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)

@minecrrrr

minecrrrr commented Jun 19, 2026

Copy link
Copy Markdown
Contributor

I refactored this to make the transformation more explicit and reduce intermediate variables.
If you think the original version is clearer in this context, I’m fine reverting it

@MukjepScarlet MukjepScarlet added Stale conflict PR has merge conflicts labels Jun 25, 2026
@github-actions github-actions Bot removed the Stale label Jun 28, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

conflict PR has merge conflicts

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants