GrimAnticheat / Grim

Fully async, multithreaded, predictive, open source, 3.01 reach, 1.005 timer, 0.01% speed, 99.99% antikb, "bypassable" 1.8-1.20 anticheat.
GNU General Public License v3.0
1.02k stars 289 forks source link

ChestStealer Bypass #1329

Open Legit6034 opened 6 months ago

Legit6034 commented 6 months ago

Describe the bypass and how to replicate it

Using the 1.12.2 client to bypass And Instantly grabbing all items from a chest.

Here are Code for 1.12.2Liquidbounce to put into effect

Delay=0

private val maxDelayValue: IntegerValue = object : IntegerValue("MaxDelay", 200, 0, 400) { override fun onChanged(oldValue: Int, newValue: Int) { val i = minDelayValue.get() if (i > newValue) set(i)

        nextDelay = TimeUtils.randomDelay(minDelayValue.get(), get())
    }
}

private val minDelayValue: IntegerValue = object : IntegerValue("MinDelay", 150, 0, 400) {
    override fun onChanged(oldValue: Int, newValue: Int) {
        val i = maxDelayValue.get()

        if (i < newValue)
            set(i)

        nextDelay = TimeUtils.randomDelay(get(), maxDelayValue.get())
    }
}
private val instantexploit = BoolValue("UsePacket", true)

private val eventModeValue = ListValue("OnEvent", arrayOf("Render3D", "Update", "MotionPre", "MotionPost"), "Render3D")

private val takeRandomizedValue = BoolValue("TakeRandomized", false)
private val onlyItemsValue = BoolValue("OnlyItems", false)
private val noCompassValue = BoolValue("NoCompass", false)
private val noDuplicateValue = BoolValue("NoDuplicateNonStackable", false)
private val autoCloseValue = BoolValue("AutoClose", true)
public val silenceValue = BoolValue("SilentMode", true)
public val showStringValue = BoolValue("Silent-ShowString", false)
public val stillDisplayValue = BoolValue("Silent-StillDisplay", false)

private val autoCloseMaxDelayValue: IntegerValue = object : IntegerValue("AutoCloseMaxDelay", 0, 0, 400) {
    override fun onChanged(oldValue: Int, newValue: Int) {
        val i = autoCloseMinDelayValue.get()
        if (i > newValue) set(i)
        nextCloseDelay = TimeUtils.randomDelay(autoCloseMinDelayValue.get(), this.get())
    }
}

private val autoCloseMinDelayValue: IntegerValue = object : IntegerValue("AutoCloseMinDelay", 0, 0, 400) {
    override fun onChanged(oldValue: Int, newValue: Int) {
        val i = autoCloseMaxDelayValue.get()
        if (i < newValue) set(i)
        nextCloseDelay = TimeUtils.randomDelay(this.get(), autoCloseMaxDelayValue.get())
    }
}

private val closeOnFullValue = BoolValue("CloseOnFull", true)
private val chestTitleValue = BoolValue("ChestTitle", false)

/**
 * VALUES
 */

private val delayTimer = MSTimer()
private var nextDelay = TimeUtils.randomDelay(minDelayValue.get(), maxDelayValue.get())

private val autoCloseTimer = MSTimer()
private var nextCloseDelay = TimeUtils.randomDelay(autoCloseMinDelayValue.get(), autoCloseMaxDelayValue.get())

public var contentReceived = 0

public var once = false

override fun onDisable() {
    once = false
}

@EventTarget
fun onRender3D(event: Render3DEvent?) {
    val screen = mc.currentScreen ?: return

    if (eventModeValue.get().equals("render3d", true))
        performStealer(screen)
}

@EventTarget
fun onUpdate(event: UpdateEvent) {
    if (instantexploit.get()) {
        if (classProvider.isGuiChest(mc.currentScreen)) {
            val chest = mc.currentScreen?.asGuiChest()
            val rows = chest?.inventoryRows!! * 9
            for (i in 0 until rows) {
                val slot = chest!!.inventorySlots?.getSlot(i)
                if (slot!!.hasStack) {
                    mc2.connection?.sendPacket(
                        CPacketClickWindow(
                            chest?.inventorySlots?.windowId!!,
                            i,
                            0,
                            ClickType.QUICK_MOVE,
                            slot?.stack!!.unwrap(),
                            1.toShort()
                        )
                    )
                }
            }
        }
    }
    val screen = mc.currentScreen ?: return

    if (eventModeValue.get().equals("update", true))
        performStealer(screen)

}

@EventTarget
fun onMotion(event: MotionEvent) {
    val screen = mc.currentScreen ?: return

    if (eventModeValue.get().equals("motion${event.eventState.stateName}", true))
        performStealer(screen)
}

