aboutsummaryrefslogtreecommitdiff
path: root/src/main/kotlin
diff options
context:
space:
mode:
authornea <romangraef@gmail.com>2022-10-08 21:30:30 +0200
committernea <romangraef@gmail.com>2022-10-08 21:30:30 +0200
commit864f05c18bd4de5c8d0565aee1c18c9e5e43901d (patch)
treee6fb4a80ceca4a02baf656de463e76ab24589934 /src/main/kotlin
downloadneuhax-864f05c18bd4de5c8d0565aee1c18c9e5e43901d.tar.gz
neuhax-864f05c18bd4de5c8d0565aee1c18c9e5e43901d.tar.bz2
neuhax-864f05c18bd4de5c8d0565aee1c18c9e5e43901d.zip
Initial commit (die dritte)
Diffstat (limited to 'src/main/kotlin')
-rw-r--r--src/main/kotlin/moe/nea/sky/NEUHax.kt41
-rw-r--r--src/main/kotlin/moe/nea/sky/commands/NEUHaxCommand.kt34
-rw-r--r--src/main/kotlin/moe/nea/sky/config/HaxConfigEnchanting.kt6
-rw-r--r--src/main/kotlin/moe/nea/sky/config/HaxConfigWorld.kt5
-rw-r--r--src/main/kotlin/moe/nea/sky/constants.kt7
-rw-r--r--src/main/kotlin/moe/nea/sky/features/gui/Enchanting.kt82
-rw-r--r--src/main/kotlin/moe/nea/sky/util/TimedBackoff.kt24
-rw-r--r--src/main/kotlin/moe/nea/sky/util/chatutils.kt92
-rw-r--r--src/main/kotlin/moe/nea/sky/util/click.kt11
9 files changed, 302 insertions, 0 deletions
diff --git a/src/main/kotlin/moe/nea/sky/NEUHax.kt b/src/main/kotlin/moe/nea/sky/NEUHax.kt
new file mode 100644
index 0000000..b37a619
--- /dev/null
+++ b/src/main/kotlin/moe/nea/sky/NEUHax.kt
@@ -0,0 +1,41 @@
+package moe.nea.sky
+
+import moe.nea.sky.commands.NEUHaxCommand
+import moe.nea.sky.features.gui.Enchanting
+import moe.nea.sky.util.CommandActionRegistry
+import net.minecraft.launchwrapper.Launch
+import net.minecraftforge.client.ClientCommandHandler
+import net.minecraftforge.common.MinecraftForge
+import net.minecraftforge.fml.common.Mod
+import net.minecraftforge.fml.common.Mod.EventHandler
+import net.minecraftforge.fml.common.event.FMLInitializationEvent
+import net.minecraftforge.fml.common.event.FMLPreInitializationEvent
+
+
+@Mod(
+ modid = MODID,
+ useMetadata = true,
+ clientSideOnly = true,
+ modLanguageAdapter = "cc.polyfrost.oneconfig.utils.KotlinLanguageAdapter"
+)
+object NEUHax {
+
+ val deobf by lazy { Launch.blackboard["fml.deobfuscatedEnvironment"] == true }
+
+ @EventHandler
+ fun onInit(event: FMLPreInitializationEvent) {
+ println("Deobf: $deobf")
+ }
+
+ @EventHandler
+ fun onInit(event: FMLInitializationEvent) {
+ listOf<Any>(
+ Enchanting
+ ).forEach {
+ MinecraftForge.EVENT_BUS.register(it)
+ }
+ ClientCommandHandler.instance.registerCommand(NEUHaxCommand)
+ ClientCommandHandler.instance.registerCommand(CommandActionRegistry)
+ }
+
+} \ No newline at end of file
diff --git a/src/main/kotlin/moe/nea/sky/commands/NEUHaxCommand.kt b/src/main/kotlin/moe/nea/sky/commands/NEUHaxCommand.kt
new file mode 100644
index 0000000..5825e7d
--- /dev/null
+++ b/src/main/kotlin/moe/nea/sky/commands/NEUHaxCommand.kt
@@ -0,0 +1,34 @@
+package moe.nea.sky.commands
+
+import moe.nea.sky.util.showMessage
+import net.minecraft.command.CommandBase
+import net.minecraft.command.ICommandSender
+import net.minecraftforge.fml.common.FMLCommonHandler
+
+object NEUHaxCommand : CommandBase() {
+ override fun getCommandName(): String = "neuhax"
+ override fun getCommandAliases(): List<String> = listOf("nh")
+ override fun canCommandSenderUseCommand(sender: ICommandSender?): Boolean = true
+ override fun getCommandUsage(sender: ICommandSender): String = "/neuhax help"
+
+ fun sendHelp(target: ICommandSender) {
+ target.showMessage {
+ text("There is currently no help for you.")
+ text("Check back later!")
+ text("Click here for fun").clickable("Trust me") {
+ FMLCommonHandler.instance().handleExit(-1651473007)
+ FMLCommonHandler.instance().expectServerStopped()
+ }
+ }
+ }
+
+ override fun processCommand(sender: ICommandSender, args: Array<out String>) {
+ val verb = args.singleOrNull()
+ when (verb) {
+ else -> {
+ sendHelp(sender)
+ }
+ }
+ }
+
+} \ No newline at end of file
diff --git a/src/main/kotlin/moe/nea/sky/config/HaxConfigEnchanting.kt b/src/main/kotlin/moe/nea/sky/config/HaxConfigEnchanting.kt
new file mode 100644
index 0000000..6e7e5f2
--- /dev/null
+++ b/src/main/kotlin/moe/nea/sky/config/HaxConfigEnchanting.kt
@@ -0,0 +1,6 @@
+package moe.nea.sky.config
+
+interface HaxConfigEnchanting {
+ val neuHaxSolveKeybinding: Int
+ val neuHaxTimeout: Int
+} \ No newline at end of file
diff --git a/src/main/kotlin/moe/nea/sky/config/HaxConfigWorld.kt b/src/main/kotlin/moe/nea/sky/config/HaxConfigWorld.kt
new file mode 100644
index 0000000..db9a44d
--- /dev/null
+++ b/src/main/kotlin/moe/nea/sky/config/HaxConfigWorld.kt
@@ -0,0 +1,5 @@
+package moe.nea.sky.config
+
+interface HaxConfigWorld {
+ var neuHaxMushroomWallhacks: Boolean
+} \ No newline at end of file
diff --git a/src/main/kotlin/moe/nea/sky/constants.kt b/src/main/kotlin/moe/nea/sky/constants.kt
new file mode 100644
index 0000000..69259d2
--- /dev/null
+++ b/src/main/kotlin/moe/nea/sky/constants.kt
@@ -0,0 +1,7 @@
+package moe.nea.sky
+
+import org.slf4j.LoggerFactory
+
+
+val LOGGER = LoggerFactory.getLogger("NEUHax")
+const val MODID = "neuhax"
diff --git a/src/main/kotlin/moe/nea/sky/features/gui/Enchanting.kt b/src/main/kotlin/moe/nea/sky/features/gui/Enchanting.kt
new file mode 100644
index 0000000..994d462
--- /dev/null
+++ b/src/main/kotlin/moe/nea/sky/features/gui/Enchanting.kt
@@ -0,0 +1,82 @@
+package moe.nea.sky.features.gui
+
+import io.github.moulberry.notenoughupdates.NotEnoughUpdates
+import io.github.moulberry.notenoughupdates.miscfeatures.EnchantingSolvers
+import moe.nea.sky.config.HaxConfigEnchanting
+import moe.nea.sky.util.TimedBackoff
+import moe.nea.sky.util.middleClickOn
+import net.minecraft.client.gui.inventory.GuiChest
+import net.minecraft.init.Items
+import net.minecraft.inventory.ContainerChest
+import net.minecraft.item.ItemStack
+import net.minecraftforge.client.event.GuiScreenEvent
+import net.minecraftforge.fml.common.eventhandler.SubscribeEvent
+import org.lwjgl.input.Keyboard
+import org.slf4j.LoggerFactory
+import kotlin.time.Duration.Companion.milliseconds
+import kotlin.time.ExperimentalTime
+
+@OptIn(ExperimentalTime::class)
+object Enchanting {
+
+ @JvmStatic
+ lateinit var solversInstance: EnchantingSolvers
+
+ private val LOGGER = LoggerFactory.getLogger("NEUHaxEnchanting")!!
+ private val accessible get() = solversInstance as AccessibleEnchantingSolvers
+
+ interface AccessibleEnchantingSolvers {
+ var chronomatronReplyIndex: Int
+ val chronomatronOrder: List<String>
+ var ultrasequencerReplayIndex: Int
+ val ultraSequencerOrder: Map<Int, AccessibleUltrasequencerItem>
+ }
+
+ interface AccessibleUltrasequencerItem {
+ val stack: ItemStack
+ val containerIndex: Int
+ }
+
+ val config get() = NotEnoughUpdates.INSTANCE.config.enchantingSolvers as HaxConfigEnchanting
+
+ val timer = TimedBackoff()
+
+ @SubscribeEvent
+ fun onGuiKeyPress(event: GuiScreenEvent.KeyboardInputEvent) {
+ val guiChest = event.gui as? GuiChest ?: return
+ val content = guiChest.inventorySlots as? ContainerChest ?: return
+ if (!NotEnoughUpdates.INSTANCE.config.enchantingSolvers.enableEnchantingSolvers) return
+ if (config.neuHaxSolveKeybinding != Keyboard.getEventKey()) return
+ if (!timer.markIfAtLeastPassed(config.neuHaxTimeout.milliseconds)) return
+ LOGGER.debug("Solver: ${EnchantingSolvers.currentSolver}")
+ val timerStack = content.lowerChestInventory.getStackInSlot(content.lowerChestInventory.sizeInventory - 5)
+ if (timerStack.item != Items.clock) return
+ when (EnchantingSolvers.currentSolver) {
+ EnchantingSolvers.SolverType.CHRONOMATRON -> {
+ if (accessible.chronomatronReplyIndex in accessible.chronomatronOrder.indices) {
+ val itemToClickOn = accessible.chronomatronOrder[accessible.chronomatronReplyIndex]
+ LOGGER.debug("Attempting to click on chronomatron (index ${accessible.chronomatronReplyIndex}) (name: $itemToClickOn)")
+ accessible.chronomatronReplyIndex++
+ val slotToClickOn =
+ content.inventorySlots
+ .firstOrNull { it.stack?.displayName == itemToClickOn }
+ ?.slotNumber
+ ?: return
+ LOGGER.debug("Found item to click on at slot $slotToClickOn")
+ guiChest.inventorySlots.middleClickOn(slotToClickOn)
+ }
+ }
+
+ EnchantingSolvers.SolverType.ULTRASEQUENCER -> {
+ val nextUltraSequencerItem =
+ accessible.ultraSequencerOrder[accessible.ultrasequencerReplayIndex] ?: return
+ LOGGER.debug("Attempting to click on ultrasequencer (index ${accessible.ultraSequencerOrder}) (slotindex ${nextUltraSequencerItem.containerIndex})")
+ accessible.ultrasequencerReplayIndex++
+ guiChest.inventorySlots.middleClickOn(nextUltraSequencerItem.containerIndex)
+ }
+
+ else -> return
+ }
+ }
+
+} \ No newline at end of file
diff --git a/src/main/kotlin/moe/nea/sky/util/TimedBackoff.kt b/src/main/kotlin/moe/nea/sky/util/TimedBackoff.kt
new file mode 100644
index 0000000..a8af120
--- /dev/null
+++ b/src/main/kotlin/moe/nea/sky/util/TimedBackoff.kt
@@ -0,0 +1,24 @@
+package moe.nea.sky.util
+
+import kotlin.time.Duration
+import kotlin.time.ExperimentalTime
+import kotlin.time.TimeMark
+import kotlin.time.TimeSource
+
+@ExperimentalTime
+class TimedBackoff {
+ private var timed: TimeMark? = null
+
+ fun passedTime(): Duration {
+ return timed?.elapsedNow() ?: Duration.INFINITE
+ }
+
+ fun markIfAtLeastPassed(time: Duration): Boolean {
+ if (passedTime() >= time) {
+ timed = TimeSource.Monotonic.markNow()
+ return true
+ }
+ return false
+ }
+
+} \ No newline at end of file
diff --git a/src/main/kotlin/moe/nea/sky/util/chatutils.kt b/src/main/kotlin/moe/nea/sky/util/chatutils.kt
new file mode 100644
index 0000000..6ec756f
--- /dev/null
+++ b/src/main/kotlin/moe/nea/sky/util/chatutils.kt
@@ -0,0 +1,92 @@
+package moe.nea.sky.util
+
+import net.minecraft.command.CommandBase
+import net.minecraft.command.ICommandSender
+import net.minecraft.event.ClickEvent
+import net.minecraft.event.HoverEvent
+import net.minecraft.util.ChatComponentText
+import net.minecraft.util.EnumChatFormatting
+import net.minecraft.util.IChatComponent
+import java.util.*
+
+
+enum class MessageMode(val color: EnumChatFormatting) {
+ INFO(EnumChatFormatting.AQUA), ERROR(EnumChatFormatting.RED), FATAL(EnumChatFormatting.DARK_RED);
+
+ fun format(comp: IChatComponent): IChatComponent {
+ val b = ChatComponentText("§e[NEUH] §r")
+ b.chatStyle.color = color
+ b.appendSibling(comp)
+ return b
+ }
+}
+
+object CommandActionRegistry : CommandBase() {
+ override fun getCommandName(): String = "__neuhaxactioncallback"
+
+ override fun getCommandUsage(sender: ICommandSender?): String = "Do not directly use this"
+ override fun canCommandSenderUseCommand(sender: ICommandSender?): Boolean = true
+
+ data class ActionCallback(val callable: () -> Unit, val once: Boolean)
+
+ val callbacks: MutableMap<String, ActionCallback> = mutableMapOf()
+
+ override fun processCommand(sender: ICommandSender, args: Array<out String>) {
+ val callback = args.singleOrNull()
+ if (callback == null) {
+ showFail(sender)
+ return
+ }
+ val ac = synchronized(callbacks) {
+ val actionCallback = callbacks[callback]
+ if (actionCallback == null) {
+ showFail(sender)
+ return
+ }
+ if (actionCallback.once)
+ callbacks.remove(callback)
+ actionCallback
+ }
+ ac.callable()
+ }
+
+ fun registerCallback(callable: () -> Unit, once: Boolean): String {
+ val name = UUID.randomUUID().toString()
+ val actionCallback = ActionCallback(callable, once)
+ synchronized(callbacks) {
+ callbacks[name] = actionCallback
+ }
+ return "/$commandName $name"
+ }
+
+ private fun showFail(sender: ICommandSender) {
+ sender.showMessage(MessageMode.ERROR) {
+ text("Misuse of internal callback command.")
+ }
+ }
+}
+
+class MessageTarget {
+ val aggregate = mutableListOf<IChatComponent>()
+
+ fun text(string: String): ChatComponentText {
+ return component(ChatComponentText(string))
+ }
+
+ fun <T : IChatComponent> T.clickable(hover: String, once: Boolean = true, action: () -> Unit): T {
+ chatStyle.chatHoverEvent = HoverEvent(HoverEvent.Action.SHOW_TEXT, ChatComponentText(hover))
+ chatStyle.chatClickEvent =
+ ClickEvent(ClickEvent.Action.RUN_COMMAND, CommandActionRegistry.registerCallback(action, once))
+ return this
+ }
+
+ fun <T : IChatComponent> component(comp: T): T {
+ aggregate.add(comp)
+ return comp
+ }
+
+}
+
+fun ICommandSender.showMessage(mode: MessageMode = MessageMode.INFO, block: MessageTarget.() -> Unit) {
+ MessageTarget().also(block).aggregate.map { mode.format(it) }.forEach { addChatMessage(it) }
+}
diff --git a/src/main/kotlin/moe/nea/sky/util/click.kt b/src/main/kotlin/moe/nea/sky/util/click.kt
new file mode 100644
index 0000000..f1c5c97
--- /dev/null
+++ b/src/main/kotlin/moe/nea/sky/util/click.kt
@@ -0,0 +1,11 @@
+package moe.nea.sky.util
+
+import cc.polyfrost.oneconfig.utils.dsl.mc
+import net.minecraft.inventory.Container
+
+
+fun Container.middleClickOn(slotToClickOn: Int) {
+ mc.playerController.windowClick(
+ windowId, slotToClickOn, 2, 3, mc.thePlayer
+ )
+}