1+ import com.lambda.client.event.SafeClientEvent
2+ import com.lambda.client.manager.managers.PlayerPacketManager.sendPlayerPacket
13import com.lambda.client.module.Category
24import com.lambda.client.plugin.api.PluginModule
5+ import com.lambda.client.util.math.Vec2f
36import com.lambda.client.util.text.MessageSendHelper
7+ import com.lambda.client.util.threads.defaultScope
8+ import com.lambda.client.util.threads.runSafe
9+ import com.lambda.client.util.threads.runSafeR
410import com.lambda.client.util.threads.safeListener
11+ import kotlinx.coroutines.delay
12+ import kotlinx.coroutines.launch
513import net.minecraft.client.gui.GuiScreen
614import net.minecraft.client.gui.inventory.GuiInventory
715import net.minecraft.entity.player.EntityPlayer
@@ -16,7 +24,7 @@ import net.minecraft.util.ResourceLocation
1624import net.minecraftforge.fml.common.gameevent.TickEvent
1725
1826/*
19- * @author ToxicAven
27+ * @author ToxicAven
2028 */
2129
2230internal object AutoItemDupe: PluginModule(
@@ -26,30 +34,36 @@ internal object AutoItemDupe: PluginModule(
2634 pluginMain = AutoDupeLoader
2735) {
2836 private val cancelGUI by setting(" Cancel GUI" , true )
29- private val rotate by setting(" Rotate" , true )
30- private var instructions by setting(" Instructions" , false )
37+ private val interacting by setting(" Rotation Mode" , RotationMode .SPOOF , description = " Force view client side, only server side or no interaction at all" )
38+ private var instructions by setting(" Instructions" , true )
39+
40+ @Suppress(" UNUSED" )
41+ enum class RotationMode {
42+ OFF , SPOOF , VIEW_LOCK
43+ }
3144
3245 private var currentWaitPhase = WaitPhase .NONE
3346 private var startTimeStamp = 0L
3447 private var countBefore = 0
3548 private var idBefore = 0
3649 private var slotBefore = 0
37- private var inProgress = false
3850 private var lastClickStamp = System .currentTimeMillis()
3951 private var recipeLocation: ResourceLocation = ResourceLocation (" wooden_button" )
4052 // The only way this would be null is if your game is *FUCKED*
4153 private var pktRecipe: IRecipe = CraftingManager .REGISTRY .getObject(recipeLocation)!!
4254
4355 init {
4456 onEnable {
45- val check = checkForPlanks()
46- if (check == - 1 ) abort(" Planks were not found in inventory." ) else currentWaitPhase = WaitPhase .DROP
47-
48- if (instructions) {
49- MessageSendHelper .sendChatMessage(" To do the dupe, have wooden planks in your inventory, hold the item you wish to dupe, and toggle the module. wait until the item is picked back up." )
50- MessageSendHelper .sendWarningMessage(" Shulkers cannot be duped using this method. use 'AutoShulkerDupe' for those." )
51- instructions = false
52- }
57+ runSafeR {
58+ val check = checkForPlanks()
59+ if (check == - 1 ) abort(" Planks were not found in inventory." ) else currentWaitPhase = WaitPhase .DROP
60+
61+ if (instructions) {
62+ MessageSendHelper .sendChatMessage(" To do the dupe, have wooden planks in your inventory, hold the item you wish to dupe, and toggle the module. wait until the item is picked back up." )
63+ MessageSendHelper .sendWarningMessage(" Shulkers cannot be duped using this method. use 'AutoShulkerDupe' for those." )
64+ instructions = false
65+ }
66+ } ? : disable()
5367 }
5468
5569 onDisable {
@@ -61,18 +75,22 @@ internal object AutoItemDupe: PluginModule(
6175
6276 if (currentWaitPhase == WaitPhase .DROP ) {
6377
64- if (mc. player.inventory.getCurrentItem().isEmpty) abort(" You need to hold an item." )
78+ if (player.inventory.getCurrentItem().isEmpty) abort(" You need to hold an item." )
6579
6680 if (System .currentTimeMillis() - startTimeStamp < 120L ) {
67- if (! mc. player.recipeBook.isGuiOpen) mc. player.recipeBook.isGuiOpen = true
81+ if (! player.recipeBook.isGuiOpen) player.recipeBook.isGuiOpen = true
6882 }
69- if (rotate) mc.player.rotationPitch = 180f
70- idBefore = Item .getIdFromItem(mc.player.inventory.getCurrentItem().item)
83+
84+ updateRotation()
85+
86+ idBefore = Item .getIdFromItem(player.inventory.getCurrentItem().item)
7187 countBefore = countItem(idBefore)
72- slotBefore = mc. player.inventory.currentItem
88+ slotBefore = player.inventory.currentItem
7389 throwAllInSlot(slotBefore + 36 )
74- if (! cancelGUI) mc.displayGuiScreen(GuiInventory (mc.player as EntityPlayer ) as GuiScreen )
75- if (! mc.player.recipeBook.isGuiOpen) abort(" Failed to open Recipe Book. Try opening it manually." )
90+
91+ if (! cancelGUI) mc.displayGuiScreen(GuiInventory (player as EntityPlayer ) as GuiScreen )
92+ if (! player.recipeBook.isGuiOpen) abort(" Failed to open Recipe Book. Try opening it manually." )
93+
7694 currentWaitPhase = WaitPhase .PICKUP
7795 }
7896
@@ -83,46 +101,56 @@ internal object AutoItemDupe: PluginModule(
83101 }
84102 }
85103
86- private fun countItem (itemId : Int ): Int {
104+ private fun SafeClientEvent.updateRotation () {
105+ when (interacting) {
106+ RotationMode .SPOOF -> {
107+ sendPlayerPacket {
108+ rotate(Vec2f (player.rotationYaw, 180f ))
109+ }
110+ }
111+ RotationMode .VIEW_LOCK -> {
112+ player.rotationPitch = 180f
113+ }
114+ else -> {
115+ // RotationMode.OFF
116+ }
117+ }
118+ }
119+
120+ private fun SafeClientEvent.countItem (itemId : Int ): Int {
87121 val itemList: ArrayList <Int > = getSlots(itemId)
88122 var currentCount = 0
89123 val iterator: Iterator <Int > = itemList.iterator()
90124 while (iterator.hasNext()) {
91125 val i = iterator.next()
92- currentCount + = mc. player.inventory.getStackInSlot(i).count
126+ currentCount + = player.inventory.getStackInSlot(i).count
93127 }
94128 return currentCount
95129 }
96130
97- private fun getSlots (itemID : Int ): ArrayList <Int > {
131+ private fun SafeClientEvent. getSlots (itemID : Int ): ArrayList <Int > {
98132 val slots = ArrayList <Int >()
99133 for (i in 0 .. 8 ) {
100- if (Item .getIdFromItem(mc. player.inventory.getStackInSlot(i).item) == itemID) slots.add(Integer .valueOf(i))
134+ if (Item .getIdFromItem(player.inventory.getStackInSlot(i).item) == itemID) slots.add(Integer .valueOf(i))
101135 }
102136 return slots
103137 }
104138
105139 private fun throwAllInSlot (slot : Int ) {
106- if (inProgress) return
107- val thread: Thread = object : Thread () {
108- override fun run () {
109- inProgress = true
110- mc.playerController.windowClick(mc.player.inventoryContainer.windowId, slot, 1 , ClickType .THROW , mc.player as EntityPlayer )
111- try {
112- sleep(1000 )
113- mc.player.connection.sendPacket(CPacketPlaceRecipe (0 , pktRecipe, false ))
114- } catch (e: InterruptedException ) {
115- abort(" Tossing was interrupted." )
116- }
117- inProgress = false
140+ defaultScope.launch {
141+ runSafe {
142+ playerController.windowClick(player.inventoryContainer.windowId, slot, 1 , ClickType .THROW , player)
143+ }
144+ delay(1000L )
145+ runSafe {
146+ connection.sendPacket(CPacketPlaceRecipe (0 , pktRecipe, false ))
118147 }
119148 }
120- thread.start()
121149 }
122150
123- private fun checkForPlanks (): Int {
151+ private fun SafeClientEvent. checkForPlanks (): Int {
124152 for (i in 0 .. 35 ) {
125- val stack = mc. player.inventory.getStackInSlot(i)
153+ val stack = player.inventory.getStackInSlot(i)
126154 if (stack.item is ItemBlock ) {
127155 val block = (stack.item as ItemBlock ).block
128156 if (block == Blocks .PLANKS ) {
0 commit comments