diff options
author | nea <romangraef@gmail.com> | 2022-10-08 21:30:30 +0200 |
---|---|---|
committer | nea <romangraef@gmail.com> | 2022-10-08 21:30:30 +0200 |
commit | 864f05c18bd4de5c8d0565aee1c18c9e5e43901d (patch) | |
tree | e6fb4a80ceca4a02baf656de463e76ab24589934 | |
download | neuhax-864f05c18bd4de5c8d0565aee1c18c9e5e43901d.tar.gz neuhax-864f05c18bd4de5c8d0565aee1c18c9e5e43901d.tar.bz2 neuhax-864f05c18bd4de5c8d0565aee1c18c9e5e43901d.zip |
Initial commit (die dritte)
26 files changed, 987 insertions, 0 deletions
diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..69fa48a --- /dev/null +++ b/.gitignore @@ -0,0 +1,6 @@ +.idea/ +.vscode/ +run/ +build/ +.gradle/ + diff --git a/build.gradle.kts b/build.gradle.kts new file mode 100644 index 0000000..faca950 --- /dev/null +++ b/build.gradle.kts @@ -0,0 +1,128 @@ +plugins { + idea + java + id("gg.essential.loom") version "0.10.0.+" + id("dev.architectury.architectury-pack200") version "0.1.3" + id("com.github.johnrengelman.shadow") version "7.1.2" + kotlin("jvm") version "1.7.10" + kotlin("plugin.serialization") version "1.7.10" +} + +group = "moe.nea.sky" +version = "1.0.0" + +// Toolchains: +java { + toolchain.languageVersion.set(JavaLanguageVersion.of(8)) +} + +sourceSets.main { + output.setResourcesDir(file("$buildDir/classes/kotlin/main")) +} + +// Dependencies: + +repositories { + mavenCentral() + mavenLocal() + maven("https://jitpack.io/") { + content { + includeGroupByRegex("(com|io)\\.github\\..+") + } + } + maven("https://repo.spongepowered.org/maven/") + maven("https://repo.polyfrost.cc/releases") + // If you don't want to log in with your real minecraft account, remove this line + maven("https://pkgs.dev.azure.com/djtheredstoner/DevAuth/_packaging/public/maven/v1") +} + +val shadowImpl: Configuration by configurations.creating { + configurations.implementation.get().extendsFrom(this) +} + +val runtimeMod by configurations.creating { + isTransitive = false + isVisible = false +} + +dependencies { + minecraft("com.mojang:minecraft:1.8.9") + mappings("de.oceanlabs.mcp:mcp_stable:22-1.8.9") + forge("net.minecraftforge:forge:1.8.9-11.15.1.2318-1.8.9") + + shadowImpl("org.spongepowered:mixin:0.7.11-SNAPSHOT") { + isTransitive = false + } + compileOnly("cc.polyfrost:oneconfig-1.8.9-forge:0.1.0-alpha+") // Should not be included in jar + shadowImpl("cc.polyfrost:oneconfig-wrapper-launchwrapper:1.0.0-alpha+") // Should be included in jar + annotationProcessor("org.spongepowered:mixin:0.8.4-SNAPSHOT") + // If you don't want to log in with your real minecraft account, remove this line + runtimeOnly("me.djtheredstoner:DevAuth-forge-legacy:1.1.0") + + modCompileOnly(runtimeMod("com.github.romangraef:notenoughupdates:30f7cf9e:all")!!) +} + +// Minecraft configuration: +loom { + log4jConfigs.from(file("log4j2.xml")) + launchConfigs { + "client" { + // If you don't want mixins, remove these lines + property("mixin.debug", "true") + property("asmhelper.verbose", "true") + arg("--tweakClass", "cc.polyfrost.oneconfigwrapper.OneConfigWrapper") + arg("--mixin", "mixins.neuhax.json") + val modFiles = runtimeMod.files + arg("--mods", modFiles.joinToString(",") { it.relativeTo(file("run")).path }) + } + } + runConfigs { + delete("server") + } + forge { + pack200Provider.set(dev.architectury.pack200.java.Pack200Adapter()) + // If you don't want mixins, remove this lines + mixinConfig("mixins.neuhax.json") + } + // If you don't want mixins, remove these lines + mixin { + defaultRefmapName.set("mixins.neuhax.refmap.json") + } +} + + +// Tasks: + +tasks.withType(JavaCompile::class) { + options.encoding = "UTF-8" +} + +tasks.withType(Jar::class) { + archiveBaseName.set("sky.nea.moe") + manifest.attributes.run { + this["FMLCorePluginContainsFMLMod"] = "true" + this["ForceLoadAsMod"] = "true" + + // If you don't want mixins, remove these lines + this["TweakClass"] = "cc.polyfrost.oneconfigwrapper.OneConfigWrapper" + this["MixinConfigs"] = "mixins.neuhax.json" + } +} + + +val remapJar by tasks.named<net.fabricmc.loom.task.RemapJarTask>("remapJar") { + archiveClassifier.set("thicc") + from(tasks.shadowJar) + input.set(tasks.shadowJar.get().archiveFile) +} + +tasks.shadowJar { + archiveClassifier.set("all-dev") + configurations = listOf(shadowImpl) + + // If you want to include other dependencies and shadow them, you can relocate them in here + fun relocate(name: String) = relocate(name, "nea.moe.sky.deps.$name") +} + +tasks.assemble.get().dependsOn(tasks.remapJar) + diff --git a/gradle.properties b/gradle.properties new file mode 100644 index 0000000..7a79fe1 --- /dev/null +++ b/gradle.properties @@ -0,0 +1,2 @@ +loom.platform=forge +org.gradle.jvmargs=-Xmx2g diff --git a/gradle/wrapper/gradle-wrapper.jar b/gradle/wrapper/gradle-wrapper.jar Binary files differnew file mode 100644 index 0000000..e708b1c --- /dev/null +++ b/gradle/wrapper/gradle-wrapper.jar diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties new file mode 100644 index 0000000..8049c68 --- /dev/null +++ b/gradle/wrapper/gradle-wrapper.properties @@ -0,0 +1,5 @@ +distributionBase=GRADLE_USER_HOME +distributionPath=wrapper/dists +distributionUrl=https\://services.gradle.org/distributions/gradle-7.5-bin.zip +zipStoreBase=GRADLE_USER_HOME +zipStorePath=wrapper/dists @@ -0,0 +1,185 @@ +#!/usr/bin/env sh + +# +# Copyright 2015 the original author or authors. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# https://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +############################################################################## +## +## Gradle start up script for UN*X +## +############################################################################## + +# Attempt to set APP_HOME +# Resolve links: $0 may be a link +PRG="$0" +# Need this for relative symlinks. +while [ -h "$PRG" ] ; do + ls=`ls -ld "$PRG"` + link=`expr "$ls" : '.*-> \(.*\)$'` + if expr "$link" : '/.*' > /dev/null; then + PRG="$link" + else + PRG=`dirname "$PRG"`"/$link" + fi +done +SAVED="`pwd`" +cd "`dirname \"$PRG\"`/" >/dev/null +APP_HOME="`pwd -P`" +cd "$SAVED" >/dev/null + +APP_NAME="Gradle" +APP_BASE_NAME=`basename "$0"` + +# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' + +# Use the maximum available, or set MAX_FD != -1 to use that value. +MAX_FD="maximum" + +warn () { + echo "$*" +} + +die () { + echo + echo "$*" + echo + exit 1 +} + +# OS specific support (must be 'true' or 'false'). +cygwin=false +msys=false +darwin=false +nonstop=false +case "`uname`" in + CYGWIN* ) + cygwin=true + ;; + Darwin* ) + darwin=true + ;; + MINGW* ) + msys=true + ;; + NONSTOP* ) + nonstop=true + ;; +esac + +CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar + + +# Determine the Java command to use to start the JVM. +if [ -n "$JAVA_HOME" ] ; then + if [ -x "$JAVA_HOME/jre/sh/java" ] ; then + # IBM's JDK on AIX uses strange locations for the executables + JAVACMD="$JAVA_HOME/jre/sh/java" + else + JAVACMD="$JAVA_HOME/bin/java" + fi + if [ ! -x "$JAVACMD" ] ; then + die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME + +Please set the JAVA_HOME variable in your environment to match the +location of your Java installation." + fi +else + JAVACMD="java" + which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. + +Please set the JAVA_HOME variable in your environment to match the +location of your Java installation." +fi + +# Increase the maximum file descriptors if we can. +if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then + MAX_FD_LIMIT=`ulimit -H -n` + if [ $? -eq 0 ] ; then + if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then + MAX_FD="$MAX_FD_LIMIT" + fi + ulimit -n $MAX_FD + if [ $? -ne 0 ] ; then + warn "Could not set maximum file descriptor limit: $MAX_FD" + fi + else + warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT" + fi +fi + +# For Darwin, add options to specify how the application appears in the dock +if $darwin; then + GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\"" +fi + +# For Cygwin or MSYS, switch paths to Windows format before running java +if [ "$cygwin" = "true" -o "$msys" = "true" ] ; then + APP_HOME=`cygpath --path --mixed "$APP_HOME"` + CLASSPATH=`cygpath --path --mixed "$CLASSPATH"` + + JAVACMD=`cygpath --unix "$JAVACMD"` + + # We build the pattern for arguments to be converted via cygpath + ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null` + SEP="" + for dir in $ROOTDIRSRAW ; do + ROOTDIRS="$ROOTDIRS$SEP$dir" + SEP="|" + done + OURCYGPATTERN="(^($ROOTDIRS))" + # Add a user-defined pattern to the cygpath arguments + if [ "$GRADLE_CYGPATTERN" != "" ] ; then + OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)" + fi + # Now convert the arguments - kludge to limit ourselves to /bin/sh + i=0 + for arg in "$@" ; do + CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -` + CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option + + if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition + eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"` + else + eval `echo args$i`="\"$arg\"" + fi + i=`expr $i + 1` + done + case $i in + 0) set -- ;; + 1) set -- "$args0" ;; + 2) set -- "$args0" "$args1" ;; + 3) set -- "$args0" "$args1" "$args2" ;; + 4) set -- "$args0" "$args1" "$args2" "$args3" ;; + 5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;; + 6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;; + 7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;; + 8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;; + 9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;; + esac +fi + +# Escape application args +save () { + for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done + echo " " +} +APP_ARGS=`save "$@"` + +# Collect all arguments for the java command, following the shell quoting and substitution rules +eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS" + +exec "$JAVACMD" "$@" diff --git a/gradlew.bat b/gradlew.bat new file mode 100644 index 0000000..107acd3 --- /dev/null +++ b/gradlew.bat @@ -0,0 +1,89 @@ +@rem +@rem Copyright 2015 the original author or authors. +@rem +@rem Licensed under the Apache License, Version 2.0 (the "License"); +@rem you may not use this file except in compliance with the License. +@rem You may obtain a copy of the License at +@rem +@rem https://www.apache.org/licenses/LICENSE-2.0 +@rem +@rem Unless required by applicable law or agreed to in writing, software +@rem distributed under the License is distributed on an "AS IS" BASIS, +@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +@rem See the License for the specific language governing permissions and +@rem limitations under the License. +@rem + +@if "%DEBUG%" == "" @echo off +@rem ########################################################################## +@rem +@rem Gradle startup script for Windows +@rem +@rem ########################################################################## + +@rem Set local scope for the variables with windows NT shell +if "%OS%"=="Windows_NT" setlocal + +set DIRNAME=%~dp0 +if "%DIRNAME%" == "" set DIRNAME=. +set APP_BASE_NAME=%~n0 +set APP_HOME=%DIRNAME% + +@rem Resolve any "." and ".." in APP_HOME to make it shorter. +for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi + +@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m" + +@rem Find java.exe +if defined JAVA_HOME goto findJavaFromJavaHome + +set JAVA_EXE=java.exe +%JAVA_EXE% -version >NUL 2>&1 +if "%ERRORLEVEL%" == "0" goto execute + +echo. +echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. +echo. +echo Please set the JAVA_HOME variable in your environment to match the +echo location of your Java installation. + +goto fail + +:findJavaFromJavaHome +set JAVA_HOME=%JAVA_HOME:"=% +set JAVA_EXE=%JAVA_HOME%/bin/java.exe + +if exist "%JAVA_EXE%" goto execute + +echo. +echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% +echo. +echo Please set the JAVA_HOME variable in your environment to match the +echo location of your Java installation. + +goto fail + +:execute +@rem Setup the command line + +set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar + + +@rem Execute Gradle +"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %* + +:end +@rem End local scope for the variables with windows NT shell +if "%ERRORLEVEL%"=="0" goto mainEnd + +:fail +rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of +rem the _cmd.exe /c_ return code! +if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 +exit /b 1 + +:mainEnd +if "%OS%"=="Windows_NT" endlocal + +:omega diff --git a/log4j2.xml b/log4j2.xml new file mode 100644 index 0000000..362efd0 --- /dev/null +++ b/log4j2.xml @@ -0,0 +1,11 @@ +<?xml version="1.0" encoding="UTF-8"?> +<Configuration> + <!-- Filter out Hypixel scoreboard and sound errors --> + <RegexFilter status="WARN" + regex="Error executing task.*|Unable to play unknown soundEvent.*|Zip file .* failed to read properly, it will be ignored.*|There was a problem reading the entry META-INF/versions/9/module-info.class in the jar .*|Unable to read a class file correctly.*|Mixing .* from mixins.notenoughupdates.json.*|The jar file .* has a security seal for path .*|The jar file .* is trying to seal already secured path .*" + onMatch="DENY" + onMismatch="NEUTRAL"/> + <Loggers> + <Logger name="NEUHaxEnchanting" level="debug"/> + </Loggers> +</Configuration>
\ No newline at end of file diff --git a/settings.gradle.kts b/settings.gradle.kts new file mode 100644 index 0000000..e162c4d --- /dev/null +++ b/settings.gradle.kts @@ -0,0 +1,21 @@ +pluginManagement { + repositories { + mavenCentral() + gradlePluginPortal() + maven("https://oss.sonatype.org/content/repositories/snapshots") + maven("https://maven.architectury.dev/") + maven("https://maven.fabricmc.net") + maven("https://maven.minecraftforge.net/") + maven("https://repo.spongepowered.org/maven/") + maven("https://repo.sk1er.club/repository/maven-releases/") + } + resolutionStrategy { + eachPlugin { + when (requested.id.id) { + "gg.essential.loom" -> useModule("gg.essential:architectury-loom:${requested.version}") + } + } + } +} + +rootProject.name = "neuhax" diff --git a/src/main/java/moe/nea/sky/mixin/MixinEnchantingSolvers.java b/src/main/java/moe/nea/sky/mixin/MixinEnchantingSolvers.java new file mode 100644 index 0000000..e21718b --- /dev/null +++ b/src/main/java/moe/nea/sky/mixin/MixinEnchantingSolvers.java @@ -0,0 +1,65 @@ +package moe.nea.sky.mixin; + +import io.github.moulberry.notenoughupdates.miscfeatures.EnchantingSolvers; +import moe.nea.sky.features.gui.Enchanting; +import org.spongepowered.asm.mixin.Final; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.Shadow; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; + +import java.util.List; +import java.util.Map; + +@Mixin(EnchantingSolvers.class) +public class MixinEnchantingSolvers implements Enchanting.AccessibleEnchantingSolvers { + @Shadow + private static int chronomatronReplayIndex; + + @Shadow + @Final + private static List<String> chronomatronOrder; + + @Shadow + private static int ultrasequencerReplayIndex; + + @Shadow + @Final + private static Map<Integer, Enchanting.AccessibleUltrasequencerItem> ultraSequencerOrder; + + @Inject(method = "<init>", at = @At("RETURN")) + public void init(CallbackInfo ci) { + Enchanting.solversInstance = (EnchantingSolvers) (Object) this; + } + + @Override + public int getChronomatronReplyIndex() { + return chronomatronReplayIndex; + } + + @Override + public void setChronomatronReplyIndex(int i) { + chronomatronReplayIndex = i; + } + + @Override + public List<String> getChronomatronOrder() { + return chronomatronOrder; + } + + @Override + public int getUltrasequencerReplayIndex() { + return ultrasequencerReplayIndex; + } + + @Override + public void setUltrasequencerReplayIndex(int i) { + ultrasequencerReplayIndex = i; + } + + @Override + public Map<Integer, Enchanting.AccessibleUltrasequencerItem> getUltraSequencerOrder() { + return ultraSequencerOrder; + } +} diff --git a/src/main/java/moe/nea/sky/mixin/MixinFMLHandshakeMessageModList.java b/src/main/java/moe/nea/sky/mixin/MixinFMLHandshakeMessageModList.java new file mode 100644 index 0000000..df8cee3 --- /dev/null +++ b/src/main/java/moe/nea/sky/mixin/MixinFMLHandshakeMessageModList.java @@ -0,0 +1,24 @@ +package moe.nea.sky.mixin; + +import moe.nea.sky.ConstantsKt; +import net.minecraftforge.fml.common.network.handshake.FMLHandshakeMessage; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.Shadow; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; + +import java.util.List; +import java.util.Map; + + +@Mixin(FMLHandshakeMessage.ModList.class) +public abstract class MixinFMLHandshakeMessageModList { + + @Shadow public abstract Map<String, String> modList(); + + @Inject(method = "<init>(Ljava/util/List;)V", at = @At(value = "RETURN")) + public void onInitLast(List modList, CallbackInfo ci) { + modList().remove(ConstantsKt.MODID); + } +} diff --git a/src/main/java/moe/nea/sky/mixin/MixinGlowingMushroomHighlighter.java b/src/main/java/moe/nea/sky/mixin/MixinGlowingMushroomHighlighter.java new file mode 100644 index 0000000..4b31225 --- /dev/null +++ b/src/main/java/moe/nea/sky/mixin/MixinGlowingMushroomHighlighter.java @@ -0,0 +1,19 @@ +package moe.nea.sky.mixin; + +import io.github.moulberry.notenoughupdates.NotEnoughUpdates; +import io.github.moulberry.notenoughupdates.miscfeatures.world.GlowingMushroomHighlighter; +import moe.nea.sky.config.HaxConfigWorld; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; + +@Mixin(GlowingMushroomHighlighter.class) +public class MixinGlowingMushroomHighlighter { + @Inject(method = "canPlayerSee", at = @At("HEAD"), cancellable = true, remap = false) + public void onCanPlayerSee(double xCoord, double yCoord, double zCoord, CallbackInfoReturnable<Boolean> cir) { + if (((HaxConfigWorld) NotEnoughUpdates.INSTANCE.config.world).getNeuHaxMushroomWallhacks()) { + cir.setReturnValue(true); + } + } +} diff --git a/src/main/java/moe/nea/sky/mixin/MixinUltrasequencerItem.java b/src/main/java/moe/nea/sky/mixin/MixinUltrasequencerItem.java new file mode 100644 index 0000000..97cce00 --- /dev/null +++ b/src/main/java/moe/nea/sky/mixin/MixinUltrasequencerItem.java @@ -0,0 +1,27 @@ +package moe.nea.sky.mixin; + +import moe.nea.sky.features.gui.Enchanting; +import net.minecraft.item.ItemStack; +import org.jetbrains.annotations.NotNull; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.Shadow; + +@Mixin(targets = "io.github.moulberry.notenoughupdates.miscfeatures.EnchantingSolvers$UltrasequencerItem") +public class MixinUltrasequencerItem implements Enchanting.AccessibleUltrasequencerItem { + @Shadow + private ItemStack stack; + + @Shadow + private int containerIndex; + + @NotNull + @Override + public ItemStack getStack() { + return stack; + } + + @Override + public int getContainerIndex() { + return containerIndex; + } +} diff --git a/src/main/java/moe/nea/sky/mixin/config/MixinHaxConfigEnchanting.java b/src/main/java/moe/nea/sky/mixin/config/MixinHaxConfigEnchanting.java new file mode 100644 index 0000000..0ad861f --- /dev/null +++ b/src/main/java/moe/nea/sky/mixin/config/MixinHaxConfigEnchanting.java @@ -0,0 +1,36 @@ +package moe.nea.sky.mixin.config; + +import com.google.gson.annotations.Expose; +import io.github.moulberry.notenoughupdates.core.config.annotations.*; +import io.github.moulberry.notenoughupdates.options.seperateSections.Enchanting; +import moe.nea.sky.config.HaxConfigEnchanting; +import org.lwjgl.input.Keyboard; +import org.spongepowered.asm.mixin.Mixin; + +@Mixin(Enchanting.class) +public class MixinHaxConfigEnchanting implements HaxConfigEnchanting { + @ConfigOption(name = "NEU Hax", desc = "NEU Hax enhancements to enchanting") + @ConfigEditorAccordion(id = 10000) + public boolean neuHaxAccordion = false; + + @Expose + @ConfigOption(name = "Auto solve Keybinding", desc = "Press this button to click on the next correct item") + @ConfigAccordionId(id = 10000) + @ConfigEditorKeybind(defaultKey = Keyboard.KEY_SPACE) + public int neuHaxSolveKeybinding = Keyboard.KEY_SPACE; + + @Expose + @ConfigOption(name = "Auto solve speed", desc = "How fast you can press the button to solve, in milliseconds") + @ConfigEditorSlider(minValue = 10, maxValue = 500, minStep = 10) + public int neuHaxTimeout = 100; + + @Override + public int getNeuHaxSolveKeybinding() { + return neuHaxSolveKeybinding; + } + + @Override + public int getNeuHaxTimeout() { + return neuHaxTimeout; + } +} diff --git a/src/main/java/moe/nea/sky/mixin/config/MixinHaxConfigWorld.java b/src/main/java/moe/nea/sky/mixin/config/MixinHaxConfigWorld.java new file mode 100644 index 0000000..971d0cd --- /dev/null +++ b/src/main/java/moe/nea/sky/mixin/config/MixinHaxConfigWorld.java @@ -0,0 +1,33 @@ +package moe.nea.sky.mixin.config; + +import com.google.gson.annotations.Expose; +import io.github.moulberry.notenoughupdates.core.config.annotations.ConfigAccordionId; +import io.github.moulberry.notenoughupdates.core.config.annotations.ConfigEditorAccordion; +import io.github.moulberry.notenoughupdates.core.config.annotations.ConfigEditorBoolean; +import io.github.moulberry.notenoughupdates.core.config.annotations.ConfigOption; +import io.github.moulberry.notenoughupdates.options.seperateSections.WorldConfig; +import moe.nea.sky.config.HaxConfigWorld; +import org.spongepowered.asm.mixin.Mixin; + +@Mixin(WorldConfig.class) +public class MixinHaxConfigWorld implements HaxConfigWorld { + @ConfigOption(name = "NEU Hax", desc = "NEU Hax enhancements to the world") + @ConfigEditorAccordion(id = 10000) + public boolean neuHaxAccordion = false; + + @Expose + @ConfigOption(name = "Mushroom Wallhacks", desc = "See glowing mushrooms through walls") + @ConfigAccordionId(id = 10000) + @ConfigEditorBoolean + public boolean neuHaxMushroomWallhacks = true; + + @Override + public boolean getNeuHaxMushroomWallhacks() { + return this.neuHaxMushroomWallhacks; + } + + @Override + public void setNeuHaxMushroomWallhacks(boolean b) { + this.neuHaxMushroomWallhacks = b; + } +} 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 + ) +} diff --git a/src/main/resources/mcmod.info b/src/main/resources/mcmod.info new file mode 100644 index 0000000..79e597f --- /dev/null +++ b/src/main/resources/mcmod.info @@ -0,0 +1,18 @@ +[ + { + "modid": "neuhax", + "name": "NEUHAX", + "description": "Improvements to NotEnoughUpdates", + "version": "1.1.0", + "mcversion": "1.8.9", + "url": "https://git.nea.moe/nea/neuhax", + "updateUrl": "", + "authorList": [ + "Linnea Gräf" + ], + "credits": "", + "logoFile": "", + "screenshots": [], + "dependencies": [] + } +] diff --git a/src/main/resources/mixins.neuhax.json b/src/main/resources/mixins.neuhax.json new file mode 100644 index 0000000..8d80776 --- /dev/null +++ b/src/main/resources/mixins.neuhax.json @@ -0,0 +1,16 @@ +{ + "package": "moe.nea.sky.mixin", + "refmap": "mixins.neuhax.refmap.json", + "minVersion": "0.7", + "compatibilityLevel": "JAVA_8", + "mixins": [ + "MixinEnchantingSolvers", + "MixinFMLHandshakeMessageModList", + "MixinGlowingMushroomHighlighter", + "MixinUltrasequencerItem", + "config.MixinHaxConfigEnchanting", + "config.MixinHaxConfigWorld" + ], + "client": [ + ] +} |