Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -215,7 +215,7 @@ tasks {

kotlin {
compilerOptions {
freeCompilerArgs.add("-Xcontext-parameters")
freeCompilerArgs.addAll("-Xcontext-parameters", "-Xconsistent-data-class-copy-visibility")
}

jvmToolchain(21)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,11 @@
import com.lambda.event.EventFlow;
import com.lambda.event.events.InventoryEvent;
import com.lambda.event.events.WorldEvent;
import com.lambda.interaction.request.inventory.InventoryManager;
import com.lambda.module.modules.movement.Velocity;
import com.lambda.module.modules.render.NoRender;
import com.llamalad7.mixinextras.injector.wrapmethod.WrapMethod;
import com.llamalad7.mixinextras.injector.wrapoperation.Operation;
import net.minecraft.client.network.ClientPlayNetworkHandler;
import net.minecraft.client.network.PlayerListEntry;
import net.minecraft.network.packet.s2c.play.*;
Expand Down Expand Up @@ -103,4 +106,14 @@ public boolean onServerMetadata(ClientPlayNetworkHandler clientPlayNetworkHandle
void injectVelocity(ExplosionS2CPacket packet, CallbackInfo ci) {
if (Velocity.getExplosion() && Velocity.INSTANCE.isEnabled()) ci.cancel();
}

@WrapMethod(method = "onScreenHandlerSlotUpdate")
private void wrapOnScreenHandlerSlotUpdate(ScreenHandlerSlotUpdateS2CPacket packet, Operation<Void> original) {
InventoryManager.onSlotUpdate(packet, original);
}

@WrapMethod(method = "onInventory")
private void wrapOnInventory(InventoryS2CPacket packet, Operation<Void> original) {
InventoryManager.onInventoryUpdate(packet, original);
}
}
2 changes: 1 addition & 1 deletion src/main/kotlin/com/lambda/config/groups/BreakSettings.kt
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ class BreakSettings(
override val breakDelay by c.setting("Break Delay", 0, 0..6, 1, "The delay between breaking blocks", " tick(s)", visibility = vis).group(baseGroup, Group.General)

// Timing
override val breakStageMask by c.setting("Break Stage Mask", setOf(TickEvent.Input.Post), description = "The sub-tick timing at which break actions can be performed", visibility = vis).group(baseGroup, Group.General)
override val tickStageMask by c.setting("Break Stage Mask", setOf<TickEvent>(TickEvent.Input.Post), description = "The sub-tick timing at which break actions can be performed", visibility = vis).group(baseGroup, Group.General)

// Swap
override val swapMode by c.setting("Swap Mode", BreakConfig.SwapMode.End, "Decides when to swap to the best suited tool when breaking a block", visibility = vis).group(baseGroup, Group.General)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ class InteractSettings(
) : InteractConfig, SettingGroup(c) {
override val rotate by c.setting("Rotate For Interact", true, "Rotates the player to look at the block when interacting", visibility = vis).group(baseGroup)
override val swingHand by c.setting("Swing On Interact", true, "Swings the players hand after interacting", visibility = vis).group(baseGroup)
override val interactStageMask by c.setting("Interact Stage Mask", setOf(TickEvent.Input.Post), description = "The sub-tick timing at which interact actions are performed", visibility = vis).group(baseGroup)
override val tickStageMask by c.setting("Interact Stage Mask", setOf<TickEvent>(TickEvent.Input.Post), description = "The sub-tick timing at which interact actions are performed", visibility = vis).group(baseGroup)
override val interactSwingType by c.setting("Interact Swing Type", BuildConfig.SwingType.Vanilla, "The style of swing") { vis() && swingHand }.group(baseGroup)
override val interactConfirmationMode by c.setting("Interact Confirmation Mode", InteractConfig.InteractConfirmationMode.InteractThenAwait, "The style of confirmation for interactions", visibility = vis).group(baseGroup)
}
4 changes: 4 additions & 0 deletions src/main/kotlin/com/lambda/config/groups/InventorySettings.kt
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
package com.lambda.config.groups

import com.lambda.config.Configurable
import com.lambda.event.events.TickEvent
import com.lambda.interaction.request.inventory.InventoryConfig
import com.lambda.util.NamedEnum
import com.lambda.util.item.ItemUtils
Expand All @@ -28,10 +29,13 @@ class InventorySettings(
vis: () -> Boolean = { true }
) : InventoryConfig, SettingGroup(c) {
enum class Group(override val displayName: String) : NamedEnum {
General("General"),
Container("Container"),
Access("Access")
}

override val actionsPerSecond by c.setting("Actions Per Second", 100, 0..100, 1, "How many inventory actions can be performed per tick", visibility = vis).group(baseGroup, Group.General)
override val tickStageMask by c.setting("Inventory Stage Mask", setOf<TickEvent>(TickEvent.Pre, TickEvent.Input.Pre, TickEvent.Input.Post, TickEvent.Player.Post), description = "The sub-tick timing at which inventory actions are performed", visibility = vis).group(baseGroup, Group.General)
override val disposables by c.setting("Disposables", ItemUtils.defaultDisposables, ItemUtils.defaultDisposables, "Items that will be ignored when checking for a free slot", vis).group(baseGroup, Group.Container)
override val swapWithDisposables by c.setting("Swap With Disposables", true, "Swap items with disposable ones", vis).group(baseGroup, Group.Container)
override val providerPriority by c.setting("Provider Priority", InventoryConfig.Priority.WithMinItems, "What container to prefer when retrieving the item from", vis).group(baseGroup, Group.Container)
Expand Down
2 changes: 1 addition & 1 deletion src/main/kotlin/com/lambda/config/groups/PlaceSettings.kt
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ class PlaceSettings(
override val rotateForPlace by c.setting("Rotate For Place", true, "Rotate towards block while placing", visibility = vis).group(baseGroup)
override val airPlace by c.setting("Air Place", AirPlaceMode.None, "Allows for placing blocks without adjacent faces", visibility = vis).group(baseGroup)
override val axisRotateSetting by c.setting("Axis Rotate", true, "Overrides the Rotate For Place setting and rotates the player on each axis to air place rotational blocks") { vis() && airPlace.isEnabled }.group(baseGroup)
override val placeStageMask by c.setting("Place Stage mask", setOf(TickEvent.Input.Post), description = "The sub-tick timing at which place actions are performed", visibility = vis).group(baseGroup)
override val tickStageMask by c.setting("Place Stage mask", setOf<TickEvent>(TickEvent.Input.Post), description = "The sub-tick timing at which place actions are performed", visibility = vis).group(baseGroup)
override val placeConfirmationMode by c.setting("Place Confirmation", PlaceConfirmationMode.PlaceThenAwait, "Wait for block placement confirmation", visibility = vis).group(baseGroup)
override val maxPendingPlacements by c.setting("Max Pending Placements", 5, 0..30, 1, "The maximum amount of pending placements", visibility = vis).group(baseGroup)
override val placementsPerTick by c.setting("Places Per Tick", 1, 1..30, 1, "Maximum instant block places per tick", visibility = vis).group(baseGroup)
Expand Down
2 changes: 1 addition & 1 deletion src/main/kotlin/com/lambda/context/AutomatedSafeContext.kt
Original file line number Diff line number Diff line change
Expand Up @@ -20,4 +20,4 @@ package com.lambda.context
class AutomatedSafeContext(
safeContext: SafeContext,
automated: Automated
) : SafeContext by safeContext, Automated by automated
) : IAutomatedSafeContext, SafeContext by safeContext, Automated by automated
3 changes: 3 additions & 0 deletions src/main/kotlin/com/lambda/context/AutomationConfig.kt
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,9 @@ object AutomationConfig : Configurable(LambdaConfig), Automated {
override val hotbarConfig = HotbarSettings(this, Group.Hotbar)
override val eatConfig = EatSettings(this, Group.Eat)

val avoidDesync by setting("Avoid Desync", true, "Cancels incoming inventory update packets if they match previous actions").group(Group.Debug)
val maxDesyncCache by setting("Max Desync Cache", 30, 1..30, 1, "Maximum cached previous inventory actions") { avoidDesync }.group(Group.Debug)
val desyncTimeout by setting("Desync Timeout", 30, 1..30, 1, unit = " ticks", description = "Time to store previous inventory actions before dropping the cache") { avoidDesync }.group(Group.Debug)
val showAllEntries by setting("Show All Entries", false, "Show all entries in the task tree").group(Group.Debug)
val shrinkFactor by setting("Shrink Factor", 0.001, 0.0..1.0, 0.001).group(Group.Debug)
val ignoreItemDropWarnings by setting("Ignore Drop Warnings", false, "Hides the item drop warnings from the break manager").group(Group.Debug)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,6 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/

package com.lambda.interaction.material.transfer
package com.lambda.context

class TransferSelection
interface IAutomatedSafeContext : SafeContext, Automated
Original file line number Diff line number Diff line change
Expand Up @@ -19,10 +19,11 @@ package com.lambda.interaction.material.container.containers

import com.lambda.Lambda.mc
import com.lambda.context.Automated
import com.lambda.context.SafeContext
import com.lambda.event.events.TickEvent
import com.lambda.event.listener.SafeListener.Companion.listen
import com.lambda.interaction.material.StackSelection
import com.lambda.interaction.material.container.MaterialContainer
import com.lambda.interaction.material.transfer.TransactionExecutor
import com.lambda.interaction.request.inventory.InventoryRequest.Companion.inventoryRequest
import com.lambda.task.Task
import com.lambda.util.item.ItemStackUtils.equal
import com.lambda.util.player.gamemode
Expand All @@ -41,57 +42,63 @@ data object CreativeContainer : MaterialContainer(Rank.Creative) {
override fun spaceAvailable(selection: StackSelection): Int =
if (mc.player?.isCreative == true && selection.optimalStack != null) Int.MAX_VALUE else 0

class CreativeDeposit @Ta5kBuilder constructor(val selection: StackSelection) : Task<Unit>() {
class CreativeDeposit @Ta5kBuilder constructor(val selection: StackSelection, automated: Automated) : Task<Unit>(), Automated by automated {
override val name: String get() = "Removing $selection from creative inventory"

override fun SafeContext.onStart() {
if (!gamemode.isCreative) {
// ToDo: Maybe switch gamemode?
throw NotInCreativeModeException()
}
init {
listen<TickEvent.Pre> {
if (!gamemode.isCreative) {
// ToDo: Maybe switch gamemode?
throw NotInCreativeModeException()
}

TransactionExecutor.transfer(player.currentScreenHandler) {
player.currentScreenHandler?.slots?.let { slots ->
selection.filterSlots(slots).forEach {
clickCreativeStack(ItemStack.EMPTY, it.id)
inventoryRequest {
player.currentScreenHandler?.slots?.let { slots ->
selection.filterSlots(slots).forEach {
clickCreativeStack(ItemStack.EMPTY, it.id)
}
}
}
}.finally {
success()
}.execute(this@CreativeDeposit)
onComplete { success() }
}.submit(queueIfClosed = false)
}
}
}

context(automated: Automated)
override fun deposit(selection: StackSelection) = CreativeDeposit(selection)
override fun deposit(selection: StackSelection) = CreativeDeposit(selection, automated)

class CreativeWithdrawal @Ta5kBuilder constructor(val selection: StackSelection) : Task<Unit>() {
class CreativeWithdrawal @Ta5kBuilder constructor(val selection: StackSelection, automated: Automated) : Task<Unit>(), Automated by automated {
override val name: String get() = "Withdrawing $selection from creative inventory"

override fun SafeContext.onStart() {
selection.optimalStack?.let { optimalStack ->
if (player.mainHandStack.equal(optimalStack)) return
init {
listen<TickEvent.Pre> {
selection.optimalStack?.let { optimalStack ->
if (player.mainHandStack.equal(optimalStack)) {
success()
return@listen
}

if (!gamemode.isCreative) {
// ToDo: Maybe switch gamemode?
throw NotInCreativeModeException()
if (!gamemode.isCreative) {
// ToDo: Maybe switch gamemode?
throw NotInCreativeModeException()
}

inventoryRequest {
clickCreativeStack(optimalStack, 36 + player.inventory.selectedSlot)
action { player.inventory.selectedStack = optimalStack }
onComplete { success() }
}.submit(queueIfClosed = false)
return@listen
}

TransactionExecutor.transfer(player.currentScreenHandler) {
clickCreativeStack(optimalStack, 36 + player.inventory.selectedSlot)
}.finally {
success()
}.execute(this@CreativeWithdrawal)
return
throw NoOptimalStackException()
}

throw NoOptimalStackException()
}
}

// Withdraws items from the creative menu to the player's main hand
context(automated: Automated)
override fun withdraw(selection: StackSelection) = CreativeWithdrawal(selection)
override fun withdraw(selection: StackSelection) = CreativeWithdrawal(selection, automated)

class NotInCreativeModeException : IllegalStateException("Insufficient permission: not in creative mode")
class NoOptimalStackException : IllegalStateException("Cannot move item: no optimal stack")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,15 +19,13 @@ package com.lambda.interaction.material.container.containers

import com.lambda.Lambda.mc
import com.lambda.context.Automated
import com.lambda.context.SafeContext
import com.lambda.event.events.TickEvent
import com.lambda.event.listener.SafeListener.Companion.listen
import com.lambda.interaction.material.ContainerTask
import com.lambda.interaction.material.StackSelection
import com.lambda.interaction.material.container.MaterialContainer
import com.lambda.interaction.material.transfer.TransactionExecutor.Companion.transfer
import com.lambda.interaction.request.inventory.InventoryRequest.Companion.inventoryRequest
import com.lambda.util.item.ItemStackUtils.equal
import com.lambda.util.player.SlotUtils.combined
import com.lambda.util.player.SlotUtils.hotbar
import com.lambda.util.player.SlotUtils.storage
import com.lambda.util.text.buildText
import com.lambda.util.text.literal
import net.minecraft.item.ItemStack
Expand All @@ -40,41 +38,47 @@ object MainHandContainer : MaterialContainer(Rank.MainHand) {

override val description = buildText { literal("MainHand") }

class HandDeposit @Ta5kBuilder constructor(val selection: StackSelection, val hand: Hand) : ContainerTask() {
class HandDeposit @Ta5kBuilder constructor(
val selection: StackSelection,
val hand: Hand,
automated: Automated
) : ContainerTask(), Automated by automated {
override val name: String get() = "Depositing [$selection] to ${hand.name.lowercase().replace("_", " ")}"

override fun SafeContext.onStart() {
val moveStack = InventoryContainer.matchingStacks(selection).firstOrNull() ?: run {
failure("No matching stacks found in inventory")
return
}

val handStack = player.getStackInHand(hand)
if (moveStack.equal(handStack)) {
success()
return
}

transfer(player.currentScreenHandler) {
val stackInOffHand = moveStack.equal(player.offHandStack)
if (hand == Hand.MAIN_HAND && stackInOffHand) {
swapHands()
return@transfer
init {
listen<TickEvent.Pre> {
val moveStack = InventoryContainer.matchingStacks(selection).firstOrNull() ?: run {
failure("No matching stacks found in inventory")
return@listen
}

when (moveStack) {
in player.hotbar -> swapToHotbarSlot(player.hotbar.indexOf(moveStack))
// ToDo: Use pickFromInventory
in player.storage -> swap(player.combined.indexOf(moveStack), 0)
val handStack = player.getStackInHand(hand)
if (moveStack.equal(handStack)) {
success()
return@listen
}

if (hand == Hand.OFF_HAND) swapHands()
}.finally {
success()
}.execute(this@HandDeposit)
inventoryRequest {
val stackInOffHand = moveStack.equal(player.offHandStack)
val stackInMainHand = moveStack.equal(player.mainHandStack)
if ((hand == Hand.MAIN_HAND && stackInOffHand) || (hand == Hand.OFF_HAND && stackInMainHand)) {
swapHands()
return@inventoryRequest
}

val slot = player.currentScreenHandler.slots.first { it.stack == moveStack } ?: throw NotInInventoryException()
swap(slot.id, player.inventory.selectedSlot)

if (hand == Hand.OFF_HAND) swapHands()

onComplete { success() }
}.submit(queueIfClosed = false)
}
}
}

context(automated: Automated)
override fun deposit(selection: StackSelection) = HandDeposit(selection, Hand.MAIN_HAND)
override fun deposit(selection: StackSelection) = HandDeposit(selection, Hand.MAIN_HAND, automated)

class NotInInventoryException : IllegalStateException("Cannot find stack in inventory")
}
Original file line number Diff line number Diff line change
Expand Up @@ -34,5 +34,5 @@ object OffHandContainer : MaterialContainer(Rank.OffHand) {
override val description = buildText { literal("OffHand") }

context(automated: Automated)
override fun deposit(selection: StackSelection) = MainHandContainer.HandDeposit(selection, Hand.OFF_HAND)
override fun deposit(selection: StackSelection) = MainHandContainer.HandDeposit(selection, Hand.OFF_HAND, automated)
}

This file was deleted.

Loading
Loading