├── .gitignore ├── LICENSE ├── README.md ├── build.gradle ├── gradle.properties ├── gradle └── wrapper │ ├── gradle-wrapper.jar │ └── gradle-wrapper.properties ├── gradlew ├── gradlew.bat └── src └── main ├── java └── cn │ └── origin │ └── cube │ ├── Cube.java │ ├── command │ ├── Command.java │ ├── CommandInfo.java │ ├── CommandManager.kt │ └── commands │ │ ├── HelpCommand.java │ │ ├── ModuleBindCommand.kt │ │ ├── PreFixCommand.kt │ │ └── ReloadCommand.java │ ├── event │ ├── EventManager.kt │ └── events │ │ ├── EventStage.java │ │ ├── client │ │ ├── DisplayGuiScreenEvent.java │ │ ├── PacketEvent.java │ │ └── SettingChangeEvent.java │ │ ├── player │ │ └── UpdateWalkingPlayerEvent.java │ │ └── world │ │ └── Render3DEvent.java │ ├── font │ ├── AWTFontRenderer.kt │ ├── CachedFont.kt │ ├── FontManager.java │ ├── MinecraftFontRenderer.kt │ └── texture │ │ ├── AbstractTexture.kt │ │ ├── MipmapTexture.kt │ │ └── TextureUtils.kt │ ├── guis │ ├── CategoryPanel.kt │ ├── ClickGuiScreen.kt │ ├── HudEditorScreen.kt │ └── buttons │ │ ├── Button.kt │ │ ├── ModuleButton.kt │ │ ├── SettingButton.kt │ │ └── setting │ │ ├── BindSettingButton.kt │ │ ├── BooleanSettingButton.kt │ │ ├── ModeSettingButton.kt │ │ ├── NumberSliderButton.kt │ │ └── StringSettingButton.kt │ ├── inject │ ├── ForgeCoreModsLoader.kt │ └── client │ │ ├── MixinEntityPlayerSP.java │ │ ├── MixinMinecraft.java │ │ └── MixinNetworkManager.java │ ├── managers │ ├── ConfigManager.kt │ └── FriendManager.kt │ ├── module │ ├── AbstractModule.java │ ├── Category.java │ ├── HudModule.java │ ├── HudModuleInfo.java │ ├── Module.java │ ├── ModuleInfo.java │ ├── ModuleManager.kt │ ├── huds │ │ ├── ModuleArrayList.java │ │ └── WaterMark.java │ └── modules │ │ ├── client │ │ ├── ChatSuffix.java │ │ ├── ClickGui.java │ │ └── HudEditor.java │ │ ├── combat │ │ ├── KillAura.java │ │ └── Surround.java │ │ ├── function │ │ ├── FakeKick.java │ │ ├── MiddleClick.kt │ │ └── NoRotate.java │ │ ├── movement │ │ ├── AutoWalk.java │ │ └── Sprint.java │ │ ├── visual │ │ ├── BlockHighlight.java │ │ └── FullBright.java │ │ └── world │ │ ├── AutoRespawn.java │ │ └── FakePlayer.java │ ├── settings │ ├── BindSetting.java │ ├── BooleanSetting.java │ ├── DoubleSetting.java │ ├── FloatSetting.java │ ├── IntegerSetting.java │ ├── LongSetting.java │ ├── ModeSetting.java │ ├── NumberSetting.java │ ├── Setting.java │ └── StringSetting.java │ └── utils │ ├── IconFont.kt │ ├── Timer.java │ ├── Utils.java │ ├── client │ └── ChatUtil.java │ ├── gl │ ├── GlStateUtils.kt │ └── Quad.kt │ ├── player │ ├── BlockUtil.java │ ├── InventoryUtil.java │ └── RotationUtil.java │ └── render │ ├── ColorUtils.kt │ ├── Render2DUtil.java │ └── Render3DUtil.java └── resources ├── assets └── fonts │ ├── CubeBaseIcon.ttf │ └── CustomFont.ttf ├── cube_at.cfg ├── mcmod.info └── mixins.cube.json /.gitignore: -------------------------------------------------------------------------------- 1 | # Project exclude paths 2 | /.gradle/ 3 | /build/ 4 | /build/classes/java/main/ -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2022 jiyun233 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # CubeBase 2 | ## A Minecraft 1.12.2 Hack mod base for 2b2t skidder 3 | 4 | # Usage 5 | * Hold shift anywhere and right-click to open git Bash 6 | * Clone this repo 7 | * Open your intellij new project form Existing Sources 8 | * Wating gradle Sync 9 | -------------------------------------------------------------------------------- /build.gradle: -------------------------------------------------------------------------------- 1 | buildscript { 2 | repositories { 3 | mavenCentral() 4 | maven { 5 | url = "https://files.minecraftforge.net/maven" 6 | } 7 | maven { 8 | url = 'https://repo.spongepowered.org/repository/maven-public/' 9 | } 10 | } 11 | dependencies { 12 | classpath 'net.minecraftforge.gradle:ForgeGradle:4.+' 13 | classpath 'org.spongepowered:mixingradle:0.7-SNAPSHOT' 14 | classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version" 15 | } 16 | } 17 | 18 | apply plugin: 'java' 19 | apply plugin: 'kotlin' 20 | 21 | apply plugin: 'net.minecraftforge.gradle' 22 | apply plugin: 'org.spongepowered.mixin' 23 | 24 | version project.modVersion 25 | group project.modGroup 26 | 27 | compileJava { 28 | sourceCompatibility = targetCompatibility = '1.8' 29 | options.encoding = 'UTF-8' 30 | } 31 | 32 | compileKotlin { 33 | kotlinOptions.jvmTarget = '1.8' 34 | } 35 | 36 | repositories { 37 | maven { 38 | url = 'https://repo.spongepowered.org/repository/maven-public/' 39 | } 40 | maven { 41 | url = "https://jitpack.io" 42 | } 43 | mavenCentral() 44 | } 45 | 46 | minecraft { 47 | mappings channel: 'stable', version: '39-1.12' 48 | 49 | accessTransformer = file('src/main/resources/cube_at.cfg') 50 | 51 | runs { 52 | client { 53 | workingDirectory project.file('run') 54 | 55 | property 'fml.coreMods.load', 'cn.origin.cube.inject.ForgeCoreModsLoader' 56 | property 'mixin.env.disableRefMap', 'true' 57 | 58 | property 'forge.logging.markers', 'SCAN,REGISTRIES,REGISTRYDUMP' 59 | property 'forge.logging.console.level', 'debug' 60 | } 61 | } 62 | } 63 | 64 | configurations { 65 | jarDepend 66 | } 67 | 68 | dependencies { 69 | minecraft "net.minecraftforge:forge:$mcVersion" 70 | 71 | jarDepend("org.spongepowered:mixin:0.7.11-SNAPSHOT") { 72 | exclude module: 'launchwrapper' 73 | exclude module: 'log4j-core' 74 | exclude module: 'guava' 75 | exclude module: 'gson' 76 | exclude module: 'commons-io' 77 | } 78 | 79 | annotationProcessor('org.spongepowered:mixin:0.8.2:processor') { 80 | exclude module: 'gson' 81 | } 82 | jarDepend("org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version") { 83 | exclude module: 'kotlin-stdlib-common' 84 | exclude module: 'annotations' 85 | } 86 | 87 | jarDepend("org.jetbrains.kotlin:kotlin-stdlib-jdk8:$kotlin_version") { 88 | exclude module: 'kotlin-stdlib-common' 89 | exclude module: 'annotations' 90 | } 91 | 92 | compileOnly "org.jetbrains.kotlin:kotlin-stdlib-common:$kotlin_version" 93 | 94 | compileOnly 'org.jetbrains.kotlinx:kotlinx-coroutines-core:1.6.4' 95 | 96 | implementation configurations.jarDepend 97 | } 98 | 99 | 100 | mixin { 101 | defaultObfuscationEnv 'searge' 102 | add sourceSets.main, 'mixins.cube.refmap.json' 103 | } 104 | 105 | 106 | processResources { 107 | inputs.property 'version', project.version 108 | inputs.property 'mcversion', project.mcVersion 109 | 110 | filteringCharset 'UTF-8' 111 | 112 | from(sourceSets.main.resources.srcDirs) { 113 | include 'mcmod.info' 114 | expand 'version': project.version, 115 | 'mcversion': project.mcVersion, 116 | 'modVersion': project.modVersion 117 | } 118 | 119 | from(sourceSets.main.resources.srcDirs) { 120 | exclude 'mcmod.info' 121 | } 122 | 123 | rename '(.+_at.cfg)', 'META-INF/$1' 124 | } 125 | 126 | 127 | jar { 128 | manifest { 129 | attributes( 130 | "FMLCorePluginContainsFMLMod": "true", 131 | "FMLCorePlugin": "cn.origin.cube.inject.ForgeCoreModsLoader", 132 | 'MixinConfigs': 'mixins.cube.json', 133 | 'tweakClass': 'org.spongepowered.asm.launch.MixinTweaker', 134 | 'TweakOrder': 0, 135 | 'ForceLoadAsMod': 'true', 136 | 'FMLAT': 'cube_at.cfg' 137 | ) 138 | } 139 | from { configurations.jarDepend.collect { it.isDirectory() ? it : zipTree(it) } } 140 | } -------------------------------------------------------------------------------- /gradle.properties: -------------------------------------------------------------------------------- 1 | # Sets default memory used for gradle commands. Can be overridden by user or command line properties. 2 | # This is required to provide enough memory for the Minecraft decompilation process. 3 | org.gradle.jvmargs=-Xmx3G 4 | org.gradle.daemon=false 5 | modGroup=dev.jiyun233.cube 6 | modVersion=0.1 7 | mcVersion=1.12.2-14.23.5.2860 8 | kotlin_version=1.7.10 -------------------------------------------------------------------------------- /gradle/wrapper/gradle-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jiyun233/CubeBase/d0ba15713b92f517a4c9894c08d31cca6f71db5b/gradle/wrapper/gradle-wrapper.jar -------------------------------------------------------------------------------- /gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | distributionBase=GRADLE_USER_HOME 2 | distributionPath=wrapper/dists 3 | zipStoreBase=GRADLE_USER_HOME 4 | zipStorePath=wrapper/dists 5 | distributionUrl=https\://services.gradle.org/distributions/gradle-6.8.3-bin.zip 6 | -------------------------------------------------------------------------------- /gradlew: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env sh 2 | 3 | ############################################################################## 4 | ## 5 | ## Gradle start up script for UN*X 6 | ## 7 | ############################################################################## 8 | 9 | # Attempt to set APP_HOME 10 | # Resolve links: $0 may be a link 11 | PRG="$0" 12 | # Need this for relative symlinks. 13 | while [ -h "$PRG" ] ; do 14 | ls=`ls -ld "$PRG"` 15 | link=`expr "$ls" : '.*-> \(.*\)$'` 16 | if expr "$link" : '/.*' > /dev/null; then 17 | PRG="$link" 18 | else 19 | PRG=`dirname "$PRG"`"/$link" 20 | fi 21 | done 22 | SAVED="`pwd`" 23 | cd "`dirname \"$PRG\"`/" >/dev/null 24 | APP_HOME="`pwd -P`" 25 | cd "$SAVED" >/dev/null 26 | 27 | APP_NAME="Gradle" 28 | APP_BASE_NAME=`basename "$0"` 29 | 30 | # Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. 31 | DEFAULT_JVM_OPTS="" 32 | 33 | # Use the maximum available, or set MAX_FD != -1 to use that value. 34 | MAX_FD="maximum" 35 | 36 | warn () { 37 | echo "$*" 38 | } 39 | 40 | die () { 41 | echo 42 | echo "$*" 43 | echo 44 | exit 1 45 | } 46 | 47 | # OS specific support (must be 'true' or 'false'). 48 | cygwin=false 49 | msys=false 50 | darwin=false 51 | nonstop=false 52 | case "`uname`" in 53 | CYGWIN* ) 54 | cygwin=true 55 | ;; 56 | Darwin* ) 57 | darwin=true 58 | ;; 59 | MINGW* ) 60 | msys=true 61 | ;; 62 | NONSTOP* ) 63 | nonstop=true 64 | ;; 65 | esac 66 | 67 | CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar 68 | 69 | # Determine the Java command to use to start the JVM. 70 | if [ -n "$JAVA_HOME" ] ; then 71 | if [ -x "$JAVA_HOME/jre/sh/java" ] ; then 72 | # IBM's JDK on AIX uses strange locations for the executables 73 | JAVACMD="$JAVA_HOME/jre/sh/java" 74 | else 75 | JAVACMD="$JAVA_HOME/bin/java" 76 | fi 77 | if [ ! -x "$JAVACMD" ] ; then 78 | die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME 79 | 80 | Please set the JAVA_HOME variable in your environment to match the 81 | location of your Java installation." 82 | fi 83 | else 84 | JAVACMD="java" 85 | which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 86 | 87 | Please set the JAVA_HOME variable in your environment to match the 88 | location of your Java installation." 89 | fi 90 | 91 | # Increase the maximum file descriptors if we can. 92 | if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then 93 | MAX_FD_LIMIT=`ulimit -H -n` 94 | if [ $? -eq 0 ] ; then 95 | if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then 96 | MAX_FD="$MAX_FD_LIMIT" 97 | fi 98 | ulimit -n $MAX_FD 99 | if [ $? -ne 0 ] ; then 100 | warn "Could not set maximum file descriptor limit: $MAX_FD" 101 | fi 102 | else 103 | warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT" 104 | fi 105 | fi 106 | 107 | # For Darwin, add options to specify how the application appears in the dock 108 | if $darwin; then 109 | GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\"" 110 | fi 111 | 112 | # For Cygwin, switch paths to Windows format before running java 113 | if $cygwin ; then 114 | APP_HOME=`cygpath --path --mixed "$APP_HOME"` 115 | CLASSPATH=`cygpath --path --mixed "$CLASSPATH"` 116 | JAVACMD=`cygpath --unix "$JAVACMD"` 117 | 118 | # We build the pattern for arguments to be converted via cygpath 119 | ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null` 120 | SEP="" 121 | for dir in $ROOTDIRSRAW ; do 122 | ROOTDIRS="$ROOTDIRS$SEP$dir" 123 | SEP="|" 124 | done 125 | OURCYGPATTERN="(^($ROOTDIRS))" 126 | # Add a user-defined pattern to the cygpath arguments 127 | if [ "$GRADLE_CYGPATTERN" != "" ] ; then 128 | OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)" 129 | fi 130 | # Now convert the arguments - kludge to limit ourselves to /bin/sh 131 | i=0 132 | for arg in "$@" ; do 133 | CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -` 134 | CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option 135 | 136 | if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition 137 | eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"` 138 | else 139 | eval `echo args$i`="\"$arg\"" 140 | fi 141 | i=$((i+1)) 142 | done 143 | case $i in 144 | (0) set -- ;; 145 | (1) set -- "$args0" ;; 146 | (2) set -- "$args0" "$args1" ;; 147 | (3) set -- "$args0" "$args1" "$args2" ;; 148 | (4) set -- "$args0" "$args1" "$args2" "$args3" ;; 149 | (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;; 150 | (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;; 151 | (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;; 152 | (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;; 153 | (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;; 154 | esac 155 | fi 156 | 157 | # Escape application args 158 | save () { 159 | for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done 160 | echo " " 161 | } 162 | APP_ARGS=$(save "$@") 163 | 164 | # Collect all arguments for the java command, following the shell quoting and substitution rules 165 | eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS" 166 | 167 | # by default we should be in the correct project dir, but when run from Finder on Mac, the cwd is wrong 168 | if [ "$(uname)" = "Darwin" ] && [ "$HOME" = "$PWD" ]; then 169 | cd "$(dirname "$0")" 170 | fi 171 | 172 | exec "$JAVACMD" "$@" 173 | -------------------------------------------------------------------------------- /gradlew.bat: -------------------------------------------------------------------------------- 1 | @if "%DEBUG%" == "" @echo off 2 | @rem ########################################################################## 3 | @rem 4 | @rem Gradle startup script for Windows 5 | @rem 6 | @rem ########################################################################## 7 | 8 | @rem Set local scope for the variables with windows NT shell 9 | if "%OS%"=="Windows_NT" setlocal 10 | 11 | set DIRNAME=%~dp0 12 | if "%DIRNAME%" == "" set DIRNAME=. 13 | set APP_BASE_NAME=%~n0 14 | set APP_HOME=%DIRNAME% 15 | 16 | @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. 17 | set DEFAULT_JVM_OPTS= 18 | 19 | @rem Find java.exe 20 | if defined JAVA_HOME goto findJavaFromJavaHome 21 | 22 | set JAVA_EXE=java.exe 23 | %JAVA_EXE% -version >NUL 2>&1 24 | if "%ERRORLEVEL%" == "0" goto init 25 | 26 | echo. 27 | echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 28 | echo. 29 | echo Please set the JAVA_HOME variable in your environment to match the 30 | echo location of your Java installation. 31 | 32 | goto fail 33 | 34 | :findJavaFromJavaHome 35 | set JAVA_HOME=%JAVA_HOME:"=% 36 | set JAVA_EXE=%JAVA_HOME%/bin/java.exe 37 | 38 | if exist "%JAVA_EXE%" goto init 39 | 40 | echo. 41 | echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% 42 | echo. 43 | echo Please set the JAVA_HOME variable in your environment to match the 44 | echo location of your Java installation. 45 | 46 | goto fail 47 | 48 | :init 49 | @rem Get command-line arguments, handling Windows variants 50 | 51 | if not "%OS%" == "Windows_NT" goto win9xME_args 52 | 53 | :win9xME_args 54 | @rem Slurp the command line arguments. 55 | set CMD_LINE_ARGS= 56 | set _SKIP=2 57 | 58 | :win9xME_args_slurp 59 | if "x%~1" == "x" goto execute 60 | 61 | set CMD_LINE_ARGS=%* 62 | 63 | :execute 64 | @rem Setup the command line 65 | 66 | set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar 67 | 68 | @rem Execute Gradle 69 | "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS% 70 | 71 | :end 72 | @rem End local scope for the variables with windows NT shell 73 | if "%ERRORLEVEL%"=="0" goto mainEnd 74 | 75 | :fail 76 | rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of 77 | rem the _cmd.exe /c_ return code! 78 | if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 79 | exit /b 1 80 | 81 | :mainEnd 82 | if "%OS%"=="Windows_NT" endlocal 83 | 84 | :omega 85 | -------------------------------------------------------------------------------- /src/main/java/cn/origin/cube/Cube.java: -------------------------------------------------------------------------------- 1 | package cn.origin.cube; 2 | 3 | import cn.origin.cube.command.CommandManager; 4 | import cn.origin.cube.event.EventManager; 5 | import cn.origin.cube.font.FontManager; 6 | import cn.origin.cube.guis.ClickGuiScreen; 7 | import cn.origin.cube.guis.HudEditorScreen; 8 | import cn.origin.cube.managers.ConfigManager; 9 | import cn.origin.cube.managers.FriendManager; 10 | import cn.origin.cube.module.ModuleManager; 11 | import net.minecraftforge.fml.common.Mod; 12 | import net.minecraftforge.fml.common.event.FMLInitializationEvent; 13 | import net.minecraftforge.fml.common.event.FMLPreInitializationEvent; 14 | import org.apache.logging.log4j.LogManager; 15 | import org.apache.logging.log4j.Logger; 16 | import org.lwjgl.opengl.Display; 17 | 18 | import java.awt.*; 19 | import java.io.IOException; 20 | 21 | @Mod(modid = Cube.MOD_ID, name = Cube.MOD_NAME, version = Cube.MOD_VERSION) 22 | public class Cube { 23 | public static final String MOD_ID = "cube"; 24 | 25 | public static final String MOD_NAME = "Cube Base"; 26 | 27 | public static final String MOD_VERSION = "0.1"; 28 | public static final Logger logger = LogManager.getLogger("Cube"); 29 | public static EventManager eventManager = null; 30 | public static FontManager fontManager = null; 31 | public static ClickGuiScreen clickGui = null; 32 | public static HudEditorScreen hudEditor = null; 33 | public static FriendManager friendManager = null; 34 | public static ModuleManager moduleManager = null; 35 | public static ConfigManager configManager = null; 36 | public static CommandManager commandManager = null; 37 | 38 | public static String commandPrefix = "."; 39 | 40 | @Mod.EventHandler 41 | public void preInit(FMLPreInitializationEvent event) { 42 | logger.info("Begin loading Cube Base"); 43 | Display.setTitle(MOD_NAME + " | " + MOD_VERSION); 44 | } 45 | 46 | @Mod.EventHandler 47 | public void init(FMLInitializationEvent event) { 48 | try { 49 | logger.info("Loading Cube Base..."); 50 | loadManagers(); 51 | } catch (IOException | FontFormatException e) { 52 | throw new RuntimeException(e); 53 | } 54 | } 55 | 56 | private void loadManagers() throws IOException, FontFormatException { 57 | fontManager = new FontManager(); 58 | friendManager = new FriendManager(); 59 | moduleManager = new ModuleManager(); 60 | eventManager = new EventManager(); 61 | clickGui = new ClickGuiScreen(); 62 | hudEditor = new HudEditorScreen(); 63 | configManager = new ConfigManager(); 64 | commandManager = new CommandManager(); 65 | } 66 | } 67 | -------------------------------------------------------------------------------- /src/main/java/cn/origin/cube/command/Command.java: -------------------------------------------------------------------------------- 1 | package cn.origin.cube.command; 2 | 3 | import cn.origin.cube.module.ModuleInfo; 4 | import org.jetbrains.annotations.NotNull; 5 | 6 | import java.util.List; 7 | 8 | public abstract class Command { 9 | public final String name; 10 | public final String[] aliases; 11 | 12 | public final String descriptions; 13 | 14 | public final String usage; 15 | 16 | public Command() { 17 | this.name = getAnnotation().name(); 18 | this.aliases = getAnnotation().aliases(); 19 | this.descriptions = getAnnotation().descriptions(); 20 | this.usage = getAnnotation().usage(); 21 | } 22 | 23 | public abstract void execute(String[] args); 24 | 25 | private CommandInfo getAnnotation() { 26 | if (getClass().isAnnotationPresent(CommandInfo.class)) { 27 | return getClass().getAnnotation(CommandInfo.class); 28 | } 29 | throw new IllegalStateException("No Annotation on class " + this.getClass().getCanonicalName() + "!"); 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /src/main/java/cn/origin/cube/command/CommandInfo.java: -------------------------------------------------------------------------------- 1 | package cn.origin.cube.command; 2 | 3 | import java.lang.annotation.Retention; 4 | import java.lang.annotation.RetentionPolicy; 5 | 6 | @Retention(RetentionPolicy.RUNTIME) 7 | public @interface CommandInfo { 8 | String name(); 9 | String[] aliases() default {}; 10 | 11 | String descriptions(); 12 | 13 | String usage(); 14 | 15 | } 16 | -------------------------------------------------------------------------------- /src/main/java/cn/origin/cube/command/CommandManager.kt: -------------------------------------------------------------------------------- 1 | package cn.origin.cube.command 2 | 3 | import cn.origin.cube.Cube 4 | import cn.origin.cube.command.commands.HelpCommand 5 | import cn.origin.cube.command.commands.ModuleBindCommand 6 | import cn.origin.cube.command.commands.PreFixCommand 7 | import cn.origin.cube.command.commands.ReloadCommand 8 | import cn.origin.cube.module.modules.client.ClickGui 9 | import cn.origin.cube.utils.client.ChatUtil 10 | import java.util.* 11 | 12 | 13 | class CommandManager { 14 | val commands = arrayListOf() 15 | 16 | init { 17 | register(ModuleBindCommand()) 18 | register(PreFixCommand()) 19 | register(HelpCommand()) 20 | register(ReloadCommand()) 21 | } 22 | 23 | private fun register(command: Command) { 24 | if (!commands.contains(command)) commands.add(command) 25 | } 26 | 27 | fun run(run: String) { 28 | val readString: String = run.trim().substring(Cube.commandPrefix.length).trim() 29 | var commandResolved = false 30 | val hasArgs = readString.trim { it <= ' ' }.contains(" ") 31 | val commandName = if (hasArgs) readString.split(" ".toRegex()).dropLastWhile { it.isEmpty() } 32 | .toTypedArray()[0] else readString.trim { it <= ' ' } 33 | val args: Array = 34 | if (hasArgs) readString.substring(commandName.length).trim { it <= ' ' }.split(" ".toRegex()) 35 | .dropLastWhile { it.isEmpty() } 36 | .toTypedArray() else arrayOfNulls(0) 37 | 38 | for (command in commands) { 39 | if (command.name.trim().lowercase() 40 | == (commandName.trim { it <= ' ' }.lowercase(Locale.getDefault())).lowercase() 41 | || command.aliases.ignoreCaseContains(commandName.trim { it <= ' ' }.lowercase(Locale.getDefault())) 42 | ) { 43 | command.execute(args) 44 | commandResolved = true 45 | break 46 | } 47 | } 48 | if (!commandResolved) { 49 | ChatUtil.sendMessage("&c&lUnknown command.") 50 | } 51 | } 52 | 53 | 54 | private fun Array.ignoreCaseContains(string: String): Boolean { 55 | for (s in this) { 56 | if (s.trim().lowercase() == string.lowercase()) return true 57 | } 58 | return false 59 | } 60 | } -------------------------------------------------------------------------------- /src/main/java/cn/origin/cube/command/commands/HelpCommand.java: -------------------------------------------------------------------------------- 1 | package cn.origin.cube.command.commands; 2 | 3 | import cn.origin.cube.Cube; 4 | import cn.origin.cube.command.Command; 5 | import cn.origin.cube.command.CommandInfo; 6 | import cn.origin.cube.utils.client.ChatUtil; 7 | 8 | import java.util.Arrays; 9 | 10 | @CommandInfo(name = "help", aliases = {"?", "h"}, descriptions = "Show command list", usage = "Help") 11 | public class HelpCommand extends Command { 12 | @Override 13 | public void execute(String[] args) { 14 | ChatUtil.sendMessage("Commands list:"); 15 | for (Command command : Cube.commandManager.getCommands()) { 16 | ChatUtil.sendColoredMessage("&bCommand: &6" + command.name + "&b " + command.descriptions + " &bUsage: " + command.usage + " &bAliases: " + Arrays.toString(command.aliases)); 17 | } 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /src/main/java/cn/origin/cube/command/commands/ModuleBindCommand.kt: -------------------------------------------------------------------------------- 1 | package cn.origin.cube.command.commands 2 | 3 | import cn.origin.cube.Cube 4 | import cn.origin.cube.command.Command 5 | import cn.origin.cube.command.CommandInfo 6 | import cn.origin.cube.module.AbstractModule 7 | import cn.origin.cube.module.ModuleManager 8 | import cn.origin.cube.settings.BindSetting 9 | import cn.origin.cube.utils.client.ChatUtil 10 | import org.lwjgl.input.Keyboard 11 | import java.util.* 12 | 13 | 14 | @CommandInfo(name = "bind", aliases = ["KeyBind"],descriptions = "Bind module to key",usage = "bind ") 15 | class ModuleBindCommand : Command() { 16 | override fun execute(args: Array) { 17 | if (args.size == 1) { 18 | ChatUtil.sendNoSpamMessage("&cPlease specify a module.") 19 | return 20 | } 21 | try { 22 | val module = args[0] 23 | val rKey = args[1] 24 | val m: AbstractModule? = Cube.moduleManager.getModuleByName(module) 25 | if (m == null) { 26 | ChatUtil.sendNoSpamMessage("Unknown module '$module'!") 27 | return 28 | } 29 | val key = Keyboard.getKeyIndex(rKey.uppercase()) 30 | if (Keyboard.KEY_NONE == key) { 31 | ChatUtil.sendMessage("&cUnknown Key $rKey") 32 | return 33 | } 34 | m.keyBind.value = BindSetting.KeyBind(key) 35 | ChatUtil.sendMessage("&aSuccess bind ${m.name} to key: ${args[1]}") 36 | } catch (e: Exception) { 37 | ChatUtil.sendMessage("&c&lUsage: bind ") 38 | } 39 | } 40 | } -------------------------------------------------------------------------------- /src/main/java/cn/origin/cube/command/commands/PreFixCommand.kt: -------------------------------------------------------------------------------- 1 | package cn.origin.cube.command.commands 2 | 3 | import cn.origin.cube.Cube 4 | import cn.origin.cube.command.Command 5 | import cn.origin.cube.command.CommandInfo 6 | import cn.origin.cube.utils.client.ChatUtil 7 | 8 | @CommandInfo(name = "prefix", descriptions = "Change command prefix", usage = "prefix ") 9 | class PreFixCommand : Command() { 10 | override fun execute(args: Array) { 11 | if (args.isEmpty()) { 12 | ChatUtil.sendMessage("&c&lUsage: prefix ") 13 | return 14 | } 15 | Cube.commandPrefix = args[0] 16 | Cube.configManager.saveCommand() 17 | ChatUtil.sendNoSpamMessage("&aPrefix set to ${args[0]}") 18 | } 19 | } -------------------------------------------------------------------------------- /src/main/java/cn/origin/cube/command/commands/ReloadCommand.java: -------------------------------------------------------------------------------- 1 | package cn.origin.cube.command.commands; 2 | 3 | import cn.origin.cube.Cube; 4 | import cn.origin.cube.command.Command; 5 | import cn.origin.cube.command.CommandInfo; 6 | import cn.origin.cube.utils.client.ChatUtil; 7 | 8 | @CommandInfo(name = "reload", aliases = {"reloadConfig"}, descriptions = "reload configuration file", usage = "reload") 9 | public class ReloadCommand extends Command { 10 | 11 | @Override 12 | public void execute(String[] args) { 13 | Cube.configManager.loadAll(); 14 | ChatUtil.sendMessage("&aSuccess reload all configurations"); 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /src/main/java/cn/origin/cube/event/EventManager.kt: -------------------------------------------------------------------------------- 1 | package cn.origin.cube.event 2 | 3 | import cn.origin.cube.Cube 4 | import cn.origin.cube.event.events.world.Render3DEvent 5 | import cn.origin.cube.utils.Utils 6 | import net.minecraft.client.Minecraft 7 | import net.minecraft.client.renderer.GlStateManager 8 | import net.minecraftforge.client.event.ClientChatEvent 9 | import net.minecraftforge.client.event.RenderGameOverlayEvent 10 | import net.minecraftforge.client.event.RenderWorldLastEvent 11 | import net.minecraftforge.common.MinecraftForge 12 | import net.minecraftforge.fml.common.eventhandler.SubscribeEvent 13 | import net.minecraftforge.fml.common.gameevent.InputEvent 14 | import net.minecraftforge.fml.common.gameevent.TickEvent.ClientTickEvent 15 | import net.minecraftforge.fml.common.network.FMLNetworkEvent.ClientConnectedToServerEvent 16 | import net.minecraftforge.fml.common.network.FMLNetworkEvent.ClientDisconnectionFromServerEvent 17 | import org.lwjgl.input.Keyboard 18 | 19 | 20 | class EventManager { 21 | val mc: Minecraft = Minecraft.getMinecraft() 22 | 23 | init { 24 | MinecraftForge.EVENT_BUS.register(this) 25 | } 26 | 27 | @SubscribeEvent 28 | fun onKeyInput(event: InputEvent.KeyInputEvent) { 29 | if (event.isCanceled || !Keyboard.getEventKeyState() || Keyboard.getEventKey() <= 0) return 30 | for (module in Cube.moduleManager!!.allModuleList) { 31 | if (module.keyBind.value.keyCode <= 0) continue 32 | if (Keyboard.isKeyDown(module.keyBind.value.keyCode)) module.toggle() 33 | } 34 | } 35 | 36 | @SubscribeEvent 37 | fun onTick(event: ClientTickEvent) { 38 | if (Utils.nullCheck()) return 39 | Cube.moduleManager!!.onUpdate() 40 | } 41 | 42 | @SubscribeEvent 43 | fun onLogin(event: ClientConnectedToServerEvent) { 44 | if (Utils.nullCheck()) return 45 | Cube.moduleManager!!.onLogin() 46 | } 47 | 48 | @SubscribeEvent 49 | fun onLogout(event: ClientDisconnectionFromServerEvent) { 50 | if (Utils.nullCheck()) return 51 | Cube.moduleManager!!.onLogout() 52 | } 53 | 54 | 55 | @SubscribeEvent 56 | fun onRender2D(e: RenderGameOverlayEvent.Text) { 57 | if (e.type == RenderGameOverlayEvent.ElementType.TEXT) { 58 | Cube.moduleManager!!.onRender2D() 59 | } 60 | } 61 | 62 | @SubscribeEvent 63 | fun onWorldRender(event: RenderWorldLastEvent) { 64 | if (event.isCanceled) return 65 | mc.profiler.startSection("CubeBase") 66 | GlStateManager.disableTexture2D() 67 | GlStateManager.enableBlend() 68 | GlStateManager.disableAlpha() 69 | GlStateManager.tryBlendFuncSeparate(770, 771, 1, 0) 70 | GlStateManager.shadeModel(7425) 71 | GlStateManager.disableDepth() 72 | GlStateManager.glLineWidth(1.0f) 73 | val render3dEvent = Render3DEvent(event.partialTicks) 74 | Cube.moduleManager!!.onRender3D(render3dEvent) 75 | GlStateManager.glLineWidth(1.0f) 76 | GlStateManager.shadeModel(7424) 77 | GlStateManager.disableBlend() 78 | GlStateManager.enableAlpha() 79 | GlStateManager.enableTexture2D() 80 | GlStateManager.enableDepth() 81 | GlStateManager.enableCull() 82 | GlStateManager.enableCull() 83 | GlStateManager.depthMask(true) 84 | GlStateManager.enableTexture2D() 85 | GlStateManager.enableBlend() 86 | GlStateManager.enableDepth() 87 | mc.profiler.endSection() 88 | } 89 | 90 | @SubscribeEvent 91 | fun onChat(event: ClientChatEvent) { 92 | if (event.message.startsWith(Cube.commandPrefix)) { 93 | Cube.commandManager.run(event.message) 94 | event.isCanceled = true; 95 | Minecraft.getMinecraft().ingameGUI.chatGUI.addToSentMessages(event.message); 96 | } 97 | } 98 | } -------------------------------------------------------------------------------- /src/main/java/cn/origin/cube/event/events/EventStage.java: -------------------------------------------------------------------------------- 1 | package cn.origin.cube.event.events; 2 | 3 | import net.minecraftforge.fml.common.eventhandler.Event; 4 | 5 | public class EventStage 6 | extends Event { 7 | private int stage; 8 | 9 | public EventStage() { 10 | } 11 | 12 | public EventStage(int stage) { 13 | this.stage = stage; 14 | } 15 | 16 | public int getStage() { 17 | return this.stage; 18 | } 19 | 20 | public void setStage(int stage) { 21 | this.stage = stage; 22 | } 23 | 24 | } 25 | 26 | -------------------------------------------------------------------------------- /src/main/java/cn/origin/cube/event/events/client/DisplayGuiScreenEvent.java: -------------------------------------------------------------------------------- 1 | package cn.origin.cube.event.events.client; 2 | 3 | import cn.origin.cube.event.events.EventStage; 4 | import net.minecraft.client.gui.GuiScreen; 5 | 6 | public class DisplayGuiScreenEvent 7 | extends EventStage { 8 | private GuiScreen screen; 9 | 10 | public DisplayGuiScreenEvent(GuiScreen screen) { 11 | this.screen = screen; 12 | } 13 | 14 | public GuiScreen getScreen() { 15 | return this.screen; 16 | } 17 | 18 | public void setScreen(GuiScreen screen) { 19 | this.screen = screen; 20 | } 21 | 22 | public static class Closed 23 | extends DisplayGuiScreenEvent { 24 | public Closed(GuiScreen screen) { 25 | super(screen); 26 | } 27 | } 28 | 29 | public static class Displayed 30 | extends DisplayGuiScreenEvent { 31 | public Displayed(GuiScreen screen) { 32 | super(screen); 33 | } 34 | } 35 | } 36 | 37 | -------------------------------------------------------------------------------- /src/main/java/cn/origin/cube/event/events/client/PacketEvent.java: -------------------------------------------------------------------------------- 1 | package cn.origin.cube.event.events.client; 2 | 3 | import cn.origin.cube.event.events.EventStage; 4 | import net.minecraft.network.Packet; 5 | import net.minecraftforge.fml.common.eventhandler.Cancelable; 6 | 7 | public class PacketEvent 8 | extends EventStage { 9 | public final Packet packet; 10 | 11 | public PacketEvent(int stage, Packet packet) { 12 | super(stage); 13 | this.packet = packet; 14 | } 15 | 16 | public > T getPacket() { 17 | return (T) this.packet; 18 | } 19 | 20 | @Cancelable 21 | public static class Send 22 | extends PacketEvent { 23 | public Send(int stage, Packet packet) { 24 | super(stage, packet); 25 | } 26 | } 27 | 28 | @Cancelable 29 | public static class Receive 30 | extends PacketEvent { 31 | public Receive(int stage, Packet packet) { 32 | super(stage, packet); 33 | } 34 | } 35 | } 36 | 37 | -------------------------------------------------------------------------------- /src/main/java/cn/origin/cube/event/events/client/SettingChangeEvent.java: -------------------------------------------------------------------------------- 1 | package cn.origin.cube.event.events.client; 2 | 3 | import cn.origin.cube.event.events.EventStage; 4 | import cn.origin.cube.settings.Setting; 5 | 6 | public class SettingChangeEvent extends EventStage { 7 | public final Setting setting; 8 | 9 | public final T oldValue; 10 | 11 | public final T newValue; 12 | 13 | public SettingChangeEvent(Setting setting, T oldValue, T newValue) { 14 | this.setting = setting; 15 | this.oldValue = oldValue; 16 | this.newValue = newValue; 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /src/main/java/cn/origin/cube/event/events/player/UpdateWalkingPlayerEvent.java: -------------------------------------------------------------------------------- 1 | package cn.origin.cube.event.events.player; 2 | 3 | import cn.origin.cube.event.events.EventStage; 4 | 5 | public class UpdateWalkingPlayerEvent extends EventStage { 6 | public UpdateWalkingPlayerEvent() { 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /src/main/java/cn/origin/cube/event/events/world/Render3DEvent.java: -------------------------------------------------------------------------------- 1 | package cn.origin.cube.event.events.world; 2 | 3 | import cn.origin.cube.event.events.EventStage; 4 | 5 | public class Render3DEvent 6 | extends EventStage { 7 | private final float partialTicks; 8 | 9 | public Render3DEvent(float partialTicks) { 10 | this.partialTicks = partialTicks; 11 | } 12 | 13 | public float getPartialTicks() { 14 | return this.partialTicks; 15 | } 16 | } 17 | 18 | -------------------------------------------------------------------------------- /src/main/java/cn/origin/cube/font/AWTFontRenderer.kt: -------------------------------------------------------------------------------- 1 | package cn.origin.cube.font 2 | 3 | import cn.origin.cube.font.texture.MipmapTexture 4 | import net.minecraft.client.Minecraft 5 | import net.minecraft.client.renderer.GlStateManager 6 | import net.minecraft.client.renderer.texture.TextureUtil 7 | import org.lwjgl.opengl.GL11.* 8 | import org.lwjgl.opengl.GL12 9 | import org.lwjgl.opengl.GL14 10 | import java.awt.Color 11 | import java.awt.Font 12 | import java.awt.RenderingHints 13 | import java.awt.image.BufferedImage 14 | 15 | /** 16 | * Generate new bitmap based font renderer 17 | */ 18 | class AWTFontRenderer(val font: Font, startChar: Int = 0, stopChar: Int = 256, private var loadingScreen: Boolean = false) { 19 | 20 | companion object { 21 | const val TEXTURE_WIDTH = 1024 22 | const val TEXTURE_WIDTH_DOUBLE = 1024.0 23 | const val MAX_TEXTURE_HEIGHT = 4096 24 | 25 | var assumeNonVolatile: Boolean = false 26 | val activeFontRenderers: ArrayList = ArrayList() 27 | 28 | private var gcTicks: Int = 0 29 | private const val GC_TICKS = 600 // Start garbage collection every 600 frames 30 | private const val CACHED_FONT_REMOVAL_TIME = 30000 // Remove cached texts after 30s of not being used 31 | 32 | fun garbageCollectionTick() { 33 | if (gcTicks++ > GC_TICKS) { 34 | activeFontRenderers.forEach { it.collectGarbage() } 35 | gcTicks = 0 36 | } 37 | } 38 | } 39 | 40 | private fun collectGarbage() { 41 | val currentTime = System.currentTimeMillis() 42 | 43 | cachedStrings 44 | .filter { currentTime - it.value.lastUsage > CACHED_FONT_REMOVAL_TIME } 45 | .forEach { 46 | glDeleteLists(it.value.displayList, 1) 47 | it.value.deleted = true 48 | cachedStrings.remove(it.key) 49 | } 50 | } 51 | 52 | private var fontHeight = -1 53 | private val charLocations = arrayOfNulls(stopChar) 54 | 55 | private val cachedStrings: HashMap = HashMap() 56 | 57 | private var textureID = -1 58 | // private var glyphChunk: TestGlyphChunk? = null 59 | private var textureWidth = 0 60 | private var textureHeight = 0 61 | 62 | val height: Int 63 | get() = (fontHeight - 8) / 2 64 | 65 | init { 66 | renderBitmap(startChar, stopChar) 67 | 68 | activeFontRenderers.add(this) 69 | } 70 | 71 | /** 72 | * Allows you to draw a string with the target font 73 | * 74 | * @param text to render 75 | * @param x location for target position 76 | * @param y location for target position 77 | * @param color of the text 78 | */ 79 | fun drawString(text: String, x: Double, y: Double, color: Int) { 80 | val scale = 0.25 81 | val reverse = 1 / scale 82 | 83 | glPushMatrix() 84 | glScaled(scale, scale, 1.0) 85 | glTranslated(x * 2F, y * 2.0 - 2.0, 0.0) 86 | 87 | bindGlTexture() 88 | 89 | val red = (color shr 16 and 0xff) / 255F 90 | val green = (color shr 8 and 0xff) / 255F 91 | val blue = (color and 0xff) / 255F 92 | val alpha = (color shr 24 and 0xff) / 255F 93 | 94 | glColor4f(red, green, blue, alpha) 95 | 96 | var currX = 0.0 97 | 98 | val cached: CachedFont? = cachedStrings[text] 99 | 100 | if (cached != null) { 101 | glCallList(cached.displayList) 102 | cached.lastUsage = System.currentTimeMillis() 103 | glPopMatrix() 104 | 105 | return 106 | } 107 | 108 | var list = -1 109 | 110 | if (assumeNonVolatile) { 111 | list = glGenLists(1) 112 | 113 | glNewList(list, GL_COMPILE_AND_EXECUTE) 114 | } 115 | 116 | glBegin(GL_QUADS) 117 | 118 | for (char in text.toCharArray()) { 119 | if (char.code >= charLocations.size) { 120 | glEnd() 121 | 122 | // Ugly solution, because floating point numbers, but I think that shouldn't be that much of a problem 123 | glScaled(reverse, reverse, reverse) 124 | Minecraft.getMinecraft().fontRenderer.drawString("$char", currX.toFloat() * scale.toFloat() + 1, 2f, color, false) 125 | currX += Minecraft.getMinecraft().fontRenderer.getStringWidth("$char") * reverse 126 | 127 | glScaled(scale, scale, scale) 128 | 129 | bindGlTexture() 130 | 131 | glColor4f(red, green, blue, alpha) 132 | 133 | glBegin(GL_QUADS) 134 | } else { 135 | val fontChar = charLocations[char.code] ?: continue 136 | 137 | drawChar(fontChar, currX.toFloat(), 0f) 138 | currX += fontChar.width - 8.0 139 | } 140 | } 141 | 142 | glEnd() 143 | 144 | if (assumeNonVolatile) { 145 | cachedStrings[text] = CachedFont(list, System.currentTimeMillis()) 146 | glEndList() 147 | } 148 | 149 | glPopMatrix() 150 | } 151 | 152 | /** 153 | * Draw char from texture to display 154 | * 155 | * @param char target font char to render 156 | * @param x target position x to render 157 | * @param y target position y to render 158 | */ 159 | private fun drawChar(char: CharLocation, x: Float, y: Float) { 160 | val width = char.width.toFloat() 161 | val height = char.height.toFloat() 162 | val srcX = char.x.toFloat() 163 | val srcY = char.y.toFloat() 164 | val renderX = srcX / textureWidth 165 | val renderY = srcY / textureHeight 166 | val renderWidth = width / textureWidth 167 | val renderHeight = height / textureHeight 168 | 169 | glTexCoord2f(renderX, renderY) 170 | glVertex2f(x, y) 171 | glTexCoord2f(renderX, renderY + renderHeight) 172 | glVertex2f(x, y + height) 173 | glTexCoord2f(renderX + renderWidth, renderY + renderHeight) 174 | glVertex2f(x + width, y + height) 175 | glTexCoord2f(renderX + renderWidth, renderY) 176 | glVertex2f(x + width, y) 177 | } 178 | 179 | /** 180 | * Render font chars to a bitmap 181 | */ 182 | private fun renderBitmap(startChar: Int, stopChar: Int) { 183 | val fontImages = arrayOfNulls(stopChar) 184 | 185 | // val bufferedImage = BufferedImage(TEXTURE_WIDTH, MAX_TEXTURE_HEIGHT, BufferedImage.TYPE_INT_ARGB) 186 | // val graphics2D = bufferedImage.graphics as Graphics2D 187 | // graphics2D.background = Color(0, 0, 0, 0) 188 | 189 | var rowHeight = 0 190 | var charX = 0 191 | var charY = 0 192 | 193 | for (targetChar in startChar until stopChar) { 194 | val fontImage = drawCharToImage(targetChar.toChar()) 195 | val fontChar = CharLocation(charX, charY, fontImage.width, fontImage.height) 196 | 197 | if (fontChar.height > fontHeight) fontHeight = fontChar.height 198 | if (fontChar.height > rowHeight) rowHeight = fontChar.height 199 | 200 | charLocations[targetChar] = fontChar 201 | fontImages[targetChar] = fontImage 202 | 203 | // graphics2D.drawImage(fontImage, charX, charY, null) 204 | charX += fontChar.width 205 | 206 | if (charX > 2048) { 207 | if (charX > textureWidth) textureWidth = charX 208 | charX = 0 209 | charY += rowHeight 210 | rowHeight = 0 211 | } 212 | } 213 | 214 | textureHeight = charY + rowHeight 215 | val textureImage = BufferedImage(textureWidth, textureHeight, BufferedImage.TYPE_INT_ARGB) 216 | // (textureImage.graphics as Graphics2D).drawImage(bufferedImage, 0, 0, null) 217 | 218 | val textureGraphics2D = textureImage.createGraphics() 219 | textureGraphics2D.font = font 220 | textureGraphics2D.color = Color(255, 255, 255, 0) 221 | textureGraphics2D.fillRect(0, 0, textureWidth, textureHeight) 222 | textureGraphics2D.color = Color.WHITE 223 | 224 | for (targetChar in startChar until stopChar) 225 | if (fontImages[targetChar] != null && charLocations[targetChar] != null) 226 | textureGraphics2D.drawImage(fontImages[targetChar], charLocations[targetChar]!!.x, charLocations[targetChar]!!.y, null) 227 | 228 | // glyphChunk = TestGlyphChunk(createTexture(textureImage)) 229 | textureID = TextureUtil.uploadTextureImageAllocate(TextureUtil.glGenTextures(), textureImage, true, true) 230 | } 231 | 232 | /** 233 | * Draw a char to a buffered image 234 | * 235 | * @param ch char to render 236 | * @return image of the char 237 | */ 238 | private fun drawCharToImage(ch: Char): BufferedImage { 239 | val tempGraphics2D = BufferedImage(1, 1, BufferedImage.TYPE_INT_ARGB).createGraphics() 240 | tempGraphics2D.font = font 241 | 242 | val fontMetrics = tempGraphics2D.fontMetrics 243 | tempGraphics2D.dispose() 244 | 245 | var charWidth = fontMetrics.charWidth(ch) + 8 246 | if (charWidth <= 0) charWidth = 7 247 | 248 | var charHeight = fontMetrics.height + 3 249 | if (charHeight <= 0) charHeight = font.size 250 | 251 | val fontImage = BufferedImage(charWidth, charHeight, BufferedImage.TYPE_INT_ARGB) 252 | val graphics = fontImage.createGraphics() 253 | 254 | graphics.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON) 255 | // graphics.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints.VALUE_TEXT_ANTIALIAS_ON) 256 | graphics.font = font 257 | graphics.color = Color.WHITE 258 | graphics.drawString(ch.toString(), 3, 1 + fontMetrics.ascent) 259 | graphics.dispose() 260 | 261 | return fontImage 262 | } 263 | 264 | /** 265 | * Calculate the string width of a text 266 | * 267 | * @param text for width calculation 268 | * @return the width of the text 269 | */ 270 | fun getStringWidth(text: String): Int { 271 | var width = 0 272 | val reverse = 1 / 0.25 273 | 274 | for (c in text.toCharArray()) { 275 | width += if (c.code >= charLocations.size) { 276 | (Minecraft.getMinecraft().fontRenderer.getStringWidth("$c") * reverse).toInt() 277 | } else { 278 | val fontChar = charLocations[ 279 | if (c.code < charLocations.size) 280 | c.code 281 | else 282 | '\u0003'.code 283 | ] ?: continue 284 | 285 | fontChar.width - 8 286 | } 287 | } 288 | 289 | return width / 2 290 | } 291 | 292 | private fun bindGlTexture() { 293 | // glyphChunk?.texture?.bindTexture() 294 | // glyphChunk?.updateLodBias(0.0F * 0.25F - 0.5F) 295 | if (this.loadingScreen) glBindTexture(GL_TEXTURE_2D, textureID) else GlStateManager.bindTexture(textureID) 296 | } 297 | 298 | private fun createTexture(bufferedImage: BufferedImage) = MipmapTexture(bufferedImage, GL_ALPHA, 4).apply { 299 | bindTexture() 300 | glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL12.GL_CLAMP_TO_EDGE) 301 | glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL12.GL_CLAMP_TO_EDGE) 302 | glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST) 303 | glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR) 304 | glTexParameterf(GL_TEXTURE_2D, GL14.GL_TEXTURE_LOD_BIAS, 0.0F) 305 | unbindTexture() 306 | } 307 | 308 | fun delete() { 309 | if (textureID != -1) { 310 | glDeleteTextures(textureID) 311 | textureID = -1 312 | } 313 | 314 | activeFontRenderers.remove(this) 315 | } 316 | 317 | fun finalize() { 318 | delete() 319 | } 320 | 321 | /** 322 | * Data class for saving char location of the font image 323 | */ 324 | private data class CharLocation(var x: Int, var y: Int, var width: Int, var height: Int) 325 | } -------------------------------------------------------------------------------- /src/main/java/cn/origin/cube/font/CachedFont.kt: -------------------------------------------------------------------------------- 1 | package cn.origin.cube.font 2 | 3 | import org.lwjgl.opengl.GL11.glDeleteLists 4 | 5 | data class CachedFont(val displayList: Int, var lastUsage: Long, var deleted: Boolean = false) { 6 | protected fun finalize() { 7 | if (!deleted) { 8 | glDeleteLists(displayList, 1) 9 | } 10 | } 11 | } -------------------------------------------------------------------------------- /src/main/java/cn/origin/cube/font/FontManager.java: -------------------------------------------------------------------------------- 1 | package cn.origin.cube.font; 2 | 3 | import cn.origin.cube.Cube; 4 | 5 | import java.awt.*; 6 | import java.io.IOException; 7 | import java.util.Objects; 8 | 9 | public class FontManager { 10 | public MinecraftFontRenderer CustomFont; 11 | 12 | public MinecraftFontRenderer IconFont; 13 | 14 | public FontManager() throws IOException, FontFormatException { 15 | CustomFont = new MinecraftFontRenderer(Font.createFont(Font.PLAIN, Objects.requireNonNull(Cube.class.getResourceAsStream("/assets/fonts/CustomFont.ttf"))).deriveFont(38f)); 16 | IconFont = new MinecraftFontRenderer(Font.createFont(Font.PLAIN, Objects.requireNonNull(Cube.class.getResourceAsStream("/assets/fonts/CubeBaseIcon.ttf"))).deriveFont(38f)); 17 | } 18 | 19 | public MinecraftFontRenderer getCustomFont(float size) { 20 | try { 21 | return new MinecraftFontRenderer(Font.createFont(Font.PLAIN,Objects.requireNonNull(Cube.class.getResourceAsStream("/assets/fonts/CustomFont.ttf"))).deriveFont(size)); 22 | } catch (FontFormatException | IOException e) { 23 | throw new RuntimeException(e); 24 | } 25 | } 26 | 27 | public MinecraftFontRenderer getIconFont(float size) { 28 | try { 29 | return new MinecraftFontRenderer(Font.createFont(Font.PLAIN,Objects.requireNonNull(Cube.class.getResourceAsStream("/assets/fonts/CubeBaseIcon.ttf"))).deriveFont(size)); 30 | } catch (FontFormatException | IOException e) { 31 | throw new RuntimeException(e); 32 | } 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /src/main/java/cn/origin/cube/font/MinecraftFontRenderer.kt: -------------------------------------------------------------------------------- 1 | package cn.origin.cube.font 2 | 3 | import cn.origin.cube.utils.gl.GlStateUtils 4 | import cn.origin.cube.utils.render.ColorUtils 5 | import cn.origin.cube.utils.render.Render2DUtil 6 | import net.minecraft.client.Minecraft 7 | import net.minecraft.client.gui.FontRenderer 8 | import net.minecraft.client.renderer.GlStateManager 9 | import net.minecraft.client.renderer.OpenGlHelper.glUseProgram 10 | import net.minecraft.util.ResourceLocation 11 | import org.lwjgl.opengl.GL11.glTranslated 12 | import java.awt.Font 13 | 14 | class MinecraftFontRenderer(val font: Font) : FontRenderer( 15 | Minecraft.getMinecraft().gameSettings, 16 | ResourceLocation("textures/font/ascii.png"), 17 | Minecraft.getMinecraft().textureManager, 18 | false 19 | ) { 20 | val fontHeight: Int 21 | 22 | private val defaultFont = AWTFontRenderer(font) 23 | 24 | private var renderFont = AWTFontRenderer(font) 25 | private val boldFont = AWTFontRenderer(font.deriveFont(Font.BOLD)) 26 | private val italicFont = AWTFontRenderer(font.deriveFont(Font.ITALIC)) 27 | private val boldItalicFont = AWTFontRenderer(font.deriveFont(Font.BOLD or Font.ITALIC)) 28 | 29 | val height: Int get() = renderFont.height / 2 30 | val size: Int get() = renderFont.font.size 31 | 32 | init { 33 | fontHeight = height 34 | FONT_HEIGHT = height 35 | } 36 | 37 | enum class FontStyle { 38 | Default, Plain, Italic, Bold, BoldItalic 39 | } 40 | 41 | fun setFontStyle(fontStyle: FontStyle) { 42 | val style = when (fontStyle) { 43 | FontStyle.Default -> defaultFont.font.style 44 | FontStyle.Plain -> Font.PLAIN 45 | FontStyle.Italic -> Font.ITALIC 46 | FontStyle.Bold -> Font.BOLD 47 | FontStyle.BoldItalic -> Font.BOLD or Font.ITALIC 48 | } 49 | renderFont = AWTFontRenderer(font.deriveFont(style)) 50 | } 51 | 52 | fun drawString(s: String?, x: Float, y: Float, color: Int) = drawString(s, x, y, color, false) 53 | 54 | override fun drawStringWithShadow(text: String?, x: Float, y: Float, color: Int) = 55 | drawString(text, x, y, color, true) 56 | 57 | fun drawCenteredString(s: String, x: Float, y: Float, color: Int, shadow: Boolean) = 58 | drawString(s, x - getStringWidth(s) / 2F, y, color, shadow) 59 | 60 | fun drawCenteredStringWithShadow(s: String, x: Float, y: Float, color: Int) = 61 | drawString(s, x - getStringWidth(s) / 2F, y, color, true) 62 | 63 | fun drawStringdrawCenteredString(s: String, x: Float, y: Float, color: Int) = 64 | drawStringWithShadow(s, x - getStringWidth(s) / 2F, y, color) 65 | 66 | override fun drawString(text: String?, x: Float, y: Float, color: Int, shadow: Boolean): Int { 67 | val currentText: String? 68 | currentText = text ?: return 0 69 | 70 | val currY = y - 3F 71 | if (currentText.contains("\n")) { 72 | val parts = currentText.split("\n") 73 | var newY = 0.0f 74 | for (s in parts) { 75 | drawText(s, x, currY + newY, color, shadow) 76 | newY += height 77 | } 78 | return 0 79 | } 80 | 81 | if (shadow) { 82 | glUseProgram(0) 83 | val alpha = 1 - (color shr 24 and 0xFF) / 255 84 | drawText(currentText, x + 1f, currY + 1f, 0xFF000000.toInt(), true) 85 | // drawText(currentText, x + 1f, currY + 1f, Color(0, 0, 0, alpha * 150).rgb, true) 86 | } 87 | 88 | return drawText(currentText, x, currY, color, false) 89 | } 90 | 91 | private fun drawText(text: String?, x: Float, y: Float, color: Int, ignoreColor: Boolean): Int { 92 | if (text == null) return 0 93 | 94 | if (text.isNullOrEmpty()) return x.toInt() 95 | 96 | glTranslated(x - 1.5, y + 0.5, 0.0) 97 | GlStateManager.disableOutlineMode() 98 | GlStateUtils.texture2d(true) 99 | GlStateUtils.lighting(false) 100 | 101 | GlStateUtils.alpha(false) 102 | GlStateUtils.blend(true) 103 | 104 | GlStateUtils.cull(false) 105 | GlStateUtils.lineSmooth(true) 106 | GlStateUtils.hintPolygon(true) 107 | GlStateUtils.smooth(true) 108 | 109 | // glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE) 110 | // glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE) 111 | // glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST) 112 | // glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR) 113 | // glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_LOD_BIAS, -0.25f) 114 | 115 | var currentColour = color 116 | 117 | if (currentColour == 553648127) { 118 | currentColour = 16777215 119 | } 120 | 121 | if (currentColour and -0x4000000 == 0) 122 | currentColour = currentColour or -16777216 123 | 124 | val defaultColor = currentColour 125 | 126 | val alpha = (currentColour shr 24 and 0xff) 127 | 128 | if (text.contains("§")) { 129 | val parts = text.split("§") 130 | var currentFont = renderFont 131 | 132 | var width = 0.0 133 | 134 | // Color code states 135 | var randomCase = false 136 | var bold = false 137 | var italic = false 138 | var strikeThrough = false 139 | var underline = false 140 | 141 | parts.forEachIndexed { index, part -> 142 | if (part.isEmpty()) return@forEachIndexed 143 | 144 | if (index == 0) { 145 | currentFont.drawString(part, width, 0.0, currentColour) 146 | width += currentFont.getStringWidth(part) 147 | } else { 148 | val words = part.substring(1) 149 | val type = part[0] 150 | when (val colorIndex = "0123456789abcdefklmnor".indexOf(type)) { 151 | in 0..15 -> { 152 | if (!ignoreColor) currentColour = ColorUtils.hexColors[colorIndex] or (alpha shl 24) 153 | bold = false 154 | italic = false 155 | randomCase = false 156 | underline = false 157 | strikeThrough = false 158 | } 159 | 160 | 16 -> randomCase = true 161 | 17 -> bold = true 162 | 18 -> strikeThrough = true 163 | 19 -> underline = true 164 | 20 -> italic = true 165 | 21 -> { 166 | currentColour = color 167 | 168 | if (currentColour and -67108864 == 0) currentColour = currentColour or -16777216 169 | 170 | if (currentColour and -0x4000000 == 0) { 171 | currentColour = currentColour or -0x1000000 172 | } 173 | 174 | bold = false 175 | italic = false 176 | randomCase = false 177 | underline = false 178 | strikeThrough = false 179 | } 180 | } 181 | 182 | currentFont = if (bold && italic) 183 | boldItalicFont 184 | else if (bold) 185 | boldFont 186 | else if (italic) 187 | italicFont 188 | else 189 | renderFont 190 | 191 | if (randomCase) { 192 | currentFont.drawString(ColorUtils.randomMagicText(words), width, 0.0, currentColour) 193 | } else { 194 | currentFont.drawString(words, width, 0.0, currentColour) 195 | } 196 | 197 | if (strikeThrough) 198 | Render2DUtil.drawLine( 199 | width / 2.0 + 1, 200 | currentFont.height / 3.0, 201 | (width + currentFont.getStringWidth(words)) / 2.0 + 1, 202 | currentFont.height / 3.0, 203 | fontHeight / 16F 204 | ) 205 | 206 | if (underline) 207 | Render2DUtil.drawLine( 208 | width / 2.0 + 1, 209 | currentFont.height / 2.0, 210 | (width + currentFont.getStringWidth(words)) / 2.0 + 1, 211 | currentFont.height / 2.0, 212 | fontHeight / 16F 213 | ) 214 | 215 | width += currentFont.getStringWidth(words) 216 | } 217 | } 218 | } else { 219 | // Color code states 220 | renderFont.drawString(text, 0.0, 0.0, currentColour) 221 | } 222 | 223 | GlStateUtils.hintPolygon(false) 224 | 225 | GlStateUtils.smooth(false) 226 | GlStateUtils.lineSmooth(false) 227 | GlStateUtils.blend(false) 228 | 229 | GlStateUtils.alpha(true) 230 | GlStateUtils.cull(true) 231 | 232 | // GlStateUtils.resetTexParam() 233 | 234 | glTranslated(-(x - 1.5), -(y + 0.5), 0.0) 235 | 236 | GlStateUtils.resetColour() 237 | 238 | return (x + getStringWidth(text)).toInt() 239 | } 240 | 241 | override fun getColorCode(charCode: Char) = 242 | ColorUtils.hexColors[getColorIndex(charCode)] 243 | 244 | override fun getStringWidth(text: String?): Int { 245 | var currentText = text 246 | 247 | currentText = text ?: return 0 248 | 249 | return if (currentText.contains("§")) { 250 | val parts = currentText.split("§") 251 | 252 | var currentFont = renderFont 253 | var width = 0 254 | var bold = false 255 | var italic = false 256 | 257 | parts.forEachIndexed { index, part -> 258 | if (part.isEmpty()) 259 | return@forEachIndexed 260 | 261 | if (index == 0) { 262 | width += currentFont.getStringWidth(part) 263 | } else { 264 | val words = part.substring(1) 265 | val type = part[0] 266 | val colorIndex = getColorIndex(type) 267 | when { 268 | colorIndex < 16 -> { 269 | bold = false 270 | italic = false 271 | } 272 | 273 | colorIndex == 17 -> bold = true 274 | colorIndex == 20 -> italic = true 275 | colorIndex == 21 -> { 276 | bold = false 277 | italic = false 278 | } 279 | } 280 | 281 | currentFont = if (bold && italic) 282 | boldItalicFont 283 | else if (bold) 284 | boldFont 285 | else if (italic) 286 | italicFont 287 | else 288 | renderFont 289 | 290 | width += currentFont.getStringWidth(words) 291 | } 292 | } 293 | 294 | width / 2 295 | } else 296 | renderFont.getStringWidth(currentText) / 2 297 | } 298 | 299 | override fun getCharWidth(character: Char) = getStringWidth(character.toString()) 300 | 301 | companion object { 302 | @JvmStatic 303 | fun getColorIndex(type: Char): Int { 304 | return when (type) { 305 | in '0'..'9' -> type - '0' 306 | in 'a'..'f' -> type - 'a' + 10 307 | in 'k'..'o' -> type - 'k' + 16 308 | 'r' -> 21 309 | else -> -1 310 | } 311 | } 312 | } 313 | } -------------------------------------------------------------------------------- /src/main/java/cn/origin/cube/font/texture/AbstractTexture.kt: -------------------------------------------------------------------------------- 1 | package cn.origin.cube.font.texture 2 | 3 | import net.minecraft.client.renderer.GlStateManager 4 | import net.minecraft.client.renderer.texture.TextureUtil 5 | import org.lwjgl.opengl.GL11.glGenTextures 6 | import java.awt.image.BufferedImage 7 | 8 | abstract class AbstractTexture { 9 | 10 | var textureID: Int = -1; private set 11 | 12 | abstract val width: Int 13 | abstract val height: Int 14 | 15 | fun genTexture() { 16 | textureID = glGenTextures() 17 | } 18 | 19 | fun genTexture(image: BufferedImage) { 20 | textureID = TextureUtil.uploadTextureImageAllocate(TextureUtil.glGenTextures(), image, true, true) 21 | } 22 | 23 | fun bindTexture() { 24 | if (textureID != -1) { 25 | GlStateManager.bindTexture(textureID) 26 | } 27 | } 28 | 29 | fun unbindTexture() { 30 | GlStateManager.bindTexture(0) 31 | } 32 | 33 | fun deleteTexture() { 34 | if (textureID != -1) { 35 | GlStateManager.deleteTexture(textureID) 36 | textureID = -1 37 | } 38 | } 39 | 40 | override fun equals(other: Any?) = 41 | this === other 42 | || other is AbstractTexture 43 | && this.textureID == other.textureID 44 | 45 | override fun hashCode() = textureID 46 | 47 | } -------------------------------------------------------------------------------- /src/main/java/cn/origin/cube/font/texture/MipmapTexture.kt: -------------------------------------------------------------------------------- 1 | package cn.origin.cube.font.texture 2 | 3 | import cn.origin.cube.font.texture.TextureUtils.scaleDownPretty 4 | import org.lwjgl.opengl.GL11.GL_TEXTURE_2D 5 | import org.lwjgl.opengl.GL11.glTexParameteri 6 | import org.lwjgl.opengl.GL12.* 7 | import java.awt.image.BufferedImage 8 | 9 | class MipmapTexture(bufferedImage: BufferedImage, format: Int, levels: Int) : AbstractTexture() { 10 | 11 | override val width = bufferedImage.width 12 | override val height = bufferedImage.height 13 | 14 | init { 15 | // Generate texture id and bind it 16 | genTexture() 17 | // genTexture(bufferedImage) 18 | 19 | bindTexture() 20 | 21 | // Setup mipmap levels 22 | glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_LOD, 0) 23 | glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LOD, levels) 24 | glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 0) 25 | glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, levels) 26 | 27 | // Generate level 0 (original size) texture 28 | TextureUtils.uploadImage(bufferedImage, 0, format, width, height) 29 | 30 | // Generate mipmaps 31 | if (levels > 0) { 32 | for (i in 1..levels) { 33 | val newWidth = width shr i 34 | val newHeight = height shr i 35 | val scaled = bufferedImage.scaleDownPretty(newWidth, newHeight) 36 | 37 | TextureUtils.uploadImage(scaled, i, format, newWidth, newHeight) 38 | } 39 | } 40 | 41 | // Unbind texture 42 | unbindTexture() 43 | } 44 | 45 | } -------------------------------------------------------------------------------- /src/main/java/cn/origin/cube/font/texture/TextureUtils.kt: -------------------------------------------------------------------------------- 1 | package cn.origin.cube.font.texture 2 | 3 | import net.minecraft.client.renderer.GLAllocation 4 | import org.lwjgl.opengl.GL11.GL_TEXTURE_2D 5 | import org.lwjgl.opengl.GL11.glTexImage2D 6 | import org.lwjgl.opengl.GL12.GL_BGRA 7 | import org.lwjgl.opengl.GL12.GL_UNSIGNED_INT_8_8_8_8_REV 8 | import java.awt.RenderingHints 9 | import java.awt.Transparency 10 | import java.awt.image.BufferedImage 11 | import java.nio.IntBuffer 12 | import kotlin.math.roundToInt 13 | import kotlin.math.sqrt 14 | 15 | object TextureUtils { 16 | private val buffer: IntBuffer = GLAllocation.createDirectIntBuffer(0x400000) 17 | 18 | fun uploadImage(bufferedImage: BufferedImage, level: Int, format: Int, width: Int, height: Int) { 19 | val data = IntArray(width * height) 20 | bufferedImage.getRGB(0, 0, width, height, data, 0, width) 21 | buffer.put(data) 22 | 23 | buffer.flip() 24 | glTexImage2D(GL_TEXTURE_2D, level, format, width, height, 0, GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, buffer) 25 | buffer.clear() 26 | } 27 | 28 | fun BufferedImage.scaleDownPretty(targetWidth: Int, targetHeight: Int): BufferedImage { 29 | val type = if (this.transparency == Transparency.OPAQUE) { 30 | BufferedImage.TYPE_INT_RGB 31 | } else { 32 | BufferedImage.TYPE_INT_ARGB 33 | } 34 | 35 | var bufferedImage: BufferedImage = this 36 | 37 | var width = this.width 38 | var height = this.height 39 | 40 | val divisorX = sqrt((width / targetWidth).toDouble()) 41 | val divisorY = sqrt((height / targetHeight).toDouble()) 42 | 43 | do { 44 | if (width > targetWidth) { 45 | width = (width / divisorX).roundToInt().coerceAtLeast(targetWidth) 46 | } 47 | 48 | if (height > targetHeight) { 49 | height = (height / divisorY).roundToInt().coerceAtLeast(targetHeight) 50 | } 51 | 52 | val tempImage = BufferedImage(width, height, type) 53 | val graphics2D = tempImage.createGraphics() 54 | 55 | graphics2D.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BILINEAR) 56 | graphics2D.drawImage(bufferedImage, 0, 0, width, height, null) 57 | graphics2D.dispose() 58 | 59 | bufferedImage = tempImage 60 | } while (width != targetWidth || height != targetHeight) 61 | 62 | return bufferedImage 63 | } 64 | } -------------------------------------------------------------------------------- /src/main/java/cn/origin/cube/guis/CategoryPanel.kt: -------------------------------------------------------------------------------- 1 | package cn.origin.cube.guis 2 | 3 | import cn.origin.cube.Cube 4 | import cn.origin.cube.guis.buttons.ModuleButton 5 | import cn.origin.cube.module.Category 6 | import cn.origin.cube.module.modules.client.ClickGui 7 | import cn.origin.cube.utils.render.Render2DUtil 8 | import java.awt.Color 9 | import java.util.* 10 | 11 | class CategoryPanel( 12 | var x: Float, 13 | var y: Float, 14 | var width: Float, 15 | var height: Float, 16 | var category: Category, 17 | ) { 18 | val modules = arrayListOf() 19 | var isShowModules = true 20 | private var dragging = false 21 | private var x2 = 0.0f 22 | private var y2 = 0.0f 23 | 24 | init { 25 | for (module in Cube.moduleManager!!.getModulesByCategory(this.category).sortedBy { it.name }) { 26 | modules.add(ModuleButton(this.width, this.height * 0.85f, this, module)) 27 | } 28 | } 29 | 30 | fun onDraw(mouseX: Int, mouseY: Int) { 31 | if (this.dragging) { 32 | this.x = this.x2 + mouseX 33 | this.y = this.y2 + mouseY 34 | } 35 | Render2DUtil.drawRect(x, y, width, height, ClickGui.getCurrentColor().rgb) 36 | Cube.fontManager!!.IconFont.drawStringWithShadow( 37 | category.icon, 38 | x + 3, 39 | y + (height / 2) - (Cube.fontManager!!.IconFont.height / 4), 40 | Color.WHITE.rgb 41 | ) 42 | Cube.fontManager!!.CustomFont.drawStringWithShadow( 43 | category.getName(), 44 | x + 5 + Cube.fontManager!!.IconFont.getStringWidth(category.icon), 45 | y + (height / 2) - (Cube.fontManager!!.CustomFont.height / 4), 46 | Color.WHITE.rgb 47 | ) 48 | if (modules.isEmpty() || !isShowModules) return 49 | var calcYPos = this.y + this.height 50 | for (moduleButton in modules) { 51 | moduleButton.drawButton(this.x, calcYPos, mouseX, mouseY) 52 | calcYPos += moduleButton.height 53 | if (moduleButton.isShowSettings && moduleButton.settings.isNotEmpty()) { 54 | var buttonX: Double = (moduleButton.x + moduleButton.height).toDouble() 55 | for (settingButton in moduleButton.settings.filter { it.value.isVisible }) { 56 | settingButton.drawButton(x + (this.width - settingButton.width) / 2, calcYPos, mouseX, mouseY) 57 | calcYPos += settingButton.height 58 | buttonX = (x + (this.width - settingButton.width) / 2).toDouble() 59 | } 60 | Render2DUtil.drawLine( 61 | buttonX, 62 | (moduleButton.y + moduleButton.height).toDouble(), 63 | buttonX, 64 | calcYPos.toDouble(), 65 | 0.75f, 66 | ClickGui.getCurrentColor() 67 | ) 68 | } 69 | } 70 | } 71 | 72 | fun mouseClicked(mouseX: Int, mouseY: Int, mouseButton: Int) { 73 | if (mouseButton == 0 && this.isHoveredCategoryTab(mouseX, mouseY)) { 74 | this.x2 = this.x - mouseX 75 | this.y2 = this.y - mouseY 76 | this.dragging = true 77 | } 78 | modules.forEach { it.mouseClicked(mouseX, mouseY, mouseButton) } 79 | } 80 | 81 | fun mouseReleased(mouseX: Int, mouseY: Int, mouseButton: Int) { 82 | if (mouseButton == 0) { 83 | this.dragging = false 84 | } 85 | if (mouseButton == 1 && this.isHoveredCategoryTab(mouseX, mouseY)) { 86 | this.isShowModules = !this.isShowModules 87 | } 88 | modules.forEach { it.mouseReleased(mouseX, mouseY, mouseButton) } 89 | } 90 | 91 | private fun isHoveredCategoryTab(mouseX: Int, mouseY: Int): Boolean { 92 | return mouseX >= this.x && mouseX <= this.x + this.width && mouseY >= this.y && mouseY <= this.y + this.height 93 | } 94 | 95 | fun keyTyped(typedChar: Char, keyCode: Int) { 96 | modules.forEach { it.keyTyped(typedChar, keyCode) } 97 | } 98 | } -------------------------------------------------------------------------------- /src/main/java/cn/origin/cube/guis/ClickGuiScreen.kt: -------------------------------------------------------------------------------- 1 | package cn.origin.cube.guis 2 | 3 | import cn.origin.cube.Cube 4 | import cn.origin.cube.module.Category 5 | import cn.origin.cube.module.modules.client.ClickGui 6 | import cn.origin.cube.utils.render.Render2DUtil 7 | import net.minecraft.client.gui.GuiScreen 8 | import org.lwjgl.input.Mouse 9 | import java.awt.Color 10 | 11 | class ClickGuiScreen : GuiScreen() { 12 | val panels = arrayListOf() 13 | 14 | init { 15 | var x = 20.0f 16 | for (category in Category.values().asList().stream().filter { !it.isHud }) { 17 | panels.add(CategoryPanel(x, 35.0f, 105.0f, 20.0f, category)) 18 | x += 110 19 | } 20 | } 21 | 22 | override fun drawScreen(mouseX: Int, mouseY: Int, partialTicks: Float) { 23 | drawDefaultBackground() 24 | checkDWHeel() 25 | for (panel in panels) { 26 | panel.onDraw(mouseX, mouseY) 27 | } 28 | panels.forEach { 29 | for (moduleButton in it.modules) { 30 | if (moduleButton.isHoveredButton(mouseX, mouseY)) { 31 | Render2DUtil.drawRect( 32 | mouseX + 0.3f, 33 | mouseY + 0.3f, 34 | Cube.fontManager.CustomFont.getStringWidth(moduleButton.father.descriptions) + 2f, 35 | Cube.fontManager.CustomFont.fontHeight + 0.3f, 36 | Color(0, 0, 0, 115).rgb 37 | ) 38 | Render2DUtil.drawOutlineRect( 39 | mouseX + 0.3, 40 | mouseY + 0.3, 41 | Cube.fontManager.CustomFont.getStringWidth(moduleButton.father.descriptions) + 2.0, 42 | Cube.fontManager.CustomFont.fontHeight + 0.3, 43 | 1.0f, 44 | Color(0, 0, 0, 115) 45 | ) 46 | Cube.fontManager.CustomFont.drawStringWithShadow( 47 | moduleButton.father.descriptions, 48 | mouseX + 1.5f, 49 | mouseY + 1.5f, 50 | Color.WHITE.rgb 51 | ) 52 | } 53 | } 54 | } 55 | } 56 | 57 | private fun checkDWHeel() { 58 | val dWheel: Int = Mouse.getDWheel() 59 | if (dWheel < 0) { 60 | panels.forEach { it.y -= 10f } 61 | } else if (dWheel > 0) { 62 | panels.forEach { it.y += 10f } 63 | } 64 | } 65 | 66 | override fun mouseClicked(mouseX: Int, mouseY: Int, mousebutton: Int) { 67 | panels.forEach { it.mouseClicked(mouseX, mouseY, mousebutton) } 68 | } 69 | 70 | override fun mouseReleased(mouseX: Int, mouseY: Int, mousebutton: Int) { 71 | panels.forEach { it.mouseReleased(mouseX, mouseY, mousebutton) } 72 | } 73 | 74 | override fun keyTyped(typedChar: Char, keyCode: Int) { 75 | if (keyCode == 1) { 76 | ClickGui.INSTANCE.disable() 77 | } 78 | panels.forEach { it.keyTyped(typedChar, keyCode) } 79 | } 80 | 81 | override fun onGuiClosed() { 82 | if (ClickGui.INSTANCE.isEnabled) { 83 | ClickGui.INSTANCE.disable() 84 | } 85 | Cube.configManager.saveAll() 86 | } 87 | 88 | override fun doesGuiPauseGame(): Boolean { 89 | return false 90 | } 91 | } -------------------------------------------------------------------------------- /src/main/java/cn/origin/cube/guis/HudEditorScreen.kt: -------------------------------------------------------------------------------- 1 | package cn.origin.cube.guis 2 | 3 | import cn.origin.cube.Cube 4 | import cn.origin.cube.module.Category 5 | import cn.origin.cube.module.modules.client.HudEditor 6 | import cn.origin.cube.utils.render.Render2DUtil 7 | import net.minecraft.client.gui.GuiScreen 8 | import org.lwjgl.input.Mouse 9 | import java.awt.Color 10 | 11 | class HudEditorScreen : GuiScreen() { 12 | val panels = arrayListOf() 13 | 14 | init { 15 | var x = 20.0f 16 | for (category in Category.values().asList().stream().filter { it.isHud }) { 17 | panels.add( 18 | CategoryPanel( 19 | x, 20 | 35.0f, 21 | 105.0f, 22 | 20.0f, 23 | category 24 | ) 25 | ) 26 | x += 110 27 | } 28 | } 29 | 30 | override fun drawScreen(mouseX: Int, mouseY: Int, partialTicks: Float) { 31 | checkDWHeel() 32 | for (panel in panels) { 33 | panel.onDraw(mouseX, mouseY) 34 | } 35 | panels.forEach { 36 | for (moduleButton in it.modules) { 37 | if (moduleButton.isHoveredButton(mouseX, mouseY)) { 38 | Render2DUtil.drawRect( 39 | mouseX + 0.3f, 40 | mouseY + 0.3f, 41 | Cube.fontManager.CustomFont.getStringWidth(moduleButton.father.descriptions) + 2f, 42 | Cube.fontManager.CustomFont.fontHeight + 0.3f, 43 | Color(0, 0, 0, 115).rgb 44 | ) 45 | Render2DUtil.drawOutlineRect( 46 | mouseX + 0.3, 47 | mouseY + 0.3, 48 | Cube.fontManager.CustomFont.getStringWidth(moduleButton.father.descriptions) + 2.0, 49 | Cube.fontManager.CustomFont.fontHeight + 0.3, 50 | 1.0f, 51 | Color(0, 0, 0, 115) 52 | ) 53 | Cube.fontManager.CustomFont.drawStringWithShadow( 54 | moduleButton.father.descriptions, 55 | mouseX + 1.5f, 56 | mouseY + 1.5f, 57 | Color.WHITE.rgb 58 | ) 59 | } 60 | } 61 | } 62 | } 63 | 64 | private fun checkDWHeel() { 65 | val dWheel: Int = Mouse.getDWheel() 66 | if (dWheel < 0) { 67 | panels.forEach { it.y -= 10f } 68 | } else if (dWheel > 0) { 69 | panels.forEach { it.y += 10f } 70 | } 71 | } 72 | 73 | override fun mouseClicked(mouseX: Int, mouseY: Int, mousebutton: Int) { 74 | panels.forEach { it.mouseClicked(mouseX, mouseY, mousebutton) } 75 | } 76 | 77 | override fun mouseReleased(mouseX: Int, mouseY: Int, mousebutton: Int) { 78 | panels.forEach { it.mouseReleased(mouseX, mouseY, mousebutton) } 79 | } 80 | 81 | override fun keyTyped(typedChar: Char, keyCode: Int) { 82 | if (keyCode == 1) { 83 | HudEditor.INSTANCE.disable() 84 | } 85 | panels.forEach { it.keyTyped(typedChar, keyCode) } 86 | } 87 | 88 | override fun onGuiClosed() { 89 | if (HudEditor.INSTANCE.isEnabled) { 90 | HudEditor.INSTANCE.disable() 91 | } 92 | Cube.configManager.saveAll() 93 | } 94 | 95 | override fun doesGuiPauseGame(): Boolean { 96 | return false 97 | } 98 | } -------------------------------------------------------------------------------- /src/main/java/cn/origin/cube/guis/buttons/Button.kt: -------------------------------------------------------------------------------- 1 | package cn.origin.cube.guis.buttons 2 | 3 | import cn.origin.cube.guis.CategoryPanel 4 | import net.minecraft.client.Minecraft 5 | 6 | abstract class Button( 7 | var width: Float, 8 | var height: Float, 9 | var panelFather: CategoryPanel 10 | ) { 11 | val mc: Minecraft = Minecraft.getMinecraft() 12 | var x: Float = 0.0f; 13 | var y: Float = 0.0f; 14 | 15 | abstract fun drawButton(x: Float, y: Float, mouseX: Int, mouseY: Int) 16 | 17 | open fun mouseClicked(mouseX: Int, mouseY: Int, mouseButton: Int) {} 18 | open fun mouseReleased(mouseX: Int, mouseY: Int, mouseButton: Int) {} 19 | fun isHoveredButton(mouseX: Int, mouseY: Int): Boolean { 20 | return mouseX > x && mouseX < x + this.width && mouseY > y && mouseY < y + this.height 21 | } 22 | 23 | open fun keyTyped(typedChar: Char, keyCode: Int) {} 24 | } -------------------------------------------------------------------------------- /src/main/java/cn/origin/cube/guis/buttons/ModuleButton.kt: -------------------------------------------------------------------------------- 1 | package cn.origin.cube.guis.buttons 2 | 3 | import cn.origin.cube.Cube 4 | import cn.origin.cube.guis.CategoryPanel 5 | import cn.origin.cube.guis.buttons.setting.* 6 | import cn.origin.cube.module.AbstractModule 7 | import cn.origin.cube.module.modules.client.ClickGui 8 | import cn.origin.cube.settings.* 9 | import cn.origin.cube.utils.COG 10 | import cn.origin.cube.utils.render.Render2DUtil 11 | import java.awt.Color 12 | 13 | class ModuleButton(width: Float, height: Float, panel: CategoryPanel, val father: AbstractModule) : 14 | Button(width, height, panel) { 15 | 16 | var isShowSettings = false 17 | val settings = arrayListOf>() 18 | private var x2 = 0.0f 19 | private var y2 = 0.0f 20 | private var dragging = false 21 | 22 | init { 23 | if (father.settingList.isNotEmpty()) { 24 | for (setting in father.settingList) { 25 | if (setting is BooleanSetting) { 26 | settings.add(BooleanSettingButton(width * 0.98f, height, setting, this)) 27 | } 28 | if (setting is BindSetting) { 29 | settings.add(BindSettingButton(width * 0.98f, height, setting, this)) 30 | } 31 | if (setting is NumberSetting<*>) { 32 | settings.add(NumberSliderButton(width * 0.98f, height, setting, this)) 33 | } 34 | if (setting is ModeSetting<*>) { 35 | settings.add(ModeSettingButton(width * 0.98f, height, setting, this)) 36 | } 37 | if (setting is StringSetting) { 38 | settings.add(StringSettingButton(width * 0.98f, height, setting, this)) 39 | } 40 | } 41 | } 42 | if (father.commonSettings.isNotEmpty()) { 43 | for (setting in father.commonSettings) { 44 | if (setting is BooleanSetting) { 45 | settings.add(BooleanSettingButton(width * 0.98f, height, setting, this)) 46 | } 47 | if (setting is BindSetting) { 48 | settings.add(BindSettingButton(width * 0.98f, height, setting, this)) 49 | } 50 | if (setting is NumberSetting<*>) { 51 | settings.add(NumberSliderButton(width * 0.98f, height, setting, this)) 52 | } 53 | if (setting is ModeSetting<*>) { 54 | settings.add(ModeSettingButton(width * 0.98f, height, setting, this)) 55 | } 56 | if (setting is StringSetting) { 57 | settings.add(StringSettingButton(width * 0.98f, height, setting, this)) 58 | } 59 | } 60 | } 61 | } 62 | 63 | override fun drawButton(x: Float, y: Float, mouseX: Int, mouseY: Int) { 64 | if (father.isHud && father.isEnabled) { 65 | this.solveHUDPos(mouseX, mouseY) 66 | Cube.fontManager.CustomFont.drawString( 67 | (father.name + " X:" + father.x).toString() + " Y:" + father.y, 68 | father.x, 69 | father.y - Cube.fontManager.CustomFont.fontHeight, 70 | ClickGui.getCurrentColor().rgb 71 | ) 72 | Render2DUtil.drawRect( 73 | father.x - 1, 74 | father.y - 1, 75 | father.width + 1, 76 | father.height + 1, 77 | Color(25, 25, 25, 125).rgb 78 | ) 79 | } 80 | Render2DUtil.drawRect(x, y, this.width, this.height, Color(15, 15, 15, 105).rgb) 81 | Cube.fontManager!!.CustomFont.drawStringWithShadow( 82 | father.name, 83 | x + 3, 84 | y + (height / 2) - (Cube.fontManager!!.CustomFont.height / 4), 85 | if (father.isEnabled) ClickGui.getCurrentColor().rgb else Color.WHITE.rgb 86 | ) 87 | Cube.fontManager!!.IconFont.drawStringWithShadow( 88 | COG, (x + width) - 3 - Cube.fontManager!!.IconFont.getStringWidth( 89 | COG 90 | ), y + (height / 2) - (Cube.fontManager!!.IconFont.height / 4), Color.WHITE.rgb 91 | ) 92 | this.x = x 93 | this.y = y 94 | } 95 | 96 | override fun mouseClicked(mouseX: Int, mouseY: Int, mouseButton: Int) { 97 | if (settings.isNotEmpty()) { 98 | settings.forEach { it.mouseClicked(mouseX, mouseY, mouseButton) } 99 | } 100 | if (mouseButton == 0 && this.isHoveredHUD(mouseX, mouseY)) { 101 | this.x2 = this.father.x - mouseX 102 | this.y2 = this.father.y - mouseY 103 | this.dragging = true 104 | return 105 | } 106 | if (!isHoveredButton(mouseX, mouseY)) { 107 | return 108 | } 109 | when (mouseButton) { 110 | 0 -> father.toggle() 111 | 1 -> isShowSettings = !isShowSettings 112 | } 113 | } 114 | 115 | private fun isHoveredHUD(mouseX: Int, mouseY: Int): Boolean { 116 | return mouseX >= this.father.x.coerceAtMost(this.father.x + this.father.width) && mouseX <= this.father.x.coerceAtLeast( 117 | this.father.x + this.father.width 118 | ) && mouseY >= this.father.y.coerceAtMost(this.father.y + this.father.height) && mouseY <= this.father.y.coerceAtLeast( 119 | this.father.y + this.father.height 120 | ) 121 | } 122 | 123 | 124 | private fun solveHUDPos(mouseX: Int, mouseY: Int) { 125 | if (dragging) { 126 | this.father.x = x2 + mouseX 127 | this.father.y = y2 + mouseY 128 | } 129 | if (this.father.x.coerceAtMost(this.father.x + this.father.width) < 0) { 130 | this.father.x = if (this.father.x < this.father.x + this.father.width) 0.0f else -this.father.width 131 | } 132 | if (this.father.x.coerceAtLeast(this.father.x + this.father.width) > this.mc.displayWidth / 2) { 133 | this.father.x = 134 | if (this.father.x < this.father.x + this.father.width) (this.mc.displayWidth / 2 - this.father.width) else (this.mc.displayWidth / 2).toFloat() 135 | } 136 | if (this.father.y.coerceAtMost(this.father.y + this.father.height) < 0) { 137 | this.father.y = if (this.father.y < this.father.y + this.father.height) 0.0f else -this.father.height 138 | } 139 | if (this.father.y.coerceAtLeast(this.father.y + this.father.height) > this.mc.displayHeight / 2) { 140 | this.father.y = 141 | if (this.father.y < this.father.y + this.father.height) (this.mc.displayHeight / 2 - this.father.height) else (this.mc.displayHeight / 2).toFloat() 142 | } 143 | } 144 | 145 | override fun mouseReleased(mouseX: Int, mouseY: Int, mouseButton: Int) { 146 | if (mouseButton == 0) { 147 | this.dragging = false 148 | } 149 | if (settings.isNotEmpty()) { 150 | settings.forEach { it.mouseReleased(mouseX, mouseY, mouseButton) } 151 | } 152 | } 153 | 154 | override fun keyTyped(typedChar: Char, keyCode: Int) { 155 | if (settings.isNotEmpty()) { 156 | settings.forEach { it.keyTyped(typedChar, keyCode) } 157 | } 158 | } 159 | } -------------------------------------------------------------------------------- /src/main/java/cn/origin/cube/guis/buttons/SettingButton.kt: -------------------------------------------------------------------------------- 1 | package cn.origin.cube.guis.buttons 2 | 3 | import cn.origin.cube.guis.CategoryPanel 4 | import cn.origin.cube.settings.Setting 5 | 6 | abstract class SettingButton>( 7 | width: Float, 8 | height: Float, 9 | val value: Setting<*>, 10 | val father: ModuleButton 11 | ) : Button(width, height, father.panelFather) { 12 | 13 | } -------------------------------------------------------------------------------- /src/main/java/cn/origin/cube/guis/buttons/setting/BindSettingButton.kt: -------------------------------------------------------------------------------- 1 | package cn.origin.cube.guis.buttons.setting 2 | 3 | import cn.origin.cube.Cube 4 | import cn.origin.cube.guis.buttons.ModuleButton 5 | import cn.origin.cube.guis.buttons.SettingButton 6 | import cn.origin.cube.settings.BindSetting 7 | import cn.origin.cube.settings.BindSetting.KeyBind 8 | import cn.origin.cube.utils.render.Render2DUtil 9 | import org.lwjgl.input.Keyboard 10 | import java.awt.Color 11 | 12 | class BindSettingButton( 13 | width: Float, 14 | height: Float, 15 | value: BindSetting, 16 | father: ModuleButton 17 | ) : SettingButton(width, height, value, father) { 18 | 19 | private var listening = false 20 | 21 | override fun drawButton(x: Float, y: Float, mouseX: Int, mouseY: Int) { 22 | Render2DUtil.drawRect(x, y, this.width, this.height, Color(15, 15, 15, 95).rgb) 23 | Cube.fontManager!!.CustomFont.drawStringWithShadow( 24 | "${value.name}: ${if (listening) "..." else Keyboard.getKeyName((value.value as KeyBind).keyCode)}", 25 | x + 3, 26 | y + (height / 2) - (Cube.fontManager!!.CustomFont.height / 4), 27 | Color.WHITE.rgb 28 | ) 29 | this.x = x 30 | this.y = y 31 | } 32 | 33 | override fun mouseClicked(mouseX: Int, mouseY: Int, mouseButton: Int) { 34 | if (!isHoveredButton(mouseX, mouseY) || !value.isVisible || !father.isShowSettings) { 35 | return 36 | } 37 | when (mouseButton) { 38 | 0 -> listening = true 39 | 1 -> value.value = value.defaultValue 40 | } 41 | } 42 | 43 | override fun keyTyped(typedChar: Char, keyCode: Int) { 44 | if (this.listening) { 45 | (value as BindSetting).value = KeyBind(keyCode) 46 | this.listening = false 47 | } 48 | } 49 | } -------------------------------------------------------------------------------- /src/main/java/cn/origin/cube/guis/buttons/setting/BooleanSettingButton.kt: -------------------------------------------------------------------------------- 1 | package cn.origin.cube.guis.buttons.setting 2 | 3 | import cn.origin.cube.Cube 4 | import cn.origin.cube.guis.buttons.ModuleButton 5 | import cn.origin.cube.guis.buttons.SettingButton 6 | import cn.origin.cube.module.modules.client.ClickGui 7 | import cn.origin.cube.settings.BooleanSetting 8 | import cn.origin.cube.utils.render.Render2DUtil 9 | import java.awt.Color 10 | 11 | class BooleanSettingButton( 12 | width: Float, 13 | height: Float, 14 | value: BooleanSetting, 15 | father: ModuleButton 16 | ) : SettingButton(width, height, value, father) { 17 | override fun drawButton(x: Float, y: Float, mouseX: Int, mouseY: Int) { 18 | Render2DUtil.drawRect(x, y, this.width, this.height, Color(15, 15, 15, 95).rgb) 19 | Cube.fontManager!!.CustomFont.drawStringWithShadow( 20 | value.name, 21 | x + 3, 22 | y + (height / 2) - (Cube.fontManager!!.CustomFont.height / 4), 23 | if (value.value as Boolean) ClickGui.getCurrentColor().rgb else Color.WHITE.rgb 24 | ) 25 | this.x = x 26 | this.y = y 27 | } 28 | 29 | override fun mouseClicked(mouseX: Int, mouseY: Int, mouseButton: Int) { 30 | if (!isHoveredButton(mouseX, mouseY) || !value.isVisible || !father.isShowSettings) { 31 | return 32 | } 33 | when (mouseButton) { 34 | 0, 1 -> value.value = !(value.value as Boolean) 35 | } 36 | } 37 | 38 | } -------------------------------------------------------------------------------- /src/main/java/cn/origin/cube/guis/buttons/setting/ModeSettingButton.kt: -------------------------------------------------------------------------------- 1 | package cn.origin.cube.guis.buttons.setting 2 | 3 | import cn.origin.cube.Cube 4 | import cn.origin.cube.guis.buttons.ModuleButton 5 | import cn.origin.cube.guis.buttons.SettingButton 6 | import cn.origin.cube.settings.ModeSetting 7 | import cn.origin.cube.utils.render.Render2DUtil 8 | import java.awt.Color 9 | 10 | class ModeSettingButton( 11 | width: Float, 12 | height: Float, 13 | value: ModeSetting<*>, 14 | father: ModuleButton 15 | ) : SettingButton>(width, height, value, father) { 16 | override fun drawButton(x: Float, y: Float, mouseX: Int, mouseY: Int) { 17 | Render2DUtil.drawRect(x, y, this.width, this.height, Color(15, 15, 15, 95).rgb) 18 | Cube.fontManager!!.CustomFont.drawStringWithShadow( 19 | value.name, 20 | x + 3, 21 | y + (height / 2) - (Cube.fontManager!!.CustomFont.height / 4), 22 | Color.WHITE.rgb 23 | ) 24 | Cube.fontManager!!.CustomFont.drawStringWithShadow( 25 | (value as ModeSetting<*>).valueAsString, 26 | x + width - 3 - Cube.fontManager!!.CustomFont.getStringWidth(value.valueAsString), 27 | y + (height / 2) - (Cube.fontManager!!.CustomFont.height / 4), 28 | Color.WHITE.rgb 29 | ) 30 | this.x = x 31 | this.y = y 32 | } 33 | 34 | override fun mouseClicked(mouseX: Int, mouseY: Int, mouseButton: Int) { 35 | if (!this.isHoveredButton(mouseX, mouseY) || !value.isVisible || !father.isShowSettings) { 36 | return 37 | } 38 | if (mouseButton == 0) { 39 | (this.value as ModeSetting<*>).forwardLoop() 40 | } 41 | } 42 | } -------------------------------------------------------------------------------- /src/main/java/cn/origin/cube/guis/buttons/setting/NumberSliderButton.kt: -------------------------------------------------------------------------------- 1 | package cn.origin.cube.guis.buttons.setting 2 | 3 | import cn.origin.cube.Cube 4 | import cn.origin.cube.guis.buttons.ModuleButton 5 | import cn.origin.cube.guis.buttons.SettingButton 6 | import cn.origin.cube.module.modules.client.ClickGui 7 | import cn.origin.cube.settings.* 8 | import cn.origin.cube.utils.render.Render2DUtil 9 | import java.awt.Color 10 | import java.math.RoundingMode 11 | import java.text.DecimalFormat 12 | import kotlin.math.roundToInt 13 | import kotlin.math.roundToLong 14 | 15 | 16 | class NumberSliderButton(width: Float, height: Float, value: Setting<*>, father: ModuleButton) : 17 | SettingButton>(width, height, value, father) { 18 | private lateinit var min: Number 19 | private lateinit var max: Number 20 | private var difference = 0 21 | private var dargging = false 22 | 23 | init { 24 | when (value) { 25 | is DoubleSetting -> { 26 | min = value.minValue 27 | max = value.maxValue 28 | } 29 | 30 | is FloatSetting -> { 31 | min = value.minValue 32 | max = value.maxValue 33 | } 34 | 35 | is IntegerSetting -> { 36 | min = value.minValue 37 | max = value.maxValue 38 | } 39 | 40 | is LongSetting -> { 41 | min = value.minValue 42 | max = value.maxValue 43 | } 44 | } 45 | 46 | difference = max.toInt() - min.toInt() 47 | } 48 | 49 | override fun drawButton(x: Float, y: Float, mouseX: Int, mouseY: Int) { 50 | dragSetting(mouseX) 51 | Render2DUtil.drawRect(x, y, this.width, this.height, Color(15, 15, 15, 95).rgb) 52 | Render2DUtil.drawRect( 53 | x, 54 | y + 0.5f, 55 | if ((value.value as Number).toDouble() <= min.toDouble()) 0.0f else width * partialMultiplier(), 56 | height - 1.0f, 57 | ClickGui.getCurrentColor().rgb 58 | ) 59 | Cube.fontManager!!.CustomFont.drawStringWithShadow( 60 | value.name, 61 | x + 3, 62 | y + (height / 2) - (Cube.fontManager!!.CustomFont.height / 4), 63 | Color.WHITE.rgb 64 | ) 65 | Cube.fontManager!!.CustomFont.drawStringWithShadow( 66 | when (value) { 67 | is FloatSetting -> getNoMoreThanOneDigits(value.value) 68 | is DoubleSetting -> getNoMoreThanTwoDigits(value.value) 69 | else -> { 70 | value.value.toString() 71 | } 72 | }, 73 | x + width - 3 - Cube.fontManager!!.CustomFont.getStringWidth( 74 | when (value) { 75 | is FloatSetting -> getNoMoreThanOneDigits(value.value) 76 | is DoubleSetting -> getNoMoreThanTwoDigits(value.value) 77 | else -> { 78 | value.value.toString() 79 | } 80 | } 81 | ), 82 | y + (height / 2) - (Cube.fontManager!!.CustomFont.height / 4), 83 | Color.WHITE.rgb 84 | ) 85 | this.x = x 86 | this.y = y 87 | } 88 | 89 | override fun mouseClicked(mouseX: Int, mouseY: Int, mouseButton: Int) { 90 | if (isHoveredButton(mouseX, mouseY) && mouseButton == 0 && value.isVisible && panelFather.isShowModules) { 91 | dargging = true 92 | } 93 | } 94 | 95 | override fun mouseReleased(mouseX: Int, mouseY: Int, mouseButton: Int) { 96 | if (mouseButton == 0) { 97 | dargging = false 98 | } 99 | } 100 | 101 | private fun dragSetting(mouseX: Int) { 102 | if (dargging) { 103 | setSettingFromX(mouseX) 104 | } 105 | } 106 | 107 | private fun setSettingFromX(mouseX: Int) { 108 | val percent = (mouseX.toFloat() - x) / width 109 | when (this.value) { 110 | is DoubleSetting -> { 111 | val result = this.value.minValue + (difference.toFloat() * percent).toDouble() 112 | if (result > this.value.maxValue) { 113 | this.value.value = this.value.maxValue 114 | } else if (result < this.value.minValue) { 115 | this.value.value = this.value.minValue 116 | } else { 117 | this.value.value = result 118 | } 119 | } 120 | 121 | is FloatSetting -> { 122 | val result = this.value.minValue + difference.toFloat() * percent 123 | if (result > this.value.maxValue) { 124 | this.value.value = this.value.maxValue 125 | } else if (result < this.value.minValue) { 126 | this.value.value = this.value.minValue 127 | } else { 128 | this.value.value = result 129 | } 130 | } 131 | 132 | is IntegerSetting -> { 133 | val result = this.value.minValue + (difference.toFloat() * percent) 134 | if (result > this.value.maxValue) { 135 | this.value.value = this.value.maxValue 136 | } else if (result < this.value.minValue) { 137 | this.value.value = this.value.minValue 138 | } else { 139 | this.value.value = result.roundToInt() 140 | } 141 | } 142 | 143 | is LongSetting -> { 144 | val result = this.value.minValue + (difference.toFloat() * percent).roundToLong() 145 | if (result > this.value.maxValue) { 146 | this.value.value = this.value.maxValue 147 | } else if (result < this.value.minValue) { 148 | this.value.value = this.value.minValue 149 | } else { 150 | this.value.value = result 151 | } 152 | } 153 | } 154 | } 155 | 156 | private fun middle(): Float { 157 | return max.toFloat() - min.toFloat() 158 | } 159 | 160 | private fun part(): Float { 161 | return (this.value.value as Number).toFloat() - min.toFloat() 162 | } 163 | 164 | private fun partialMultiplier(): Float { 165 | return part() / middle() 166 | } 167 | 168 | private fun getNoMoreThanTwoDigits(number: Double): String { 169 | val format = DecimalFormat("0.##") 170 | format.roundingMode = RoundingMode.FLOOR 171 | return format.format(number) 172 | } 173 | 174 | private fun getNoMoreThanOneDigits(number: Float): String { 175 | val format = DecimalFormat("0.#") 176 | format.roundingMode = RoundingMode.FLOOR 177 | return format.format(number) 178 | } 179 | } -------------------------------------------------------------------------------- /src/main/java/cn/origin/cube/guis/buttons/setting/StringSettingButton.kt: -------------------------------------------------------------------------------- 1 | package cn.origin.cube.guis.buttons.setting 2 | 3 | import cn.origin.cube.Cube 4 | import cn.origin.cube.guis.buttons.ModuleButton 5 | import cn.origin.cube.guis.buttons.SettingButton 6 | import cn.origin.cube.settings.StringSetting 7 | import cn.origin.cube.utils.Timer 8 | import cn.origin.cube.utils.client.ChatUtil 9 | import cn.origin.cube.utils.render.Render2DUtil 10 | import net.minecraft.util.ChatAllowedCharacters 11 | import org.lwjgl.input.Keyboard 12 | import java.awt.Color 13 | import java.util.concurrent.atomic.AtomicReference 14 | 15 | 16 | class StringSettingButton( 17 | width: Float, 18 | height: Float, 19 | value: StringSetting, 20 | father: ModuleButton 21 | ) : SettingButton(width, height, value, father) { 22 | 23 | private var inputting = false 24 | private val stringRef = AtomicReference(value.value) 25 | 26 | private var awa = false 27 | 28 | private var addText = "|" 29 | 30 | private val timer: Timer = Timer() 31 | 32 | override fun drawButton(x: Float, y: Float, mouseX: Int, mouseY: Int) { 33 | if (timer.passed(500)) { 34 | if (awa) { 35 | addText = " " 36 | awa = false 37 | } else { 38 | addText = "|" 39 | awa = true 40 | } 41 | timer.reset() 42 | } 43 | val renderString = stringRef.get() + addText 44 | Render2DUtil.drawRect(x, y, this.width, this.height, Color(15, 15, 15, 95).rgb) 45 | Cube.fontManager!!.CustomFont.drawStringWithShadow( 46 | if (inputting) renderString else ChatUtil.translateAlternateColorCodes(value.name + ": " + value.value), 47 | x + 3, 48 | y + (height / 2) - (Cube.fontManager!!.CustomFont.height / 4), 49 | Color.WHITE.rgb 50 | ) 51 | this.x = x 52 | this.y = y 53 | } 54 | 55 | 56 | private fun backspace() { 57 | val cache = stringRef.get() ?: return 58 | stringRef.set(cache.takeIf { it.isNotEmpty() }?.substring(0 until cache.length - 1) ?: "") 59 | } 60 | 61 | private operator fun AtomicReference.plusAssign(c: Char) { 62 | stringRef.set(stringRef.get() + c) 63 | } 64 | 65 | private fun setString() { 66 | value.value = stringRef.get() ?: return 67 | inputting = false 68 | } 69 | 70 | override fun mouseClicked(mouseX: Int, mouseY: Int, mouseButton: Int) { 71 | if (this.isHoveredButton(mouseX, mouseY) && mouseButton == 0 && value.isVisible && father.isShowSettings) { 72 | if (inputting) { 73 | setString() 74 | } else { 75 | inputting = true 76 | timer.reset() 77 | } 78 | } else { 79 | inputting = false 80 | setString() 81 | } 82 | } 83 | 84 | override fun keyTyped(typedChar: Char, keyCode: Int) { 85 | super.keyTyped(typedChar, keyCode) 86 | if (inputting) { 87 | when (keyCode) { 88 | Keyboard.KEY_ESCAPE -> return 89 | Keyboard.KEY_BACK -> { 90 | backspace() 91 | } 92 | 93 | Keyboard.KEY_RETURN -> { 94 | setString() 95 | } 96 | } 97 | if (ChatAllowedCharacters.isAllowedCharacter(typedChar)) { 98 | stringRef += typedChar 99 | } 100 | } 101 | } 102 | } -------------------------------------------------------------------------------- /src/main/java/cn/origin/cube/inject/ForgeCoreModsLoader.kt: -------------------------------------------------------------------------------- 1 | package cn.origin.cube.inject 2 | 3 | import cn.origin.cube.Cube 4 | import net.minecraftforge.fml.relauncher.IFMLLoadingPlugin 5 | import net.minecraftforge.fml.relauncher.IFMLLoadingPlugin.MCVersion 6 | import org.spongepowered.asm.launch.MixinBootstrap 7 | import org.spongepowered.asm.mixin.MixinEnvironment 8 | import org.spongepowered.asm.mixin.Mixins 9 | 10 | @MCVersion("1.12.2") 11 | @IFMLLoadingPlugin.Name("Cube") 12 | class ForgeCoreModsLoader : IFMLLoadingPlugin { 13 | init { 14 | MixinBootstrap.init() 15 | Mixins.addConfiguration("mixins.cube.json") 16 | MixinEnvironment.getDefaultEnvironment().obfuscationContext = "searge" 17 | Cube.logger.info(MixinEnvironment.getDefaultEnvironment().obfuscationContext) 18 | } 19 | override fun getASMTransformerClass(): Array { return arrayOfNulls(0) } 20 | override fun getModContainerClass(): String? { return null } 21 | override fun getSetupClass(): String? { return null } 22 | override fun injectData(data: Map) {} 23 | override fun getAccessTransformerClass(): String? { return null } 24 | } -------------------------------------------------------------------------------- /src/main/java/cn/origin/cube/inject/client/MixinEntityPlayerSP.java: -------------------------------------------------------------------------------- 1 | package cn.origin.cube.inject.client; 2 | 3 | import cn.origin.cube.event.events.player.UpdateWalkingPlayerEvent; 4 | import net.minecraft.client.entity.EntityPlayerSP; 5 | import net.minecraftforge.common.MinecraftForge; 6 | import org.spongepowered.asm.mixin.Mixin; 7 | import org.spongepowered.asm.mixin.injection.At; 8 | import org.spongepowered.asm.mixin.injection.Inject; 9 | import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; 10 | 11 | @Mixin(EntityPlayerSP.class) 12 | public class MixinEntityPlayerSP { 13 | 14 | @Inject(method = "onUpdateWalkingPlayer",at = @At("RETURN")) 15 | private void onUpdateWalkingPlayer(CallbackInfo ci){ 16 | UpdateWalkingPlayerEvent event = new UpdateWalkingPlayerEvent(); 17 | MinecraftForge.EVENT_BUS.post(event); 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /src/main/java/cn/origin/cube/inject/client/MixinMinecraft.java: -------------------------------------------------------------------------------- 1 | package cn.origin.cube.inject.client; 2 | 3 | import cn.origin.cube.Cube; 4 | import cn.origin.cube.event.events.client.DisplayGuiScreenEvent; 5 | import net.minecraft.client.Minecraft; 6 | import net.minecraft.client.gui.GuiScreen; 7 | import net.minecraft.crash.CrashReport; 8 | import net.minecraftforge.common.MinecraftForge; 9 | import org.spongepowered.asm.mixin.Mixin; 10 | import org.spongepowered.asm.mixin.injection.At; 11 | import org.spongepowered.asm.mixin.injection.Inject; 12 | import org.spongepowered.asm.mixin.injection.Redirect; 13 | import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; 14 | 15 | import java.util.Objects; 16 | 17 | @Mixin(Minecraft.class) 18 | public class MixinMinecraft { 19 | @Redirect(method = {"run"}, at = @At(value = "INVOKE", target = "Lnet/minecraft/client/Minecraft;displayCrashReport(Lnet/minecraft/crash/CrashReport;)V")) 20 | public void onCrashReport(Minecraft minecraft, CrashReport crashReport) { 21 | this.saveNekoConfiguration(); 22 | } 23 | 24 | @Inject(method = {"shutdown"}, at = @At(value = "HEAD")) 25 | public void shutdown(CallbackInfo info) { 26 | this.saveNekoConfiguration(); 27 | } 28 | 29 | @Inject(method = "displayGuiScreen", at = @At("HEAD"), cancellable = true) 30 | public void displayGuiScreen(GuiScreen guiScreenIn, CallbackInfo info) { 31 | DisplayGuiScreenEvent.Closed closeEvent = new DisplayGuiScreenEvent.Closed(Minecraft.getMinecraft().currentScreen); 32 | MinecraftForge.EVENT_BUS.post(closeEvent); 33 | DisplayGuiScreenEvent.Displayed displayEvent = new DisplayGuiScreenEvent.Displayed(guiScreenIn); 34 | MinecraftForge.EVENT_BUS.post(displayEvent); 35 | } 36 | 37 | public void saveNekoConfiguration() { 38 | Cube.logger.warn("Saving configuration please wait..."); 39 | Objects.requireNonNull(Cube.configManager).saveAll(); 40 | Cube.logger.warn("Configuration saved!"); 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /src/main/java/cn/origin/cube/inject/client/MixinNetworkManager.java: -------------------------------------------------------------------------------- 1 | package cn.origin.cube.inject.client; 2 | 3 | import cn.origin.cube.event.events.client.PacketEvent; 4 | import io.netty.channel.ChannelHandlerContext; 5 | import net.minecraft.network.NetworkManager; 6 | import net.minecraft.network.Packet; 7 | import net.minecraftforge.common.MinecraftForge; 8 | import org.spongepowered.asm.mixin.Mixin; 9 | import org.spongepowered.asm.mixin.injection.At; 10 | import org.spongepowered.asm.mixin.injection.Inject; 11 | import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; 12 | 13 | @Mixin(value = {NetworkManager.class}) 14 | public class MixinNetworkManager { 15 | @Inject(method = {"sendPacket(Lnet/minecraft/network/Packet;)V"}, at = {@At(value = "HEAD")}, cancellable = true) 16 | private void onSendPacketPre(Packet packet, CallbackInfo info) { 17 | PacketEvent.Send event = new PacketEvent.Send(0, packet); 18 | MinecraftForge.EVENT_BUS.post(event); 19 | if (event.isCanceled()) { 20 | info.cancel(); 21 | } 22 | } 23 | 24 | @Inject(method = {"channelRead0"}, at = {@At(value = "HEAD")}, cancellable = true) 25 | private void onChannelReadPre(ChannelHandlerContext context, Packet packet, CallbackInfo info) { 26 | PacketEvent.Receive event = new PacketEvent.Receive(0, packet); 27 | MinecraftForge.EVENT_BUS.post(event); 28 | if (event.isCanceled()) { 29 | info.cancel(); 30 | } 31 | } 32 | } -------------------------------------------------------------------------------- /src/main/java/cn/origin/cube/managers/ConfigManager.kt: -------------------------------------------------------------------------------- 1 | package cn.origin.cube.managers 2 | 3 | import cn.origin.cube.Cube 4 | import cn.origin.cube.module.AbstractModule 5 | import cn.origin.cube.settings.* 6 | import com.google.gson.Gson 7 | import com.google.gson.GsonBuilder 8 | import com.google.gson.JsonObject 9 | import java.io.File 10 | import java.nio.charset.StandardCharsets 11 | import java.nio.file.Files 12 | 13 | 14 | class ConfigManager { 15 | private val path = File(Cube.MOD_NAME) 16 | 17 | init { 18 | initModules() 19 | initFriend() 20 | initGuis() 21 | initCommand() 22 | } 23 | 24 | private fun initModules() { 25 | if (!path.exists()) { 26 | path.mkdirs() 27 | } 28 | for (module in Cube.moduleManager!!.allModuleList) { 29 | val modulePath = getModulePath(module) 30 | if (!modulePath.exists()) { 31 | saveModuleConfig(module) 32 | } else { 33 | loadModule(module) 34 | } 35 | } 36 | } 37 | 38 | private fun initFriend() { 39 | if (!path.exists()) { 40 | path.mkdirs() 41 | } 42 | val friendFile = File(path, "Friends.json") 43 | if (!friendFile.exists()) { 44 | friendFile.parentFile.mkdirs() 45 | friendFile.createNewFile() 46 | } else { 47 | val moduleJson = Gson().fromJson( 48 | String(Files.readAllBytes(friendFile.toPath()), StandardCharsets.UTF_8), 49 | ArrayList::class.java 50 | ) ?: return 51 | moduleJson.forEach { Cube.friendManager!!.add(it.toString()) } 52 | } 53 | } 54 | 55 | private fun initGuis() { 56 | if (!path.exists()) { 57 | path.mkdirs() 58 | } 59 | val guiFile = File(path, "Guis.json") 60 | if (!guiFile.exists()) { 61 | guiFile.parentFile.mkdirs() 62 | guiFile.createNewFile() 63 | val guiJson = JsonObject() 64 | guiJson.add("ClickGui", clickGuiJson()) 65 | guiJson.add("HudEditor", hudEditorJson()) 66 | Files.write( 67 | guiFile.toPath(), GsonBuilder().setPrettyPrinting().create().toJson(guiJson).toByteArray( 68 | StandardCharsets.UTF_8 69 | ) 70 | ) 71 | } else { 72 | loadClickGui() 73 | loadHudEditor() 74 | } 75 | } 76 | 77 | private fun initCommand() { 78 | if (!path.exists()) { 79 | path.mkdirs() 80 | } 81 | val commandFile = File(path, "Command.json") 82 | if (!commandFile.exists()) { 83 | commandFile.parentFile.mkdirs() 84 | commandFile.createNewFile() 85 | val commandJson = JsonObject() 86 | commandJson.addProperty("Prefix", Cube.commandPrefix) 87 | Files.write( 88 | commandFile.toPath(), GsonBuilder().setPrettyPrinting().create().toJson(commandJson).toByteArray( 89 | StandardCharsets.UTF_8 90 | ) 91 | ) 92 | } else { 93 | val commandJson = Gson().fromJson( 94 | String(Files.readAllBytes(commandFile.toPath()), StandardCharsets.UTF_8), 95 | JsonObject::class.java 96 | ) ?: return 97 | Cube.commandPrefix = commandJson.get("Prefix").asString 98 | } 99 | } 100 | 101 | private fun saveModuleConfig(module: AbstractModule) { 102 | val modulePath = getModulePath(module) 103 | if (!modulePath.exists()) { 104 | modulePath.parentFile.mkdirs() 105 | modulePath.createNewFile() 106 | } 107 | modulePath.parentFile.mkdirs() 108 | modulePath.createNewFile() 109 | val moduleJson = JsonObject() 110 | moduleJson.addProperty("Name", module.name) 111 | moduleJson.addProperty("Toggle", module.toggle) 112 | if (module.isHud) { 113 | moduleJson.addProperty("HudXPos", module.x) 114 | moduleJson.addProperty("HudYPos", module.y) 115 | moduleJson.addProperty("HudWidth", module.width) 116 | moduleJson.addProperty("HudHeight", module.height) 117 | } 118 | if (module.settingList.isNotEmpty()) { 119 | val settingObject = JsonObject() 120 | for (setting in module.settingList) { 121 | saveSetting(setting, settingObject) 122 | } 123 | moduleJson.add("Settings", settingObject) 124 | } 125 | if (module.commonSettings.isNotEmpty()) { 126 | val settingObject = JsonObject() 127 | for (setting in module.commonSettings) { 128 | saveSetting(setting, settingObject) 129 | } 130 | moduleJson.add("CommonSettings", settingObject) 131 | } 132 | Files.write( 133 | modulePath.toPath(), GsonBuilder().setPrettyPrinting().create().toJson(moduleJson).toByteArray( 134 | StandardCharsets.UTF_8 135 | ) 136 | ) 137 | } 138 | 139 | private fun loadModule(module: AbstractModule) { 140 | val modulePath = getModulePath(module) 141 | if (!modulePath.exists()) return 142 | val moduleJson = Gson().fromJson( 143 | String(Files.readAllBytes(modulePath.toPath()), StandardCharsets.UTF_8), 144 | JsonObject::class.java 145 | ) ?: return 146 | module.name = moduleJson.get("Name").asString 147 | val toggle = moduleJson.get("Toggle").asBoolean 148 | if (module.isEnabled && !toggle) { 149 | module.toggle = false 150 | } 151 | if (!module.isEnabled && toggle) { 152 | module.toggle = true 153 | } 154 | if (module.isHud) { 155 | module.x = moduleJson.get("HudXPos").asFloat 156 | module.y = moduleJson.get("HudYPos").asFloat 157 | module.width = moduleJson.get("HudWidth").asFloat 158 | module.height = moduleJson.get("HudHeight").asFloat 159 | } 160 | val element = moduleJson.get("Settings") ?: return 161 | val settingsJson = element.asJsonObject 162 | if (settingsJson != null) { 163 | for (setting in module.settingList) { 164 | setSetting(setting, settingsJson) 165 | } 166 | } 167 | val commonSettingsJson = moduleJson.get("CommonSettings").asJsonObject 168 | if (commonSettingsJson != null) { 169 | for (setting in module.commonSettings) { 170 | setSetting(setting, commonSettingsJson) 171 | } 172 | } 173 | } 174 | 175 | private fun clickGuiJson(): JsonObject { 176 | val jsonObject = JsonObject() 177 | for (panel in Cube.clickGui!!.panels) { 178 | val panelJson = JsonObject() 179 | panelJson.addProperty("IsShowModules", panel.isShowModules) 180 | panelJson.addProperty("X", panel.x) 181 | panelJson.addProperty("Y", panel.y) 182 | jsonObject.add(panel.category.getName(), panelJson) 183 | } 184 | return jsonObject 185 | } 186 | 187 | private fun hudEditorJson(): JsonObject { 188 | val jsonObject = JsonObject() 189 | for (panel in Cube.hudEditor!!.panels) { 190 | val panelJson = JsonObject() 191 | panelJson.addProperty("IsShowModules", panel.isShowModules) 192 | panelJson.addProperty("X", panel.x) 193 | panelJson.addProperty("Y", panel.y) 194 | jsonObject.add(panel.category.getName(), panelJson) 195 | } 196 | return jsonObject 197 | } 198 | 199 | private fun loadClickGui() { 200 | val guiFile = File(path, "Guis.json") 201 | if (!guiFile.exists()) return 202 | val json = Gson().fromJson( 203 | String(Files.readAllBytes(guiFile.toPath()), StandardCharsets.UTF_8), 204 | JsonObject::class.java 205 | ) ?: return 206 | val guiJson = json.get("ClickGui").asJsonObject 207 | for (panel in Cube.clickGui!!.panels) { 208 | if (guiJson.has(panel.category.getName())) { 209 | val panelJson = guiJson.get(panel.category.getName()).asJsonObject 210 | panel.isShowModules = panelJson.get("IsShowModules").asBoolean 211 | panel.x = panelJson.get("X").asFloat 212 | panel.y = panelJson.get("Y").asFloat 213 | } 214 | } 215 | } 216 | 217 | private fun loadHudEditor() { 218 | val guiFile = File(path, "Guis.json") 219 | if (!guiFile.exists()) return 220 | val json = Gson().fromJson( 221 | String(Files.readAllBytes(guiFile.toPath()), StandardCharsets.UTF_8), 222 | JsonObject::class.java 223 | ) ?: return 224 | val guiJson = json.get("HudEditor").asJsonObject 225 | for (panel in Cube.hudEditor!!.panels) { 226 | if (guiJson.has(panel.category.getName())) { 227 | val panelJson = guiJson.get(panel.category.getName()).asJsonObject 228 | panel.isShowModules = panelJson.get("IsShowModules").asBoolean 229 | panel.x = panelJson.get("X").asFloat 230 | panel.y = panelJson.get("Y").asFloat 231 | } 232 | } 233 | } 234 | 235 | private fun saveAllModules() { 236 | for (module in Cube.moduleManager!!.allModuleList) { 237 | saveModuleConfig(module) 238 | } 239 | } 240 | 241 | 242 | private fun loadAllModules() { 243 | for (module in Cube.moduleManager!!.allModuleList) { 244 | loadModule(module) 245 | } 246 | } 247 | 248 | private fun saveAllGuis() { 249 | if (!path.exists()) { 250 | path.mkdirs() 251 | } 252 | val guiFile = File(path, "Guis.json") 253 | if (!guiFile.exists()) { 254 | guiFile.parentFile.mkdirs() 255 | guiFile.createNewFile() 256 | } 257 | val guiJson = JsonObject() 258 | guiJson.add("ClickGui", clickGuiJson()) 259 | guiJson.add("HudEditor", hudEditorJson()) 260 | Files.write( 261 | guiFile.toPath(), GsonBuilder().setPrettyPrinting().create().toJson(guiJson).toByteArray( 262 | StandardCharsets.UTF_8 263 | ) 264 | ) 265 | } 266 | 267 | private fun loadAllGuis() { 268 | loadClickGui() 269 | loadHudEditor() 270 | } 271 | 272 | private fun saveFriends() { 273 | if (!path.exists()) { 274 | path.mkdirs() 275 | } 276 | val friendFile = File(path, "Friends.json") 277 | if (!friendFile.exists()) { 278 | friendFile.parentFile.mkdirs() 279 | friendFile.createNewFile() 280 | } 281 | Files.write( 282 | friendFile.toPath(), Gson().toJson(Cube.friendManager!!.getAllFriend()).toByteArray( 283 | StandardCharsets.UTF_8 284 | ) 285 | ) 286 | } 287 | 288 | private fun loadFriends() { 289 | val friendFile = File(path, "Friends.json") 290 | if (!friendFile.exists()) { 291 | return 292 | } 293 | val moduleJson = Gson().fromJson( 294 | String(Files.readAllBytes(friendFile.toPath()), StandardCharsets.UTF_8), 295 | ArrayList::class.java 296 | ) ?: return 297 | moduleJson.forEach { Cube.friendManager!!.add(it.toString()) } 298 | } 299 | 300 | fun saveCommand() { 301 | if (!path.exists()) { 302 | path.mkdirs() 303 | } 304 | val commandFile = File(path, "Command.json") 305 | if (!commandFile.exists()) { 306 | commandFile.parentFile.mkdirs() 307 | commandFile.createNewFile() 308 | } 309 | val commandJson = JsonObject() 310 | commandJson.addProperty("Prefix", Cube.commandPrefix) 311 | Files.write( 312 | commandFile.toPath(), GsonBuilder().setPrettyPrinting().create().toJson(commandJson).toByteArray( 313 | StandardCharsets.UTF_8 314 | ) 315 | ) 316 | } 317 | 318 | private fun loadCommand() { 319 | val commandFile = File(path, "Command.json") 320 | val commandJson = Gson().fromJson( 321 | String(Files.readAllBytes(commandFile.toPath()), StandardCharsets.UTF_8), 322 | JsonObject::class.java 323 | ) ?: return 324 | Cube.commandPrefix = commandJson.get("Prefix").asString 325 | } 326 | 327 | private fun saveSetting(setting: Setting<*>, jsonObject: JsonObject): JsonObject { 328 | when (setting) { 329 | is BooleanSetting -> jsonObject.addProperty(setting.name, setting.value) 330 | is BindSetting -> jsonObject.addProperty(setting.name, setting.value.keyCode) 331 | is DoubleSetting -> jsonObject.addProperty(setting.name, setting.value) 332 | is FloatSetting -> jsonObject.addProperty(setting.name, setting.value) 333 | is IntegerSetting -> jsonObject.addProperty(setting.name, setting.value) 334 | is LongSetting -> jsonObject.addProperty(setting.name, setting.value) 335 | is ModeSetting<*> -> jsonObject.addProperty(setting.name, setting.value.name) 336 | is StringSetting -> jsonObject.addProperty(setting.name, setting.value) 337 | } 338 | return jsonObject 339 | } 340 | 341 | private fun setSetting(setting: Setting<*>, jsonObject: JsonObject) { 342 | if (jsonObject.has(setting.name)) { 343 | when (setting) { 344 | is BooleanSetting -> setting.value = jsonObject.get(setting.name).asBoolean 345 | is BindSetting -> setting.value = BindSetting.KeyBind(jsonObject.get(setting.name).asInt) 346 | is DoubleSetting -> setting.value = jsonObject.get(setting.name).asDouble 347 | is FloatSetting -> setting.value = jsonObject.get(setting.name).asFloat 348 | is IntegerSetting -> setting.value = jsonObject.get(setting.name).asInt 349 | is LongSetting -> setting.value = jsonObject.get(setting.name).asLong 350 | is StringSetting -> setting.value = jsonObject.get(setting.name).asString 351 | is ModeSetting<*> -> setting.setValueByString(jsonObject.get(setting.name).asString) 352 | } 353 | } 354 | } 355 | 356 | private fun getModulePath(module: AbstractModule): File { 357 | return File("$path/modules/${module.category.name}/${module.name}.json") 358 | } 359 | 360 | fun saveAll() { 361 | saveAllModules() 362 | saveAllGuis() 363 | saveFriends() 364 | saveCommand() 365 | } 366 | 367 | fun loadAll() { 368 | loadAllModules() 369 | loadAllGuis() 370 | loadFriends() 371 | loadCommand() 372 | } 373 | } 374 | 375 | -------------------------------------------------------------------------------- /src/main/java/cn/origin/cube/managers/FriendManager.kt: -------------------------------------------------------------------------------- 1 | package cn.origin.cube.managers 2 | 3 | import cn.origin.cube.utils.client.ChatUtil 4 | import net.minecraft.entity.player.EntityPlayer 5 | 6 | class FriendManager { 7 | private val friendList = arrayListOf() 8 | fun isFriend(name: String): Boolean { 9 | return friendList.contains(name) 10 | } 11 | 12 | fun isFriend(player: EntityPlayer): Boolean { 13 | return isFriend(player.name) 14 | } 15 | 16 | fun getAllFriend(): ArrayList { 17 | return friendList 18 | } 19 | 20 | fun add(name: String) { 21 | if (!friendList.contains(name)) { 22 | friendList.add(name) 23 | ChatUtil.sendMessage("&e$name &6has been friend") 24 | } 25 | } 26 | 27 | fun add(player: EntityPlayer) { 28 | add(player.name) 29 | } 30 | 31 | fun remove(name: String) { 32 | if (friendList.contains(name)) { 33 | friendList.remove(name) 34 | ChatUtil.sendMessage("&e$name &6has been unfriend") 35 | } 36 | } 37 | 38 | fun remove(player: EntityPlayer) { 39 | remove(player.name) 40 | } 41 | } -------------------------------------------------------------------------------- /src/main/java/cn/origin/cube/module/AbstractModule.java: -------------------------------------------------------------------------------- 1 | package cn.origin.cube.module; 2 | 3 | import cn.origin.cube.event.events.world.Render3DEvent; 4 | import cn.origin.cube.settings.*; 5 | import cn.origin.cube.utils.client.ChatUtil; 6 | import net.minecraft.client.Minecraft; 7 | import net.minecraftforge.common.MinecraftForge; 8 | 9 | import java.util.ArrayList; 10 | 11 | public abstract class AbstractModule { 12 | public static final Minecraft mc = Minecraft.getMinecraft(); 13 | public String name; 14 | public String descriptions; 15 | public boolean toggle; 16 | public Category category; 17 | public boolean isHud; 18 | public float x; 19 | public float y; 20 | public float width; 21 | public float height; 22 | 23 | public final BindSetting keyBind = new BindSetting("KeyBind", new BindSetting.KeyBind(0), this); 24 | 25 | public final ArrayList> settingList = new ArrayList<>(); 26 | 27 | public final ArrayList> commonSettings = new ArrayList<>(); 28 | 29 | /** 30 | * Check world or player is null to avoid NullPointerException 31 | * 32 | * @return nullable as boolean 33 | */ 34 | public boolean fullNullCheck() { 35 | return mc.world == null || mc.player == null; 36 | } 37 | 38 | /** 39 | * when module enable runs 40 | */ 41 | public void onEnable() { 42 | } 43 | 44 | /** 45 | * when module disable runs 46 | */ 47 | public void onDisable() { 48 | } 49 | 50 | /** 51 | * when player login world runs 52 | */ 53 | public void onLogin() { 54 | } 55 | 56 | /** 57 | * when player logout world runs 58 | */ 59 | public void onLogout() { 60 | } 61 | 62 | /** 63 | * on Client Update 64 | */ 65 | public void onUpdate() { 66 | } 67 | 68 | public void onRender3D(Render3DEvent event) { 69 | } 70 | 71 | public void onRender2D() { 72 | } 73 | 74 | public void enable() { 75 | this.toggle = true; 76 | MinecraftForge.EVENT_BUS.register(this); 77 | this.onEnable(); 78 | } 79 | 80 | public void disable() { 81 | this.toggle = false; 82 | MinecraftForge.EVENT_BUS.unregister(this); 83 | this.onDisable(); 84 | } 85 | 86 | public void toggle() { 87 | if (this.toggle) { 88 | this.disable(); 89 | } else { 90 | this.enable(); 91 | } 92 | } 93 | 94 | 95 | public BooleanSetting registerSetting(String name, boolean value) { 96 | BooleanSetting setting = new BooleanSetting(name, value, this); 97 | this.settingList.add(setting); 98 | return setting; 99 | } 100 | 101 | public IntegerSetting registerSetting(String name, int currentValue, int minValue, int maxValue) { 102 | IntegerSetting setting = new IntegerSetting(name, currentValue, minValue, maxValue, this); 103 | this.settingList.add(setting); 104 | return setting; 105 | } 106 | 107 | public FloatSetting registerSetting(String name, float currentValue, float minValue, float maxValue) { 108 | FloatSetting setting = new FloatSetting(name, currentValue, minValue, maxValue, this); 109 | this.settingList.add(setting); 110 | return setting; 111 | } 112 | 113 | public DoubleSetting registerSetting(String name, double currentValue, double minValue, double maxValue) { 114 | DoubleSetting setting = new DoubleSetting(name, currentValue, minValue, maxValue, this); 115 | this.settingList.add(setting); 116 | return setting; 117 | } 118 | 119 | public LongSetting registerSetting(String name, long currentValue, long minValue, long maxValue) { 120 | LongSetting setting = new LongSetting(name, currentValue, minValue, maxValue, this); 121 | this.settingList.add(setting); 122 | return setting; 123 | } 124 | 125 | public BindSetting registerSetting(String name, BindSetting.KeyBind key) { 126 | BindSetting setting = new BindSetting(name, key, this); 127 | this.settingList.add(setting); 128 | return setting; 129 | } 130 | 131 | public StringSetting registerSetting(String name, String key) { 132 | StringSetting setting = new StringSetting(name, key, this); 133 | this.settingList.add(setting); 134 | return setting; 135 | } 136 | 137 | public > ModeSetting registerSetting(String name, Enum mode){ 138 | ModeSetting value = new ModeSetting(name,mode,this); 139 | settingList.add(value); 140 | return value; 141 | } 142 | 143 | 144 | public boolean isEnabled() { 145 | return toggle; 146 | } 147 | 148 | public String getHudInfo() { 149 | return null; 150 | } 151 | 152 | public String getFullHud() { 153 | return this.name + (getHudInfo() == null ? "" : ChatUtil.translateAlternateColorCodes(" &8[&r&l" + getHudInfo() + "&8]")); 154 | } 155 | } 156 | -------------------------------------------------------------------------------- /src/main/java/cn/origin/cube/module/Category.java: -------------------------------------------------------------------------------- 1 | package cn.origin.cube.module; 2 | 3 | import cn.origin.cube.utils.IconFontKt; 4 | 5 | public enum Category { 6 | COMBAT("Combat", IconFontKt.TARGET, false), 7 | MOVEMENT("Movement", IconFontKt.METER, false), 8 | VISUAL("Visual", IconFontKt.EYE, false), 9 | WORLD("World", IconFontKt.EARTH, false), 10 | FUNCTION("Function", IconFontKt.COGS, false), 11 | CLIENT("Client", IconFontKt.EQUALIZER, false), 12 | HUD("Hud", IconFontKt.PENCLI, true); 13 | 14 | private final String name; 15 | private final String icon; 16 | public final boolean isHud; 17 | 18 | Category(String name, String icon, boolean isHud) { 19 | this.name = name; 20 | this.icon = icon; 21 | this.isHud = isHud; 22 | } 23 | 24 | public String getName() { 25 | return name; 26 | } 27 | 28 | public String getIcon() { 29 | return icon; 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /src/main/java/cn/origin/cube/module/HudModule.java: -------------------------------------------------------------------------------- 1 | package cn.origin.cube.module; 2 | 3 | import cn.origin.cube.settings.BindSetting; 4 | 5 | public class HudModule extends AbstractModule { 6 | public HudModule() { 7 | this.name = getAnnotation().name(); 8 | this.descriptions = getAnnotation().descriptions(); 9 | this.category = getAnnotation().category(); 10 | this.keyBind.setValue(new BindSetting.KeyBind(getAnnotation().defaultKeyBind())); 11 | this.toggle = getAnnotation().defaultEnable(); 12 | this.isHud = true; 13 | this.x = getAnnotation().x(); 14 | this.y = getAnnotation().y(); 15 | this.width = getAnnotation().width(); 16 | this.height = getAnnotation().height(); 17 | 18 | this.commonSettings.add(keyBind); 19 | } 20 | 21 | private HudModuleInfo getAnnotation() { 22 | if (getClass().isAnnotationPresent(HudModuleInfo.class)) { 23 | return getClass().getAnnotation(HudModuleInfo.class); 24 | } 25 | throw new IllegalStateException("No Annotation on class " + this.getClass().getCanonicalName() + "!"); 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /src/main/java/cn/origin/cube/module/HudModuleInfo.java: -------------------------------------------------------------------------------- 1 | package cn.origin.cube.module; 2 | 3 | import java.lang.annotation.Retention; 4 | import java.lang.annotation.RetentionPolicy; 5 | 6 | @Retention(RetentionPolicy.RUNTIME) 7 | public @interface HudModuleInfo { 8 | String name(); 9 | 10 | String descriptions(); 11 | 12 | Category category(); 13 | 14 | int defaultKeyBind() default 0; 15 | 16 | boolean defaultEnable() default false; 17 | 18 | float x(); 19 | 20 | float y(); 21 | 22 | float width() default 0.0f; 23 | 24 | float height() default 0.0f; 25 | } 26 | -------------------------------------------------------------------------------- /src/main/java/cn/origin/cube/module/Module.java: -------------------------------------------------------------------------------- 1 | package cn.origin.cube.module; 2 | 3 | import cn.origin.cube.settings.BindSetting; 4 | import cn.origin.cube.settings.BooleanSetting; 5 | 6 | public class Module extends AbstractModule { 7 | 8 | public BooleanSetting visible = new BooleanSetting("Visible", true, this); 9 | 10 | public Module() { 11 | this.name = getAnnotation().name(); 12 | this.descriptions = getAnnotation().descriptions(); 13 | this.category = getAnnotation().category(); 14 | this.keyBind.setValue(new BindSetting.KeyBind(getAnnotation().defaultKeyBind())); 15 | this.toggle = getAnnotation().defaultEnable(); 16 | this.isHud = false; 17 | 18 | this.settingList.add(visible); 19 | this.commonSettings.add(keyBind); 20 | } 21 | 22 | private ModuleInfo getAnnotation() { 23 | if (getClass().isAnnotationPresent(ModuleInfo.class)) { 24 | return getClass().getAnnotation(ModuleInfo.class); 25 | } 26 | throw new IllegalStateException("No Annotation on class " + this.getClass().getCanonicalName() + "!"); 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /src/main/java/cn/origin/cube/module/ModuleInfo.java: -------------------------------------------------------------------------------- 1 | package cn.origin.cube.module; 2 | 3 | import java.lang.annotation.Retention; 4 | import java.lang.annotation.RetentionPolicy; 5 | 6 | @Retention(RetentionPolicy.RUNTIME) 7 | public @interface ModuleInfo { 8 | String name(); 9 | 10 | String descriptions(); 11 | 12 | Category category(); 13 | 14 | int defaultKeyBind() default 0; 15 | 16 | boolean defaultEnable() default false; 17 | } 18 | -------------------------------------------------------------------------------- /src/main/java/cn/origin/cube/module/ModuleManager.kt: -------------------------------------------------------------------------------- 1 | package cn.origin.cube.module 2 | 3 | import cn.origin.cube.event.events.world.Render3DEvent 4 | import cn.origin.cube.module.huds.ModuleArrayList 5 | import cn.origin.cube.module.huds.WaterMark 6 | import cn.origin.cube.module.modules.client.ClickGui 7 | import cn.origin.cube.module.modules.client.HudEditor 8 | import cn.origin.cube.module.modules.combat.KillAura 9 | import cn.origin.cube.module.modules.combat.Surround 10 | import cn.origin.cube.module.modules.function.FakeKick 11 | import cn.origin.cube.module.modules.function.MiddleClick 12 | import cn.origin.cube.module.modules.function.NoRotate 13 | import cn.origin.cube.module.modules.movement.AutoWalk 14 | import cn.origin.cube.module.modules.movement.Sprint 15 | import cn.origin.cube.module.modules.visual.BlockHighlight 16 | import cn.origin.cube.module.modules.visual.FullBright 17 | import cn.origin.cube.module.modules.world.AutoRespawn 18 | import cn.origin.cube.module.modules.world.FakePlayer 19 | 20 | class ModuleManager { 21 | var allModuleList = ArrayList() 22 | var moduleList = ArrayList() 23 | var hudList = ArrayList() 24 | 25 | init { 26 | //Client 27 | registerModule(ClickGui()) 28 | registerModule(HudEditor()) 29 | 30 | //Combat 31 | registerModule(Surround()) 32 | registerModule(KillAura()) 33 | 34 | //Function 35 | registerModule(MiddleClick()) 36 | registerModule(FakeKick()) 37 | registerModule(NoRotate()) 38 | 39 | //Movement 40 | registerModule(Sprint()) 41 | registerModule(AutoWalk()) 42 | 43 | //Visual 44 | registerModule(FullBright()) 45 | registerModule(BlockHighlight()) 46 | 47 | //World 48 | registerModule(FakePlayer()) 49 | registerModule(AutoRespawn()) 50 | 51 | //Hud 52 | registerModule(WaterMark()) 53 | registerModule(ModuleArrayList()) 54 | 55 | } 56 | 57 | private fun registerModule(module: AbstractModule) { 58 | if (!allModuleList.contains(module)) allModuleList.add(module) 59 | if (module.isHud) { 60 | if (!hudList.contains(module)) hudList.add(module as HudModule) 61 | } else if (!moduleList.contains(module)) { 62 | moduleList.add(module as Module) 63 | } 64 | } 65 | 66 | fun getModulesByCategory(category: Category): List { 67 | return allModuleList.filter { it.category == category } 68 | } 69 | 70 | fun getModuleByClass(clazz: Class<*>): AbstractModule? { 71 | for (abstractModule in allModuleList) { 72 | if (abstractModule::class.java == clazz) return abstractModule 73 | } 74 | return null 75 | } 76 | 77 | 78 | fun getModuleByName(name: String): AbstractModule? { 79 | for (abstractModule in allModuleList) { 80 | if (abstractModule.name.lowercase() == name.lowercase()) return abstractModule 81 | } 82 | return null 83 | } 84 | 85 | fun onUpdate() { 86 | allModuleList.filter { it.isEnabled }.forEach { it.onUpdate() } 87 | } 88 | 89 | fun onLogin() { 90 | allModuleList.filter { it.isEnabled }.forEach { it.onLogin() } 91 | } 92 | 93 | fun onLogout() { 94 | allModuleList.filter { it.isEnabled }.forEach { it.onLogout() } 95 | } 96 | 97 | fun onRender3D(event: Render3DEvent) { 98 | allModuleList.filter { it.isEnabled }.forEach { it.onRender3D(event) } 99 | } 100 | 101 | fun onRender2D() { 102 | allModuleList.filter { it.isEnabled }.forEach { it.onRender2D() } 103 | } 104 | } -------------------------------------------------------------------------------- /src/main/java/cn/origin/cube/module/huds/ModuleArrayList.java: -------------------------------------------------------------------------------- 1 | package cn.origin.cube.module.huds; 2 | 3 | import cn.origin.cube.Cube; 4 | import cn.origin.cube.module.*; 5 | import cn.origin.cube.module.modules.client.ClickGui; 6 | import cn.origin.cube.settings.ModeSetting; 7 | 8 | import java.util.Comparator; 9 | import java.util.stream.Collectors; 10 | 11 | @HudModuleInfo(name = "ModuleArrayList", descriptions = "Show all enable module", category = Category.HUD, y = 100, x = 100) 12 | public class ModuleArrayList extends HudModule { 13 | 14 | public ModeSetting alignSetting = registerSetting("Align", alignMode.Left); 15 | public ModeSetting sortSetting = registerSetting("Sort", sortMode.Top); 16 | public int count = 0; 17 | 18 | @Override 19 | public void onRender2D() { 20 | count = 0; 21 | Cube.moduleManager.getModuleList().stream() 22 | .filter(AbstractModule::isEnabled) 23 | .filter(module -> module.visible.getValue()) 24 | .sorted(Comparator.comparing(module -> Cube.fontManager.CustomFont.getStringWidth(module.getFullHud()) 25 | * (sortSetting.getValue().equals(sortMode.Bottom) ? 1 : -1))) 26 | .forEach(module -> { 27 | float modWidth = Cube.fontManager.CustomFont.getStringWidth(module.getFullHud()); 28 | String modText = module.getFullHud(); 29 | if (alignMode.Right.equals(alignSetting.getValue())) { 30 | Cube.fontManager.CustomFont.drawStringWithShadow(modText, 31 | (int) (this.x - 2 - modWidth + this.width), 32 | this.y + (10 * count), 33 | ClickGui.getCurrentColor().getRGB()); 34 | } else { 35 | Cube.fontManager.CustomFont.drawStringWithShadow(modText, 36 | this.x - 2, 37 | this.y + (10 * count), 38 | ClickGui.getCurrentColor().getRGB()); 39 | } 40 | count++; 41 | }); 42 | width = Cube.moduleManager.getModuleList().stream() 43 | .filter(AbstractModule::isEnabled) 44 | .noneMatch(module -> module.visible.getValue()) ? 20 : 45 | Cube.fontManager.CustomFont.getStringWidth(Cube.moduleManager.getModuleList() 46 | .stream().filter(AbstractModule::isEnabled) 47 | .filter(module -> module.visible.getValue()) 48 | .sorted(Comparator.comparing(module -> Cube.fontManager.CustomFont.getStringWidth(module.getFullHud()) * (-1))) 49 | .collect(Collectors.toList()).get(0).getFullHud()); 50 | height = ((Cube.fontManager.CustomFont.getHeight() + 1) * 51 | (int) Cube.moduleManager.getModuleList().stream() 52 | .filter(AbstractModule::isEnabled).count()); 53 | } 54 | 55 | enum alignMode { 56 | Left, 57 | Right 58 | } 59 | 60 | enum sortMode { 61 | Top, 62 | Bottom 63 | } 64 | } 65 | -------------------------------------------------------------------------------- /src/main/java/cn/origin/cube/module/huds/WaterMark.java: -------------------------------------------------------------------------------- 1 | package cn.origin.cube.module.huds; 2 | 3 | import cn.origin.cube.Cube; 4 | import cn.origin.cube.module.Category; 5 | import cn.origin.cube.module.HudModule; 6 | import cn.origin.cube.module.HudModuleInfo; 7 | import cn.origin.cube.module.modules.client.ClickGui; 8 | import cn.origin.cube.settings.FloatSetting; 9 | import org.lwjgl.opengl.GL11; 10 | 11 | @HudModuleInfo(name = "WaterMark", x = 114, y = 114, descriptions = "Show hack name", category = Category.HUD) 12 | public class WaterMark extends HudModule { 13 | public FloatSetting Scala = registerSetting("Size", 1.0f, 0.0f, 3.0f); 14 | 15 | @Override 16 | public void onRender2D() { 17 | GL11.glPushMatrix(); 18 | GL11.glTranslated(this.x, (float) this.y, 0); 19 | GL11.glScaled((double) this.Scala.getValue(), (double) this.Scala.getValue(), 0.0); 20 | Cube.fontManager.CustomFont.drawString("Cube Base", 0, 0, ClickGui.getCurrentColor().getRGB()); 21 | GL11.glPopMatrix(); 22 | this.width = (int) ((float) Cube.fontManager.CustomFont.getStringWidth("Cube Base") * this.Scala.getValue()); 23 | this.height = (int) ((float) Cube.fontManager.CustomFont.getHeight() * this.Scala.getValue()); 24 | } 25 | 26 | } 27 | -------------------------------------------------------------------------------- /src/main/java/cn/origin/cube/module/modules/client/ChatSuffix.java: -------------------------------------------------------------------------------- 1 | package cn.origin.cube.module.modules.client; 2 | 3 | import cn.origin.cube.Cube; 4 | import cn.origin.cube.event.events.client.PacketEvent; 5 | import cn.origin.cube.module.Category; 6 | import cn.origin.cube.module.Module; 7 | import cn.origin.cube.module.ModuleInfo; 8 | import net.minecraft.network.play.client.CPacketChatMessage; 9 | import net.minecraftforge.fml.common.eventhandler.SubscribeEvent; 10 | 11 | @ModuleInfo(name = "ChatSuffix", descriptions = "Chat suffix", category = Category.CLIENT) 12 | public class ChatSuffix extends Module { 13 | 14 | @SubscribeEvent 15 | public void onPacketSend(PacketEvent.Send event) { 16 | if (event.getStage() == 0) { 17 | if (event.getPacket() instanceof CPacketChatMessage) { 18 | String s = ((CPacketChatMessage) event.getPacket()).getMessage(); 19 | if (s.startsWith("/")) return; 20 | s += " | " + Cube.MOD_NAME + " " + Cube.MOD_VERSION; 21 | if (s.length() >= 256) s = s.substring(0, 256); 22 | ((CPacketChatMessage) event.getPacket()).message = s; 23 | } 24 | } 25 | } 26 | } -------------------------------------------------------------------------------- /src/main/java/cn/origin/cube/module/modules/client/ClickGui.java: -------------------------------------------------------------------------------- 1 | package cn.origin.cube.module.modules.client; 2 | 3 | import cn.origin.cube.Cube; 4 | import cn.origin.cube.guis.ClickGuiScreen; 5 | import cn.origin.cube.managers.ConfigManager; 6 | import cn.origin.cube.module.Category; 7 | import cn.origin.cube.module.Module; 8 | import cn.origin.cube.module.ModuleInfo; 9 | import cn.origin.cube.settings.BooleanSetting; 10 | import cn.origin.cube.settings.FloatSetting; 11 | import cn.origin.cube.settings.IntegerSetting; 12 | import cn.origin.cube.settings.StringSetting; 13 | import org.lwjgl.input.Keyboard; 14 | 15 | import java.awt.*; 16 | 17 | @ModuleInfo(name = "ClickGui", descriptions = "open click gui screen", category = Category.CLIENT, defaultKeyBind = Keyboard.KEY_RSHIFT) 18 | public final class ClickGui extends Module { 19 | public BooleanSetting rainbow = registerSetting("Rainbow", false); 20 | public IntegerSetting red = registerSetting("Red", 25, 0, 255).booleanDisVisible(rainbow); 21 | public IntegerSetting green = registerSetting("Green", 115, 0, 255).booleanDisVisible(rainbow); 22 | public IntegerSetting blue = registerSetting("Blue", 255, 0, 255).booleanDisVisible(rainbow); 23 | public FloatSetting speed = registerSetting("RainbowSpeed", 1.0f, 0.1f, 10.0f).booleanVisible(rainbow); 24 | public FloatSetting saturation = registerSetting("Saturation", 0.65f, 0.0f, 1.0f).booleanVisible(rainbow); 25 | public FloatSetting brightness = registerSetting("Brightness", 1.0f, 0.0f, 1.0f).booleanVisible(rainbow); 26 | 27 | public static ClickGui INSTANCE; 28 | 29 | public ClickGui() { 30 | INSTANCE = this; 31 | } 32 | 33 | public void onEnable() { 34 | if (!this.fullNullCheck() && !(Module.mc.currentScreen instanceof ClickGuiScreen)) { 35 | Module.mc.displayGuiScreen(Cube.clickGui); 36 | } 37 | 38 | } 39 | 40 | public void onDisable() { 41 | if (!this.fullNullCheck() && Module.mc.currentScreen instanceof ClickGuiScreen) { 42 | Module.mc.displayGuiScreen(null); 43 | ConfigManager configManager = Cube.configManager; 44 | configManager.saveAll(); 45 | } 46 | } 47 | 48 | public static Color getRainbow() { 49 | float hue = (float) (System.currentTimeMillis() % 11520L) / 11520.0f * INSTANCE.speed.getValue(); 50 | return new Color(Color.HSBtoRGB(hue, INSTANCE.saturation.getValue(), INSTANCE.brightness.getValue())); 51 | } 52 | 53 | public static Color getCurrentColor() { 54 | return INSTANCE.rainbow.getValue() ? getRainbow() : new Color(INSTANCE.red.getValue(), INSTANCE.green.getValue(), INSTANCE.blue.getValue()); 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /src/main/java/cn/origin/cube/module/modules/client/HudEditor.java: -------------------------------------------------------------------------------- 1 | package cn.origin.cube.module.modules.client; 2 | 3 | import cn.origin.cube.Cube; 4 | import cn.origin.cube.guis.HudEditorScreen; 5 | import cn.origin.cube.managers.ConfigManager; 6 | import cn.origin.cube.module.Category; 7 | import cn.origin.cube.module.Module; 8 | import cn.origin.cube.module.ModuleInfo; 9 | import org.lwjgl.input.Keyboard; 10 | 11 | @ModuleInfo( 12 | name = "HudEditor", 13 | descriptions = "open Hud screen", 14 | category = Category.CLIENT, 15 | defaultKeyBind = Keyboard.KEY_GRAVE 16 | ) 17 | public class HudEditor extends Module { 18 | 19 | public static HudEditor INSTANCE; 20 | 21 | public HudEditor() { 22 | INSTANCE = this; 23 | } 24 | 25 | public void onEnable() { 26 | if (!this.fullNullCheck() && !(Module.mc.currentScreen instanceof HudEditorScreen)) { 27 | Module.mc.displayGuiScreen(Cube.hudEditor); 28 | } 29 | } 30 | 31 | public void onDisable() { 32 | if (!this.fullNullCheck() && Module.mc.currentScreen instanceof HudEditorScreen) { 33 | Module.mc.displayGuiScreen(null); 34 | ConfigManager configManager = Cube.configManager; 35 | configManager.saveAll(); 36 | } 37 | 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /src/main/java/cn/origin/cube/module/modules/combat/KillAura.java: -------------------------------------------------------------------------------- 1 | package cn.origin.cube.module.modules.combat; 2 | 3 | import cn.origin.cube.Cube; 4 | import cn.origin.cube.event.events.player.UpdateWalkingPlayerEvent; 5 | import cn.origin.cube.module.Category; 6 | import cn.origin.cube.module.Module; 7 | import cn.origin.cube.module.ModuleInfo; 8 | import cn.origin.cube.settings.BooleanSetting; 9 | import cn.origin.cube.settings.DoubleSetting; 10 | import cn.origin.cube.settings.ModeSetting; 11 | import cn.origin.cube.utils.player.InventoryUtil; 12 | import cn.origin.cube.utils.player.RotationUtil; 13 | import net.minecraft.entity.Entity; 14 | import net.minecraft.entity.EntityLivingBase; 15 | import net.minecraft.entity.player.EntityPlayer; 16 | import net.minecraft.item.ItemAxe; 17 | import net.minecraft.item.ItemStack; 18 | import net.minecraft.item.ItemSword; 19 | import net.minecraft.network.play.client.CPacketUseEntity; 20 | import net.minecraft.util.EnumHand; 21 | import net.minecraft.util.math.Vec3d; 22 | import net.minecraftforge.fml.common.eventhandler.SubscribeEvent; 23 | 24 | @ModuleInfo(name = "KillAura", descriptions = "Auto attack entity", category = Category.COMBAT) 25 | public class KillAura extends Module { 26 | DoubleSetting hittingRange = registerSetting("Range", 5.5, 0.1, 10.0); 27 | BooleanSetting hitDelay = registerSetting("HitDelay", true); 28 | BooleanSetting packet = registerSetting("PacketHit", false); 29 | BooleanSetting swimArm = registerSetting("SwimArm", true).booleanVisible(packet); 30 | BooleanSetting rotate = registerSetting("Rotate", true); 31 | 32 | BooleanSetting playerOnly = registerSetting("PlayerOnly", true); 33 | BooleanSetting weaponOnly = registerSetting("WeaponOnly", true); 34 | BooleanSetting switchWeapon = registerSetting("SwitchWeapon", false); 35 | ModeSetting weaponCurrent = registerSetting("CurrentWeapon", currentW.NONE).boolean2NVisible(switchWeapon, weaponOnly); 36 | 37 | @SubscribeEvent 38 | public void onUpdateWalkingPlayer(UpdateWalkingPlayerEvent event) { 39 | boolean isReadyAttack = mc.player.getCooledAttackStrength(0.0f) >= 1; 40 | if (hitDelay.getValue()) { 41 | if (!isReadyAttack) return; 42 | } 43 | mc.world.loadedEntityList.stream() 44 | .filter(entity -> entity instanceof EntityLivingBase) 45 | .filter(entity -> mc.player.getDistance(entity) <= hittingRange.getValue()) 46 | .filter(entity -> !Cube.friendManager.isFriend(entity.getName())) 47 | .filter(entity -> entity != mc.player) 48 | .forEach(target -> { 49 | if (playerOnly.getValue()) { 50 | if (!(target instanceof EntityPlayer)) return; 51 | } 52 | if (switchWeapon.getValue()) { 53 | int currentSlot; 54 | if (currentW.SWORD.equals(weaponCurrent.getValue())) { 55 | if ((currentSlot = InventoryUtil.findHotbarItem(ItemSword.class)) != -1) { 56 | InventoryUtil.switchToHotbarSlot(currentSlot, false); 57 | } 58 | } else if (currentW.AXE.equals(weaponCurrent.getValue())) { 59 | if ((currentSlot = InventoryUtil.findHotbarItem(ItemAxe.class)) != -1) { 60 | InventoryUtil.switchToHotbarSlot(currentSlot, false); 61 | } 62 | } 63 | } 64 | if (rotate.getValue()) rotateTo(target); 65 | if (!weaponCurrent.getValue().equals(currentW.NONE)) { 66 | if (mc.player.getHeldItemMainhand() == ItemStack.EMPTY 67 | || !(weaponCurrent.getValue().equals(currentW.AXE) ? ItemAxe.class : ItemSword.class) 68 | .isInstance(mc.player.getHeldItemMainhand().getItem())) { 69 | return; 70 | } 71 | } 72 | attack(target); 73 | }); 74 | 75 | } 76 | 77 | public void rotateTo(Entity target) { 78 | RotationUtil.faceVector(new Vec3d(target.posX, target.posY + 1, target.posZ), true); 79 | } 80 | 81 | public void attack(Entity entity) { 82 | if (packet.getValue()) { 83 | mc.playerController.connection.sendPacket(new CPacketUseEntity(entity)); 84 | if (swimArm.getValue()) mc.player.swingArm(EnumHand.MAIN_HAND); 85 | } else { 86 | mc.playerController.attackEntity(mc.player, entity); 87 | } 88 | } 89 | 90 | enum currentW { 91 | NONE, 92 | SWORD, 93 | AXE 94 | } 95 | 96 | } 97 | -------------------------------------------------------------------------------- /src/main/java/cn/origin/cube/module/modules/combat/Surround.java: -------------------------------------------------------------------------------- 1 | package cn.origin.cube.module.modules.combat; 2 | 3 | import cn.origin.cube.event.events.player.UpdateWalkingPlayerEvent; 4 | import cn.origin.cube.module.Category; 5 | import cn.origin.cube.module.Module; 6 | import cn.origin.cube.module.ModuleInfo; 7 | import cn.origin.cube.settings.BooleanSetting; 8 | import cn.origin.cube.utils.player.BlockUtil; 9 | import cn.origin.cube.utils.player.InventoryUtil; 10 | import net.minecraft.block.BlockObsidian; 11 | import net.minecraft.util.EnumHand; 12 | import net.minecraft.util.math.BlockPos; 13 | import net.minecraftforge.fml.common.eventhandler.SubscribeEvent; 14 | 15 | @ModuleInfo(name = "Surround", descriptions = "Auto place block surround feet", category = Category.COMBAT) 16 | public class Surround extends Module { 17 | public static BlockPos[] surroundPos = new BlockPos[]{ 18 | new BlockPos(0, -1, 0), 19 | new BlockPos(1, -1, 0), 20 | new BlockPos(-1, -1, 0), 21 | new BlockPos(0, -1, 1), 22 | new BlockPos(0, -1, -1), 23 | new BlockPos(1, 0, 0), 24 | new BlockPos(-1, 0, 0), 25 | new BlockPos(0, 0, 1), 26 | new BlockPos(0, 0, -1), 27 | }; 28 | public int slot; 29 | public int oldslot; 30 | public BlockPos startPos; 31 | public BooleanSetting packet = registerSetting("Packet", true); 32 | public BooleanSetting rot = registerSetting("Rotate", false); 33 | public BlockPos newPos2; 34 | 35 | @Override 36 | public void onEnable() { 37 | if (fullNullCheck()) return; 38 | startPos = new BlockPos(Math.floor(mc.player.posX), Math.floor(mc.player.posY), Math.floor(mc.player.posZ)); 39 | } 40 | 41 | 42 | @SubscribeEvent 43 | public void onUpdate(UpdateWalkingPlayerEvent event) { 44 | if (fullNullCheck()) { 45 | this.toggle(); 46 | return; 47 | } 48 | slot = InventoryUtil.findHotbarBlock(BlockObsidian.class); 49 | oldslot = mc.player.inventory.currentItem; 50 | if (startPos != null) { 51 | if (!startPos.equals(new BlockPos(Math.floor(mc.player.posX), Math.floor(mc.player.posY), Math.floor(mc.player.posZ)))) { 52 | this.toggle(); 53 | return; 54 | } 55 | } 56 | if (slot == -1) { 57 | toggle(); 58 | return; 59 | } 60 | for (BlockPos pos : surroundPos) { 61 | newPos2 = addPos(pos); 62 | if (slot == -1) this.toggle(); 63 | InventoryUtil.switchToHotbarSlot(slot, false); 64 | BlockUtil.placeBlock(newPos2, EnumHand.MAIN_HAND, rot.getValue(), packet.getValue()); 65 | InventoryUtil.switchToHotbarSlot(oldslot, false); 66 | } 67 | } 68 | 69 | public BlockPos addPos(BlockPos pos) { 70 | BlockPos pPos = new BlockPos(mc.player); 71 | return new BlockPos(pPos.getX() + pos.getX(), pPos.getY() + pos.getY(), pPos.getZ() + pos.getZ()); 72 | } 73 | } 74 | -------------------------------------------------------------------------------- /src/main/java/cn/origin/cube/module/modules/function/FakeKick.java: -------------------------------------------------------------------------------- 1 | package cn.origin.cube.module.modules.function; 2 | 3 | import cn.origin.cube.module.Category; 4 | import cn.origin.cube.module.Module; 5 | import cn.origin.cube.module.ModuleInfo; 6 | import cn.origin.cube.settings.StringSetting; 7 | import cn.origin.cube.utils.client.ChatUtil; 8 | import net.minecraft.util.text.TextComponentString; 9 | 10 | @ModuleInfo(name = "FakeKick", descriptions = "Disconnection form server", category = Category.FUNCTION) 11 | public class FakeKick extends Module { 12 | 13 | StringSetting msg = registerSetting("KickMessage", "&c&lYou has been banned form server!"); 14 | 15 | @Override 16 | public void onEnable() { 17 | if (!mc.isSingleplayer()) { 18 | mc.player.connection.getNetworkManager().closeChannel(new TextComponentString(ChatUtil.translateAlternateColorCodes(msg.getValue()))); 19 | } else { 20 | ChatUtil.sendMessage("&cCouldn't use it in SinglePlayer!"); 21 | } 22 | this.disable(); 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /src/main/java/cn/origin/cube/module/modules/function/MiddleClick.kt: -------------------------------------------------------------------------------- 1 | package cn.origin.cube.module.modules.function 2 | 3 | import cn.origin.cube.Cube 4 | import cn.origin.cube.module.Category 5 | import cn.origin.cube.module.Module 6 | import cn.origin.cube.module.ModuleInfo 7 | import cn.origin.cube.settings.ModeSetting 8 | import cn.origin.cube.utils.player.InventoryUtil 9 | import net.minecraft.entity.player.EntityPlayer 10 | import net.minecraft.init.Items 11 | import net.minecraft.item.ItemEnderPearl 12 | import net.minecraft.util.EnumHand 13 | import net.minecraft.util.math.RayTraceResult 14 | import org.lwjgl.input.Mouse 15 | 16 | @ModuleInfo(name = "MiddleClick", descriptions = "Click mouse middle button", category = Category.FUNCTION) 17 | class MiddleClick : Module() { 18 | private var mode: ModeSetting = registerSetting("Mode", clickType.ENDRPEARL) 19 | private var clicked = false 20 | override fun onUpdate() { 21 | if (mode.value == clickType.FRIEND) { 22 | if (mc.currentScreen == null) { 23 | if (Mouse.isButtonDown(2)) { 24 | if (!clicked) { 25 | val result = mc.objectMouseOver 26 | if (result != null && result.typeOfHit == RayTraceResult.Type.ENTITY) { 27 | val entity = result.entityHit 28 | if (entity is EntityPlayer) { 29 | val name = entity.getName() 30 | if (Cube.friendManager!!.isFriend(name)) { 31 | Cube.friendManager!!.remove(name) 32 | } else { 33 | Cube.friendManager!!.add(name) 34 | } 35 | } 36 | } 37 | } 38 | clicked = true 39 | } else { 40 | clicked = false 41 | } 42 | } 43 | } else { 44 | val oldSlot = mc.player.inventory.currentItem 45 | if (Mouse.isButtonDown(2)) { 46 | val var2 = mc.objectMouseOver 47 | if (var2.typeOfHit != RayTraceResult.Type.ENTITY && var2.typeOfHit != RayTraceResult.Type.BLOCK) { 48 | val p = InventoryUtil.findHotbarItem(ItemEnderPearl::class.java) 49 | if (p == -1) { 50 | return 51 | } 52 | InventoryUtil.switchToHotbarSlot(p, false) 53 | try { 54 | mc.playerController.processRightClick( 55 | mc.player, 56 | mc.world, 57 | if (mc.player.heldItemOffhand.item === Items.ENDER_PEARL) EnumHand.OFF_HAND else EnumHand.MAIN_HAND 58 | ) 59 | } catch (ignored: Exception) { 60 | } 61 | InventoryUtil.switchToHotbarSlot(oldSlot, false) 62 | } 63 | } 64 | } 65 | } 66 | 67 | enum class clickType { 68 | FRIEND, ENDRPEARL 69 | } 70 | } -------------------------------------------------------------------------------- /src/main/java/cn/origin/cube/module/modules/function/NoRotate.java: -------------------------------------------------------------------------------- 1 | package cn.origin.cube.module.modules.function; 2 | 3 | import cn.origin.cube.event.events.client.PacketEvent; 4 | import cn.origin.cube.module.Category; 5 | import cn.origin.cube.module.Module; 6 | import cn.origin.cube.module.ModuleInfo; 7 | import net.minecraft.network.play.server.SPacketPlayerPosLook; 8 | import net.minecraftforge.fml.common.eventhandler.SubscribeEvent; 9 | 10 | @ModuleInfo(name = "NoRotate", descriptions = "Dangerous to use might desync you.", category = Category.FUNCTION) 11 | public class NoRotate extends Module { 12 | private boolean cancelPackets = true; 13 | private boolean timerReset = false; 14 | 15 | @Override 16 | public void onUpdate() { 17 | if (this.timerReset && !this.cancelPackets) { 18 | this.cancelPackets = true; 19 | this.timerReset = false; 20 | } 21 | } 22 | 23 | @SubscribeEvent 24 | public void onPacketReceive(PacketEvent.Receive event) { 25 | if (fullNullCheck()) return; 26 | if (event.getStage() == 0 && this.cancelPackets && event.getPacket() instanceof SPacketPlayerPosLook) { 27 | SPacketPlayerPosLook packet = event.getPacket(); 28 | packet.yaw = NoRotate.mc.player.rotationYaw; 29 | packet.pitch = NoRotate.mc.player.rotationPitch; 30 | } 31 | } 32 | } 33 | 34 | -------------------------------------------------------------------------------- /src/main/java/cn/origin/cube/module/modules/movement/AutoWalk.java: -------------------------------------------------------------------------------- 1 | package cn.origin.cube.module.modules.movement; 2 | 3 | import cn.origin.cube.module.Category; 4 | import cn.origin.cube.module.Module; 5 | import cn.origin.cube.module.ModuleInfo; 6 | import net.minecraftforge.client.event.InputUpdateEvent; 7 | import net.minecraftforge.fml.common.eventhandler.SubscribeEvent; 8 | 9 | @ModuleInfo(name = "AutoWalk", descriptions = "Auto move forward", category = Category.MOVEMENT) 10 | public class AutoWalk extends Module { 11 | @SubscribeEvent 12 | public void onUpdateInput(InputUpdateEvent event) { 13 | event.getMovementInput().moveForward = 1.0f; 14 | } 15 | } 16 | 17 | -------------------------------------------------------------------------------- /src/main/java/cn/origin/cube/module/modules/movement/Sprint.java: -------------------------------------------------------------------------------- 1 | package cn.origin.cube.module.modules.movement; 2 | 3 | import cn.origin.cube.module.Category; 4 | import cn.origin.cube.module.Module; 5 | import cn.origin.cube.module.ModuleInfo; 6 | import cn.origin.cube.settings.BooleanSetting; 7 | 8 | @ModuleInfo(name = "Sprint", descriptions = "Always run fast", category = Category.MOVEMENT) 9 | public class Sprint extends Module { 10 | 11 | public BooleanSetting Legit = registerSetting("Legit", false); 12 | 13 | @Override 14 | public void onUpdate() { 15 | if (fullNullCheck() || mc.player.isElytraFlying() || mc.player.capabilities.isFlying) { 16 | return; 17 | } 18 | if (Legit.getValue()) { 19 | try { 20 | mc.player.setSprinting(!mc.player.collidedHorizontally && mc.player.moveForward > 0); 21 | } catch (Exception ignored) { 22 | } 23 | } else { 24 | if (mc.player.moveForward != 0.0 || mc.player.moveStrafing != 0.0) { 25 | mc.player.setSprinting(true); 26 | } 27 | } 28 | } 29 | 30 | @Override 31 | public String getHudInfo() { 32 | return Legit.getValue() ? "Legit" : "Normal"; 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /src/main/java/cn/origin/cube/module/modules/visual/BlockHighlight.java: -------------------------------------------------------------------------------- 1 | package cn.origin.cube.module.modules.visual; 2 | 3 | import cn.origin.cube.event.events.world.Render3DEvent; 4 | import cn.origin.cube.module.Category; 5 | import cn.origin.cube.module.Module; 6 | import cn.origin.cube.module.ModuleInfo; 7 | import cn.origin.cube.module.modules.client.ClickGui; 8 | import cn.origin.cube.settings.BooleanSetting; 9 | import cn.origin.cube.settings.FloatSetting; 10 | import cn.origin.cube.settings.IntegerSetting; 11 | import cn.origin.cube.utils.render.Render3DUtil; 12 | import net.minecraft.block.material.Material; 13 | import net.minecraft.client.Minecraft; 14 | import net.minecraft.util.math.BlockPos; 15 | import net.minecraft.util.math.RayTraceResult; 16 | 17 | import java.awt.*; 18 | 19 | @ModuleInfo(name = "BlockHighlight", descriptions = "Render current block", category = Category.VISUAL) 20 | public class BlockHighlight extends Module { 21 | private final BooleanSetting outline = registerSetting("Outline", true); 22 | private final BooleanSetting full = registerSetting("FullBlock", true); 23 | private final FloatSetting width = registerSetting("OutlineWidth", 1.5f, 0.0f, 10.0f).booleanVisible(outline); 24 | 25 | private final IntegerSetting alpha = registerSetting("Alpha", 55, 0, 255).booleanVisible(full); 26 | 27 | @Override 28 | public void onRender3D(Render3DEvent event) { 29 | if (fullNullCheck()) return; 30 | BlockPos blockpos; 31 | Minecraft mc = Minecraft.getMinecraft(); 32 | RayTraceResult ray = mc.objectMouseOver; 33 | if (ray != null && ray.typeOfHit == RayTraceResult.Type.BLOCK && mc.world.getBlockState(blockpos = ray.getBlockPos()).getMaterial() != Material.AIR && mc.world.getWorldBorder().contains(blockpos)) { 34 | Render3DUtil.drawBlockBox(blockpos, new Color(ClickGui.getCurrentColor().getRed(), ClickGui.getCurrentColor().getGreen(), ClickGui.getCurrentColor().getBlue(), full.getValue() ? alpha.getValue() : 0), outline.getValue(), width.getValue()); 35 | } 36 | } 37 | } 38 | 39 | -------------------------------------------------------------------------------- /src/main/java/cn/origin/cube/module/modules/visual/FullBright.java: -------------------------------------------------------------------------------- 1 | package cn.origin.cube.module.modules.visual; 2 | 3 | import cn.origin.cube.module.Category; 4 | import cn.origin.cube.module.Module; 5 | import cn.origin.cube.module.ModuleInfo; 6 | import cn.origin.cube.settings.FloatSetting; 7 | import cn.origin.cube.settings.IntegerSetting; 8 | import cn.origin.cube.settings.ModeSetting; 9 | import net.minecraft.init.MobEffects; 10 | import net.minecraft.potion.PotionEffect; 11 | 12 | @ModuleInfo(name = "FullBright", descriptions = "Always light", category = Category.VISUAL) 13 | public class FullBright extends Module { 14 | 15 | ModeSetting modeSetting = registerSetting("Mode", mode.GAMMA); 16 | FloatSetting gamma = registerSetting("Gamma", 800f, -10f, 1000f).modeOrVisible(modeSetting, mode.GAMMA, mode.BOTH); 17 | 18 | @Override 19 | public void onEnable() { 20 | if (modeSetting.getValue().equals(mode.GAMMA) || modeSetting.getValue().equals(mode.BOTH)) { 21 | mc.gameSettings.gammaSetting = gamma.getValue(); 22 | } 23 | if (modeSetting.getValue().equals(mode.POTION) || modeSetting.getValue().equals(mode.BOTH)) { 24 | mc.player.addPotionEffect(new PotionEffect(MobEffects.NIGHT_VISION, 100)); 25 | } 26 | } 27 | 28 | @Override 29 | public void onDisable() { 30 | mc.gameSettings.gammaSetting = 1f; 31 | mc.player.removePotionEffect(MobEffects.NIGHT_VISION); 32 | } 33 | 34 | private enum mode { 35 | GAMMA, 36 | POTION, 37 | BOTH 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /src/main/java/cn/origin/cube/module/modules/world/AutoRespawn.java: -------------------------------------------------------------------------------- 1 | package cn.origin.cube.module.modules.world; 2 | 3 | import cn.origin.cube.module.Category; 4 | import cn.origin.cube.module.Module; 5 | import cn.origin.cube.module.ModuleInfo; 6 | import net.minecraft.client.gui.GuiGameOver; 7 | 8 | @ModuleInfo(name = "AutoRespawn", descriptions = "Anti Death Screen", category = Category.WORLD) 9 | public class AutoRespawn extends Module { 10 | @Override 11 | public void onUpdate() { 12 | if (AutoRespawn.mc.currentScreen instanceof GuiGameOver && AutoRespawn.mc.player.getHealth() >= 0.0f) { 13 | AutoRespawn.mc.player.respawnPlayer(); 14 | AutoRespawn.mc.displayGuiScreen(null); 15 | } 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /src/main/java/cn/origin/cube/module/modules/world/FakePlayer.java: -------------------------------------------------------------------------------- 1 | package cn.origin.cube.module.modules.world; 2 | 3 | import cn.origin.cube.module.Category; 4 | import cn.origin.cube.module.Module; 5 | import cn.origin.cube.module.ModuleInfo; 6 | import cn.origin.cube.settings.StringSetting; 7 | import cn.origin.cube.utils.client.ChatUtil; 8 | import com.mojang.authlib.GameProfile; 9 | import net.minecraft.client.entity.EntityOtherPlayerMP; 10 | 11 | import java.util.UUID; 12 | 13 | @ModuleInfo(name = "FakePlayer", descriptions = "Spawn other player", category = Category.WORLD) 14 | public class FakePlayer extends Module { 15 | private final StringSetting name = registerSetting("name", "FakePlayer"); 16 | private EntityOtherPlayerMP otherPlayer; 17 | 18 | @Override 19 | public void onEnable() { 20 | if (fullNullCheck()) { 21 | this.disable(); 22 | return; 23 | } 24 | this.otherPlayer = null; 25 | if (mc.player != null) { 26 | this.otherPlayer = new EntityOtherPlayerMP(mc.world, new GameProfile(UUID.randomUUID(), this.name.getValue())); 27 | ChatUtil.sendMessage(ChatUtil.AQUA + String.format("%s has been spawned.", this.name.getValue())); 28 | this.otherPlayer.copyLocationAndAnglesFrom(mc.player); 29 | this.otherPlayer.rotationYawHead = mc.player.rotationYawHead; 30 | mc.world.addEntityToWorld(-100, this.otherPlayer); 31 | } 32 | } 33 | 34 | @Override 35 | public void onDisable() { 36 | if (mc.world != null && mc.player != null) { 37 | super.onDisable(); 38 | if (otherPlayer == null) return; 39 | mc.world.removeEntity(this.otherPlayer); 40 | } 41 | } 42 | } 43 | 44 | -------------------------------------------------------------------------------- /src/main/java/cn/origin/cube/settings/BindSetting.java: -------------------------------------------------------------------------------- 1 | package cn.origin.cube.settings; 2 | 3 | import cn.origin.cube.module.AbstractModule; 4 | 5 | public class BindSetting extends Setting { 6 | public BindSetting(String name, KeyBind value, AbstractModule father) { 7 | super(name, value, father); 8 | } 9 | 10 | public BindSetting booleanVisible(BooleanSetting setting) { 11 | return (BindSetting) this.visible(v -> setting.getValue()); 12 | } 13 | 14 | public BindSetting booleanDisVisible(BooleanSetting setting) { 15 | return (BindSetting) this.visible(v -> !setting.getValue()); 16 | } 17 | 18 | public BindSetting modeVisible(ModeSetting setting, Enum currentValue) { 19 | return (BindSetting) this.visible(v -> setting.getValue().equals(currentValue)); 20 | } 21 | 22 | public BindSetting modeOrVisible(ModeSetting setting, Enum currentValue, Enum secondValue) { 23 | return (BindSetting) this.visible(v -> setting.getValue().equals(currentValue) || setting.getValue().equals(secondValue)); 24 | } 25 | 26 | public BindSetting modeDisVisible(ModeSetting setting, Enum currentValue) { 27 | return (BindSetting) this.visible(v -> !setting.getValue().equals(currentValue)); 28 | } 29 | 30 | public static class KeyBind { 31 | private int keyCode; 32 | 33 | public KeyBind(int keyCode) { 34 | this.keyCode = keyCode; 35 | } 36 | 37 | public int getKeyCode() { 38 | return keyCode; 39 | } 40 | 41 | public void setKeyCode(int keyCode) { 42 | this.keyCode = keyCode; 43 | } 44 | 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /src/main/java/cn/origin/cube/settings/BooleanSetting.java: -------------------------------------------------------------------------------- 1 | package cn.origin.cube.settings; 2 | 3 | import cn.origin.cube.module.AbstractModule; 4 | 5 | public class BooleanSetting extends Setting{ 6 | public BooleanSetting(String name, Boolean value, AbstractModule father) { 7 | super(name, value, father); 8 | } 9 | public BooleanSetting booleanVisible(BooleanSetting setting) { 10 | return (BooleanSetting) this.visible(v -> setting.getValue()); 11 | } 12 | 13 | public BooleanSetting booleanDisVisible(BooleanSetting setting) { 14 | return (BooleanSetting) this.visible(v -> !setting.getValue()); 15 | } 16 | 17 | public BooleanSetting modeVisible(ModeSetting setting, Enum currentValue) { 18 | return (BooleanSetting) this.visible(v -> setting.getValue().equals(currentValue)); 19 | } 20 | 21 | public BooleanSetting modeOrVisible(ModeSetting setting, Enum currentValue, Enum secondValue) { 22 | return (BooleanSetting) this.visible(v -> setting.getValue().equals(currentValue) || setting.getValue().equals(secondValue)); 23 | } 24 | 25 | public BooleanSetting modeDisVisible(ModeSetting setting, Enum currentValue) { 26 | return (BooleanSetting) this.visible(v -> !setting.getValue().equals(currentValue)); 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /src/main/java/cn/origin/cube/settings/DoubleSetting.java: -------------------------------------------------------------------------------- 1 | package cn.origin.cube.settings; 2 | 3 | import cn.origin.cube.module.AbstractModule; 4 | 5 | public class DoubleSetting extends NumberSetting { 6 | 7 | public Double maxValue; 8 | public Double minValue; 9 | 10 | public DoubleSetting(String name, Double value, Double minValue, Double maxValue, AbstractModule father) { 11 | super(name, value, father); 12 | this.maxValue = maxValue; 13 | this.minValue = minValue; 14 | } 15 | 16 | public DoubleSetting booleanVisible(BooleanSetting setting) { 17 | return (DoubleSetting) this.visible(v -> setting.getValue()); 18 | } 19 | 20 | public DoubleSetting booleanDisVisible(BooleanSetting setting) { 21 | return (DoubleSetting) this.visible(v -> !setting.getValue()); 22 | } 23 | 24 | public DoubleSetting modeVisible(ModeSetting setting, Enum currentValue) { 25 | return (DoubleSetting) this.visible(v -> setting.getValue().equals(currentValue)); 26 | } 27 | 28 | public DoubleSetting modeOrVisible(ModeSetting setting, Enum currentValue, Enum secondValue) { 29 | return (DoubleSetting) this.visible(v -> setting.getValue().equals(currentValue) || setting.getValue().equals(secondValue)); 30 | } 31 | 32 | public DoubleSetting modeDisVisible(ModeSetting setting, Enum currentValue) { 33 | return (DoubleSetting) this.visible(v -> !setting.getValue().equals(currentValue)); 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /src/main/java/cn/origin/cube/settings/FloatSetting.java: -------------------------------------------------------------------------------- 1 | package cn.origin.cube.settings; 2 | 3 | import cn.origin.cube.module.AbstractModule; 4 | 5 | public class FloatSetting extends NumberSetting{ 6 | 7 | public Float maxValue; 8 | public Float minValue; 9 | public FloatSetting(String name, Float value, Float minValue, Float maxValue, AbstractModule father) { 10 | super(name, value, father); 11 | this.maxValue = maxValue; 12 | this.minValue = minValue; 13 | } 14 | public FloatSetting booleanVisible(BooleanSetting setting) { 15 | return (FloatSetting) this.visible(v -> setting.getValue()); 16 | } 17 | 18 | public FloatSetting booleanDisVisible(BooleanSetting setting) { 19 | return (FloatSetting) this.visible(v -> !setting.getValue()); 20 | } 21 | 22 | public FloatSetting modeVisible(ModeSetting setting, Enum currentValue) { 23 | return (FloatSetting) this.visible(v -> setting.getValue().equals(currentValue)); 24 | } 25 | 26 | public FloatSetting modeOrVisible(ModeSetting setting, Enum currentValue, Enum secondValue) { 27 | return (FloatSetting) this.visible(v -> setting.getValue().equals(currentValue) || setting.getValue().equals(secondValue)); 28 | } 29 | 30 | public FloatSetting modeDisVisible(ModeSetting setting, Enum currentValue) { 31 | return (FloatSetting) this.visible(v -> !setting.getValue().equals(currentValue)); 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /src/main/java/cn/origin/cube/settings/IntegerSetting.java: -------------------------------------------------------------------------------- 1 | package cn.origin.cube.settings; 2 | 3 | import cn.origin.cube.module.AbstractModule; 4 | 5 | public class IntegerSetting extends NumberSetting{ 6 | 7 | public Integer maxValue; 8 | public Integer minValue; 9 | public IntegerSetting(String name, Integer value, Integer minValue, Integer maxValue, AbstractModule father) { 10 | super(name, value, father); 11 | this.maxValue = maxValue; 12 | this.minValue = minValue; 13 | } 14 | 15 | public IntegerSetting booleanVisible(BooleanSetting setting) { 16 | return (IntegerSetting) this.visible(v -> setting.getValue()); 17 | } 18 | 19 | public IntegerSetting booleanDisVisible(BooleanSetting setting) { 20 | return (IntegerSetting) this.visible(v -> !setting.getValue()); 21 | } 22 | 23 | public IntegerSetting modeVisible(ModeSetting setting, Enum currentValue) { 24 | return (IntegerSetting) this.visible(v -> setting.getValue().equals(currentValue)); 25 | } 26 | 27 | public IntegerSetting modeOrVisible(ModeSetting setting, Enum currentValue, Enum secondValue) { 28 | return (IntegerSetting) this.visible(v -> setting.getValue().equals(currentValue) || setting.getValue().equals(secondValue)); 29 | } 30 | 31 | public IntegerSetting modeDisVisible(ModeSetting setting, Enum currentValue) { 32 | return (IntegerSetting) this.visible(v -> !setting.getValue().equals(currentValue)); 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /src/main/java/cn/origin/cube/settings/LongSetting.java: -------------------------------------------------------------------------------- 1 | package cn.origin.cube.settings; 2 | 3 | import cn.origin.cube.module.AbstractModule; 4 | 5 | public class LongSetting extends NumberSetting { 6 | public Long maxValue; 7 | public Long minValue; 8 | 9 | public LongSetting(String name, Long value, Long minValue, Long maxValue, AbstractModule father) { 10 | super(name, value, father); 11 | this.maxValue = maxValue; 12 | this.minValue = minValue; 13 | } 14 | 15 | public LongSetting booleanVisible(BooleanSetting setting) { 16 | return (LongSetting) this.visible(v -> setting.getValue()); 17 | } 18 | 19 | public LongSetting booleanDisVisible(BooleanSetting setting) { 20 | return (LongSetting) this.visible(v -> !setting.getValue()); 21 | } 22 | 23 | public LongSetting modeVisible(ModeSetting setting, Enum currentValue) { 24 | return (LongSetting) this.visible(v -> setting.getValue().equals(currentValue)); 25 | } 26 | 27 | public LongSetting modeOrVisible(ModeSetting setting, Enum currentValue, Enum secondValue) { 28 | return (LongSetting) this.visible(v -> setting.getValue().equals(currentValue) || setting.getValue().equals(secondValue)); 29 | } 30 | 31 | public LongSetting modeDisVisible(ModeSetting setting, Enum currentValue) { 32 | return (LongSetting) this.visible(v -> !setting.getValue().equals(currentValue)); 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /src/main/java/cn/origin/cube/settings/ModeSetting.java: -------------------------------------------------------------------------------- 1 | package cn.origin.cube.settings; 2 | 3 | import cn.origin.cube.module.AbstractModule; 4 | 5 | import java.util.Arrays; 6 | 7 | 8 | public class ModeSetting> extends Setting { 9 | 10 | private int index; 11 | 12 | public ModeSetting(String name, T clazz, AbstractModule father) { 13 | super(name, clazz, father); 14 | this.index = getIndexMode(clazz); 15 | } 16 | 17 | public > ModeSetting booleanVisible(BooleanSetting setting) { 18 | return (ModeSetting) super.visible((Object v) -> setting.getValue()); 19 | } 20 | 21 | public > ModeSetting boolean2NVisible(BooleanSetting setting, BooleanSetting setting2) { 22 | boolean b = setting.getValue() || setting2.getValue(); 23 | return (ModeSetting) super.visible((Object v) -> b); 24 | } 25 | 26 | public String getValueAsString() { 27 | return getValue().toString(); 28 | } 29 | 30 | public void setValueByString(String str) { 31 | setValue((T) Enum.valueOf(getValue().getClass(), str)); 32 | } 33 | 34 | @Override 35 | public void setValue(T value) { 36 | super.setValue(value); 37 | index = getIndexMode(getValue()); 38 | } 39 | 40 | public void forwardLoop() { 41 | this.index = this.index < this.getModes().length - 1 ? ++this.index : 0; 42 | setValue(this.getModes()[index]); 43 | } 44 | 45 | public int getIndexMode(T clazz) { 46 | for (int E = 0; E < getModes().length; E++) { 47 | if (getModes()[E] == clazz) { 48 | return E; 49 | } 50 | } 51 | return 0; 52 | } 53 | 54 | public T[] getModes() { 55 | return (T[]) this.getValue().getClass().getEnumConstants(); 56 | } 57 | 58 | public String[] getModesAsStrings() { 59 | return Arrays.stream(getModes()).map(Enum::toString).toArray(String[]::new); 60 | } 61 | 62 | public > ModeSetting booleanDisVisible(BooleanSetting setting) { 63 | return (ModeSetting) super.visible((Object v) -> !setting.getValue()); 64 | } 65 | 66 | public > ModeSetting modeVisible(ModeSetting value, Enum mode) { 67 | this.visibility.add(v -> value.getValue() == mode); 68 | return (ModeSetting) this; 69 | } 70 | } 71 | -------------------------------------------------------------------------------- /src/main/java/cn/origin/cube/settings/NumberSetting.java: -------------------------------------------------------------------------------- 1 | package cn.origin.cube.settings; 2 | 3 | import cn.origin.cube.module.AbstractModule; 4 | 5 | public abstract class NumberSetting extends Setting { 6 | 7 | public NumberSetting(String name, T value, AbstractModule father) { 8 | super(name, value, father); 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /src/main/java/cn/origin/cube/settings/Setting.java: -------------------------------------------------------------------------------- 1 | package cn.origin.cube.settings; 2 | 3 | import cn.origin.cube.event.events.client.SettingChangeEvent; 4 | import cn.origin.cube.module.AbstractModule; 5 | import net.minecraftforge.common.MinecraftForge; 6 | import org.jetbrains.annotations.NotNull; 7 | 8 | import java.util.ArrayList; 9 | import java.util.List; 10 | import java.util.function.Predicate; 11 | 12 | public abstract class Setting { 13 | @NotNull 14 | private T value; 15 | 16 | private final T defaultValue; 17 | 18 | private final String name; 19 | private final AbstractModule father; 20 | 21 | List> visibility = new ArrayList<>(); 22 | 23 | public Setting(String name, T value, AbstractModule father) { 24 | this.value = value; 25 | this.defaultValue = value; 26 | this.name = name; 27 | this.father = father; 28 | } 29 | 30 | public Setting visible(Predicate predicate) { 31 | this.visibility.add(predicate); 32 | return this; 33 | } 34 | 35 | public String getName() { 36 | return name; 37 | } 38 | 39 | public AbstractModule getFatherModule() { 40 | return father; 41 | } 42 | 43 | public T getDefaultValue() { 44 | return defaultValue; 45 | } 46 | 47 | @NotNull 48 | public T getValue() { 49 | return value; 50 | } 51 | 52 | public void setValue(T value) { 53 | T oldValue = this.value; 54 | this.value = value; 55 | SettingChangeEvent event = new SettingChangeEvent<>(this, oldValue, value); 56 | MinecraftForge.EVENT_BUS.post(event); 57 | } 58 | 59 | public boolean isVisible() { 60 | for (Predicate predicate : this.visibility) { 61 | if (predicate.test(this)) continue; 62 | return false; 63 | } 64 | return true; 65 | } 66 | 67 | 68 | } 69 | -------------------------------------------------------------------------------- /src/main/java/cn/origin/cube/settings/StringSetting.java: -------------------------------------------------------------------------------- 1 | package cn.origin.cube.settings; 2 | 3 | import cn.origin.cube.module.AbstractModule; 4 | 5 | public class StringSetting extends Setting{ 6 | public StringSetting(String name, String value, AbstractModule father) { 7 | super(name, value, father); 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /src/main/java/cn/origin/cube/utils/IconFont.kt: -------------------------------------------------------------------------------- 1 | package cn.origin.cube.utils 2 | 3 | const val PENCLI = "a" 4 | const val FILE = "b" 5 | const val FILES = "c" 6 | const val STACK = "d" 7 | const val TAG = "e" 8 | const val TAGS = "f" 9 | const val PUSHPIN = "g" 10 | const val DATABASE = "h" 11 | const val SEARCH = "i" 12 | const val LOCK = "j" 13 | const val UNLOCK = "k" 14 | const val WRENCH = "l" 15 | const val EQUALIZER = "m" 16 | const val EQUALIZER2 = "n" 17 | const val COG = "o" 18 | const val COGS = "p" 19 | const val MAGIC_WAND = "q" 20 | const val METER = "r" 21 | const val AIRPLANE = "s" 22 | const val TARGET = "t" 23 | const val POWER = "u" 24 | const val MENU = "v" 25 | const val EARTH = "w" 26 | const val PAPERCLIP = "x" 27 | const val EYE = "y" 28 | const val BOOKMARK = "z" 29 | const val BOOKMARKS = "A" 30 | const val SUN = "B" 31 | const val PLUS = "C" 32 | const val MINUS = "D" 33 | const val ERROR = "E" 34 | const val ARROW_UP = "G" 35 | const val ARROW_RIGHT = "H" 36 | const val ARROW_DOWN = "I" 37 | const val ARROW_LEFT = "J" 38 | const val PARAGRAPH = "K" 39 | const val CLOUD = "L" 40 | const val STACK_OVER_FLOW = "M" 41 | 42 | 43 | -------------------------------------------------------------------------------- /src/main/java/cn/origin/cube/utils/Timer.java: -------------------------------------------------------------------------------- 1 | package cn.origin.cube.utils; 2 | 3 | public class Timer { 4 | private long time = this.getCurrentTime(); 5 | 6 | protected final long getCurrentTime() { 7 | return System.currentTimeMillis(); 8 | } 9 | 10 | public final long getTime() { 11 | return this.time; 12 | } 13 | 14 | protected final void setTime(long l2) { 15 | this.time = l2; 16 | } 17 | 18 | private final long current = System.currentTimeMillis(); 19 | 20 | public boolean passed(long ms) { 21 | return System.currentTimeMillis() - this.time >= ms; 22 | } 23 | 24 | public boolean passed(double ms) { 25 | return System.currentTimeMillis() - this.time >= ms; 26 | } 27 | 28 | public long convertToNS(long time) { 29 | return time * 1000000L; 30 | } 31 | 32 | public void setMs(long ms) { 33 | this.time = System.nanoTime() - convertToNS(ms); 34 | } 35 | 36 | public void reset() { 37 | this.time = System.currentTimeMillis(); 38 | } 39 | 40 | public boolean hasReached(long var1) { 41 | return System.currentTimeMillis() - this.current >= var1; 42 | } 43 | 44 | public boolean hasReached(long var1, boolean var3) { 45 | if (var3) { 46 | this.reset(); 47 | } 48 | return System.currentTimeMillis() - this.current >= var1; 49 | } 50 | 51 | public boolean passedS(double s) { 52 | return this.passedMs((long) s * 1000L); 53 | } 54 | 55 | public boolean passedDms(double dms) { 56 | return this.passedMs((long) dms * 10L); 57 | } 58 | 59 | public boolean passedDs(double ds) { 60 | return this.passedMs((long) ds * 100L); 61 | } 62 | 63 | public boolean passedMs(long ms) { 64 | return System.currentTimeMillis() - this.time >= ms; 65 | } 66 | 67 | public long timePassed(long n) { 68 | return System.currentTimeMillis() - n; 69 | } 70 | 71 | public long getPassedTimeMs() { 72 | return System.currentTimeMillis() - this.time; 73 | } 74 | 75 | public final boolean passedTicks(int ticks) { 76 | return this.passed(ticks * 50); 77 | } 78 | 79 | public void resetTimeSkipTo(final long p_MS) { 80 | this.time = System.currentTimeMillis() + p_MS; 81 | } 82 | 83 | public boolean passed(float ms) { 84 | return System.currentTimeMillis() - this.time >= ms; 85 | } 86 | 87 | public boolean passed(int ms) { 88 | return System.currentTimeMillis() - this.time >= ms; 89 | } 90 | } 91 | 92 | -------------------------------------------------------------------------------- /src/main/java/cn/origin/cube/utils/Utils.java: -------------------------------------------------------------------------------- 1 | package cn.origin.cube.utils; 2 | 3 | import net.minecraft.client.Minecraft; 4 | 5 | public class Utils { 6 | public static final Minecraft mc = Minecraft.getMinecraft(); 7 | public static boolean nullCheck() { 8 | return mc.player == null || mc.world == null; 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /src/main/java/cn/origin/cube/utils/client/ChatUtil.java: -------------------------------------------------------------------------------- 1 | package cn.origin.cube.utils.client; 2 | 3 | import cn.origin.cube.utils.Utils; 4 | import net.minecraft.client.Minecraft; 5 | import net.minecraft.client.gui.GuiNewChat; 6 | import net.minecraft.util.text.TextComponentString; 7 | import net.minecraftforge.fml.relauncher.Side; 8 | import net.minecraftforge.fml.relauncher.SideOnly; 9 | 10 | public class ChatUtil { 11 | public static char COLOR_PREFIX = '\u00A7'; 12 | 13 | public static final String BLACK = COLOR_PREFIX + "0"; 14 | public static final String DARK_BLUE = COLOR_PREFIX + "1"; 15 | public static final String DARK_GREEN = COLOR_PREFIX + "2"; 16 | public static final String DARK_AQUA = COLOR_PREFIX + "3"; 17 | public static final String DARK_RED = COLOR_PREFIX + "4"; 18 | public static final String DARK_PURPLE = COLOR_PREFIX + "5"; 19 | public static final String GOLD = COLOR_PREFIX + "6"; 20 | public static final String GRAY = COLOR_PREFIX + "7"; 21 | public static final String DARK_GRAY = COLOR_PREFIX + "8"; 22 | public static final String BLUE = COLOR_PREFIX + "9"; 23 | public static final String GREEN = COLOR_PREFIX + "a"; 24 | public static final String AQUA = COLOR_PREFIX + "b"; 25 | public static final String RED = COLOR_PREFIX + "c"; 26 | public static final String LIGHT_PURPLE = COLOR_PREFIX + "d"; 27 | public static final String YELLOW = COLOR_PREFIX + "e"; 28 | public static final String WHITE = COLOR_PREFIX + "f"; 29 | public static final String OBFUSCATED = COLOR_PREFIX + "k"; 30 | public static final String BOLD = COLOR_PREFIX + "l"; 31 | public static final String STRIKE_THROUGH = COLOR_PREFIX + "m"; 32 | public static final String UNDER_LINE = COLOR_PREFIX + "n"; 33 | public static final String ITALIC = COLOR_PREFIX + "o"; 34 | public static final String RESET = COLOR_PREFIX + "r"; 35 | 36 | 37 | public static final String PREFIX = translateAlternateColorCodes("&8[&9&lCube&bBase&8]&r"); 38 | 39 | public static String translateAlternateColorCodes(String textToTranslate) { 40 | char[] b = textToTranslate.toCharArray(); 41 | for (int i = 0; i < b.length - 1; i++) { 42 | if (b[i] == '&' && "0123456789AaBbCcDdEeFfKkLlMmNnOoRrXx".indexOf(b[i + 1]) > -1) { 43 | b[i] = COLOR_PREFIX; 44 | b[i + 1] = Character.toLowerCase(b[i + 1]); 45 | } 46 | } 47 | return new String(b); 48 | } 49 | 50 | 51 | public static void sendRawMessage(String message) { 52 | Minecraft.getMinecraft().ingameGUI.getChatGUI().printChatMessage(new TextComponentString(message)); 53 | } 54 | 55 | public static void sendColoredMessage(String message) { 56 | sendRawMessage(translateAlternateColorCodes(message)); 57 | } 58 | 59 | 60 | public static void sendMessage(String message) { 61 | sendColoredMessage(PREFIX + message); 62 | } 63 | 64 | @SideOnly(Side.CLIENT) 65 | public static void sendNoSpamRawMessage(String message) { 66 | if (Utils.nullCheck()) return; 67 | final GuiNewChat chat = Minecraft.getMinecraft().ingameGUI.getChatGUI(); 68 | chat.printChatMessageWithOptionalDeletion(new TextComponentString(message), 135820); 69 | } 70 | 71 | public static void sendNoSpamColoredMessage(String message) { 72 | sendNoSpamRawMessage(translateAlternateColorCodes(message)); 73 | } 74 | 75 | public static void sendNoSpamMessage(String message) { 76 | sendNoSpamColoredMessage(PREFIX + message); 77 | } 78 | } 79 | -------------------------------------------------------------------------------- /src/main/java/cn/origin/cube/utils/gl/GlStateUtils.kt: -------------------------------------------------------------------------------- 1 | package cn.origin.cube.utils.gl 2 | 3 | import net.minecraft.client.Minecraft 4 | import net.minecraft.client.gui.ScaledResolution 5 | import net.minecraft.client.renderer.GlStateManager 6 | import org.lwjgl.opengl.GL11.* 7 | 8 | object GlStateUtils { 9 | 10 | private var lastScissor: Quad? = null 11 | private val scissorList = ArrayList>() 12 | 13 | fun scissor(x: Int, y: Int, width: Int, height: Int) { 14 | lastScissor = Quad(x, y, width, height) 15 | glScissor(x, y, width, height) 16 | } 17 | 18 | fun pushScissor() { 19 | lastScissor?.let { 20 | scissorList.add(it) 21 | } 22 | } 23 | 24 | fun popScissor() { 25 | scissorList.removeLastOrNull()?.let { 26 | scissor(it.first, it.second, it.third, it.fourth) 27 | } 28 | } 29 | 30 | @JvmStatic 31 | var colorLock = false 32 | private set 33 | 34 | @JvmStatic 35 | fun useVbo(): Boolean { 36 | return Minecraft.getMinecraft().gameSettings.useVbo 37 | } 38 | 39 | @JvmStatic 40 | fun matrix(state: Boolean) { 41 | if (state) { 42 | glPushMatrix() 43 | } else { 44 | glPopMatrix() 45 | } 46 | } 47 | 48 | @JvmStatic 49 | fun blend(state: Boolean) { 50 | if (state) { 51 | GlStateManager.enableBlend() 52 | GlStateManager.tryBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_ONE, GL_ZERO) 53 | // glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA) 54 | } else { 55 | GlStateManager.disableBlend() 56 | } 57 | } 58 | 59 | @JvmStatic 60 | fun alpha(state: Boolean) { 61 | if (state) { 62 | GlStateManager.enableAlpha() 63 | } else { 64 | GlStateManager.disableAlpha() 65 | } 66 | } 67 | 68 | @JvmStatic 69 | fun smooth(state: Boolean) { 70 | if (state) { 71 | GlStateManager.shadeModel(GL_SMOOTH) 72 | } else { 73 | GlStateManager.shadeModel(GL_FLAT) 74 | } 75 | } 76 | 77 | @JvmStatic 78 | fun lineSmooth(state: Boolean) { 79 | if (state) { 80 | glEnable(GL_LINE_SMOOTH) 81 | glHint(GL_LINE_SMOOTH_HINT, GL_NICEST) 82 | } else { 83 | glDisable(GL_LINE_SMOOTH) 84 | glHint(GL_LINE_SMOOTH_HINT, GL_DONT_CARE) 85 | } 86 | } 87 | 88 | @JvmStatic 89 | fun hintPolygon(state: Boolean) { 90 | if (state) { 91 | glHint(GL_POLYGON_SMOOTH_HINT, GL_NICEST) 92 | } else { 93 | glHint(GL_POLYGON_SMOOTH_HINT, GL_DONT_CARE) 94 | } 95 | } 96 | 97 | @JvmStatic 98 | fun depth(state: Boolean) { 99 | if (state) { 100 | GlStateManager.enableDepth() 101 | } else { 102 | GlStateManager.disableDepth() 103 | } 104 | } 105 | 106 | fun depthMask(state: Boolean) { 107 | if (state) { 108 | GlStateManager.depthMask(true) 109 | } else { 110 | GlStateManager.depthMask(false) 111 | } 112 | } 113 | 114 | @JvmStatic 115 | fun texture2d(state: Boolean) { 116 | if (state) { 117 | GlStateManager.enableTexture2D() 118 | } else { 119 | GlStateManager.disableTexture2D() 120 | } 121 | } 122 | 123 | fun cull(state: Boolean) { 124 | if (state) { 125 | GlStateManager.enableCull() 126 | } else { 127 | GlStateManager.disableCull() 128 | } 129 | } 130 | 131 | @JvmStatic 132 | fun lighting(state: Boolean) { 133 | if (state) { 134 | GlStateManager.enableLighting() 135 | } else { 136 | GlStateManager.disableLighting() 137 | } 138 | } 139 | 140 | fun polygon(state: Boolean) { 141 | if (state) { 142 | GlStateManager.enablePolygonOffset() 143 | GlStateManager.doPolygonOffset(1.0F, -1500000.0F) 144 | } else { 145 | GlStateManager.disablePolygonOffset() 146 | GlStateManager.doPolygonOffset(1.0F, 1500000.0F) 147 | } 148 | } 149 | 150 | 151 | @JvmStatic 152 | fun resetColour() { 153 | glColor4f(1.0f, 1.0f, 1.0f, 1.0f) 154 | } 155 | 156 | @JvmStatic 157 | fun colorLock(state: Boolean) { 158 | colorLock = state 159 | } 160 | 161 | @JvmStatic 162 | fun rescale(width: Double, height: Double) { 163 | GlStateManager.clear(256) 164 | GlStateManager.viewport(0, 0, Minecraft.getMinecraft().displayWidth, Minecraft.getMinecraft().displayHeight) 165 | GlStateManager.matrixMode(GL_PROJECTION) 166 | GlStateManager.loadIdentity() 167 | GlStateManager.ortho(0.0, width, height, 0.0, 1000.0, 3000.0) 168 | GlStateManager.matrixMode(GL_MODELVIEW) 169 | GlStateManager.loadIdentity() 170 | GlStateManager.translate(0.0f, 0.0f, -2000.0f) 171 | } 172 | 173 | @JvmStatic 174 | fun rescaleActual() { 175 | rescale(Minecraft.getMinecraft().displayWidth.toDouble(), Minecraft.getMinecraft().displayHeight.toDouble()) 176 | } 177 | 178 | @JvmStatic 179 | fun rescaleMc() { 180 | val resolution = ScaledResolution(Minecraft.getMinecraft()) 181 | rescale(resolution.scaledWidth_double, resolution.scaledHeight_double) 182 | } 183 | 184 | } -------------------------------------------------------------------------------- /src/main/java/cn/origin/cube/utils/gl/Quad.kt: -------------------------------------------------------------------------------- 1 | package cn.origin.cube.utils.gl 2 | 3 | import java.io.Serializable 4 | 5 | data class Quad( 6 | val first: A, 7 | val second: B, 8 | val third: C, 9 | val fourth: D 10 | ) : Serializable { 11 | override fun toString(): String = "($first, $second, $third, $fourth)" 12 | } -------------------------------------------------------------------------------- /src/main/java/cn/origin/cube/utils/player/BlockUtil.java: -------------------------------------------------------------------------------- 1 | package cn.origin.cube.utils.player; 2 | 3 | import net.minecraft.block.Block; 4 | import net.minecraft.block.state.IBlockState; 5 | import net.minecraft.client.Minecraft; 6 | import net.minecraft.init.Blocks; 7 | import net.minecraft.network.play.client.CPacketAnimation; 8 | import net.minecraft.network.play.client.CPacketEntityAction; 9 | import net.minecraft.network.play.client.CPacketPlayerTryUseItemOnBlock; 10 | import net.minecraft.util.EnumFacing; 11 | import net.minecraft.util.EnumHand; 12 | import net.minecraft.util.math.BlockPos; 13 | import net.minecraft.util.math.Vec3d; 14 | 15 | import java.util.ArrayList; 16 | import java.util.Arrays; 17 | import java.util.Iterator; 18 | import java.util.List; 19 | 20 | public class BlockUtil { 21 | private static final Minecraft mc = Minecraft.getMinecraft(); 22 | public static List blackList; 23 | public static List shulkerList; 24 | 25 | static { 26 | blackList = Arrays.asList(Blocks.ENDER_CHEST, Blocks.CHEST, Blocks.TRAPPED_CHEST, Blocks.CRAFTING_TABLE, Blocks.ANVIL, Blocks.BREWING_STAND, Blocks.HOPPER, Blocks.DROPPER, Blocks.DISPENSER); 27 | shulkerList = Arrays.asList(Blocks.WHITE_SHULKER_BOX, Blocks.ORANGE_SHULKER_BOX, Blocks.MAGENTA_SHULKER_BOX, Blocks.LIGHT_BLUE_SHULKER_BOX, Blocks.YELLOW_SHULKER_BOX, Blocks.LIME_SHULKER_BOX, Blocks.PINK_SHULKER_BOX, Blocks.GRAY_SHULKER_BOX, Blocks.SILVER_SHULKER_BOX, Blocks.CYAN_SHULKER_BOX, Blocks.PURPLE_SHULKER_BOX, Blocks.BLUE_SHULKER_BOX, Blocks.BROWN_SHULKER_BOX, Blocks.GREEN_SHULKER_BOX, Blocks.RED_SHULKER_BOX, Blocks.BLACK_SHULKER_BOX); 28 | } 29 | public static void placeBlock(BlockPos pos, EnumHand hand, boolean rotate, boolean packet) { 30 | EnumFacing side = getFirstFacing(pos); 31 | if (side == null) { 32 | return; 33 | } 34 | BlockPos neighbour = pos.offset(side); 35 | EnumFacing opposite = side.getOpposite(); 36 | Vec3d hitVec = new Vec3d(neighbour).add(0.5, 0.5, 0.5).add(new Vec3d(opposite.getDirectionVec()).scale(0.5)); 37 | Block neighbourBlock = mc.world.getBlockState(neighbour).getBlock(); 38 | if (!mc.player.isSneaking() && (blackList.contains(neighbourBlock) || shulkerList.contains(neighbourBlock))) { 39 | mc.player.connection.sendPacket(new CPacketEntityAction(mc.player, CPacketEntityAction.Action.START_SNEAKING)); 40 | mc.player.setSneaking(true); 41 | } 42 | if (rotate) { 43 | RotationUtil.faceVector(hitVec, true); 44 | } 45 | rightClickBlock(neighbour, hitVec, hand, opposite, packet); 46 | mc.rightClickDelayTimer = 4; 47 | } 48 | 49 | public static void rightClickBlock(BlockPos pos, Vec3d vec, EnumHand hand, EnumFacing direction, boolean packet) { 50 | if (packet) { 51 | mc.player.connection.sendPacket(new CPacketPlayerTryUseItemOnBlock(pos, direction, hand, 0.5f, 1.0f, 0.5f)); 52 | } else { 53 | mc.playerController.processRightClickBlock(mc.player, mc.world, pos, direction, vec, hand); 54 | } 55 | mc.player.connection.sendPacket(new CPacketAnimation(EnumHand.MAIN_HAND)); 56 | mc.rightClickDelayTimer = 4; 57 | } 58 | 59 | 60 | public static EnumFacing getFirstFacing(BlockPos pos) { 61 | Iterator iterator = getPossibleSides(pos).iterator(); 62 | if (iterator.hasNext()) { 63 | return iterator.next(); 64 | } 65 | return null; 66 | } 67 | 68 | public static List getPossibleSides(BlockPos pos) { 69 | List facings = new ArrayList(); 70 | if (mc.world == null || pos == null) { 71 | return facings; 72 | } 73 | for (EnumFacing side : EnumFacing.values()) { 74 | BlockPos neighbour = pos.offset(side); 75 | IBlockState blockState = mc.world.getBlockState(neighbour); 76 | if (blockState.getBlock().canCollideCheck(blockState, false) && !blockState.getMaterial().isReplaceable()) { 77 | facings.add(side); 78 | } 79 | } 80 | return facings; 81 | } 82 | } 83 | -------------------------------------------------------------------------------- /src/main/java/cn/origin/cube/utils/player/InventoryUtil.java: -------------------------------------------------------------------------------- 1 | package cn.origin.cube.utils.player; 2 | 3 | import net.minecraft.block.Block; 4 | import net.minecraft.client.Minecraft; 5 | import net.minecraft.item.ItemBlock; 6 | import net.minecraft.item.ItemStack; 7 | import net.minecraft.network.play.client.CPacketClickWindow; 8 | import net.minecraft.network.play.client.CPacketHeldItemChange; 9 | 10 | public class InventoryUtil { 11 | private static final Minecraft mc = Minecraft.getMinecraft(); 12 | 13 | public static int findHotbarItem(final Class clazz) { 14 | for (int i = 0; i < 9; ++i) { 15 | final ItemStack stack = mc.player.inventory.getStackInSlot(i); 16 | if (stack != ItemStack.EMPTY) { 17 | if (clazz.isInstance(stack.getItem())) { 18 | return i; 19 | } 20 | } 21 | } 22 | return -1; 23 | } 24 | 25 | public static void switchToHotbarSlot(final int slot, final boolean silent) { 26 | if (mc.player == null || mc.world == null || mc.player.inventory == null) { 27 | return; 28 | } 29 | if (mc.player.inventory.currentItem == slot || slot < 0) { 30 | return; 31 | } 32 | if (silent) { 33 | mc.player.connection.sendPacket(new CPacketHeldItemChange(slot)); 34 | mc.playerController.updateController(); 35 | } else { 36 | mc.player.connection.sendPacket(new CPacketHeldItemChange(slot)); 37 | mc.player.inventory.currentItem = slot; 38 | mc.playerController.updateController(); 39 | } 40 | } 41 | 42 | public static int findHotbarBlock(final Class clazz) { 43 | for (int i = 0; i < 9; ++i) { 44 | final ItemStack stack = mc.player.inventory.getStackInSlot(i); 45 | if (stack != ItemStack.EMPTY) { 46 | if (clazz.isInstance(stack.getItem())) { 47 | return i; 48 | } 49 | if (stack.getItem() instanceof ItemBlock) { 50 | final Block block = ((ItemBlock) stack.getItem()).getBlock(); 51 | if (clazz.isInstance(block)) { 52 | return i; 53 | } 54 | } 55 | } 56 | } 57 | return -1; 58 | } 59 | 60 | } 61 | -------------------------------------------------------------------------------- /src/main/java/cn/origin/cube/utils/player/RotationUtil.java: -------------------------------------------------------------------------------- 1 | package cn.origin.cube.utils.player; 2 | 3 | import net.minecraft.client.Minecraft; 4 | import net.minecraft.network.play.client.CPacketPlayer; 5 | import net.minecraft.util.math.MathHelper; 6 | import net.minecraft.util.math.Vec3d; 7 | 8 | public class RotationUtil { 9 | private static final Minecraft mc = Minecraft.getMinecraft(); 10 | 11 | public static Vec3d getEyesPos() { 12 | return new Vec3d(RotationUtil.mc.player.posX, RotationUtil.mc.player.posY + (double) RotationUtil.mc.player.getEyeHeight(), RotationUtil.mc.player.posZ); 13 | } 14 | public static void faceVector(Vec3d vec, boolean normalizeAngle) { 15 | float[] rotations = RotationUtil.getLegitRotations(vec); 16 | RotationUtil.mc.player.connection.sendPacket(new CPacketPlayer.Rotation(rotations[0], normalizeAngle ? (float) MathHelper.normalizeAngle((int) rotations[1], 360) : rotations[1], RotationUtil.mc.player.onGround)); 17 | } 18 | 19 | public static float[] getLegitRotations(Vec3d vec) { 20 | Vec3d eyesPos = RotationUtil.getEyesPos(); 21 | double diffX = vec.x - eyesPos.x; 22 | double diffY = vec.y - eyesPos.y; 23 | double diffZ = vec.z - eyesPos.z; 24 | double diffXZ = Math.sqrt(diffX * diffX + diffZ * diffZ); 25 | float yaw = (float) Math.toDegrees(Math.atan2(diffZ, diffX)) - 90.0f; 26 | float pitch = (float) (-Math.toDegrees(Math.atan2(diffY, diffXZ))); 27 | return new float[]{RotationUtil.mc.player.rotationYaw + MathHelper.wrapDegrees(yaw - RotationUtil.mc.player.rotationYaw), RotationUtil.mc.player.rotationPitch + MathHelper.wrapDegrees(pitch - RotationUtil.mc.player.rotationPitch)}; 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /src/main/java/cn/origin/cube/utils/render/ColorUtils.kt: -------------------------------------------------------------------------------- 1 | package cn.origin.cube.utils.render 2 | 3 | import java.awt.Color 4 | import java.util.* 5 | import java.util.regex.Pattern 6 | 7 | object ColorUtils { 8 | /** Array of the special characters that are allowed in any text drawing of Minecraft. */ 9 | val allowedCharactersArray = charArrayOf('/', '\n', '\r', '\t', '\u0000', ' ', '`', '?', '*', '\\', '<', '>', '|', '\"', ':') 10 | 11 | private fun isAllowedCharacter(character: Char): Boolean { 12 | return character.code != 167 && character.code >= 32 && character.code != 127 13 | } 14 | 15 | private val COLOR_PATTERN = Pattern.compile("(?i)§[0-9A-FK-OR]") 16 | 17 | val hexColors = IntArray(16) 18 | 19 | init { 20 | repeat(16) { i -> 21 | val baseColor = (i shr 3 and 1) * 85 22 | 23 | val red = (i shr 2 and 1) * 170 + baseColor + if (i == 6) 85 else 0 24 | val green = (i shr 1 and 1) * 170 + baseColor 25 | val blue = (i and 1) * 170 + baseColor 26 | 27 | hexColors[i] = red and 255 shl 16 or (green and 255 shl 8) or (blue and 255) 28 | } 29 | } 30 | 31 | @JvmStatic 32 | fun stripColor(input: String): String { 33 | return COLOR_PATTERN.matcher(input).replaceAll("") 34 | } 35 | 36 | @JvmStatic 37 | fun translateAlternateColorCodes(textToTranslate: String): String { 38 | val chars = textToTranslate.toCharArray() 39 | 40 | for (i in 0 until chars.size - 1) { 41 | if (chars[i] == '&' && "0123456789AaBbCcDdEeFfKkLlMmNnOoRr".contains(chars[i + 1], true)) { 42 | chars[i] = '§' 43 | chars[i + 1] = Character.toLowerCase(chars[i + 1]) 44 | } 45 | } 46 | 47 | return String(chars) 48 | } 49 | 50 | fun randomMagicText(text: String): String { 51 | val stringBuilder = StringBuilder() 52 | val allowedCharacters = "\u00c0\u00c1\u00c2\u00c8\u00ca\u00cb\u00cd\u00d3\u00d4\u00d5\u00da\u00df\u00e3\u00f5\u011f\u0130\u0131\u0152\u0153\u015e\u015f\u0174\u0175\u017e\u0207\u0000\u0000\u0000\u0000\u0000\u0000\u0000 !\"#$%&\'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~\u0000\u00c7\u00fc\u00e9\u00e2\u00e4\u00e0\u00e5\u00e7\u00ea\u00eb\u00e8\u00ef\u00ee\u00ec\u00c4\u00c5\u00c9\u00e6\u00c6\u00f4\u00f6\u00f2\u00fb\u00f9\u00ff\u00d6\u00dc\u00f8\u00a3\u00d8\u00d7\u0192\u00e1\u00ed\u00f3\u00fa\u00f1\u00d1\u00aa\u00ba\u00bf\u00ae\u00ac\u00bd\u00bc\u00a1\u00ab\u00bb\u2591\u2592\u2593\u2502\u2524\u2561\u2562\u2556\u2555\u2563\u2551\u2557\u255d\u255c\u255b\u2510\u2514\u2534\u252c\u251c\u2500\u253c\u255e\u255f\u255a\u2554\u2569\u2566\u2560\u2550\u256c\u2567\u2568\u2564\u2565\u2559\u2558\u2552\u2553\u256b\u256a\u2518\u250c\u2588\u2584\u258c\u2590\u2580\u03b1\u03b2\u0393\u03c0\u03a3\u03c3\u03bc\u03c4\u03a6\u0398\u03a9\u03b4\u221e\u2205\u2208\u2229\u2261\u00b1\u2265\u2264\u2320\u2321\u00f7\u2248\u00b0\u2219\u00b7\u221a\u207f\u00b2\u25a0\u0000" 53 | 54 | for (c in text.toCharArray()) { 55 | if (isAllowedCharacter(c)) { 56 | val index = Random().nextInt(allowedCharacters.length) 57 | stringBuilder.append(allowedCharacters.toCharArray()[index]) 58 | } 59 | } 60 | 61 | return stringBuilder.toString() 62 | } 63 | 64 | @JvmStatic 65 | fun rainbow(): Color { 66 | val currentColor = Color(Color.HSBtoRGB((System.nanoTime() + 400000L) / 10000000000F % 1, 1F, 1F)) 67 | return Color(currentColor.red / 255F * 1F, currentColor.green / 255f * 1F, currentColor.blue / 255F * 1F, currentColor.alpha / 255F) 68 | } 69 | 70 | // TODO: Use kotlin optional argument feature 71 | 72 | @JvmStatic 73 | fun rainbow(offset: Long): Color { 74 | val currentColor = Color(Color.HSBtoRGB((System.nanoTime() + offset) / 10000000000F % 1, 1F, 1F)) 75 | return Color(currentColor.red / 255F * 1F, currentColor.green / 255F * 1F, currentColor.blue / 255F * 1F, 76 | currentColor.alpha / 255F) 77 | } 78 | 79 | @JvmStatic 80 | fun rainbow(alpha: Float) = rainbow(400000L, alpha) 81 | 82 | @JvmStatic 83 | fun rainbow(alpha: Int) = rainbow(400000L, alpha / 255) 84 | 85 | @JvmStatic 86 | fun rainbow(offset: Long, alpha: Int) = rainbow(offset, alpha.toFloat() / 255) 87 | 88 | @JvmStatic 89 | fun rainbow(offset: Long, alpha: Float): Color { 90 | val currentColor = Color(Color.HSBtoRGB((System.nanoTime() + offset) / 10000000000F % 1, 1F, 1F)) 91 | return Color(currentColor.red / 255F * 1F, currentColor.green / 255f * 1F, currentColor.blue / 255F * 1F, alpha) 92 | } 93 | } 94 | -------------------------------------------------------------------------------- /src/main/java/cn/origin/cube/utils/render/Render2DUtil.java: -------------------------------------------------------------------------------- 1 | package cn.origin.cube.utils.render; 2 | 3 | import net.minecraft.client.renderer.BufferBuilder; 4 | import net.minecraft.client.renderer.GlStateManager; 5 | import net.minecraft.client.renderer.Tessellator; 6 | import net.minecraft.client.renderer.vertex.DefaultVertexFormats; 7 | import org.lwjgl.opengl.GL11; 8 | 9 | import java.awt.*; 10 | 11 | public class Render2DUtil { 12 | 13 | public static void setColor(Color color) { 14 | GL11.glColor4d((double) color.getRed() / 255.0, (double) color.getGreen() / 255.0, (double) color.getBlue() / 255.0, (double) color.getAlpha() / 255.0); 15 | } 16 | 17 | public static void drawRect(float x, float y, float w, float h, int color) { 18 | float alpha = (float) (color >> 24 & 0xFF) / 255.0f; 19 | float red = (float) (color >> 16 & 0xFF) / 255.0f; 20 | float green = (float) (color >> 8 & 0xFF) / 255.0f; 21 | float blue = (float) (color & 0xFF) / 255.0f; 22 | Tessellator tessellator = Tessellator.getInstance(); 23 | BufferBuilder bufferbuilder = tessellator.getBuffer(); 24 | GlStateManager.enableBlend(); 25 | GlStateManager.disableTexture2D(); 26 | GlStateManager.tryBlendFuncSeparate(770, 771, 1, 0); 27 | bufferbuilder.begin(7, DefaultVertexFormats.POSITION_COLOR); 28 | bufferbuilder.pos(x, y + h, 0.0).color(red, green, blue, alpha).endVertex(); 29 | bufferbuilder.pos(x + w, y + h, 0.0).color(red, green, blue, alpha).endVertex(); 30 | bufferbuilder.pos(x + w, y, 0.0).color(red, green, blue, alpha).endVertex(); 31 | bufferbuilder.pos(x, y, 0.0).color(red, green, blue, alpha).endVertex(); 32 | tessellator.draw(); 33 | GlStateManager.enableTexture2D(); 34 | GlStateManager.disableBlend(); 35 | } 36 | 37 | public static void drawOutlineRect(double x, double y, double w, double h, float lineWidth, Color color) { 38 | drawLine(x, y, x + w, y, lineWidth, color); 39 | drawLine(x, y, x, y + h, lineWidth, color); 40 | drawLine(x, y + h, x + w, y + h, lineWidth, color); 41 | drawLine(x + w, y, x + w, y + h, lineWidth, color); 42 | } 43 | 44 | public static void drawLine(Double x1, Double y1, Double x2, Double y2, Float lineWidth) { 45 | GL11.glDisable(3553); 46 | GL11.glEnable(3042); 47 | GL11.glLineWidth(lineWidth); 48 | GL11.glShadeModel(7425); 49 | GL11.glBegin(2); 50 | GL11.glVertex2d(x1, y1); 51 | GL11.glVertex2d(x2, y2); 52 | GL11.glEnd(); 53 | GL11.glShadeModel(7424); 54 | GL11.glDisable(3042); 55 | GL11.glEnable(3553); 56 | } 57 | 58 | public static void drawLine(double x1, double y1, double x2, double y2, float lineWidth, Color ColorStart) { 59 | GL11.glDisable(3553); 60 | GL11.glEnable(3042); 61 | GL11.glLineWidth(lineWidth); 62 | GL11.glShadeModel(7425); 63 | GL11.glBegin(2); 64 | setColor(ColorStart); 65 | GL11.glVertex2d(x1, y1); 66 | GL11.glVertex2d(x2, y2); 67 | GL11.glEnd(); 68 | GL11.glShadeModel(7424); 69 | GL11.glDisable(3042); 70 | GL11.glEnable(3553); 71 | } 72 | } 73 | -------------------------------------------------------------------------------- /src/main/java/cn/origin/cube/utils/render/Render3DUtil.java: -------------------------------------------------------------------------------- 1 | package cn.origin.cube.utils.render; 2 | 3 | import net.minecraft.client.Minecraft; 4 | import net.minecraft.client.renderer.BufferBuilder; 5 | import net.minecraft.client.renderer.GlStateManager; 6 | import net.minecraft.client.renderer.RenderGlobal; 7 | import net.minecraft.client.renderer.Tessellator; 8 | import net.minecraft.client.renderer.culling.Frustum; 9 | import net.minecraft.client.renderer.culling.ICamera; 10 | import net.minecraft.client.renderer.vertex.DefaultVertexFormats; 11 | import net.minecraft.util.math.AxisAlignedBB; 12 | import net.minecraft.util.math.BlockPos; 13 | import org.lwjgl.opengl.GL11; 14 | 15 | import java.awt.*; 16 | import java.util.Objects; 17 | 18 | import static org.lwjgl.opengl.GL11.*; 19 | 20 | public class Render3DUtil extends Tessellator { 21 | private static final Render3DUtil INSTANCE = new Render3DUtil(); 22 | public static Minecraft mc = Minecraft.getMinecraft(); 23 | public static ICamera camera = new Frustum(); 24 | 25 | public Render3DUtil() { 26 | super(0x200000); 27 | } 28 | 29 | public static void prepare(int mode) { 30 | prepareGL(); 31 | begin(mode); 32 | } 33 | 34 | public static void release() { 35 | render(); 36 | releaseGL(); 37 | } 38 | 39 | public static void render() { 40 | INSTANCE.draw(); 41 | } 42 | 43 | public static void releaseGL() { 44 | GlStateManager.enableCull(); 45 | GlStateManager.depthMask(true); 46 | GlStateManager.enableTexture2D(); 47 | GlStateManager.enableBlend(); 48 | GlStateManager.enableDepth(); 49 | GlStateManager.color(1.0f, 1.0f, 1.0f); 50 | GL11.glColor4f(1.0f, 1.0f, 1.0f, 1.0f); 51 | } 52 | 53 | public static void begin(int mode) { 54 | INSTANCE.getBuffer().begin(mode, DefaultVertexFormats.POSITION_COLOR); 55 | } 56 | 57 | public static void drawBlockBox(BlockPos pos, Color color, boolean outline, float lineWidth) { 58 | drawBBBox(new AxisAlignedBB(pos), color, color.getAlpha(), lineWidth, outline); 59 | } 60 | 61 | public static void drawBoxOutline(BlockPos pos,Color color,float lineWidth){ 62 | drawBoundingBox(new AxisAlignedBB(pos), lineWidth, color.getRed(), color.getGreen(), color.getBlue(), 255); 63 | } 64 | 65 | public static void drawBBBox(AxisAlignedBB BB, Color colour, int alpha, float lineWidth, boolean outline) { 66 | AxisAlignedBB bb = new AxisAlignedBB(BB.minX - mc.getRenderManager().viewerPosX, BB.minY - mc.getRenderManager().viewerPosY, BB.minZ - mc.getRenderManager().viewerPosZ, BB.maxX - mc.getRenderManager().viewerPosX, BB.maxY - mc.getRenderManager().viewerPosY, BB.maxZ - mc.getRenderManager().viewerPosZ); 67 | camera.setPosition(Objects.requireNonNull(mc.getRenderViewEntity()).posX, mc.getRenderViewEntity().posY, mc.getRenderViewEntity().posZ); 68 | if (camera.isBoundingBoxInFrustum(new AxisAlignedBB(bb.minX + mc.getRenderManager().viewerPosX, bb.minY + mc.getRenderManager().viewerPosY, bb.minZ + mc.getRenderManager().viewerPosZ, bb.maxX + mc.getRenderManager().viewerPosX, bb.maxY + mc.getRenderManager().viewerPosY, bb.maxZ + mc.getRenderManager().viewerPosZ))) { 69 | prepare(GL_QUADS); 70 | GlStateManager.enableBlend(); 71 | GlStateManager.disableDepth(); 72 | GlStateManager.tryBlendFuncSeparate(770, 771, 0, 1); 73 | GlStateManager.disableTexture2D(); 74 | GlStateManager.depthMask(false); 75 | GL11.glEnable(2848); 76 | GL11.glEnable(GL_LINE_SMOOTH); 77 | GL11.glHint(3154, 4354); 78 | GL11.glShadeModel(GL_SMOOTH); 79 | if (outline) { 80 | drawBoundingBox(bb, lineWidth, colour.getRed(), colour.getGreen(), colour.getBlue(), 255); 81 | } 82 | RenderGlobal.renderFilledBox(bb, (float) colour.getRed() / 255.0f, (float) colour.getGreen() / 255.0f, (float) colour.getBlue() / 255.0f, alpha / 255.0f); 83 | GL11.glDisable(2848); 84 | GlStateManager.depthMask(true); 85 | GlStateManager.enableDepth(); 86 | GlStateManager.enableTexture2D(); 87 | GlStateManager.disableBlend(); 88 | release(); 89 | } 90 | } 91 | 92 | public static void drawBoundingBox(AxisAlignedBB bb, float width, int red, int green, int blue, int alpha) { 93 | GL11.glLineWidth(width); 94 | GL11.glEnable(GL11.GL_LINE_SMOOTH); 95 | GlStateManager.color(red / 255f, green / 255f, blue / 255f, alpha / 255f); 96 | drawBoundingBox(bb); 97 | GlStateManager.color(1, 1, 1, 1); 98 | GL11.glDisable(GL11.GL_LINE_SMOOTH); 99 | } 100 | 101 | public static void drawBoundingBox(AxisAlignedBB boundingBox) { 102 | Tessellator tessellator = Tessellator.getInstance(); 103 | BufferBuilder vertexBuffer = tessellator.getBuffer(); 104 | vertexBuffer.begin(3, DefaultVertexFormats.POSITION); 105 | vertexBuffer.pos(boundingBox.minX, boundingBox.minY, boundingBox.minZ).endVertex(); 106 | vertexBuffer.pos(boundingBox.maxX, boundingBox.minY, boundingBox.minZ).endVertex(); 107 | vertexBuffer.pos(boundingBox.maxX, boundingBox.minY, boundingBox.maxZ).endVertex(); 108 | vertexBuffer.pos(boundingBox.minX, boundingBox.minY, boundingBox.maxZ).endVertex(); 109 | vertexBuffer.pos(boundingBox.minX, boundingBox.minY, boundingBox.minZ).endVertex(); 110 | tessellator.draw(); 111 | vertexBuffer.begin(3, DefaultVertexFormats.POSITION); 112 | vertexBuffer.pos(boundingBox.minX, boundingBox.maxY, boundingBox.minZ).endVertex(); 113 | vertexBuffer.pos(boundingBox.maxX, boundingBox.maxY, boundingBox.minZ).endVertex(); 114 | vertexBuffer.pos(boundingBox.maxX, boundingBox.maxY, boundingBox.maxZ).endVertex(); 115 | vertexBuffer.pos(boundingBox.minX, boundingBox.maxY, boundingBox.maxZ).endVertex(); 116 | vertexBuffer.pos(boundingBox.minX, boundingBox.maxY, boundingBox.minZ).endVertex(); 117 | tessellator.draw(); 118 | vertexBuffer.begin(1, DefaultVertexFormats.POSITION); 119 | vertexBuffer.pos(boundingBox.minX, boundingBox.minY, boundingBox.minZ).endVertex(); 120 | vertexBuffer.pos(boundingBox.minX, boundingBox.maxY, boundingBox.minZ).endVertex(); 121 | vertexBuffer.pos(boundingBox.maxX, boundingBox.minY, boundingBox.minZ).endVertex(); 122 | vertexBuffer.pos(boundingBox.maxX, boundingBox.maxY, boundingBox.minZ).endVertex(); 123 | vertexBuffer.pos(boundingBox.maxX, boundingBox.minY, boundingBox.maxZ).endVertex(); 124 | vertexBuffer.pos(boundingBox.maxX, boundingBox.maxY, boundingBox.maxZ).endVertex(); 125 | vertexBuffer.pos(boundingBox.minX, boundingBox.minY, boundingBox.maxZ).endVertex(); 126 | vertexBuffer.pos(boundingBox.minX, boundingBox.maxY, boundingBox.maxZ).endVertex(); 127 | tessellator.draw(); 128 | } 129 | 130 | public static void prepareGL() { 131 | GL11.glBlendFunc(770, 771); 132 | GlStateManager.tryBlendFuncSeparate(GlStateManager.SourceFactor.SRC_ALPHA, GlStateManager.DestFactor.ONE_MINUS_SRC_ALPHA, GlStateManager.SourceFactor.ONE, GlStateManager.DestFactor.ZERO); 133 | GlStateManager.glLineWidth(1.5f); 134 | GlStateManager.disableTexture2D(); 135 | GlStateManager.depthMask(false); 136 | GlStateManager.enableBlend(); 137 | GlStateManager.disableDepth(); 138 | GlStateManager.disableLighting(); 139 | GlStateManager.disableCull(); 140 | GlStateManager.enableAlpha(); 141 | GlStateManager.color(1.0f, 1.0f, 1.0f); 142 | } 143 | } 144 | -------------------------------------------------------------------------------- /src/main/resources/assets/fonts/CubeBaseIcon.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jiyun233/CubeBase/d0ba15713b92f517a4c9894c08d31cca6f71db5b/src/main/resources/assets/fonts/CubeBaseIcon.ttf -------------------------------------------------------------------------------- /src/main/resources/assets/fonts/CustomFont.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jiyun233/CubeBase/d0ba15713b92f517a4c9894c08d31cca6f71db5b/src/main/resources/assets/fonts/CustomFont.ttf -------------------------------------------------------------------------------- /src/main/resources/cube_at.cfg: -------------------------------------------------------------------------------- 1 | public net.minecraft.client.Minecraft * 2 | 3 | public net.minecraft.client.multiplayer.PlayerControllerMP * 4 | 5 | public net.minecraft.network.play.server.SPacketPlayerPosLook * 6 | public net.minecraft.network.play.client.CPacketChatMessage * -------------------------------------------------------------------------------- /src/main/resources/mcmod.info: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "modid": "cube", 4 | "name": "CubeBase", 5 | "description": "a base for 2b2t skidder", 6 | "version": "${version}", 7 | "mcversion": "${mcversion}", 8 | "url": "https://github.com/jiyun233/CubeBase/", 9 | "updateUrl": "https://github.com/jiyun233/CubeBase/release/", 10 | "authorList": [ 11 | "jiyun233" 12 | ] 13 | } 14 | ] 15 | -------------------------------------------------------------------------------- /src/main/resources/mixins.cube.json: -------------------------------------------------------------------------------- 1 | { 2 | "required": true, 3 | "package": "cn.origin.cube.inject.client", 4 | "refmap": "mixins.cube.refmap.json", 5 | "compatibilityLevel": "JAVA_8", 6 | "client": [ 7 | "MixinEntityPlayerSP", 8 | "MixinMinecraft" 9 | ], 10 | "mixins": [ 11 | "MixinNetworkManager" 12 | ] 13 | } --------------------------------------------------------------------------------