fun performStealer(screen: IGuiScreen) {
    if (once && !classProvider.isGuiChest(screen)) {
        // prevent a bug where the chest suddenly closed while not finishing stealing items inside, leaving cheststealer turned on alone.
        state = false
        return
    }

    if (!classProvider.isGuiChest(screen) || !delayTimer.hasTimePassed(nextDelay)) {
        autoCloseTimer.reset()
        return
    }

    // No Compass
    if (!once && noCompassValue.get() && mc.thePlayer!!.inventory.getCurrentItemInHand()?.item?.unlocalizedName == "item.compass")
        return

    // Chest title
    if (!once && chestTitleValue.get() && (screen.asGuiChest().lowerChestInventory == null || !screen.asGuiChest().lowerChestInventory!!.name.contains(
            classProvider.createItemStack(
                functions.getObjectFromItemRegistry(classProvider.createResourceLocation("minecraft:chest"))!!
            ).displayName)))
        return

    // inventory cleaner
    val inventoryCleaner = LiquidBounce.moduleManager[InventoryCleaner::class.java] as InventoryCleaner

    // Is empty?
    if (!isEmpty(screen.asGuiChest()) && !(closeOnFullValue.get() && fullInventory)) {
        autoCloseTimer.reset()

        // Randomized
        if (takeRandomizedValue.get()) {
            var noLoop = false
            do {
                val items = mutableListOf<ISlot>()

                for (slotIndex in 0 until screen.asGuiChest().inventoryRows * 9) {
                    val slot = screen.asGuiChest().inventorySlots?.getSlot(slotIndex)
                    val stack = slot!!.stack
                    if (stack != null && (!onlyItemsValue.get() || !classProvider.isItemBlock(stack.item)) && (!inventoryCleaner.state || inventoryCleaner.isUseful(stack, -1)))
                        items.add(slot)
                }

                val randomSlot = Random.nextInt(items.size)
                val slot = items[randomSlot]

                move(screen.asGuiChest(), slot)
                if (nextDelay == 0L || delayTimer.hasTimePassed(nextDelay))
                    noLoop = true
            } while (delayTimer.hasTimePassed(nextDelay) && items.isNotEmpty() && !noLoop)
            return
        }

        // Non randomized
        for (slotIndex in 0 until screen.asGuiChest().inventoryRows * 9) {
            val slot = screen.asGuiChest().inventorySlots?.getSlot(slotIndex)
            val stack = slot!!.stack

            if (delayTimer.hasTimePassed(nextDelay) && shouldTake(stack, inventoryCleaner)) {
                move(screen.asGuiChest(), slot)
            }
        }
    } else if (autoCloseValue.get() && screen.asGuiChest().inventorySlots!!.windowId == contentReceived && autoCloseTimer.hasTimePassed(nextCloseDelay)) {
        mc.thePlayer?.closeScreen()

        if (silenceValue.get() && !stillDisplayValue.get()) LiquidBounce.hud.addNotification(Notification("ChestStealer","Closed chest.", NotifyType.INFO))
        nextCloseDelay = TimeUtils.randomDelay(autoCloseMinDelayValue.get(), autoCloseMaxDelayValue.get())

        if (once) {
            once = false
            state = false
            return
        }
    }
}

@EventTarget
private fun onPacket(event: PacketEvent) {
    val packet = event.packet

    if (classProvider.isSPacketWindowItems(packet))
        contentReceived = packet.asSPacketWindowItems().windowId
}
private inline fun shouldTake(stack: IItemStack?, inventoryCleaner: InventoryCleaner): Boolean {
    return stack != null && !ItemUtils.isStackEmpty(stack) && (!onlyItemsValue.get() || !classProvider.isItemBlock(stack.item)) && (!inventoryCleaner.state || inventoryCleaner.isUseful(stack, -1))
}

private fun move(screen: IGuiChest, slot: ISlot) {
    screen.handleMouseClick(slot, slot.slotNumber, 0, 1)
    delayTimer.reset()
    nextDelay = TimeUtils.randomDelay(minDelayValue.get(), maxDelayValue.get())
}

private fun isEmpty(chest: IGuiChest): Boolean {
    val inventoryCleaner = LiquidBounce.moduleManager[InventoryCleaner::class.java] as InventoryCleaner

    for (i in 0 until chest.inventoryRows * 9) {
        val slot = chest.inventorySlots!!.getSlot(i)

        val stack = slot.stack

        if (shouldTake(stack, inventoryCleaner))
            return false
    }

    return true
}

private val fullInventory: Boolean
    get() = mc.thePlayer?.inventory?.mainInventory?.none { it == null }!!

}

Grim version

loyisa

Server version

loyisa

Plugins

loyisa

xuzizz commented 6 months ago

狼牙发情

ManInMyVan commented 6 months ago

Unlikely to be patched, see https://github.com/GrimAnticheat/Grim/issues/877#issuecomment-1732335335