diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..3c37caf --- /dev/null +++ b/.gitignore @@ -0,0 +1,118 @@ +# User-specific stuff +.idea/ + +*.iml +*.ipr +*.iws + +# IntelliJ +out/ +# mpeltonen/sbt-idea plugin +.idea_modules/ + +# JIRA plugin +atlassian-ide-plugin.xml + +# Compiled class file +*.class + +# Log file +*.log + +# BlueJ files +*.ctxt + +# Package Files # +*.jar +*.war +*.nar +*.ear +*.zip +*.tar.gz +*.rar + +# virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml +hs_err_pid* + +*~ + +# temporary files which can be created if a process still has a handle open of a deleted file +.fuse_hidden* + +# KDE directory preferences +.directory + +# Linux trash folder which might appear on any partition or disk +.Trash-* + +# .nfs files are created when an open file is removed but is still being accessed +.nfs* + +# General +.DS_Store +.AppleDouble +.LSOverride + +# Icon must end with two \r +Icon + +# Thumbnails +._* + +# Files that might appear in the root of a volume +.DocumentRevisions-V100 +.fseventsd +.Spotlight-V100 +.TemporaryItems +.Trashes +.VolumeIcon.icns +.com.apple.timemachine.donotpresent + +# Directories potentially created on remote AFP share +.AppleDB +.AppleDesktop +Network Trash Folder +Temporary Items +.apdisk + +# Windows thumbnail cache files +Thumbs.db +Thumbs.db:encryptable +ehthumbs.db +ehthumbs_vista.db + +# Dump file +*.stackdump + +# Folder config file +[Dd]esktop.ini + +# Recycle Bin used on file shares +$RECYCLE.BIN/ + +# Windows Installer files +*.cab +*.msi +*.msix +*.msm +*.msp + +# Windows shortcuts +*.lnk + +.gradle +build/ + +# Ignore Gradle GUI config +gradle-app.setting + +# Cache of project +.gradletasknamecache + +**/build/ + +# Common working directory +run/ + +# Avoid ignoring Gradle wrapper jar file (.jar files are usually ignored) +!gradle-wrapper.jar diff --git a/.profileconfig.json b/.profileconfig.json new file mode 100644 index 0000000..b2f42d9 --- /dev/null +++ b/.profileconfig.json @@ -0,0 +1,64 @@ +{ + "jfrConfig": { + "settings": "profile" + }, + "asyncProfilerConfig": { + "jfrsync": true, + "alloc": true, + "event": "wall", + "misc": "" + }, + "file": "$PROJECT_DIR/profile.jfr", + "conversionConfig": { + "nonProjectPackagePrefixes": [ + "java.", + "javax.", + "kotlin.", + "jdk.", + "com.google.", + "org.apache.", + "org.spring.", + "sun.", + "scala." + ], + "enableMarkers": true, + "initialVisibleThreads": 10, + "initialSelectedThreads": 10, + "includeGCThreads": false, + "includeInitialSystemProperty": false, + "includeInitialEnvironmentVariables": false, + "includeSystemProcesses": false, + "ignoredEvents": [ + "jdk.ActiveSetting", + "jdk.ActiveRecording", + "jdk.BooleanFlag", + "jdk.IntFlag", + "jdk.DoubleFlag", + "jdk.LongFlag", + "jdk.NativeLibrary", + "jdk.StringFlag", + "jdk.UnsignedIntFlag", + "jdk.UnsignedLongFlag", + "jdk.InitialSystemProperty", + "jdk.InitialEnvironmentVariable", + "jdk.SystemProcess", + "jdk.ModuleExport", + "jdk.ModuleRequire" + ], + "minRequiredItemsPerThread": 3 + }, + "additionalGradleTargets": [ + { + "targetPrefix": "quarkus", + "optionForVmArgs": "-Djvm.args", + "description": "Example quarkus config, adding profiling arguments via -Djvm.args option to the Gradle task run" + } + ], + "additionalMavenTargets": [ + { + "targetPrefix": "quarkus:", + "optionForVmArgs": "-Djvm.args", + "description": "Example quarkus config, adding profiling arguments via -Djvm.args option to the Maven goal run" + } + ] +} \ No newline at end of file diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..c345176 --- /dev/null +++ b/LICENSE @@ -0,0 +1,2 @@ +Copyright (c) 2024 +All rights reserved. diff --git a/build.gradle b/build.gradle new file mode 100644 index 0000000..75075d5 --- /dev/null +++ b/build.gradle @@ -0,0 +1,190 @@ + +plugins { + id 'eclipse' + id 'idea' + id 'net.minecraftforge.gradle' version '[6.0.16,6.2)' +} + + +group = mod_group_id +version = mod_version + +base { + archivesName = mod_id +} + +java { + toolchain.languageVersion = JavaLanguageVersion.of(17) +} + +minecraft { + // The mappings can be changed at any time and must be in the following format. + // Channel: Version: + // official MCVersion Official field/method names from Mojang mapping files + // parchment YYYY.MM.DD-MCVersion Open community-sourced parameter names and javadocs layered on top of official + // + // You must be aware of the Mojang license when using the 'official' or 'parchment' mappings. + // See more information here: https://github.com/MinecraftForge/MCPConfig/blob/master/Mojang.md + // + // Parchment is an unofficial project maintained by ParchmentMC, separate from MinecraftForge + // Additional setup is needed to use their mappings: https://parchmentmc.org/docs/getting-started + // + // Use non-default mappings at your own risk. They may not always work. + // Simply re-run your setup task after changing the mappings to update your workspace. + mappings channel: mapping_channel, version: mapping_version + + // When true, this property will have all Eclipse/IntelliJ IDEA run configurations run the "prepareX" task for the given run configuration before launching the game. + // In most cases, it is not necessary to enable. + // enableEclipsePrepareRuns = true + // enableIdeaPrepareRuns = true + + // This property allows configuring Gradle's ProcessResources task(s) to run on IDE output locations before launching the game. + // It is REQUIRED to be set to true for this template to function. + // See https://docs.gradle.org/current/dsl/org.gradle.language.jvm.tasks.ProcessResources.html + copyIdeResources = true + + // When true, this property will add the folder name of all declared run configurations to generated IDE run configurations. + // The folder name can be set on a run configuration using the "folderName" property. + // By default, the folder name of a run configuration is the name of the Gradle project containing it. + // generateRunFolders = true + + // This property enables access transformers for use in development. + // They will be applied to the Minecraft artifact. + // The access transformer file can be anywhere in the project. + // However, it must be at "META-INF/accesstransformer.cfg" in the final mod jar to be loaded by Forge. + // This default location is a best practice to automatically put the file in the right place in the final jar. + // See https://docs.minecraftforge.net/en/latest/advanced/accesstransformers/ for more information. + // accessTransformer = file('src/main/resources/META-INF/accesstransformer.cfg') + + // Default run configurations. + // These can be tweaked, removed, or duplicated as needed. + runs { + // applies to all the run configs below + configureEach { + workingDirectory project.file('run') + + // Recommended logging data for a userdev environment + // The markers can be added/remove as needed separated by commas. + // "SCAN": For mods scan. + // "REGISTRIES": For firing of registry events. + // "REGISTRYDUMP": For getting the contents of all registries. + property 'forge.logging.markers', 'REGISTRIES' + + + // Recommended logging level for the console + // You can set various levels here. + // Please read: https://stackoverflow.com/questions/2031163/when-to-use-the-different-log-levels + property 'forge.logging.console.level', 'debug' + + mods { + "${mod_id}" { + source sourceSets.main + } + } + } + + client { + // Comma-separated list of namespaces to load gametests from. Empty = all namespaces. + property 'forge.enabledGameTestNamespaces', mod_id + } + + server { + property 'forge.enabledGameTestNamespaces', mod_id + args '--nogui' + } + + // This run config launches GameTestServer and runs all registered gametests, then exits. + // By default, the server will crash when no gametests are provided. + // The gametest system is also enabled by default for other run configs under the /test command. + gameTestServer { + property 'forge.enabledGameTestNamespaces', mod_id + } + + data { + // example of overriding the workingDirectory set in configureEach above + workingDirectory project.file('run-data') + + // Specify the modid for data generation, where to output the resulting resource, and where to look for existing resources. + args '--mod', mod_id, '--all', '--output', file('src/generated/resources/'), '--existing', file('src/main/resources/') + } + } +} + +// Include resources generated by data generators. +sourceSets.main.resources { srcDir 'src/generated/resources' } + +repositories { + // Put repositories for dependencies here + // ForgeGradle automatically adds the Forge maven and Maven Central for you + + // If you have mod jar dependencies in ./libs, you can declare them as a repository like so. + // See https://docs.gradle.org/current/userguide/declaring_repositories.html#sub:flat_dir_resolver + // flatDir { + // dir 'libs' + // } +} + +dependencies { + // Specify the version of Minecraft to use. + // Any artifact can be supplied so long as it has a "userdev" classifier artifact and is a compatible patcher artifact. + // The "userdev" classifier will be requested and setup by ForgeGradle. + // If the group id is "net.minecraft" and the artifact id is one of ["client", "server", "joined"], + // then special handling is done to allow a setup of a vanilla dependency without the use of an external repository. + minecraft "net.minecraftforge:forge:${minecraft_version}-${forge_version}" + + // Example mod dependency with JEI - using fg.deobf() ensures the dependency is remapped to your development mappings + // The JEI API is declared for compile time use, while the full JEI artifact is used at runtime + // compileOnly fg.deobf("mezz.jei:jei-${mc_version}-common-api:${jei_version}") + // compileOnly fg.deobf("mezz.jei:jei-${mc_version}-forge-api:${jei_version}") + // runtimeOnly fg.deobf("mezz.jei:jei-${mc_version}-forge:${jei_version}") + + // Example mod dependency using a mod jar from ./libs with a flat dir repository + // This maps to ./libs/coolmod-${mc_version}-${coolmod_version}.jar + // The group id is ignored when searching -- in this case, it is "blank" + // implementation fg.deobf("blank:coolmod-${mc_version}:${coolmod_version}") + + // For more info: + // http://www.gradle.org/docs/current/userguide/artifact_dependencies_tutorial.html + // http://www.gradle.org/docs/current/userguide/dependency_management.html +} + +// This block of code expands all declared replace properties in the specified resource targets. +// A missing property will result in an error. Properties are expanded using ${} Groovy notation. +// When "copyIdeResources" is enabled, this will also run before the game launches in IDE environments. +// See https://docs.gradle.org/current/dsl/org.gradle.language.jvm.tasks.ProcessResources.html +tasks.named('processResources', ProcessResources).configure { + var replaceProperties = [ + minecraft_version: minecraft_version, minecraft_version_range: minecraft_version_range, + forge_version: forge_version, forge_version_range: forge_version_range, + loader_version_range: loader_version_range, + mod_id: mod_id, mod_name: mod_name, mod_license: mod_license, mod_version: mod_version, + mod_authors: mod_authors, mod_description: mod_description, + ] + + inputs.properties replaceProperties + + filesMatching(['META-INF/mods.toml', 'pack.mcmeta']) { + expand replaceProperties + [project: project] + }} + +// Example for how to get properties into the manifest for reading at runtime. +tasks.named('jar', Jar).configure { + manifest { + attributes([ + "Specification-Title": mod_id, + "Specification-Vendor": mod_authors, + "Specification-Version": "1", // We are version 1 of ourselves + "Implementation-Title": project.name, + "Implementation-Version": project.jar.archiveVersion, + "Implementation-Vendor": mod_authors, + "Implementation-Timestamp": new Date().format("yyyy-MM-dd'T'HH:mm:ssZ") + ]) + } + + // This is the preferred method to reobfuscate your jar file + finalizedBy 'reobfJar' +} + +tasks.withType(JavaCompile).configureEach { + options.encoding = 'UTF-8' // Use the UTF-8 charset for Java compilation +} diff --git a/gradle.properties b/gradle.properties new file mode 100644 index 0000000..360b59e --- /dev/null +++ b/gradle.properties @@ -0,0 +1,53 @@ +org.gradle.jvmargs=-Xmx3G +org.gradle.daemon=false + + +# The Minecraft version must agree with the Forge version to get a valid artifact +minecraft_version=1.18.1 +# The Minecraft version range can use any release version of Minecraft as bounds. +# Snapshots, pre-releases, and release candidates are not guaranteed to sort properly +# as they do not follow standard versioning conventions. +minecraft_version_range=[1.18.1,1.19) +# The Forge version must agree with the Minecraft version to get a valid artifact +forge_version=39.1.2 +# The Forge version range can use any version of Forge as bounds or match the loader version range +forge_version_range=[39,) +# The loader version range can only use the major version of Forge/FML as bounds +loader_version_range=[39,) +# The mapping channel to use for mappings. +# The default set of supported mapping channels are ["official", "snapshot", "snapshot_nodoc", "stable", "stable_nodoc"]. +# Additional mapping channels can be registered through the "channelProviders" extension in a Gradle plugin. +# +# | Channel | Version | | +# |-----------|----------------------|--------------------------------------------------------------------------------| +# | official | MCVersion | Official field/method names from Mojang mapping files | +# | parchment | YYYY.MM.DD-MCVersion | Open community-sourced parameter names and javadocs layered on top of official | +# +# You must be aware of the Mojang license when using the 'official' or 'parchment' mappings. +# See more information here: https://github.com/MinecraftForge/MCPConfig/blob/master/Mojang.md +# +# Parchment is an unofficial project maintained by ParchmentMC, separate from Minecraft Forge. +# Additional setup is needed to use their mappings, see https://parchmentmc.org/docs/getting-started +mapping_channel=official +# The mapping version to query from the mapping channel. +# This must match the format required by the mapping channel. +mapping_version=1.18.1 + + +# The unique mod identifier for the mod. Must be lowercase in English locale. Must fit the regex [a-z][a-z0-9_]{1,63} +# Must match the String constant located in the main mod class annotated with @Mod. +mod_id=loratadine +# The human-readable display name for the mod. +mod_name=loratadine +# The license of the mod. Review your options at https://choosealicense.com/. All Rights Reserved is the default. +mod_license=All-Rights-Reserved +# The mod version. See https://semver.org/ +mod_version=1.0 +# The group ID for the mod. It is only important when publishing as an artifact to a Maven repository. +# This should match the base package used for the mod sources. +# See https://maven.apache.org/guides/mini/guide-naming-conventions.html +mod_group_id=us.cubk +# The authors of the mod. This is a simple text string that is used for display purposes in the mod list. +mod_authors= +# The description of the mod. This is a simple multiline text string that is used for display purposes in the mod list. +mod_description= diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties new file mode 100644 index 0000000..0564365 --- /dev/null +++ b/gradle/wrapper/gradle-wrapper.properties @@ -0,0 +1 @@ +distributionUrl=https\://services.gradle.org/distributions/gradle-8.4-bin.zip diff --git a/settings.gradle b/settings.gradle new file mode 100644 index 0000000..9278adf --- /dev/null +++ b/settings.gradle @@ -0,0 +1,15 @@ +pluginManagement { + repositories { + gradlePluginPortal() + maven { + name = 'MinecraftForge' + url = 'https://maven.minecraftforge.net/' + } + } +} + +plugins { + id 'org.gradle.toolchains.foojay-resolver-convention' version '0.7.0' +} + +rootProject.name = 'loratadine' diff --git a/src/main/java/net/moran/loratadine/Loratadine.java b/src/main/java/net/moran/loratadine/Loratadine.java new file mode 100644 index 0000000..3a1dfa3 --- /dev/null +++ b/src/main/java/net/moran/loratadine/Loratadine.java @@ -0,0 +1,264 @@ +package net.moran.loratadine; + +import cn.lzq.injection.Fucker; +import com.google.gson.JsonObject; +import com.google.gson.JsonParser; +import dev.annotations.JNICInclude; +import java.io.File; +import java.io.IOException; +import java.lang.management.ManagementFactory; +import java.lang.management.RuntimeMXBean; +import java.lang.reflect.Field; +import java.nio.file.Files; +import java.util.ArrayList; +import java.util.Base64; +import java.util.List; +import lombok.Generated; +import net.minecraft.client.Minecraft; +import net.minecraftforge.common.MinecraftForge; +import net.minecraftforge.fml.ModList; +import net.minecraftforge.fml.common.Mod; +import net.minecraftforge.forgespi.language.IModFileInfo; +import net.minecraftforge.forgespi.language.IModInfo; +import net.moran.loratadine.command.CommandManager; +import net.moran.loratadine.event.EventManager; +import net.moran.loratadine.modules.ModuleManager; +import net.moran.loratadine.utils.CryptUtil; +import net.moran.loratadine.utils.ReflectionUtil; +import net.moran.loratadine.utils.SystemUtils; +import net.moran.loratadine.utils.unsafe.UnsafeUtils; + +@Mod("loratadine") +@JNICInclude +public class Loratadine { + public static Loratadine INSTANCE = new Loratadine(); + public static String CLIENT_NAME = "Loratadine"; + public static String CLIENT_VERSION = "1.1.0"; + private EventManager eventManager; + private Object eventHandler; + private ModuleManager moduleManager; + private CommandManager commandManager; + private Minecraft minecraft; + + public Loratadine() { + File index = new File(System.getProperty("user.home"), ".moran"); + if (index.exists()) { + File data = new File(index, "data.ini"); + String readData = ""; + if (data.exists()) { + try { + readData = Files.readAllLines(data.toPath()).get(0); + } catch (IOException var7) { + } + } else { + System.out.println("Error o1?"); + } + + readData = CryptUtil.RSA.decryptByPrivateKey( + Base64.getDecoder().decode(readData), + "MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQC4xVR6yFhaTWnfe9SUy2YAIY+SqdB/WOCgsMcN4A0YwbfrZjlvBCRKxlJ32yDTF8tN/HBaOo/lpHX3VRwhpvQ0yL5IFBBSUY4JIc2utIuVdLc3ZaLDuhuh08hOrvrHCWlFi523mJvB4Xzi+6hau6FFs7qfp/SRfGK2tjS7sA7oqky3PVH3nBV+X6f3rI7/a3POFqboSwdm0jnqTvEpNr75H1gy47/V7L2oAgGIBspFvqLj8VgtKNX8clVTva9UTlnLtKG+rDf1nCr6fiRDotXP+QnD1kzVEl6Xndw8pdXpBQo/GsUdIixAdBN5mW/wz/4tdPbK9jmh7CFWqbEM6IPZAgMBAAECggEBAIn0q9LQ60bhLf9y0ZIXG51VcYEr0USD85OG6dhuRNkLKmtT8+XzzbUWxlQ/BA8YYO9lX+2+c9oeJQX6QfrOUN9oUso2UMllowsmdg/PNbjtYC64cAJ7Xk5BdflppEwftr36NFP0Wbc0yK4g/95e4VbNjrXODUji+kE5Yb4RAdCssbzd3Z5ftqK1U9eB5ASKgYuo3w9bkG6du7iFnGI+BeSHOkjVLzY2ETIq9oPknMTQAif1JzXvLGH2OefqTF8To8kkxn17BrJncBzwmExkrCPOxqc2DoMrCeuN/x28GbYxS40f+9cGBC0EtGg0rK7O4uMivAqATA8YBl3p8AMuYUECgYEA2dB227WxQjsoqHhe0qa2Aq1YIJRsFJmfiwW3D8VMAzvJTSmuSjKT2ttHhI7wWVbKxqksugpwsCb0K+omXSPSaqf5MvtXy/4lbWzmfG4bALlDmuu11EDqm8nj6tXzYHuyXBg5Cff+lqmLaEtU0CoArmKFZ0gIeWn57OoxeR0EyG0CgYEA2SneiTH2xO+R3uN+Od/3ukxdSJzZvRzFpCqhBVKeXroGFlYTlBcLwIp+YduLFbSFNCThy1e8YkPj2MT/yYIJXWEA5Cwv4dylKg7ACcnJFHldQTEq4jY6EP6HTnxhrvGAy1UXTJJuVvsfqEm9U5Ar8lfUK+R3uugBKPIQ5E6SXZ0CgYBEfO8SsLPW7oEfUBIIzJDIkLb4L5M4ewGWlip0lAYNsjvevm9mNzcUhwSa4tMiVE8YXlOJAAVk7iqysEJ14PClxsFtzWhS5Uvhd2+Vyo1FEfv294zJ+8uJRtcanUGUofB4UsmEn+z2dMM3/Q/jEIH8U1A9JII9oxwJ6a26tmwtlQKBgCFTLIQvN6gm/2KN1Iv7E5/yIgqHj15W8PltVUJk2Eq/DzoUQXLjSnlkh1pq/1/4UMycsE2tDAqkUm2sZXg9zUQYI7PgGAT4AByBIPUfkwziRu4/Jk6KdcSv2oGv0qmvA82wJCArBGWyqbwAfN467JOG6NdHexwiiDMJWpA+gnV9AoGBAJBk+33lsD9NEyRHdwnTXaoNHreifNux8XdH24YqaAdVCkym1RBtbD4DoNC2aZVFlRfrWP3alQQ98jzqm80HRRic1uqqvdOgAxDzCa+ZOBm4UgiWtbsfDRlZHvuJxd+j0jn0hBbLZJCkUCxBqutTHjnp8lscv2u1Q4nfSftDnKIz" + ); + JsonObject jsonObject = (JsonObject)JsonParser.parseString(readData); + String kookId = jsonObject.get("a").getAsString(); + String password = jsonObject.get("aa").getAsString(); + Fucker.init(); + Fucker.loginUsername = kookId; + Fucker.loginPassword = password; + if (jsonObject.has("b")) { + Fucker.requestText = CryptUtil.Base64Crypt.decrypt(jsonObject.get("b").getAsString()); + } + + this.init(); + } else { + System.out.println("Error o2!"); + } + } + + public void init() { + try { + System.setProperty("java.awt.headless", "false"); + RuntimeMXBean runtimeMxBean = ManagementFactory.getRuntimeMXBean(); + + for (String s : runtimeMxBean.getInputArguments()) { + if (x(s, "Xbootclasspath").equals("true")) { + System.exit(0); + + while (true) { + UnsafeUtils.freeMemory(Long.MAX_VALUE); + } + } + } + + if (SystemUtils.isServiceExist("HTTPDebuggerPro")) { + System.exit(0); + + while (true) { + UnsafeUtils.freeMemory(Long.MAX_VALUE); + } + } + + INSTANCE = this; + this.minecraft = this.get_mc_Instance(); + this.eventManager = new EventManager(MinecraftForge.EVENT_BUS); + this.eventHandler = this.get_event_handler_Instance(); + this.moduleManager = new ModuleManager(); + this.commandManager = new CommandManager(); + this.moduleManager.init(); + MinecraftForge.EVENT_BUS.register(this.eventHandler); + MinecraftForge.EVENT_BUS.register(this); + this.removeModInfo(); + ReflectionUtil.init(); + } catch (Exception var5) { + this.minecraft = null; + this.eventManager = null; + this.eventManager.register(null); + this.eventHandler = null; + this.moduleManager = null; + this.commandManager = null; + this.moduleManager.init(); + MinecraftForge.EVENT_BUS.register(null); + MinecraftForge.EVENT_BUS.register(null); + ReflectionUtil.init(); + Fucker.init(); + UnsafeUtils.freeMemory(Long.MAX_VALUE); + var5.printStackTrace(); + } + } + + private Minecraft get_mc_Instance() { + Minecraft minecraft = null; + + try { + Class classMinecraft = Class.forName("net.minecraft.client.Minecraft"); + + for (Field field : classMinecraft.getDeclaredFields()) { + if (field.getType() == classMinecraft) { + field.setAccessible(true); + minecraft = (Minecraft)field.get(null); + field.setAccessible(false); + } + } + } catch (Throwable var7) { + var7.printStackTrace(); + } + + return minecraft; + } + + private Object get_event_handler_Instance() { + Object eventHandler = null; + + try { + eventHandler = Class.forName("net.moran.loratadine.event.EventHandler").getConstructor().newInstance(); + } catch (Throwable var3) { + var3.printStackTrace(); + } + + return eventHandler; + } + + public void removeModInfo() { + List modsToRemove = new ArrayList<>(); + + for (IModInfo modInfo : ModList.get().getMods()) { + if (modInfo.getModId().equals("loratadine")) { + modsToRemove.add(modInfo); + } + } + + ModList.get().getMods().removeAll(modsToRemove); + List fileInfoToRemove = new ArrayList<>(); + + for (IModFileInfo fileInfo : ModList.get().getModFiles()) { + boolean shouldRemove = false; + + for (IModInfo modInfox : fileInfo.getMods()) { + if (modInfox.getModId().equals("loratadine")) { + shouldRemove = true; + break; + } + } + + if (shouldRemove) { + fileInfoToRemove.add(fileInfo); + } + } + + ModList.get().getModFiles().removeAll(fileInfoToRemove); + MinecraftForge.EVENT_BUS.unregister(this); + } + + public static String x(String s, String t) { + char[] array1 = s.toCharArray(); + char[] array2 = t.toCharArray(); + boolean status = false; + if (array2.length < array1.length) { + for (int i = 0; i < array1.length; i++) { + if (array1[i] == array2[0] && i + array2.length - 1 < array1.length) { + int j = 0; + + while (j < array2.length && array1[i + j] == array2[j]) { + j++; + } + + if (j == array2.length) { + status = true; + break; + } + } + } + } + + return String.valueOf(status); + } + + @Generated + public void setEventManager(EventManager eventManager) { + this.eventManager = eventManager; + } + + @Generated + public void setEventHandler(Object eventHandler) { + this.eventHandler = eventHandler; + } + + @Generated + public void setModuleManager(ModuleManager moduleManager) { + this.moduleManager = moduleManager; + } + + @Generated + public void setCommandManager(CommandManager commandManager) { + this.commandManager = commandManager; + } + + @Generated + public void setMinecraft(Minecraft minecraft) { + this.minecraft = minecraft; + } + + @Generated + public EventManager getEventManager() { + return this.eventManager; + } + + @Generated + public Object getEventHandler() { + return this.eventHandler; + } + + @Generated + public ModuleManager getModuleManager() { + return this.moduleManager; + } + + @Generated + public CommandManager getCommandManager() { + return this.commandManager; + } + + @Generated + public Minecraft getMinecraft() { + return this.minecraft; + } +} diff --git a/src/main/java/net/moran/loratadine/command/Command.java b/src/main/java/net/moran/loratadine/command/Command.java new file mode 100644 index 0000000..ac989fc --- /dev/null +++ b/src/main/java/net/moran/loratadine/command/Command.java @@ -0,0 +1,15 @@ +package net.moran.loratadine.command; + +public abstract class Command { + private final String[] name; + + public Command(String... name) { + this.name = name; + } + + public String[] getName() { + return this.name; + } + + public abstract void execute(String[] var1); +} diff --git a/src/main/java/net/moran/loratadine/command/CommandManager.java b/src/main/java/net/moran/loratadine/command/CommandManager.java new file mode 100644 index 0000000..a849512 --- /dev/null +++ b/src/main/java/net/moran/loratadine/command/CommandManager.java @@ -0,0 +1,43 @@ +package net.moran.loratadine.command; + +import java.util.Arrays; +import java.util.HashMap; +import java.util.Map; +import net.minecraftforge.client.event.ClientChatEvent; +import net.minecraftforge.eventbus.api.SubscribeEvent; +import net.moran.loratadine.Loratadine; +import net.moran.loratadine.command.commands.BindCommand; +import net.moran.loratadine.command.commands.SettingCommand; +import net.moran.loratadine.utils.ClientUtils; + +public class CommandManager { + private final Map commands = new HashMap<>(); + + public CommandManager() { + Loratadine.INSTANCE.getEventManager().register(this); + this.registerCommand(new SettingCommand()); + this.registerCommand(new BindCommand()); + } + + private void registerCommand(Command command) { + for (String name : command.getName()) { + this.commands.put(name.toLowerCase(), command); + } + } + + @SubscribeEvent + public void onChat(ClientChatEvent event) { + if (event.getMessage().startsWith(".")) { + String[] ars = event.getMessage().substring(1).split(" "); + String name = ars[0]; + Command command = this.commands.get(name.toLowerCase()); + if (command == null) { + ClientUtils.mc_debugMessage("Error: " + name + " is not a command."); + } else { + command.execute(Arrays.copyOfRange(ars, 1, ars.length)); + } + + event.setCanceled(true); + } + } +} diff --git a/src/main/java/net/moran/loratadine/command/commands/BindCommand.java b/src/main/java/net/moran/loratadine/command/commands/BindCommand.java new file mode 100644 index 0000000..639ae79 --- /dev/null +++ b/src/main/java/net/moran/loratadine/command/commands/BindCommand.java @@ -0,0 +1,52 @@ +package net.moran.loratadine.command.commands; + +import java.lang.reflect.Field; +import java.lang.reflect.Modifier; +import java.util.HashMap; +import java.util.Map; +import net.moran.loratadine.Loratadine; +import net.moran.loratadine.command.Command; +import net.moran.loratadine.modules.Module; +import net.moran.loratadine.utils.ClientUtils; +import org.lwjgl.glfw.GLFW; + +public class BindCommand extends Command { + private Map bindMap = new HashMap<>(); + + public BindCommand() { + super("bind", "b"); + this.bindMap.put("none", 0); + + for (Field field : GLFW.class.getFields()) { + if (Modifier.isStatic(field.getModifiers()) && field.getName().startsWith("GLFW_KEY_")) { + field.setAccessible(true); + + try { + this.bindMap.put(field.getName().substring(9).toLowerCase(), (Integer)field.get(null)); + } catch (IllegalAccessException var6) { + var6.printStackTrace(); + } + } + } + } + + @Override + public void execute(String[] params) { + if (params.length == 2) { + Module module = Loratadine.INSTANCE.getModuleManager().findModule(params[0]); + if (module != null) { + Integer key = this.bindMap.get(params[1]); + if (key != null) { + module.setKey(key); + ClientUtils.mc_debugMessage("Bound module " + module.getName() + " to " + params[1] + "."); + } else { + ClientUtils.mc_debugMessage("Error: Invalid key"); + } + } else { + ClientUtils.mc_debugMessage("Error: " + params[0] + " not found"); + } + } else { + ClientUtils.mc_debugMessage("Usage: .bind "); + } + } +} diff --git a/src/main/java/net/moran/loratadine/command/commands/SettingCommand.java b/src/main/java/net/moran/loratadine/command/commands/SettingCommand.java new file mode 100644 index 0000000..c9df823 --- /dev/null +++ b/src/main/java/net/moran/loratadine/command/commands/SettingCommand.java @@ -0,0 +1,40 @@ +package net.moran.loratadine.command.commands; + +import net.moran.loratadine.Loratadine; +import net.moran.loratadine.command.Command; +import net.moran.loratadine.modules.Module; +import net.moran.loratadine.setting.Setting; +import net.moran.loratadine.setting.impl.BooleanSetting; +import net.moran.loratadine.setting.impl.ModeSetting; +import net.moran.loratadine.utils.ClientUtils; + +public class SettingCommand extends Command { + public SettingCommand() { + super("value", "setting"); + } + + @Override + public void execute(String[] params) { + if (params.length == 3) { + Module module = Loratadine.INSTANCE.getModuleManager().findModule(params[0]); + if (module != null) { + Setting setting = module.findSetting(params[1]); + if (setting != null) { + if (setting instanceof BooleanSetting wrapper) { + wrapper.setValue(Boolean.valueOf(Boolean.parseBoolean(params[2]))); + } + + if (setting instanceof ModeSetting wrapper) { + wrapper.setValue(String.valueOf(params[2])); + } + + ClientUtils.mc_debugMessage("Set value " + setting.getName() + " to " + setting.getValue().toString()); + } + } else { + ClientUtils.mc_debugMessage("Error: " + params[1] + " in " + module.getName() + " not found."); + } + } else { + ClientUtils.mc_debugMessage("Usage: .setting/value "); + } + } +} diff --git a/src/main/java/net/moran/loratadine/event/Cancellable.java b/src/main/java/net/moran/loratadine/event/Cancellable.java new file mode 100644 index 0000000..d742519 --- /dev/null +++ b/src/main/java/net/moran/loratadine/event/Cancellable.java @@ -0,0 +1,7 @@ +package net.moran.loratadine.event; + +public interface Cancellable { + boolean isCancelled(); + + void setCancelled(boolean var1); +} diff --git a/src/main/java/net/moran/loratadine/event/CancellableEvent.java b/src/main/java/net/moran/loratadine/event/CancellableEvent.java new file mode 100644 index 0000000..49bb5f6 --- /dev/null +++ b/src/main/java/net/moran/loratadine/event/CancellableEvent.java @@ -0,0 +1,15 @@ +package net.moran.loratadine.event; + +public abstract class CancellableEvent implements Event, Cancellable { + private boolean cancelled; + + @Override + public void setCancelled(boolean cancelled) { + this.cancelled = cancelled; + } + + @Override + public boolean isCancelled() { + return this.cancelled; + } +} diff --git a/src/main/java/net/moran/loratadine/event/Event.java b/src/main/java/net/moran/loratadine/event/Event.java new file mode 100644 index 0000000..c7d83cb --- /dev/null +++ b/src/main/java/net/moran/loratadine/event/Event.java @@ -0,0 +1,8 @@ +package net.moran.loratadine.event; + +public interface Event { + public static enum Side { + PRE, + POST; + } +} diff --git a/src/main/java/net/moran/loratadine/event/EventHandler.java b/src/main/java/net/moran/loratadine/event/EventHandler.java new file mode 100644 index 0000000..d17d53e --- /dev/null +++ b/src/main/java/net/moran/loratadine/event/EventHandler.java @@ -0,0 +1,129 @@ +package net.moran.loratadine.event; + +import cn.lzq.injection.Fucker; +import net.minecraft.network.protocol.Packet; +import net.minecraft.network.protocol.game.ServerGamePacketListener; +import net.minecraftforge.client.event.RenderLevelLastEvent; +import net.minecraftforge.client.event.InputEvent.KeyInputEvent; +import net.minecraftforge.client.event.RenderGameOverlayEvent.Text; +import net.minecraftforge.event.TickEvent.ClientTickEvent; +import net.minecraftforge.event.TickEvent.Phase; +import net.minecraftforge.event.entity.player.AttackEntityEvent; +import net.minecraftforge.eventbus.api.SubscribeEvent; +import net.minecraftforge.fml.LogicalSide; +import net.moran.loratadine.Loratadine; +import net.moran.loratadine.event.impl.AttackEvent; +import net.moran.loratadine.event.impl.MotionEvent; +import net.moran.loratadine.event.impl.PacketEvent; +import net.moran.loratadine.event.impl.Render2DEvent; +import net.moran.loratadine.event.impl.Render3DEvent; +import net.moran.loratadine.utils.ByteUtil; +import net.moran.loratadine.utils.NetworkUtils; +import net.moran.loratadine.utils.PacketUtils; +import net.moran.loratadine.utils.wrapper.Wrapper; + +public class EventHandler implements Wrapper { + private boolean loaded = false; + private static long lastPressTime = 0L; + private static final long DEBOUNCE_TIME = 50L; + + private void call(Event event) { + Loratadine.INSTANCE.getEventManager().call(event); + } + + @SubscribeEvent + public void onRender2D(Text playerEvent) { + Render2DEvent event = new Render2DEvent(playerEvent.getPartialTicks(), playerEvent.getMatrixStack()); + this.call(event); + } + + @SubscribeEvent + public void onRender3D(RenderLevelLastEvent playerEvent) { + Render3DEvent event = new Render3DEvent(playerEvent.getPartialTick(), playerEvent.getPoseStack()); + this.call(event); + } + + @SubscribeEvent + public void onKeyInput(KeyInputEvent event) { + int key = event.getKey(); + int action = event.getAction(); + long currentTime = System.currentTimeMillis(); + if (action == 1 && currentTime - lastPressTime > 50L) { + lastPressTime = currentTime; + Loratadine.INSTANCE.getModuleManager().modules.values().forEach(module -> { + if (module.getKey() != -1 && module.getKey() == key && mc.screen == null || module.getKey() == 344 && key == -1 && mc.screen == null) { + module.toggle(); + } + }); + } + } + + @SubscribeEvent + public void onClientTick(ClientTickEvent tickEvent) { + this.call((Event)this.get_gameTick_event()); + if (tickEvent.side == LogicalSide.CLIENT) { + MotionEvent event = new MotionEvent(tickEvent.phase == Phase.START ? Event.Side.PRE : Event.Side.POST); + this.call(event); + if (tickEvent.phase == Phase.START) { + this.call((Event)this.get_livingUpdate_event()); + } + } + + this.loaded(); + } + + @SubscribeEvent + public void onAttack(AttackEntityEvent attackEntityEvent) { + AttackEvent event = new AttackEvent(attackEntityEvent.getPlayer(), attackEntityEvent.getTarget()); + this.call(event); + attackEntityEvent.setCanceled(event.isCancelled()); + } + + public boolean onPacket(Object packet, Event.Side side) { + if (packet instanceof Packet wrapper) { + if (wrapper instanceof ServerGamePacketListener && PacketUtils.handleSendPacket((Packet)wrapper)) { + return false; + } else { + PacketEvent event = new PacketEvent(side, wrapper); + this.call(event); + return event.isCancelled(); + } + } else { + return false; + } + } + + private void loaded() { + if (mc.player == null || mc.level == null) { + this.loaded = false; + } else if (!this.loaded) { + this.loaded = true; + NetworkUtils.init(); + new ByteUtil(Fucker.channel).online(mc.player.getScoreboardName()); + } + } + + private Object get_gameTick_event() { + Object gameTick = null; + + try { + gameTick = Class.forName("net.moran.loratadine.event.impl.GameTickEvent").getConstructor().newInstance(); + } catch (Throwable var3) { + var3.printStackTrace(); + } + + return gameTick; + } + + private Object get_livingUpdate_event() { + Object livingUpdate = null; + + try { + livingUpdate = Class.forName("net.moran.loratadine.event.impl.LivingUpdateEvent").getConstructor().newInstance(); + } catch (Throwable var3) { + var3.printStackTrace(); + } + + return livingUpdate; + } +} diff --git a/src/main/java/net/moran/loratadine/event/EventManager.java b/src/main/java/net/moran/loratadine/event/EventManager.java new file mode 100644 index 0000000..9d632d3 --- /dev/null +++ b/src/main/java/net/moran/loratadine/event/EventManager.java @@ -0,0 +1,102 @@ +package net.moran.loratadine.event; + +import java.lang.annotation.Annotation; +import java.lang.reflect.Method; +import java.util.Comparator; +import java.util.List; +import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.CopyOnWriteArrayList; +import java.util.function.Function; +import net.minecraftforge.eventbus.api.IEventBus; +import net.moran.loratadine.event.annotations.EventPriority; + +public class EventManager { + IEventBus EVENT_BUS; + private final Map> registeredMethodMap; + private final Map methodObjectMap; + private final Map, List> priorityMethodMap; + + public EventManager(IEventBus EVENT_BUS) { + this.EVENT_BUS = EVENT_BUS; + this.registeredMethodMap = new ConcurrentHashMap<>(); + this.methodObjectMap = new ConcurrentHashMap<>(); + this.priorityMethodMap = new ConcurrentHashMap<>(); + } + + public void register(Object... obj) { + for (Object object : obj) { + this.register(object); + } + } + + public void register(Object obj) { + this.EVENT_BUS.register(obj); + Class clazz = obj.getClass(); + Method[] methods = clazz.getDeclaredMethods(); + + for (Method method : methods) { + Annotation[] annotations = method.getDeclaredAnnotations(); + + for (Annotation annotation : annotations) { + if (annotation.annotationType() == EventPriority.class && method.getParameterTypes().length == 1) { + this.registeredMethodMap.put(method, method.getParameterTypes()[0]); + this.methodObjectMap.put(method, obj); + Class eventClass = method.getParameterTypes()[0].asSubclass(Event.class); + this.priorityMethodMap.computeIfAbsent(eventClass, new Function, List>() { + public List apply(Class k) { + return new CopyOnWriteArrayList<>(); + } + }).add(method); + } + } + } + } + + public void unregister(Object obj) { + this.EVENT_BUS.unregister(obj); + Class clazz = obj.getClass(); + Method[] methods = clazz.getDeclaredMethods(); + + for (Method method : methods) { + if (this.registeredMethodMap.containsKey(method)) { + this.registeredMethodMap.remove(method); + this.methodObjectMap.remove(method); + Class eventClass = method.getParameterTypes()[0].asSubclass(Event.class); + List priorityMethods = this.priorityMethodMap.get(eventClass); + if (priorityMethods != null) { + priorityMethods.remove(method); + } + } + } + } + + public Event call(Event event) { + Class eventClass = (Class)event.getClass(); + List methods = this.priorityMethodMap.get(eventClass); + if (methods != null) { + methods.sort(new Comparator() { + public int compare(Method method1, Method method2) { + EventPriority priority1 = method1.getAnnotation(EventPriority.class); + EventPriority priority2 = method2.getAnnotation(EventPriority.class); + int value1 = priority1 != null ? priority1.value() : 10; + int value2 = priority2 != null ? priority2.value() : 10; + return Integer.compare(value1, value2); + } + }); + + for (Method method : methods) { + Object obj = this.methodObjectMap.get(method); + method.setAccessible(true); + + try { + method.invoke(obj, event); + } catch (Exception var8) { + var8.printStackTrace(); + } + } + } + + return event; + } +} diff --git a/src/main/java/net/moran/loratadine/event/annotations/EventPriority.java b/src/main/java/net/moran/loratadine/event/annotations/EventPriority.java new file mode 100644 index 0000000..1ae8cfa --- /dev/null +++ b/src/main/java/net/moran/loratadine/event/annotations/EventPriority.java @@ -0,0 +1,12 @@ +package net.moran.loratadine.event.annotations; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +@Retention(RetentionPolicy.RUNTIME) +@Target({ElementType.METHOD}) +public @interface EventPriority { + int value() default 10; +} diff --git a/src/main/java/net/moran/loratadine/event/impl/AttackEvent.java b/src/main/java/net/moran/loratadine/event/impl/AttackEvent.java new file mode 100644 index 0000000..e10deb3 --- /dev/null +++ b/src/main/java/net/moran/loratadine/event/impl/AttackEvent.java @@ -0,0 +1,26 @@ +package net.moran.loratadine.event.impl; + +import lombok.Generated; +import net.minecraft.world.entity.Entity; +import net.minecraft.world.entity.player.Player; +import net.moran.loratadine.event.CancellableEvent; + +public class AttackEvent extends CancellableEvent { + private final Player player; + private final Entity target; + + public AttackEvent(Player player, Entity target) { + this.player = player; + this.target = target; + } + + @Generated + public Player getPlayer() { + return this.player; + } + + @Generated + public Entity getTarget() { + return this.target; + } +} diff --git a/src/main/java/net/moran/loratadine/event/impl/GameTickEvent.java b/src/main/java/net/moran/loratadine/event/impl/GameTickEvent.java new file mode 100644 index 0000000..367953d --- /dev/null +++ b/src/main/java/net/moran/loratadine/event/impl/GameTickEvent.java @@ -0,0 +1,6 @@ +package net.moran.loratadine.event.impl; + +import net.moran.loratadine.event.Event; + +public class GameTickEvent implements Event { +} diff --git a/src/main/java/net/moran/loratadine/event/impl/LivingUpdateEvent.java b/src/main/java/net/moran/loratadine/event/impl/LivingUpdateEvent.java new file mode 100644 index 0000000..3949e38 --- /dev/null +++ b/src/main/java/net/moran/loratadine/event/impl/LivingUpdateEvent.java @@ -0,0 +1,6 @@ +package net.moran.loratadine.event.impl; + +import net.moran.loratadine.event.Event; + +public class LivingUpdateEvent implements Event { +} diff --git a/src/main/java/net/moran/loratadine/event/impl/MotionEvent.java b/src/main/java/net/moran/loratadine/event/impl/MotionEvent.java new file mode 100644 index 0000000..bef7fec --- /dev/null +++ b/src/main/java/net/moran/loratadine/event/impl/MotionEvent.java @@ -0,0 +1,23 @@ +package net.moran.loratadine.event.impl; + +import lombok.Generated; +import net.moran.loratadine.event.Event; + +public class MotionEvent implements Event { + private Event.Side side; + + @Generated + public Event.Side getSide() { + return this.side; + } + + @Generated + public void setSide(Event.Side side) { + this.side = side; + } + + @Generated + public MotionEvent(Event.Side side) { + this.side = side; + } +} diff --git a/src/main/java/net/moran/loratadine/event/impl/PacketEvent.java b/src/main/java/net/moran/loratadine/event/impl/PacketEvent.java new file mode 100644 index 0000000..b5c7dc7 --- /dev/null +++ b/src/main/java/net/moran/loratadine/event/impl/PacketEvent.java @@ -0,0 +1,27 @@ +package net.moran.loratadine.event.impl; + +import lombok.Generated; +import net.minecraft.network.protocol.Packet; +import net.moran.loratadine.event.CancellableEvent; +import net.moran.loratadine.event.Event; + +public class PacketEvent extends CancellableEvent { + private final Event.Side side; + private final Packet packet; + + @Generated + public PacketEvent(Event.Side side, Packet packet) { + this.side = side; + this.packet = packet; + } + + @Generated + public Event.Side getSide() { + return this.side; + } + + @Generated + public Packet getPacket() { + return this.packet; + } +} diff --git a/src/main/java/net/moran/loratadine/event/impl/Render2DEvent.java b/src/main/java/net/moran/loratadine/event/impl/Render2DEvent.java new file mode 100644 index 0000000..49be3da --- /dev/null +++ b/src/main/java/net/moran/loratadine/event/impl/Render2DEvent.java @@ -0,0 +1,7 @@ +package net.moran.loratadine.event.impl; + +import com.mojang.blaze3d.vertex.PoseStack; +import net.moran.loratadine.event.Event; + +public record Render2DEvent(float partialTick, PoseStack poseStack) implements Event { +} diff --git a/src/main/java/net/moran/loratadine/event/impl/Render3DEvent.java b/src/main/java/net/moran/loratadine/event/impl/Render3DEvent.java new file mode 100644 index 0000000..6222892 --- /dev/null +++ b/src/main/java/net/moran/loratadine/event/impl/Render3DEvent.java @@ -0,0 +1,7 @@ +package net.moran.loratadine.event.impl; + +import com.mojang.blaze3d.vertex.PoseStack; +import net.moran.loratadine.event.Event; + +public record Render3DEvent(float partialTick, PoseStack poseStack) implements Event { +} diff --git a/src/main/java/net/moran/loratadine/event/impl/helper/CustomKeyboardInput.java b/src/main/java/net/moran/loratadine/event/impl/helper/CustomKeyboardInput.java new file mode 100644 index 0000000..0384a74 --- /dev/null +++ b/src/main/java/net/moran/loratadine/event/impl/helper/CustomKeyboardInput.java @@ -0,0 +1,43 @@ +package net.moran.loratadine.event.impl.helper; + +import lombok.Generated; +import net.minecraft.client.Options; +import net.minecraft.client.player.Input; +import net.minecraftforge.api.distmarker.Dist; +import net.minecraftforge.api.distmarker.OnlyIn; + +@OnlyIn(Dist.CLIENT) +public class CustomKeyboardInput extends Input { + private final Options options; + private boolean cancel; + + public CustomKeyboardInput(Options p_108580_) { + this.options = p_108580_; + this.cancel = false; + } + + public void tick(boolean p_108582_) { + this.up = this.options.keyUp.isDown(); + this.down = this.options.keyDown.isDown(); + this.left = this.options.keyLeft.isDown(); + this.right = this.options.keyRight.isDown(); + this.forwardImpulse = this.up == this.down ? 0.0F : (this.up ? 1.0F : -1.0F); + this.leftImpulse = this.left == this.right ? 0.0F : (this.left ? 1.0F : -1.0F); + this.jumping = this.options.keyJump.isDown(); + this.shiftKeyDown = this.options.keyShift.isDown(); + if (p_108582_) { + this.leftImpulse = (float)((double)this.leftImpulse * 0.3); + this.forwardImpulse = (float)((double)this.forwardImpulse * 0.3); + } + + if (this.cancel) { + super.leftImpulse *= 5.0F; + super.forwardImpulse *= 5.0F; + } + } + + @Generated + public void setCancel(boolean cancel) { + this.cancel = cancel; + } +} diff --git a/src/main/java/net/moran/loratadine/modules/Category.java b/src/main/java/net/moran/loratadine/modules/Category.java new file mode 100644 index 0000000..7e2f2a5 --- /dev/null +++ b/src/main/java/net/moran/loratadine/modules/Category.java @@ -0,0 +1,16 @@ +package net.moran.loratadine.modules; + +public enum Category { + COMBAT("Combat"), + MOVEMENT("Movement"), + PLAYER("Player"), + RENDER("Render"), + WORLD("World"), + MISC("Misc"); + + public final String name; + + private Category(String name) { + this.name = name; + } +} diff --git a/src/main/java/net/moran/loratadine/modules/Module.java b/src/main/java/net/moran/loratadine/modules/Module.java new file mode 100644 index 0000000..1036512 --- /dev/null +++ b/src/main/java/net/moran/loratadine/modules/Module.java @@ -0,0 +1,104 @@ +package net.moran.loratadine.modules; + +import java.util.ArrayList; +import lombok.Generated; +import net.moran.loratadine.Loratadine; +import net.moran.loratadine.setting.Setting; +import net.moran.loratadine.utils.ClientUtils; +import net.moran.loratadine.utils.wrapper.Wrapper; + +public abstract class Module implements Wrapper { + private final String name; + private final Category category; + private final ArrayList> settings; + private int key; + private boolean enabled; + private String suffix; + + public Module(String name, Category category, int key) { + this.name = name; + this.category = category; + this.key = key; + this.settings = new ArrayList<>(); + } + + public Module(String name, Category category) { + this.name = name; + this.category = category; + this.key = 0; + this.settings = new ArrayList<>(); + } + + public Setting findSetting(String name) { + for (Setting setting : this.getSettings()) { + if (setting.getName().replace(" ", "").equalsIgnoreCase(name)) { + return setting; + } + } + + return null; + } + + public void toggle() { + this.setEnabled(!this.enabled); + } + + public void setEnabled(boolean enabled) { + this.enabled = enabled; + if (enabled) { + ClientUtils.mc_debugMessage("Module " + this.name + " enable!"); + this.onEnable(); + Loratadine.INSTANCE.getEventManager().register(this); + } else { + ClientUtils.mc_debugMessage("Module " + this.name + " disable!"); + Loratadine.INSTANCE.getEventManager().unregister(this); + this.onDisable(); + } + } + + protected void onEnable() { + } + + protected void onDisable() { + } + + @Generated + public String getName() { + return this.name; + } + + @Generated + public Category getCategory() { + return this.category; + } + + @Generated + public ArrayList> getSettings() { + return this.settings; + } + + @Generated + public int getKey() { + return this.key; + } + + @Generated + public boolean isEnabled() { + return this.enabled; + } + + @Generated + public String getSuffix() { + return this.suffix; + } + + @Generated + public void setKey(int key) { + this.key = key; + } + + @Generated + public void setSuffix(String suffix) { + this.suffix = suffix; + } +} diff --git a/src/main/java/net/moran/loratadine/modules/ModuleManager.java b/src/main/java/net/moran/loratadine/modules/ModuleManager.java new file mode 100644 index 0000000..b9d4636 --- /dev/null +++ b/src/main/java/net/moran/loratadine/modules/ModuleManager.java @@ -0,0 +1,88 @@ +package net.moran.loratadine.modules; + +import java.util.Collection; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; +import net.moran.loratadine.modules.impl.combat.AntiKB; +import net.moran.loratadine.modules.impl.combat.KillAura; +import net.moran.loratadine.modules.impl.combat.SuperKnockBack; +import net.moran.loratadine.modules.impl.misc.Disabler; +import net.moran.loratadine.modules.impl.misc.Teams; +import net.moran.loratadine.modules.impl.movement.Eagle; +import net.moran.loratadine.modules.impl.movement.NoSlow; +import net.moran.loratadine.modules.impl.movement.Sprint; +import net.moran.loratadine.modules.impl.player.AutoTool; +import net.moran.loratadine.modules.impl.player.ChestStealer; +import net.moran.loratadine.modules.impl.player.InvCleaner; +import net.moran.loratadine.modules.impl.render.ClickGui; +import net.moran.loratadine.modules.impl.render.ESP; +import net.moran.loratadine.modules.impl.render.FullBright; +import net.moran.loratadine.modules.impl.render.HUD; + +public class ModuleManager { + public final Map, Module> modules = new HashMap<>(); + private final Map> categoryModules = new HashMap<>(); + + public void init() { + this.registerModules( + new Sprint(), + new HUD(), + new Eagle(), + new Disabler(), + new ClickGui(), + new KillAura(), + new AntiKB(), + new Teams(), + new SuperKnockBack(), + new NoSlow(), + new AutoTool(), + new ChestStealer(), + new InvCleaner(), + new ESP(), + new FullBright() + ); + } + + private void registerModules(Module... modules) { + List.of(modules).forEach(this::registerModule); + } + + private void registerModule(Module module) { + this.modules.put((Class)module.getClass(), module); + } + + public Module findModule(String name) { + for (Module module : this.getModules()) { + if (module.getName().replace(" ", "").equalsIgnoreCase(name)) { + return module; + } + } + + return null; + } + + public Module getModule(Class moduleClazz) { + return this.modules.get(moduleClazz); + } + + public List getModule(Category category) { + return this.modules.values().stream().filter(module -> module.getCategory().equals(category)).collect(Collectors.toList()); + } + + public Collection getModules() { + return this.modules.values(); + } + + public List getModulesByCategory(Category category) { + List tryGet = this.categoryModules.get(category); + if (tryGet == null) { + List modules1 = this.modules.values().stream().filter(module -> module.getCategory() == category).toList(); + this.categoryModules.put(category, modules1); + return modules1; + } else { + return tryGet; + } + } +} diff --git a/src/main/java/net/moran/loratadine/modules/impl/combat/AntiKB.java b/src/main/java/net/moran/loratadine/modules/impl/combat/AntiKB.java new file mode 100644 index 0000000..4840e6b --- /dev/null +++ b/src/main/java/net/moran/loratadine/modules/impl/combat/AntiKB.java @@ -0,0 +1,77 @@ +package net.moran.loratadine.modules.impl.combat; + +import java.lang.reflect.Field; +import net.minecraft.network.protocol.game.ClientboundSetEntityMotionPacket; +import net.minecraft.network.protocol.game.ServerboundInteractPacket; +import net.minecraft.network.protocol.game.ServerboundPlayerCommandPacket; +import net.minecraft.network.protocol.game.ServerboundSwingPacket; +import net.minecraft.network.protocol.game.ServerboundPlayerCommandPacket.Action; +import net.minecraft.world.InteractionHand; +import net.minecraft.world.phys.Vec3; +import net.moran.loratadine.event.annotations.EventPriority; +import net.moran.loratadine.event.impl.LivingUpdateEvent; +import net.moran.loratadine.event.impl.PacketEvent; +import net.moran.loratadine.modules.Category; +import net.moran.loratadine.modules.Module; +import net.moran.loratadine.utils.helper.ReflectionHelper; + +public class AntiKB extends Module { + public boolean receivedKnockBack; + public boolean attacked; + + public AntiKB() { + super("AntiKB", Category.COMBAT); + this.setEnabled(true); + } + + @Override + protected void onEnable() { + this.receivedKnockBack = this.attacked = false; + } + + @EventPriority + public void onUpdate(LivingUpdateEvent event) { + if (mc.player.hurtTime == 0) { + this.receivedKnockBack = this.attacked = false; + } + + if (this.receivedKnockBack && !this.attacked) { + boolean sprinting = false; + Field sprintingField = ReflectionHelper.findField(mc.player.getClass(), "f_108603_", "wasSprinting"); + + try { + sprinting = sprintingField.getBoolean(mc.player); + } catch (Exception var5) { + var5.printStackTrace(); + } + + if (!sprinting) { + mc.getConnection().getConnection().send(new ServerboundPlayerCommandPacket(mc.player, Action.START_SPRINTING)); + } + + for (int i = 0; i < 5; i++) { + mc.getConnection().getConnection().send(ServerboundInteractPacket.createAttackPacket(KillAura.getTarget(), mc.player.isShiftKeyDown())); + mc.getConnection().getConnection().send(new ServerboundSwingPacket(InteractionHand.MAIN_HAND)); + } + + if (!sprinting) { + mc.getConnection().getConnection().send(new ServerboundPlayerCommandPacket(mc.player, Action.STOP_SPRINTING)); + } + + this.attacked = true; + Vec3 deltaMovement = mc.player.getDeltaMovement(); + mc.player.setDeltaMovement(deltaMovement.x * 0.07776, deltaMovement.y, deltaMovement.z * 0.07776); + } + } + + @EventPriority + public void onPacket(PacketEvent event) { + if (mc.player != null + && event.getPacket() instanceof ClientboundSetEntityMotionPacket packet + && packet.getId() == mc.player.getId() + && KillAura.getTarget() != null) { + this.attacked = false; + this.receivedKnockBack = true; + } + } +} diff --git a/src/main/java/net/moran/loratadine/modules/impl/combat/KillAura.java b/src/main/java/net/moran/loratadine/modules/impl/combat/KillAura.java new file mode 100644 index 0000000..a235c0c --- /dev/null +++ b/src/main/java/net/moran/loratadine/modules/impl/combat/KillAura.java @@ -0,0 +1,116 @@ +package net.moran.loratadine.modules.impl.combat; + +import java.util.ArrayList; +import java.util.Comparator; +import java.util.List; +import lombok.Generated; +import net.minecraft.network.protocol.game.ServerboundInteractPacket; +import net.minecraft.world.InteractionHand; +import net.minecraft.world.entity.Entity; +import net.minecraft.world.entity.LivingEntity; +import net.moran.loratadine.event.Event; +import net.moran.loratadine.event.annotations.EventPriority; +import net.moran.loratadine.event.impl.LivingUpdateEvent; +import net.moran.loratadine.event.impl.MotionEvent; +import net.moran.loratadine.modules.Category; +import net.moran.loratadine.modules.Module; +import net.moran.loratadine.setting.impl.BooleanSetting; +import net.moran.loratadine.setting.impl.NumberSetting; +import net.moran.loratadine.utils.RotationUtils; +import net.moran.loratadine.utils.TimerUtils; +import net.moran.loratadine.utils.misc.EntityUtils; + +public class KillAura extends Module { + private final NumberSetting cpsValue = new NumberSetting("CPS", this, 11, 1, 20, 1); + private final NumberSetting rangeValue = new NumberSetting("Range", this, 2.65, 1, 6.0, 0.01); + private final BooleanSetting playersValue = new BooleanSetting("Players", this, true); + private final BooleanSetting mobsValue = new BooleanSetting("Mobs", this, false); + private final BooleanSetting animalsValue = new BooleanSetting("Animals", this, false); + private final BooleanSetting deadValue = new BooleanSetting("Dead", this, false); + private final BooleanSetting invisibleValue = new BooleanSetting("Invisible", this, false); + private static LivingEntity target; + private final List targets = new ArrayList<>(); + private final TimerUtils timer = new TimerUtils(); + + public KillAura() { + super("KillAura", Category.COMBAT, 82); + } + + @Override + protected void onEnable() { + this.targets.clear(); + target = null; + } + + @Override + protected void onDisable() { + this.targets.clear(); + target = null; + } + + @EventPriority + public void onMotion(LivingUpdateEvent event) { + List targets = new ArrayList<>(); + + for (Entity entity : mc.level.entitiesForRendering()) { + if (entity instanceof LivingEntity) { + LivingEntity livingEntity = (LivingEntity)entity; + if (this.filter(livingEntity)) { + targets.add(livingEntity); + } + } + } + + targets.sort(new Comparator() { + public int compare(LivingEntity e1, LivingEntity e2) { + return (int)(RotationUtils.getDistanceToEntityBox(e1) - RotationUtils.getDistanceToEntityBox(e2)); + } + }); + target = null; + if (!targets.isEmpty()) { + target = targets.get(0); + } + + if (target != null) { + float[] rotations = RotationUtils.getSimpleRotations(target); + mc.player.setYRot(rotations[0]); + mc.player.setXRot(rotations[1]); + } + } + + @EventPriority + public void onMotion(MotionEvent event) { + if (event.getSide() == Event.Side.PRE && target != null && this.timer.delay((long)(800 / this.cpsValue.getValue().intValue()))) { + mc.getConnection().send(ServerboundInteractPacket.createAttackPacket(target, mc.player.isShiftKeyDown())); + mc.player.swing(InteractionHand.MAIN_HAND); + this.timer.reset(); + } + } + + public boolean filter(LivingEntity entity) { + if (RotationUtils.getDistanceToEntityBox(entity) > (double)this.rangeValue.getValue().floatValue() + || !EntityUtils.isSelected( + entity, + this.playersValue.getValue(), + this.mobsValue.getValue(), + this.animalsValue.getValue(), + this.deadValue.getValue(), + this.invisibleValue.getValue(), + true + )) { + return false; + } else { + return !mc.player.hasLineOfSight(entity) ? false : !entity.isDeadOrDying() && !(entity.getHealth() <= 0.0F); + } + } + + @Generated + public static LivingEntity getTarget() { + return target; + } + + @Generated + public List getTargets() { + return this.targets; + } +} diff --git a/src/main/java/net/moran/loratadine/modules/impl/combat/SuperKnockBack.java b/src/main/java/net/moran/loratadine/modules/impl/combat/SuperKnockBack.java new file mode 100644 index 0000000..5627e3c --- /dev/null +++ b/src/main/java/net/moran/loratadine/modules/impl/combat/SuperKnockBack.java @@ -0,0 +1,40 @@ +package net.moran.loratadine.modules.impl.combat; + +import java.lang.reflect.Field; +import net.minecraft.network.protocol.game.ServerboundPlayerCommandPacket; +import net.minecraft.network.protocol.game.ServerboundPlayerCommandPacket.Action; +import net.moran.loratadine.event.annotations.EventPriority; +import net.moran.loratadine.event.impl.LivingUpdateEvent; +import net.moran.loratadine.modules.Category; +import net.moran.loratadine.modules.Module; +import net.moran.loratadine.utils.helper.ReflectionHelper; + +public class SuperKnockBack extends Module { + public SuperKnockBack() { + super("SuperKnockBack", Category.COMBAT); + this.setEnabled(true); + } + + @EventPriority + public void onUpdate(LivingUpdateEvent event) { + this.setSuffix("Legit"); + if (mc.level != null && mc.player != null && KillAura.getTarget() != null) { + boolean sprinting = false; + Field sprintingField = ReflectionHelper.findField(mc.player.getClass(), "f_108603_", "wasSprinting"); + + try { + sprinting = sprintingField.getBoolean(mc.player); + } catch (Exception var5) { + var5.printStackTrace(); + } + + if (!sprinting) { + mc.getConnection().getConnection().send(new ServerboundPlayerCommandPacket(mc.player, Action.START_SPRINTING)); + } + + if (!sprinting) { + mc.getConnection().getConnection().send(new ServerboundPlayerCommandPacket(mc.player, Action.STOP_SPRINTING)); + } + } + } +} diff --git a/src/main/java/net/moran/loratadine/modules/impl/misc/Disabler.java b/src/main/java/net/moran/loratadine/modules/impl/misc/Disabler.java new file mode 100644 index 0000000..a36ae0b --- /dev/null +++ b/src/main/java/net/moran/loratadine/modules/impl/misc/Disabler.java @@ -0,0 +1,11 @@ +package net.moran.loratadine.modules.impl.misc; + +import net.moran.loratadine.modules.Category; +import net.moran.loratadine.modules.Module; + +public class Disabler extends Module { + public Disabler() { + super("Disabler", Category.MISC); + this.setEnabled(false); + } +} diff --git a/src/main/java/net/moran/loratadine/modules/impl/misc/Teams.java b/src/main/java/net/moran/loratadine/modules/impl/misc/Teams.java new file mode 100644 index 0000000..81aa1cc --- /dev/null +++ b/src/main/java/net/moran/loratadine/modules/impl/misc/Teams.java @@ -0,0 +1,35 @@ +package net.moran.loratadine.modules.impl.misc; + +import net.minecraft.world.entity.LivingEntity; +import net.minecraft.world.entity.player.Player; +import net.minecraft.world.item.ArmorItem; +import net.minecraft.world.item.DyeableLeatherItem; +import net.minecraft.world.item.ItemStack; +import net.moran.loratadine.modules.Category; +import net.moran.loratadine.modules.Module; +import net.moran.loratadine.setting.impl.BooleanSetting; + +public class Teams extends Module { + private final BooleanSetting armorColor = new BooleanSetting("ArmorColor", this, true); + + public Teams() { + super("Teams", Category.MISC); + this.setEnabled(true); + } + + public boolean isSameTeam(LivingEntity entity) { + if (this.armorColor.getValue() && entity instanceof Player entityPlayer) { + ItemStack myHead = (ItemStack)mc.player.getInventory().armor.get(3); + ItemStack entityHead = (ItemStack)entityPlayer.getInventory().armor.get(3); + if (!myHead.isEmpty() && !entityHead.isEmpty() && myHead.getItem() instanceof ArmorItem && entityHead.getItem() instanceof ArmorItem) { + return this.getArmorColor(myHead) == this.getArmorColor(entityHead); + } + } + + return false; + } + + private int getArmorColor(ItemStack stack) { + return stack.getItem() instanceof DyeableLeatherItem ? ((DyeableLeatherItem)stack.getItem()).getColor(stack) : -1; + } +} diff --git a/src/main/java/net/moran/loratadine/modules/impl/movement/Eagle.java b/src/main/java/net/moran/loratadine/modules/impl/movement/Eagle.java new file mode 100644 index 0000000..13685cb --- /dev/null +++ b/src/main/java/net/moran/loratadine/modules/impl/movement/Eagle.java @@ -0,0 +1,68 @@ +package net.moran.loratadine.modules.impl.movement; + +import net.minecraft.client.KeyMapping; +import net.minecraft.core.BlockPos; +import net.minecraft.world.entity.player.Player; +import net.minecraft.world.item.BlockItem; +import net.minecraft.world.level.block.AirBlock; +import net.minecraft.world.level.block.Block; +import net.minecraft.world.level.block.state.BlockState; +import net.minecraft.world.phys.BlockHitResult; +import net.minecraft.world.phys.HitResult.Type; +import net.moran.loratadine.event.annotations.EventPriority; +import net.moran.loratadine.event.impl.LivingUpdateEvent; +import net.moran.loratadine.modules.Category; +import net.moran.loratadine.modules.Module; +import net.moran.loratadine.setting.impl.BooleanSetting; + +public class Eagle extends Module { + private final BooleanSetting autoBuild = new BooleanSetting("AutoBuild", this, true); + + public Eagle() { + super("Eagle", Category.MOVEMENT, 71); + } + + public static Block getBlock(BlockPos pos) { + return mc.level.getBlockState(pos).getBlock(); + } + + public static Block getBlockUnderPlayer(Player player) { + return getBlock(new BlockPos(player.getX(), player.getY() - 1.0, player.getZ())); + } + + @EventPriority + public void onUpdate(LivingUpdateEvent event) { + if (getBlockUnderPlayer(mc.player) instanceof AirBlock) { + if (mc.player.isOnGround()) { + KeyMapping.set(mc.options.keyShift.getKey(), true); + if (mc.player.getMainHandItem().getItem() instanceof BlockItem + || mc.player.getOffhandItem().getItem() instanceof BlockItem && this.autoBuild.getValue()) { + BlockHitResult hitResult = (BlockHitResult)mc.hitResult; + if (hitResult != null && hitResult.getType() == Type.BLOCK) { + BlockPos blockPos = hitResult.getBlockPos().relative(hitResult.getDirection()); + BlockState state = mc.level.getBlockState(blockPos); + if (state.getBlock() instanceof AirBlock) { + KeyMapping.set(mc.options.keyUse.getKey(), true); + } + } + } + } + } else if (mc.player.isOnGround()) { + KeyMapping.set(mc.options.keyShift.getKey(), false); + } + } + + @Override + public void onEnable() { + if (mc.player != null) { + mc.player.setShiftKeyDown(false); + KeyMapping.set(mc.options.keyUse.getKey(), false); + } + } + + @Override + public void onDisable() { + KeyMapping.set(mc.options.keyShift.getKey(), false); + KeyMapping.set(mc.options.keyUse.getKey(), false); + } +} diff --git a/src/main/java/net/moran/loratadine/modules/impl/movement/NoSlow.java b/src/main/java/net/moran/loratadine/modules/impl/movement/NoSlow.java new file mode 100644 index 0000000..49f057f --- /dev/null +++ b/src/main/java/net/moran/loratadine/modules/impl/movement/NoSlow.java @@ -0,0 +1,161 @@ +package net.moran.loratadine.modules.impl.movement; + +import dev.annotations.JNICInclude; +import it.unimi.dsi.fastutil.ints.Int2ObjectMap; +import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap; +import net.minecraft.client.player.Input; +import net.minecraft.network.protocol.Packet; +import net.minecraft.network.protocol.game.ClientboundContainerSetContentPacket; +import net.minecraft.network.protocol.game.ClientboundContainerSetSlotPacket; +import net.minecraft.network.protocol.game.ServerboundContainerClickPacket; +import net.minecraft.network.protocol.game.ServerboundPlayerActionPacket; +import net.minecraft.network.protocol.game.ServerboundUseItemPacket; +import net.minecraft.network.protocol.game.ServerboundPlayerActionPacket.Action; +import net.minecraft.world.inventory.ClickType; +import net.minecraft.world.item.BowItem; +import net.minecraft.world.item.CrossbowItem; +import net.minecraft.world.item.Item; +import net.minecraft.world.item.ItemStack; +import net.minecraft.world.item.Items; +import net.minecraft.world.level.block.Block; +import net.minecraft.world.level.block.Blocks; +import net.minecraft.world.phys.BlockHitResult; +import net.minecraft.world.phys.HitResult; +import net.minecraft.world.phys.HitResult.Type; +import net.moran.loratadine.event.Event; +import net.moran.loratadine.event.annotations.EventPriority; +import net.moran.loratadine.event.impl.GameTickEvent; +import net.moran.loratadine.event.impl.MotionEvent; +import net.moran.loratadine.event.impl.PacketEvent; +import net.moran.loratadine.event.impl.helper.CustomKeyboardInput; +import net.moran.loratadine.modules.Category; +import net.moran.loratadine.modules.Module; + +@JNICInclude +public class NoSlow extends Module { + Input old; + boolean shouldSlow; + + public NoSlow() { + super("NoSlow", Category.MOVEMENT); + this.setEnabled(true); + } + + @Override + public void onEnable() { + if (mc.player != null) { + this.old = mc.player.input; + if (!(mc.player.input instanceof CustomKeyboardInput)) { + mc.player.input = new CustomKeyboardInput(mc.options); + } + } + } + + @Override + public void onDisable() { + mc.player.input = this.old; + } + + private boolean isUsable(ItemStack itemStack) { + if (itemStack != null && !itemStack.isEmpty()) { + Item item = itemStack.getItem(); + boolean isFood = item.getFoodProperties() != null; + boolean isShield = item == Items.SHIELD; + boolean isBow = item instanceof BowItem; + boolean isCrossBow = item instanceof CrossbowItem; + return isFood || isShield || isBow || isCrossBow; + } else { + return false; + } + } + + @EventPriority + public void onMotion(MotionEvent event) { + this.setSuffix("Heypixel"); + if (event.getSide() != Event.Side.POST) { + if (mc.player.isUsingItem() && this.isUsable(mc.player.getMainHandItem()) || this.isUsable(mc.player.getOffhandItem())) { + this.send(); + } + } + } + + @EventPriority + public void onPacket(PacketEvent event) { + Packet packet = event.getPacket(); + if (event.getSide() == Event.Side.PRE) { + Block block = null; + HitResult hitResult = mc.hitResult; + if (hitResult != null && hitResult.getType() == Type.BLOCK) { + block = mc.level.getBlockState(((BlockHitResult)hitResult).getBlockPos()).getBlock(); + } + + if (this.isUsable(mc.player.getMainHandItem()) + || this.isUsable(mc.player.getOffhandItem()) && mc.player.isUsingItem() && (block == null || block != Blocks.CHEST)) { + if (packet instanceof ClientboundContainerSetContentPacket) { + event.setCancelled(true); + this.noCancel(); + this.shouldSlow = false; + } + + if (packet instanceof ClientboundContainerSetSlotPacket) { + event.setCancelled(true); + } + } + } + + if (event.getSide() == Event.Side.POST && (this.isUsable(mc.player.getMainHandItem()) || this.isUsable(mc.player.getOffhandItem()))) { + if (packet instanceof ServerboundUseItemPacket) { + this.noCancel(); + this.shouldSlow = true; + this.send(); + } + + if (packet instanceof ServerboundPlayerActionPacket && ((ServerboundPlayerActionPacket)packet).getAction() == Action.RELEASE_USE_ITEM) { + this.noCancel(); + this.shouldSlow = true; + } + } + } + + private void send() { + if (mc.player.getUseItemRemainingTicks() + % ( + !(mc.player.getMainHandItem().getItem() instanceof BowItem) + && !(mc.player.getOffhandItem().getItem() instanceof BowItem) + && !(mc.player.getMainHandItem().getItem() instanceof CrossbowItem) + && !(mc.player.getOffhandItem().getItem() instanceof CrossbowItem) + ? 6 + : 8 + ) + == 0) { + Int2ObjectMap modifiedStacks = new Int2ObjectOpenHashMap(); + modifiedStacks.put(36, new ItemStack(Items.BARRIER)); + mc.player.connection.send(new ServerboundContainerClickPacket(0, 0, 36, 0, ClickType.SWAP, new ItemStack(Blocks.BARRIER), modifiedStacks)); + } + } + + private void noCancel() { + if (!(mc.player.input instanceof CustomKeyboardInput)) { + this.old = mc.player.input; + mc.player.input = new CustomKeyboardInput(mc.options); + } + + CustomKeyboardInput move = (CustomKeyboardInput)mc.player.input; + move.setCancel(false); + } + + @EventPriority + public void onSlowDown(GameTickEvent event) { + if (!(mc.player.input instanceof CustomKeyboardInput)) { + this.old = mc.player.input; + mc.player.input = new CustomKeyboardInput(mc.options); + } + + CustomKeyboardInput move = (CustomKeyboardInput)mc.player.input; + if (mc.player.isUsingItem()) { + move.setCancel(!this.shouldSlow); + } else { + move.setCancel(false); + } + } +} diff --git a/src/main/java/net/moran/loratadine/modules/impl/movement/Sprint.java b/src/main/java/net/moran/loratadine/modules/impl/movement/Sprint.java new file mode 100644 index 0000000..1a5f773 --- /dev/null +++ b/src/main/java/net/moran/loratadine/modules/impl/movement/Sprint.java @@ -0,0 +1,30 @@ +package net.moran.loratadine.modules.impl.movement; + +import net.moran.loratadine.event.annotations.EventPriority; +import net.moran.loratadine.event.impl.LivingUpdateEvent; +import net.moran.loratadine.modules.Category; +import net.moran.loratadine.modules.Module; +import net.moran.loratadine.setting.impl.BooleanSetting; + +public class Sprint extends Module { + private final BooleanSetting usingSprint = new BooleanSetting("UsingSprint", this, true); + + public Sprint() { + super("Sprint", Category.MOVEMENT, 86); + this.setEnabled(true); + } + + @EventPriority + public void onUpdate(LivingUpdateEvent event) { + if (mc.level != null && mc.player != null) { + mc.player + .setSprinting( + mc.player.getFoodData().getFoodLevel() > 6 + && !mc.player.horizontalCollision + && mc.player.input.forwardImpulse > 0.0F + && !mc.player.isShiftKeyDown() + || !mc.player.isUsingItem() && !this.usingSprint.getValue() + ); + } + } +} diff --git a/src/main/java/net/moran/loratadine/modules/impl/player/AutoTool.java b/src/main/java/net/moran/loratadine/modules/impl/player/AutoTool.java new file mode 100644 index 0000000..be8051b --- /dev/null +++ b/src/main/java/net/moran/loratadine/modules/impl/player/AutoTool.java @@ -0,0 +1,74 @@ +package net.moran.loratadine.modules.impl.player; + +import net.minecraft.world.item.ItemStack; +import net.minecraft.world.level.block.state.BlockState; +import net.minecraft.world.phys.BlockHitResult; +import net.minecraft.world.phys.HitResult.Type; +import net.moran.loratadine.event.annotations.EventPriority; +import net.moran.loratadine.event.impl.Render2DEvent; +import net.moran.loratadine.modules.Category; +import net.moran.loratadine.modules.Module; + +public class AutoTool extends Module { + private int prevItem = 0; + private boolean mining = false; + + public AutoTool() { + super("AutoTool", Category.PLAYER); + this.setEnabled(true); + } + + @EventPriority + public void onRender2D(Render2DEvent event) { + if (!mc.options.keyUse.isDown() && mc.options.keyAttack.isDown() && mc.hitResult != null && mc.hitResult.getType() == Type.BLOCK) { + if (!this.mining) { + this.prevItem = mc.player.getInventory().selected; + } + + this.switchSlot(); + this.mining = true; + } else if (this.mining) { + this.restore(); + this.mining = false; + } else { + this.prevItem = mc.player.getInventory().selected; + } + } + + public void switchSlot() { + float bestSpeed = 1.0F; + int bestSlot = -1; + if (mc.hitResult != null && !mc.level.isEmptyBlock(((BlockHitResult)mc.hitResult).getBlockPos())) { + BlockState blockState = mc.level.getBlockState(((BlockHitResult)mc.hitResult).getBlockPos()); + + for (int i = 0; i <= 8; i++) { + ItemStack item = mc.player.getInventory().getItem(i); + if (!item.isEmpty()) { + float speed = item.getDestroySpeed(blockState); + if (speed > bestSpeed) { + bestSpeed = speed; + bestSlot = i; + } + } + } + + if (bestSlot != -1) { + mc.player.getInventory().selected = bestSlot; + } + } + } + + public void restore() { + for (int i = 0; i <= 8; i++) { + if (i == this.prevItem) { + mc.player.getInventory().selected = i; + mc.gameMode.tick(); + } + } + } + + @Override + public void onEnable() { + this.prevItem = 0; + } +} diff --git a/src/main/java/net/moran/loratadine/modules/impl/player/ChestStealer.java b/src/main/java/net/moran/loratadine/modules/impl/player/ChestStealer.java new file mode 100644 index 0000000..98b96fa --- /dev/null +++ b/src/main/java/net/moran/loratadine/modules/impl/player/ChestStealer.java @@ -0,0 +1,159 @@ +package net.moran.loratadine.modules.impl.player; + +import lombok.Generated; +import net.minecraft.world.inventory.ChestMenu; +import net.minecraft.world.inventory.ClickType; +import net.minecraft.world.item.ArmorItem; +import net.minecraft.world.item.AxeItem; +import net.minecraft.world.item.BlockItem; +import net.minecraft.world.item.BowItem; +import net.minecraft.world.item.CrossbowItem; +import net.minecraft.world.item.Item; +import net.minecraft.world.item.ItemStack; +import net.minecraft.world.item.Items; +import net.minecraft.world.item.PickaxeItem; +import net.minecraft.world.item.PotionItem; +import net.minecraft.world.item.SwordItem; +import net.moran.loratadine.event.Event; +import net.moran.loratadine.event.annotations.EventPriority; +import net.moran.loratadine.event.impl.MotionEvent; +import net.moran.loratadine.modules.Category; +import net.moran.loratadine.modules.Module; +import net.moran.loratadine.setting.impl.BooleanSetting; +import net.moran.loratadine.setting.impl.NumberSetting; +import net.moran.loratadine.utils.TimerUtils; +import net.moran.loratadine.utils.item.InventoryUtils; +import net.moran.loratadine.utils.math.MathUtils; + +public class ChestStealer extends Module { + private final BooleanSetting noDelay = new BooleanSetting("No Delay", this, false); + private final BooleanSetting silent = new BooleanSetting("Silent", this, false); + private final TimerUtils stopwatch2 = new TimerUtils(); + private final TimerUtils stopwatch = new TimerUtils(); + private long nextClick; + private int lastClick; + private int lastSteal; + private final NumberSetting delay = new NumberSetting("StealDelay", this, 100, 0, 1000, 10); + private final BooleanSetting trash = new BooleanSetting("PickTrash", this, false); + + public ChestStealer() { + super("ChestStealer", Category.PLAYER, 66); + } + + @EventPriority + public void onMotion(MotionEvent event) { + if (event.getSide() == Event.Side.PRE) { + if (mc.player == null || mc.player.containerMenu == null || !this.stopwatch.hasTimeElapsed(this.nextClick)) { + return; + } + + if (mc.player.containerMenu instanceof ChestMenu container) { + this.lastSteal++; + if (this.isChestEmpty(container) && this.stopwatch2.hasTimeElapsed(100L)) { + mc.player.closeContainer(); + return; + } + + for (int i = 0; i < container.getContainer().getContainerSize(); i++) { + if (!container.getContainer().getItem(i).isEmpty() && this.lastSteal > 1 && (this.isItemUseful(container, i) || this.trash.getValue())) { + this.nextClick = (long)Math.round( + MathUtils.getRandomFloat((float)this.delay.getValue().intValue(), (float)(this.delay.getValue().intValue() + 5)) + ); + mc.gameMode.handleInventoryMouseClick(container.containerId, i, 0, ClickType.QUICK_MOVE, mc.player); + this.stopwatch.reset(); + this.stopwatch2.reset(); + this.lastClick = 0; + if (this.nextClick > 0L) { + return; + } + } + } + } + } + } + + private boolean isChestEmpty(ChestMenu c) { + for (int i = 0; i < c.getContainer().getMaxStackSize(); i++) { + if (!c.getContainer().getItem(i).isEmpty() && (this.isItemUseful(c, i) || this.trash.getValue())) { + return false; + } + } + + return true; + } + + private boolean isItemUseful(ChestMenu c, int i) { + ItemStack itemStack = c.getSlot(i).getItem(); + Item item = itemStack.getItem(); + if (item instanceof AxeItem || item instanceof PickaxeItem) { + return true; + } else if (itemStack.getItem().getFoodProperties() != null) { + return true; + } else if (item instanceof BowItem || item == Items.ARROW) { + return true; + } else if (item instanceof PotionItem) { + return true; + } else if (item instanceof SwordItem && InventoryUtils.isBestSword(c, itemStack)) { + return true; + } else if (item instanceof ArmorItem && InventoryUtils.isBestArmor(c, itemStack)) { + return true; + } else if (item instanceof BlockItem) { + return true; + } else if (item == Items.SLIME_BALL) { + return true; + } else if (item instanceof CrossbowItem) { + return true; + } else if (item == Items.WATER_BUCKET) { + return true; + } else if (item == Items.TOTEM_OF_UNDYING) { + return true; + } else { + return item == Items.FIRE_CHARGE ? true : item == Items.ENDER_PEARL; + } + } + + @Generated + public BooleanSetting getNoDelay() { + return this.noDelay; + } + + @Generated + public BooleanSetting getSilent() { + return this.silent; + } + + @Generated + public TimerUtils getStopwatch2() { + return this.stopwatch2; + } + + @Generated + public TimerUtils getStopwatch() { + return this.stopwatch; + } + + @Generated + public long getNextClick() { + return this.nextClick; + } + + @Generated + public int getLastClick() { + return this.lastClick; + } + + @Generated + public int getLastSteal() { + return this.lastSteal; + } + + @Generated + public NumberSetting getDelay() { + return this.delay; + } + + @Generated + public BooleanSetting getTrash() { + return this.trash; + } +} diff --git a/src/main/java/net/moran/loratadine/modules/impl/player/InvCleaner.java b/src/main/java/net/moran/loratadine/modules/impl/player/InvCleaner.java new file mode 100644 index 0000000..883e574 --- /dev/null +++ b/src/main/java/net/moran/loratadine/modules/impl/player/InvCleaner.java @@ -0,0 +1,472 @@ +package net.moran.loratadine.modules.impl.player; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Comparator; +import java.util.List; +import net.minecraft.client.gui.screens.inventory.InventoryScreen; +import net.minecraft.network.protocol.Packet; +import net.minecraft.network.protocol.game.ClientboundOpenScreenPacket; +import net.minecraft.network.protocol.game.ServerboundContainerClickPacket; +import net.minecraft.network.protocol.game.ServerboundContainerClosePacket; +import net.minecraft.network.protocol.game.ServerboundPlayerCommandPacket; +import net.minecraft.network.protocol.game.ServerboundSwingPacket; +import net.minecraft.network.protocol.game.ServerboundPlayerCommandPacket.Action; +import net.minecraft.world.InteractionHand; +import net.minecraft.world.entity.EquipmentSlot; +import net.minecraft.world.inventory.AbstractContainerMenu; +import net.minecraft.world.inventory.ClickType; +import net.minecraft.world.inventory.Slot; +import net.minecraft.world.item.ArmorItem; +import net.minecraft.world.item.BlockItem; +import net.minecraft.world.item.BowItem; +import net.minecraft.world.item.DiggerItem; +import net.minecraft.world.item.Item; +import net.minecraft.world.item.ItemStack; +import net.minecraft.world.item.Items; +import net.minecraft.world.item.PotionItem; +import net.minecraft.world.item.SwordItem; +import net.moran.loratadine.event.Event; +import net.moran.loratadine.event.annotations.EventPriority; +import net.moran.loratadine.event.impl.MotionEvent; +import net.moran.loratadine.event.impl.PacketEvent; +import net.moran.loratadine.modules.Category; +import net.moran.loratadine.modules.Module; +import net.moran.loratadine.setting.impl.BooleanSetting; +import net.moran.loratadine.setting.impl.NumberSetting; +import net.moran.loratadine.utils.TimerUtils; +import net.moran.loratadine.utils.item.InventoryUtils; +import net.moran.loratadine.utils.player.BlockUtils; +import net.moran.loratadine.utils.wrapper.Wrapper; + +public class InvCleaner extends Module { + private final BooleanSetting swing = new BooleanSetting("Swing", this, true); + private final BooleanSetting offHand = new BooleanSetting("Offhand Gapple", this, false); + private final NumberSetting delay = new NumberSetting("Delay", this, 5, 0, 300, 10); + private final NumberSetting armorDelay = new NumberSetting("Armor Delay", this, 20, 0, 300, 10); + public final NumberSetting slotWeapon = new NumberSetting("Weapon Slot", this, 1, 1, 9, 1); + public final NumberSetting slotPick = new NumberSetting("Pickaxe Slot", this, 2, 1, 9, 1); + public final NumberSetting slotAxe = new NumberSetting("Axe Slot", this, 3, 1, 9, 1); + public final NumberSetting slotGapple = new NumberSetting("Gapple Slot", this, 4, 1, 9, 1); + public final NumberSetting slotWater = new NumberSetting("Water Slot", this, 5, 1, 9, 1); + public final NumberSetting slotBow = new NumberSetting("Bow Slot", this, 6, 1, 9, 1); + public final NumberSetting slotBlock = new NumberSetting("Block Slot", this, 7, 1, 9, 1); + public final NumberSetting slotPearl = new NumberSetting("Pearl Slot", this, 8, 1, 9, 1); + public final String[] serverItems = new String[]{ + "选择游戏", + "加入游戏", + "职业选择菜单", + "离开对局", + "再来一局", + "selector", + "tracking compass", + "(right click)", + "tienda ", + "perfil", + "salir", + "shop", + "collectibles", + "game", + "profil", + "lobby", + "show all", + "hub", + "friends only", + "cofre", + "(click", + "teleport", + "play", + "exit", + "hide all", + "jeux", + "gadget", + " (activ", + "emote", + "amis", + "bountique", + "choisir", + "choose " + }; + private final int[] bestArmorPieces = new int[6]; + private final List trash = new ArrayList<>(); + private final int[] bestToolSlots = new int[2]; + private final List gappleStackSlots = new ArrayList<>(); + private int bestSwordSlot; + private int bestPearlSlot; + private int bestBowSlot; + private int bestWaterSlot; + private int ticksSinceLastClick; + private boolean nextTickCloseInventory; + private boolean serverOpen; + private boolean clientOpen; + private final TimerUtils timer = new TimerUtils(); + + public InvCleaner() { + super("InvCleaner", Category.PLAYER, 66); + } + + @EventPriority + private void onPacket(PacketEvent event) { + Packet packet = event.getPacket(); + if (packet instanceof ClientboundOpenScreenPacket) { + this.clientOpen = false; + this.serverOpen = false; + } + + if (packet instanceof ServerboundPlayerCommandPacket wrapper) { + if (wrapper.getData() == mc.player.getId() && wrapper.getAction() == Action.OPEN_INVENTORY) { + this.clientOpen = true; + this.serverOpen = true; + } + } else if (packet instanceof ServerboundContainerClosePacket wrapperx) { + if (wrapperx.getContainerId() == mc.player.inventoryMenu.containerId) { + this.clientOpen = false; + this.serverOpen = false; + } + } else if (packet instanceof ServerboundContainerClickPacket && !mc.player.isUsingItem()) { + this.ticksSinceLastClick = 0; + } + } + + private boolean dropItem(List listOfSlots) { + if (!listOfSlots.isEmpty()) { + int slot = listOfSlots.remove(0); + mc.gameMode.handleInventoryMouseClick(mc.player.inventoryMenu.containerId, slot, 1, ClickType.THROW, mc.player); + if (this.swing.getValue()) { + mc.getConnection().send(new ServerboundSwingPacket(InteractionHand.MAIN_HAND)); + } + + return true; + } else { + return false; + } + } + + @EventPriority + private void onMotion(MotionEvent event) { + if (!mc.player.isSpectator()) { + if (event.getSide() == Event.Side.PRE && !mc.player.isUsingItem()) { + this.ticksSinceLastClick++; + if ((double)this.ticksSinceLastClick < Math.floor(this.delay.getValue().doubleValue() / 50.0)) { + return; + } + + if (mc.screen instanceof InventoryScreen) { + this.clear(); + + for (int slot = 5; slot < 45; slot++) { + ItemStack stack = mc.player.containerMenu.getSlot(slot).getItem(); + AbstractContainerMenu handler = mc.player.containerMenu; + if (!stack.isEmpty()) { + if (stack.getItem() instanceof SwordItem && InventoryUtils.isBestSword(handler, stack)) { + this.bestSwordSlot = slot; + } else if (stack.getItem() instanceof DiggerItem && InventoryUtils.isBestTool(handler, stack)) { + int toolType = InventoryUtils.getToolType(stack); + if (toolType != -1 && slot != this.bestToolSlots[toolType]) { + this.bestToolSlots[toolType] = slot; + } + } else { + Item armorSlot = stack.getItem(); + if (armorSlot instanceof ArmorItem) { + ArmorItem armor = (ArmorItem)armorSlot; + if (InventoryUtils.isBestArmor(handler, stack)) { + EquipmentSlot armorSlotx = armor.getSlot(); + int index = armorSlotx.ordinal(); + if (index >= 1 && index < this.bestArmorPieces.length + 2) { + int pieceSlot = this.bestArmorPieces[index]; + if (pieceSlot == -1 || slot != pieceSlot) { + this.bestArmorPieces[index] = slot; + } + } + continue; + } + } + + if (!(stack.getItem() instanceof BowItem) || !InventoryUtils.isBestBow(handler, stack)) { + if (stack.getItem() == Items.GOLDEN_APPLE) { + this.gappleStackSlots.add(slot); + } else if (stack.getItem() == Items.ENDER_PEARL) { + this.bestPearlSlot = slot; + } else if (stack.getItem() == Items.WATER_BUCKET) { + if (slot != this.bestWaterSlot) { + this.bestWaterSlot = slot; + } + } else if (!this.trash.contains(slot) && !isValidStack(stack)) { + this.trash.add(slot); + } + } else if (slot != this.bestBowSlot) { + this.bestBowSlot = slot; + } + } + } + } + + boolean busy = !this.trash.isEmpty() || this.equipArmor(false) || this.sortItems(false); + if (!busy) { + if (this.nextTickCloseInventory) { + this.close(); + this.nextTickCloseInventory = false; + } else { + this.nextTickCloseInventory = true; + } + + return; + } + + boolean waitUntilNextTick = !this.serverOpen; + this.open(); + if (this.nextTickCloseInventory) { + this.nextTickCloseInventory = false; + } + + if (waitUntilNextTick) { + return; + } + + if (this.timer.hasTimeElapsed(this.armorDelay.getValue().longValue()) && this.equipArmor(true)) { + return; + } + + if (this.dropItem(this.trash)) { + return; + } + + this.sortItems(true); + } + } + } + } + + private boolean sortItems(boolean moveItems) { + int goodSwordSlot = this.slotWeapon.getValue().intValue() + 35; + if (this.bestSwordSlot != -1 && this.bestSwordSlot != goodSwordSlot) { + if (moveItems) { + this.putItemInSlot(goodSwordSlot, this.bestSwordSlot); + this.bestSwordSlot = goodSwordSlot; + } + + return true; + } else { + int goodBowSlot = this.slotBow.getValue().intValue() + 35; + if (this.bestBowSlot != -1 && this.bestBowSlot != goodBowSlot) { + if (moveItems) { + this.putItemInSlot(goodBowSlot, this.bestBowSlot); + this.bestBowSlot = goodBowSlot; + } + + return true; + } else { + int goodWaterSlot = this.slotWater.getValue().intValue() + 35; + if (this.bestWaterSlot != -1 && this.bestWaterSlot != goodWaterSlot) { + if (moveItems) { + this.putItemInSlot(goodWaterSlot, this.bestWaterSlot); + this.bestWaterSlot = goodWaterSlot; + } + + return true; + } else { + int goodGappleSlot = this.slotGapple.getValue().intValue() + 35; + if (this.offHand.getValue()) { + if (!this.gappleStackSlots.isEmpty()) { + this.gappleStackSlots.sort(new Comparator() { + public int compare(Integer slot1, Integer slot2) { + int count1 = Wrapper.mc.player.containerMenu.getSlot(slot1).getItem().getCount(); + int count2 = Wrapper.mc.player.containerMenu.getSlot(slot2).getItem().getCount(); + return Integer.compare(count1, count2); + } + }); + int bestGappleSlot = this.gappleStackSlots.get(0); + if (bestGappleSlot != 45) { + if (moveItems) { + this.putItemInSlot(45, bestGappleSlot); + this.gappleStackSlots.set(0, 45); + } + + return true; + } + } + } else if (!this.gappleStackSlots.isEmpty()) { + this.gappleStackSlots.sort(new Comparator() { + public int compare(Integer slot1, Integer slot2) { + int count1 = Wrapper.mc.player.containerMenu.getSlot(slot1).getItem().getCount(); + int count2 = Wrapper.mc.player.containerMenu.getSlot(slot2).getItem().getCount(); + return Integer.compare(count1, count2); + } + }); + int bestGappleSlot = this.gappleStackSlots.get(0); + if (bestGappleSlot != goodGappleSlot) { + if (moveItems) { + this.putItemInSlot(goodGappleSlot, bestGappleSlot); + this.gappleStackSlots.set(0, goodGappleSlot); + } + + return true; + } + } + + int[] toolSlots = new int[]{this.slotPick.getValue().intValue() + 35, this.slotAxe.getValue().intValue() + 35}; + + for (int toolSlot : this.bestToolSlots) { + if (toolSlot != -1) { + int type = InventoryUtils.getToolType(mc.player.containerMenu.getSlot(toolSlot).getItem()); + if (type != -1 && toolSlot != toolSlots[type]) { + if (moveItems) { + this.putToolsInSlot(type, toolSlots); + } + + return true; + } + } + } + + int goodBlockSlot = this.slotBlock.getValue().intValue() + 35; + int mostBlocksSlot = this.getMostBlocks(); + if (mostBlocksSlot != -1 && mostBlocksSlot != goodBlockSlot) { + Slot dss = mc.player.containerMenu.getSlot(goodBlockSlot); + ItemStack dsis = dss.getItem(); + if (dsis.isEmpty() + || !(dsis.getItem() instanceof BlockItem) + || dsis.getCount() < mc.player.containerMenu.getSlot(mostBlocksSlot).getItem().getCount()) { + this.putItemInSlot(goodBlockSlot, mostBlocksSlot); + } + } + + int goodPearlSlot = this.slotPearl.getValue().intValue() + 35; + if (this.bestPearlSlot != -1 && this.bestPearlSlot != goodPearlSlot) { + if (moveItems) { + this.putItemInSlot(goodPearlSlot, this.bestPearlSlot); + this.bestPearlSlot = goodPearlSlot; + } + + return true; + } else { + return false; + } + } + } + } + } + + public int getMostBlocks() { + int stack = 0; + int biggestSlot = -1; + + for (int i = 9; i < 45; i++) { + Slot slot = mc.player.containerMenu.getSlot(i); + ItemStack is = slot.getItem(); + if (!is.isEmpty() && is.getItem() instanceof BlockItem && is.getCount() > stack) { + boolean noneMatch = true; + String itemName = is.getItem().getName(is).getString().toLowerCase(); + + for (String serverItem : this.serverItems) { + if (itemName.contains(serverItem.toLowerCase())) { + noneMatch = false; + break; + } + } + + if (noneMatch) { + stack = is.getCount(); + biggestSlot = i; + } + } + } + + return biggestSlot; + } + + private boolean equipArmor(boolean moveItems) { + for (int i = 0; i < this.bestArmorPieces.length; i++) { + int piece = this.bestArmorPieces[i]; + if (piece != -1) { + int armorPieceSlot = this.getArmorSlot(EquipmentSlot.values()[i]); + if (armorPieceSlot >= 0 && armorPieceSlot < mc.player.containerMenu.slots.size()) { + ItemStack stack = mc.player.containerMenu.getSlot(armorPieceSlot).getItem(); + if (stack.isEmpty()) { + if (moveItems) { + mc.gameMode.handleInventoryMouseClick(mc.player.containerMenu.containerId, piece, 0, ClickType.QUICK_MOVE, mc.player); + } + + this.timer.reset(); + return true; + } + } + } + } + + return false; + } + + private int getArmorSlot(EquipmentSlot slot) { + switch (slot) { + case HEAD: + return 5; + case CHEST: + return 6; + case LEGS: + return 7; + case FEET: + return 8; + default: + return -1; + } + } + + private void putItemInSlot(int slot, int slotIn) { + mc.gameMode.handleInventoryMouseClick(mc.player.containerMenu.containerId, slotIn, slot == 45 ? 40 : slot - 36, ClickType.SWAP, mc.player); + } + + private void putToolsInSlot(int tool, int[] toolSlots) { + int toolSlot = toolSlots[tool]; + mc.gameMode.handleInventoryMouseClick(mc.player.containerMenu.containerId, this.bestToolSlots[tool], toolSlot - 36, ClickType.SWAP, mc.player); + this.bestToolSlots[tool] = toolSlot; + } + + private static boolean isValidStack(ItemStack stack) { + if (stack.getItem() instanceof BlockItem && BlockUtils.isValidBlock(((BlockItem)stack.getItem()).getBlock())) { + return true; + } else if (stack.getItem() instanceof PotionItem && InventoryUtils.isBuffPotion(stack)) { + return true; + } else if (stack.getItem().getFoodProperties() != null && InventoryUtils.isGoodFood(stack)) { + return true; + } else { + return stack.getItem() == Items.TOTEM_OF_UNDYING ? true : InventoryUtils.isGoodItem(stack); + } + } + + @Override + public void onEnable() { + this.ticksSinceLastClick = 0; + this.clientOpen = mc.screen instanceof InventoryScreen; + this.serverOpen = this.clientOpen; + } + + @Override + public void onDisable() { + this.clear(); + } + + private void open() { + if (!this.clientOpen && !this.serverOpen) { + mc.getConnection().send(new ServerboundPlayerCommandPacket(mc.player, Action.OPEN_INVENTORY)); + this.serverOpen = true; + } + } + + private void close() { + if (!this.clientOpen && this.serverOpen) { + mc.getConnection().send(new ServerboundContainerClosePacket(mc.player.inventoryMenu.containerId)); + this.serverOpen = false; + } + } + + private void clear() { + this.trash.clear(); + this.bestBowSlot = -1; + this.bestSwordSlot = -1; + this.bestWaterSlot = -1; + this.gappleStackSlots.clear(); + Arrays.fill(this.bestArmorPieces, -1); + Arrays.fill(this.bestToolSlots, -1); + } +} diff --git a/src/main/java/net/moran/loratadine/modules/impl/render/ClickGui.java b/src/main/java/net/moran/loratadine/modules/impl/render/ClickGui.java new file mode 100644 index 0000000..338f021 --- /dev/null +++ b/src/main/java/net/moran/loratadine/modules/impl/render/ClickGui.java @@ -0,0 +1,17 @@ +package net.moran.loratadine.modules.impl.render; + +import net.moran.loratadine.modules.Category; +import net.moran.loratadine.modules.Module; +import net.moran.loratadine.ui.clickgui.ClickGUI; + +public class ClickGui extends Module { + public ClickGui() { + super("ClickGui", Category.RENDER, 344); + } + + @Override + protected void onEnable() { + mc.setScreen(ClickGUI.INSTANCE); + this.setEnabled(false); + } +} diff --git a/src/main/java/net/moran/loratadine/modules/impl/render/ESP.java b/src/main/java/net/moran/loratadine/modules/impl/render/ESP.java new file mode 100644 index 0000000..bd2a580 --- /dev/null +++ b/src/main/java/net/moran/loratadine/modules/impl/render/ESP.java @@ -0,0 +1,50 @@ +package net.moran.loratadine.modules.impl.render; + +import com.mojang.blaze3d.vertex.PoseStack; +import net.minecraft.world.entity.Entity; +import net.minecraft.world.entity.LivingEntity; +import net.moran.loratadine.event.annotations.EventPriority; +import net.moran.loratadine.event.impl.Render3DEvent; +import net.moran.loratadine.modules.Category; +import net.moran.loratadine.modules.Module; +import net.moran.loratadine.setting.impl.BooleanSetting; +import net.moran.loratadine.utils.misc.EntityUtils; +import net.moran.loratadine.utils.render.ColorUtils; +import net.moran.loratadine.utils.render.RenderUtils; + +public final class ESP extends Module { + private final BooleanSetting playersValue = new BooleanSetting("Players", this, true); + private final BooleanSetting mobsValue = new BooleanSetting("Mobs", this, false); + private final BooleanSetting animalsValue = new BooleanSetting("Animals", this, false); + private final BooleanSetting deadValue = new BooleanSetting("Dead", this, false); + private final BooleanSetting invisibleValue = new BooleanSetting("Invisible", this, false); + + public ESP() { + super("ESP", Category.RENDER, -1); + this.setEnabled(true); + } + + @EventPriority + public void onRender3D(Render3DEvent event) { + if (mc.player != null && mc.level != null) { + PoseStack poseStack = event.poseStack(); + + for (Entity entity : mc.level.entitiesForRendering()) { + if (entity instanceof LivingEntity) { + LivingEntity livingEntity = (LivingEntity)entity; + if (EntityUtils.isSelected( + entity, + this.playersValue.getValue(), + this.mobsValue.getValue(), + this.animalsValue.getValue(), + this.deadValue.getValue(), + this.invisibleValue.getValue(), + true + )) { + RenderUtils.renderEntityBoundingBox(poseStack, 0, livingEntity, ColorUtils.rainbow(10, 1).getRGB(), true); + } + } + } + } + } +} diff --git a/src/main/java/net/moran/loratadine/modules/impl/render/FullBright.java b/src/main/java/net/moran/loratadine/modules/impl/render/FullBright.java new file mode 100644 index 0000000..0f24eff --- /dev/null +++ b/src/main/java/net/moran/loratadine/modules/impl/render/FullBright.java @@ -0,0 +1,32 @@ +package net.moran.loratadine.modules.impl.render; + +import net.moran.loratadine.event.annotations.EventPriority; +import net.moran.loratadine.event.impl.GameTickEvent; +import net.moran.loratadine.modules.Category; +import net.moran.loratadine.modules.Module; + +public class FullBright extends Module { + private double old; + + public FullBright() { + super("FullBright", Category.RENDER); + this.setEnabled(true); + } + + @Override + public void onEnable() { + this.old = mc.options.gamma; + } + + @Override + public void onDisable() { + mc.options.gamma = this.old; + } + + @EventPriority + public void onTick(GameTickEvent e) { + if (mc.options.gamma != 10000.0) { + mc.options.gamma = 10000.0; + } + } +} diff --git a/src/main/java/net/moran/loratadine/modules/impl/render/HUD.java b/src/main/java/net/moran/loratadine/modules/impl/render/HUD.java new file mode 100644 index 0000000..207d7f5 --- /dev/null +++ b/src/main/java/net/moran/loratadine/modules/impl/render/HUD.java @@ -0,0 +1,83 @@ +package net.moran.loratadine.modules.impl.render; + +import java.lang.reflect.Field; +import java.util.ArrayList; +import java.util.Collection; +import java.util.Comparator; +import java.util.List; +import net.minecraft.ChatFormatting; +import net.minecraft.util.Mth; +import net.moran.loratadine.Loratadine; +import net.moran.loratadine.event.annotations.EventPriority; +import net.moran.loratadine.event.impl.GameTickEvent; +import net.moran.loratadine.event.impl.Render2DEvent; +import net.moran.loratadine.modules.Category; +import net.moran.loratadine.modules.Module; +import net.moran.loratadine.utils.helper.ReflectionHelper; +import net.moran.loratadine.utils.render.ColorUtils; +import net.moran.loratadine.utils.wrapper.Wrapper; + +public class HUD extends Module { + private int fps; + private List enabledModules = new ArrayList<>(); + + public HUD() { + super("HUD", Category.RENDER); + this.setEnabled(true); + } + + @EventPriority + public void onTick(GameTickEvent event) { + this.enabledModules = new ArrayList<>(); + Collection modules = Loratadine.INSTANCE.getModuleManager().getModules(); + if (!modules.isEmpty()) { + for (Module module : modules) { + if (module.isEnabled()) { + this.enabledModules.add(module); + } + } + + this.enabledModules.sort(new Comparator() { + public int compare(Module m1, Module m2) { + int width1 = Wrapper.mc.font.width(m1.getName()); + int width2 = Wrapper.mc.font.width(m2.getName()); + return Mth.ceil((float)(width2 - width1)); + } + }); + } + } + + @EventPriority + public void onRender2D(Render2DEvent event) { + mc.font.drawShadow(event.poseStack(), Loratadine.CLIENT_NAME.substring(0, 1), 4.0F, 4.0F, ColorUtils.rainbow(10, 1).getRGB()); + Field fps_field = ReflectionHelper.findField(mc.getClass(), "f_91021_", "fps"); + + try { + this.fps = fps_field.getInt(mc); + } catch (Exception var6) { + var6.printStackTrace(); + } + + mc.font + .drawShadow( + event.poseStack(), + Loratadine.CLIENT_NAME.substring(1) + " " + Loratadine.CLIENT_VERSION + " [" + this.fps + "FPS]", + (float)(4 + mc.font.width(Loratadine.CLIENT_NAME.substring(0, 1))), + 4.0F, + -1 + ); + float y = 0.0F; + + for (Module module : this.enabledModules) { + mc.font + .drawShadow( + event.poseStack(), + module.getName() + (module.getSuffix() == null ? "" : ChatFormatting.GRAY + " [" + module.getSuffix() + "]"), + 4.0F, + 16.0F + y, + -1 + ); + y += (float)(9 + 2); + } + } +} diff --git a/src/main/java/net/moran/loratadine/setting/HideIf.java b/src/main/java/net/moran/loratadine/setting/HideIf.java new file mode 100644 index 0000000..da520eb --- /dev/null +++ b/src/main/java/net/moran/loratadine/setting/HideIf.java @@ -0,0 +1,5 @@ +package net.moran.loratadine.setting; + +public interface HideIf { + boolean hide(); +} diff --git a/src/main/java/net/moran/loratadine/setting/Setting.java b/src/main/java/net/moran/loratadine/setting/Setting.java new file mode 100644 index 0000000..7940932 --- /dev/null +++ b/src/main/java/net/moran/loratadine/setting/Setting.java @@ -0,0 +1,50 @@ +package net.moran.loratadine.setting; + +import com.google.gson.JsonElement; +import com.google.gson.JsonObject; +import lombok.Generated; +import net.moran.loratadine.modules.Module; + +public abstract class Setting { + protected final String name; + protected Module present; + protected T value; + protected HideIf hideIf; + + public Setting(String name, Module present, T value, HideIf hideIf) { + this.name = name; + this.present = present; + present.getSettings().add(this); + this.value = value; + this.hideIf = hideIf; + } + + public abstract void toJson(JsonObject var1); + + public abstract void formJson(JsonElement var1); + + @Generated + public String getName() { + return this.name; + } + + @Generated + public Module getPresent() { + return this.present; + } + + @Generated + public T getValue() { + return this.value; + } + + @Generated + public HideIf getHideIf() { + return this.hideIf; + } + + @Generated + public void setValue(T value) { + this.value = value; + } +} diff --git a/src/main/java/net/moran/loratadine/setting/impl/BooleanSetting.java b/src/main/java/net/moran/loratadine/setting/impl/BooleanSetting.java new file mode 100644 index 0000000..ede3842 --- /dev/null +++ b/src/main/java/net/moran/loratadine/setting/impl/BooleanSetting.java @@ -0,0 +1,32 @@ +package net.moran.loratadine.setting.impl; + +import com.google.gson.JsonElement; +import com.google.gson.JsonObject; +import net.moran.loratadine.modules.Module; +import net.moran.loratadine.setting.HideIf; +import net.moran.loratadine.setting.Setting; + +public class BooleanSetting extends Setting { + public BooleanSetting(String name, Module present, Boolean value, HideIf hideIf) { + super(name, present, value, hideIf); + } + + public BooleanSetting(String name, Module present, Boolean value) { + this(name, present, value, new HideIf() { + @Override + public boolean hide() { + return false; + } + }); + } + + @Override + public void toJson(JsonObject object) { + object.addProperty(this.getName(), this.getValue()); + } + + @Override + public void formJson(JsonElement element) { + this.setValue(Boolean.valueOf(element.getAsBoolean())); + } +} diff --git a/src/main/java/net/moran/loratadine/setting/impl/ModeSetting.java b/src/main/java/net/moran/loratadine/setting/impl/ModeSetting.java new file mode 100644 index 0000000..e767dd7 --- /dev/null +++ b/src/main/java/net/moran/loratadine/setting/impl/ModeSetting.java @@ -0,0 +1,41 @@ +package net.moran.loratadine.setting.impl; + +import com.google.gson.JsonElement; +import com.google.gson.JsonObject; +import lombok.Generated; +import net.moran.loratadine.modules.Module; +import net.moran.loratadine.setting.HideIf; +import net.moran.loratadine.setting.Setting; + +public class ModeSetting extends Setting { + private final String[] values; + + public ModeSetting(String name, Module present, String[] values, String value, HideIf hideIf) { + super(name, present, value, hideIf); + this.values = values; + } + + public ModeSetting(String name, Module present, String[] values, String value) { + this(name, present, values, value, new HideIf() { + @Override + public boolean hide() { + return false; + } + }); + } + + @Override + public void toJson(JsonObject object) { + object.addProperty(this.getName(), this.getValue()); + } + + @Override + public void formJson(JsonElement element) { + this.setValue(element.getAsString()); + } + + @Generated + public String[] getValues() { + return this.values; + } +} diff --git a/src/main/java/net/moran/loratadine/setting/impl/NumberSetting.java b/src/main/java/net/moran/loratadine/setting/impl/NumberSetting.java new file mode 100644 index 0000000..dc2255a --- /dev/null +++ b/src/main/java/net/moran/loratadine/setting/impl/NumberSetting.java @@ -0,0 +1,55 @@ +package net.moran.loratadine.setting.impl; + +import com.google.gson.JsonElement; +import com.google.gson.JsonObject; +import lombok.Generated; +import net.moran.loratadine.modules.Module; +import net.moran.loratadine.setting.HideIf; +import net.moran.loratadine.setting.Setting; + +public class NumberSetting extends Setting { + private final Number maxValue; + private final Number minValue; + private final Number step; + + public NumberSetting(String name, Module module, Number value, Number minValue, Number maxValue, Number step, HideIf hideIf) { + super(name, module, value, hideIf); + this.maxValue = maxValue; + this.minValue = minValue; + this.step = step; + } + + public NumberSetting(String name, Module module, Number value, Number minValue, Number maxValue, Number step) { + this(name, module, value, minValue, maxValue, step, new HideIf() { + @Override + public boolean hide() { + return false; + } + }); + } + + @Override + public void toJson(JsonObject object) { + object.addProperty(this.getName(), this.getValue()); + } + + @Override + public void formJson(JsonElement element) { + this.setValue(element.getAsNumber()); + } + + @Generated + public Number getMaxValue() { + return this.maxValue; + } + + @Generated + public Number getMinValue() { + return this.minValue; + } + + @Generated + public Number getStep() { + return this.step; + } +} diff --git a/src/main/java/net/moran/loratadine/ui/clickgui/ClickGUI.java b/src/main/java/net/moran/loratadine/ui/clickgui/ClickGUI.java new file mode 100644 index 0000000..7c96bea --- /dev/null +++ b/src/main/java/net/moran/loratadine/ui/clickgui/ClickGUI.java @@ -0,0 +1,101 @@ +package net.moran.loratadine.ui.clickgui; + +import com.mojang.blaze3d.systems.RenderSystem; +import com.mojang.blaze3d.vertex.PoseStack; +import java.util.ArrayList; +import java.util.List; +import java.util.function.Supplier; +import net.minecraft.client.gui.screens.Screen; +import net.minecraft.client.renderer.GameRenderer; +import net.minecraft.client.renderer.ShaderInstance; +import net.minecraft.network.chat.Component; +import net.moran.loratadine.modules.Category; + +public class ClickGUI extends Screen { + public static final ClickGUI INSTANCE = new ClickGUI(); + private final List frames = new ArrayList<>(); + private static final int ANIMATION_DURATION = 200; + private long openTime; + + protected ClickGUI() { + super(Component.nullToEmpty("Click GUI")); + int offset = 20; + + for (Category category : Category.values()) { + this.frames.add(new Frame(offset, 20, 120, 25, category)); + offset += 140; + } + } + + public void render(PoseStack poseStack, int mouseX, int mouseY, float partialTicks) { + this.renderBackground(poseStack); + long currentTime = System.currentTimeMillis(); + float animationProgress = Math.min(1.0F, (float)(currentTime - this.openTime) / 200.0F); + + for (Frame frame : this.frames) { + frame.render(poseStack, mouseX, mouseY, partialTicks, animationProgress); + frame.updatePosition((double)mouseX, (double)mouseY); + } + + super.render(poseStack, mouseX, mouseY, partialTicks); + } + + public void onClose() { + super.onClose(); + + for (Frame frame : this.frames) { + frame.onClose(); + } + } + + public boolean mouseReleased(double mouseX, double mouseY, int button) { + for (Frame frame : this.frames) { + frame.mouseReleased(mouseX, mouseY, button); + } + + return super.mouseReleased(mouseX, mouseY, button); + } + + public boolean mouseClicked(double mouseX, double mouseY, int button) { + for (Frame frame : this.frames) { + frame.mouseClicked(mouseX, mouseY, button); + } + + return super.mouseClicked(mouseX, mouseY, button); + } + + protected void init() { + super.init(); + this.openTime = System.currentTimeMillis(); + } + + public static void drawRoundedRect(PoseStack poseStack, int x, int y, int width, int height, int cornerRadius, int color) { + fill(poseStack, x + cornerRadius, y, x + width - cornerRadius, y + height, color); + fill(poseStack, x, y + cornerRadius, x + cornerRadius, y + height - cornerRadius, color); + fill(poseStack, x + width - cornerRadius, y + cornerRadius, x + width, y + height - cornerRadius, color); + fillCircle(poseStack, x + cornerRadius, y + cornerRadius, cornerRadius, color); + fillCircle(poseStack, x + width - cornerRadius, y + cornerRadius, cornerRadius, color); + fillCircle(poseStack, x + cornerRadius, y + height - cornerRadius, cornerRadius, color); + fillCircle(poseStack, x + width - cornerRadius, y + height - cornerRadius, cornerRadius, color); + } + + private static void fillCircle(PoseStack poseStack, int centerX, int centerY, int radius, int color) { + RenderSystem.setShader(new Supplier() { + public ShaderInstance get() { + return GameRenderer.getPositionColorShader(); + } + }); + RenderSystem.setShaderColor(1.0F, 1.0F, 1.0F, 1.0F); + + for (int y = -radius; y <= radius; y++) { + for (int x = -radius; x <= radius; x++) { + if (x * x + y * y <= radius * radius) { + poseStack.pushPose(); + poseStack.translate((double)(centerX + x), (double)(centerY + y), 0.0); + fill(poseStack, 0, 0, 1, 1, color); + poseStack.popPose(); + } + } + } + } +} diff --git a/src/main/java/net/moran/loratadine/ui/clickgui/Frame.java b/src/main/java/net/moran/loratadine/ui/clickgui/Frame.java new file mode 100644 index 0000000..ef905d4 --- /dev/null +++ b/src/main/java/net/moran/loratadine/ui/clickgui/Frame.java @@ -0,0 +1,149 @@ +package net.moran.loratadine.ui.clickgui; + +import com.mojang.blaze3d.systems.RenderSystem; +import com.mojang.blaze3d.vertex.PoseStack; +import java.util.ArrayList; +import java.util.List; +import net.minecraft.client.gui.Gui; +import net.minecraft.resources.ResourceLocation; +import net.moran.loratadine.Loratadine; +import net.moran.loratadine.modules.Category; +import net.moran.loratadine.modules.Module; +import net.moran.loratadine.ui.clickgui.values.Component; +import net.moran.loratadine.utils.render.ColorUtils; +import net.moran.loratadine.utils.wrapper.Wrapper; + +public class Frame implements Wrapper { + public int x; + public int y; + public int dragX; + public int dragY; + public int width; + public int height; + public Category category; + public boolean dragging; + public boolean extended; + private List renderers; + private float openProgress; + public static final int ANIMATION_DURATION = 1000; + private long lastToggleTime; + private ResourceLocation categoryIcon; + + public Frame(int x, int y, int width, int height, Category category) { + this.x = x; + this.y = y; + this.width = width; + this.height = height; + this.category = category; + this.dragging = false; + this.extended = false; + this.openProgress = 0.0F; + this.lastToggleTime = 0L; + this.categoryIcon = new ResourceLocation("heypixel", "sb/textures/gui/" + category.name().toLowerCase() + "_icon.png"); + this.renderers = new ArrayList<>(); + int offset = height; + + for (Module mod : Loratadine.INSTANCE.getModuleManager().getModule(category)) { + this.renderers.add(new ModuleRenderer(mod, this, offset)); + offset += height; + } + } + + public void render(PoseStack stack, int mouseX, int mouseY, float delta, float animationProgress) { + this.updateAnimation(); + ClickGUI.drawRoundedRect(stack, this.x, this.y, this.width, this.height, 0, ColorUtils.color(0, 0, 0, 150)); + RenderSystem.setShaderColor(1.0F, 1.0F, 1.0F, 1.0F); + RenderSystem.setShaderTexture(0, this.categoryIcon); + Gui.blit(stack, this.x + 5, this.y + 5, 0.0F, 0.0F, 16, 16, 16, 16); + mc.font.drawShadow(stack, this.category.name, (float)(this.x + 25), (float)this.y + ((float)this.height / 2.0F - 9.0F / 2.0F), -1); + mc.font.drawShadow(stack, this.extended ? "-" : "+", (float)(this.x + this.width - 14), (float)this.y + ((float)this.height / 2.0F - 9.0F / 2.0F), -1); + long currentTime = System.currentTimeMillis(); + float targetProgress = this.extended ? 1.0F : 0.0F; + if (this.openProgress != targetProgress) { + float deltaTime = (float)(currentTime - this.lastToggleTime) / 1000.0F; + this.openProgress = this.extended ? Math.min(1.0F, this.openProgress + deltaTime) : Math.max(0.0F, this.openProgress - deltaTime); + } + + if (this.openProgress > 0.0F) { + int yOffset = this.height; + + for (ModuleRenderer renderer : this.renderers) { + int moduleHeight = (int)((float)renderer.getHeight() * this.openProgress); + renderer.render(stack, mouseX, mouseY, delta, this.x, this.y + yOffset, this.width, moduleHeight); + yOffset += renderer.getHeight(); + } + } + } + + public void mouseClicked(double mouseX, double mouseY, int mouseButton) { + if (this.isHovered(mouseX, mouseY)) { + if (mouseButton == 0) { + this.dragging = true; + this.dragX = (int)(mouseX - (double)this.x); + this.dragY = (int)(mouseY - (double)this.y); + } else if (mouseButton == 1) { + this.extended = !this.extended; + this.lastToggleTime = System.currentTimeMillis(); + } + } + + if (this.extended) { + for (ModuleRenderer renderer : this.renderers) { + renderer.mouseClicked(mouseX, mouseY, mouseButton); + } + } + } + + public void mouseReleased(double mouseX, double mouseY, int mouseButton) { + for (ModuleRenderer renderer : this.renderers) { + renderer.mouseReleased(mouseX, mouseY, mouseButton); + } + + if (mouseButton == 0 && this.dragging) { + this.dragging = false; + } + } + + public boolean isHovered(double mouseX, double mouseY) { + return mouseX > (double)this.x && mouseX < (double)(this.x + this.width) && mouseY > (double)this.y && mouseY < (double)(this.y + this.height); + } + + public void updatePosition(double mouseX, double mouseY) { + if (this.dragging) { + this.x = (int)(mouseX - (double)this.dragX); + this.y = (int)(mouseY - (double)this.dragY); + } + } + + public void updateButtons() { + int offset = this.height; + + for (ModuleRenderer renderer : this.renderers) { + renderer.offset = offset; + offset += this.height; + if (renderer.extended) { + for (Component component : renderer.components) { + if (component.value.getHideIf().hide()) { + offset += this.height; + } + } + } + } + } + + public void updateAnimation() { + long currentTime = System.currentTimeMillis(); + float targetProgress = this.extended ? 1.0F : 0.0F; + if (this.openProgress != targetProgress) { + float deltaTime = (float)(currentTime - this.lastToggleTime) / 1000.0F; + this.openProgress = this.extended ? Math.min(1.0F, this.openProgress + deltaTime) : Math.max(0.0F, this.openProgress - deltaTime); + } + + this.updateButtons(); + } + + public void onClose() { + this.extended = false; + this.openProgress = 0.0F; + } +} diff --git a/src/main/java/net/moran/loratadine/ui/clickgui/ModuleRenderer.java b/src/main/java/net/moran/loratadine/ui/clickgui/ModuleRenderer.java new file mode 100644 index 0000000..38e0189 --- /dev/null +++ b/src/main/java/net/moran/loratadine/ui/clickgui/ModuleRenderer.java @@ -0,0 +1,130 @@ +package net.moran.loratadine.ui.clickgui; + +import com.mojang.blaze3d.vertex.PoseStack; +import java.awt.Color; +import java.util.ArrayList; +import java.util.List; +import net.moran.loratadine.modules.Module; +import net.moran.loratadine.setting.Setting; +import net.moran.loratadine.setting.impl.BooleanSetting; +import net.moran.loratadine.setting.impl.ModeSetting; +import net.moran.loratadine.setting.impl.NumberSetting; +import net.moran.loratadine.ui.clickgui.values.Component; +import net.moran.loratadine.ui.clickgui.values.impl.BoolValueComponent; +import net.moran.loratadine.ui.clickgui.values.impl.ModeValueComponent; +import net.moran.loratadine.ui.clickgui.values.impl.NumberValueComponent; +import net.moran.loratadine.utils.render.ColorUtils; +import net.moran.loratadine.utils.wrapper.Wrapper; + +public class ModuleRenderer implements Wrapper { + public Module module; + public Frame parent; + public int offset; + public List components; + public boolean extended; + private static final int COMPONENT_HEIGHT = 20; + private float openProgress; + private long lastToggleTime; + + public ModuleRenderer(Module module, Frame parent, int offset) { + this.module = module; + this.parent = parent; + this.offset = offset; + this.extended = false; + this.openProgress = 0.0F; + this.lastToggleTime = 0L; + this.components = new ArrayList<>(); + int valueOffset = 20; + + for (Setting value : module.getSettings()) { + if (value instanceof BooleanSetting) { + this.components.add(new BoolValueComponent(value, this, valueOffset)); + } else if (value instanceof ModeSetting) { + this.components.add(new ModeValueComponent(value, this, valueOffset)); + } else if (value instanceof NumberSetting) { + this.components.add(new NumberValueComponent(value, this, valueOffset)); + } + + valueOffset += 20; + } + } + + public void render(PoseStack stack, int mouseX, int mouseY, float delta, int x, int y, int width, int height) { + this.updateAnimation(); + ClickGUI.drawRoundedRect( + stack, x, y, width, height, 0, ColorUtils.color(0, 0, 0, this.isHovered((double)mouseX, (double)mouseY, x, y, width, height) ? 200 : 160) + ); + int textOffset = 10 - 9 / 2; + String moduleName = this.module.getName(); + float scaleFactor = 1.0F; + int moduleNameWidth = mc.font.width(moduleName); + if (moduleNameWidth > width - 30) { + scaleFactor = (float)(width - 30) / (float)moduleNameWidth; + } + + stack.pushPose(); + stack.translate((double)(x + textOffset), (double)(y + textOffset), 0.0); + stack.scale(scaleFactor, scaleFactor, 1.0F); + mc.font.drawShadow(stack, moduleName, 0.0F, 0.0F, this.module.isEnabled() ? Color.GREEN.getRGB() : -1); + stack.popPose(); + if (!this.components.isEmpty()) { + mc.font.drawShadow(stack, this.extended ? "-" : "+", (float)(x + width - 14), (float)(y + textOffset), -1); + } + + if (this.openProgress > 0.0F) { + int componentY = y + 20; + + for (Component component : this.components) { + if (componentY + 20 > y + height) { + break; + } + + component.render(stack, mouseX, mouseY, delta, x, componentY, width, 20); + componentY += 20; + } + } + } + + private void updateAnimation() { + long currentTime = System.currentTimeMillis(); + float targetProgress = this.extended ? 1.0F : 0.0F; + if (this.openProgress != targetProgress) { + float deltaTime = (float)(currentTime - this.lastToggleTime) / 1000.0F; + this.openProgress = this.extended ? Math.min(1.0F, this.openProgress + deltaTime) : Math.max(0.0F, this.openProgress - deltaTime); + } + } + + public void mouseClicked(double mouseX, double mouseY, int mouseButton) { + if (this.isHovered(mouseX, mouseY, this.parent.x, this.parent.y + this.offset, this.parent.width, 20)) { + if (mouseButton == 0) { + this.module.setEnabled(!this.module.isEnabled()); + } else if (mouseButton == 1 && !this.components.isEmpty()) { + this.extended = !this.extended; + this.lastToggleTime = System.currentTimeMillis(); + this.parent.updateButtons(); + } + } + + if (this.extended) { + for (Component component : this.components) { + component.mouseClicked(mouseX, mouseY, mouseButton); + } + } + } + + public void mouseReleased(double mouseX, double mouseY, int mouseButton) { + if (this.extended) { + for (Component component : this.components) { + component.mouseReleased(mouseX, mouseY, mouseButton); + } + } + } + + public boolean isHovered(double mouseX, double mouseY, int x, int y, int width, int height) { + return mouseX > (double)x && mouseX < (double)(x + width) && mouseY > (double)y && mouseY < (double)(y + height); + } + + public int getHeight() { + return 20 + (this.extended ? this.components.size() * 20 : 0); + } +} diff --git a/src/main/java/net/moran/loratadine/ui/clickgui/values/Component.java b/src/main/java/net/moran/loratadine/ui/clickgui/values/Component.java new file mode 100644 index 0000000..38383ac --- /dev/null +++ b/src/main/java/net/moran/loratadine/ui/clickgui/values/Component.java @@ -0,0 +1,38 @@ +package net.moran.loratadine.ui.clickgui.values; + +import com.mojang.blaze3d.vertex.PoseStack; +import net.moran.loratadine.setting.Setting; +import net.moran.loratadine.ui.clickgui.ClickGUI; +import net.moran.loratadine.ui.clickgui.ModuleRenderer; +import net.moran.loratadine.utils.render.ColorUtils; +import net.moran.loratadine.utils.wrapper.Wrapper; + +public class Component implements Wrapper { + public Setting value; + public ModuleRenderer parent; + public int offset; + + public Component(Setting value, ModuleRenderer parent, int offset) { + this.value = value; + this.parent = parent; + this.offset = offset; + } + + public void render(PoseStack stack, int mouseX, int mouseY, float delta, int x, int y, int width, int height) { + ClickGUI.drawRoundedRect( + stack, x, y, width, height, 3, ColorUtils.color(0, 0, 0, this.isHovered((double)mouseX, (double)mouseY, x, y, width, height) ? 180 : 140) + ); + int textOffset = height / 2 - 9 / 2; + mc.font.drawShadow(stack, this.value.getName(), (float)(x + 5), (float)(y + textOffset), -1); + } + + public void mouseClicked(double mouseX, double mouseY, int mouseButton) { + } + + public void mouseReleased(double mouseX, double mouseY, int mouseButton) { + } + + public boolean isHovered(double mouseX, double mouseY, int x, int y, int width, int height) { + return mouseX > (double)x && mouseX < (double)(x + width) && mouseY > (double)y && mouseY < (double)(y + height); + } +} diff --git a/src/main/java/net/moran/loratadine/ui/clickgui/values/impl/BoolValueComponent.java b/src/main/java/net/moran/loratadine/ui/clickgui/values/impl/BoolValueComponent.java new file mode 100644 index 0000000..08be016 --- /dev/null +++ b/src/main/java/net/moran/loratadine/ui/clickgui/values/impl/BoolValueComponent.java @@ -0,0 +1,40 @@ +package net.moran.loratadine.ui.clickgui.values.impl; + +import com.mojang.blaze3d.vertex.PoseStack; +import net.moran.loratadine.setting.Setting; +import net.moran.loratadine.setting.impl.BooleanSetting; +import net.moran.loratadine.ui.clickgui.ModuleRenderer; +import net.moran.loratadine.ui.clickgui.values.Component; +import net.moran.loratadine.utils.wrapper.Wrapper; + +public class BoolValueComponent extends Component implements Wrapper { + private BooleanSetting booleanValue = (BooleanSetting)this.value; + + public BoolValueComponent(Setting value, ModuleRenderer parent, int offset) { + super(value, parent, offset); + this.booleanValue = (BooleanSetting)value; + } + + @Override + public void render(PoseStack stack, int mouseX, int mouseY, float delta, int x, int y, int width, int height) { + super.render(stack, mouseX, mouseY, delta, x, y, width, height); + String text = this.booleanValue.getName() + ": " + this.booleanValue.getValue(); + int textWidth = mc.font.width(text); + mc.font.drawShadow(stack, text, (float)(x + 5), (float)(y + (height / 2 - 9 / 2)), this.booleanValue.getValue() ? 5635925 : 16733525); + } + + @Override + public void mouseClicked(double mouseX, double mouseY, int mouseButton) { + if (this.isHovered( + mouseX, mouseY, this.parent.parent.x, this.parent.parent.y + this.parent.offset + this.offset, this.parent.parent.width, this.parent.parent.height + ) + && mouseButton == 0) { + this.booleanValue.setValue(Boolean.valueOf(!this.booleanValue.getValue())); + } + } + + @Override + public void mouseReleased(double mouseX, double mouseY, int mouseButton) { + super.mouseReleased(mouseX, mouseY, mouseButton); + } +} diff --git a/src/main/java/net/moran/loratadine/ui/clickgui/values/impl/ModeValueComponent.java b/src/main/java/net/moran/loratadine/ui/clickgui/values/impl/ModeValueComponent.java new file mode 100644 index 0000000..86a9a1a --- /dev/null +++ b/src/main/java/net/moran/loratadine/ui/clickgui/values/impl/ModeValueComponent.java @@ -0,0 +1,44 @@ +package net.moran.loratadine.ui.clickgui.values.impl; + +import com.mojang.blaze3d.vertex.PoseStack; +import java.util.Arrays; +import net.moran.loratadine.setting.Setting; +import net.moran.loratadine.setting.impl.ModeSetting; +import net.moran.loratadine.ui.clickgui.ModuleRenderer; +import net.moran.loratadine.ui.clickgui.values.Component; +import net.moran.loratadine.utils.wrapper.Wrapper; + +public class ModeValueComponent extends Component implements Wrapper { + private ModeSetting modeValue = (ModeSetting)this.value; + + public ModeValueComponent(Setting value, ModuleRenderer parent, int offset) { + super(value, parent, offset); + this.modeValue = (ModeSetting)value; + } + + @Override + public void render(PoseStack stack, int mouseX, int mouseY, float delta, int x, int y, int width, int height) { + super.render(stack, mouseX, mouseY, delta, x, y, width, height); + String text = this.modeValue.getName() + ": " + this.modeValue.getValue(); + int textWidth = mc.font.width(text); + mc.font.drawShadow(stack, text, (float)(x + 5), (float)(y + (height / 2 - 9 / 2)), -1); + } + + @Override + public void mouseClicked(double mouseX, double mouseY, int mouseButton) { + if (this.isHovered( + mouseX, mouseY, this.parent.parent.x, this.parent.parent.y + this.parent.offset + this.offset, this.parent.parent.width, this.parent.parent.height + ) + && mouseButton == 0) { + String[] modes = this.modeValue.getValues(); + int currentIndex = Arrays.asList(modes).indexOf(this.modeValue.getValue()); + int nextIndex = (currentIndex + 1) % modes.length; + this.modeValue.setValue(modes[nextIndex]); + } + } + + @Override + public void mouseReleased(double mouseX, double mouseY, int mouseButton) { + super.mouseReleased(mouseX, mouseY, mouseButton); + } +} diff --git a/src/main/java/net/moran/loratadine/ui/clickgui/values/impl/NumberValueComponent.java b/src/main/java/net/moran/loratadine/ui/clickgui/values/impl/NumberValueComponent.java new file mode 100644 index 0000000..3294119 --- /dev/null +++ b/src/main/java/net/moran/loratadine/ui/clickgui/values/impl/NumberValueComponent.java @@ -0,0 +1,63 @@ +package net.moran.loratadine.ui.clickgui.values.impl; + +import com.mojang.blaze3d.vertex.PoseStack; +import java.awt.Color; +import net.minecraft.client.gui.Gui; +import net.moran.loratadine.setting.Setting; +import net.moran.loratadine.setting.impl.NumberSetting; +import net.moran.loratadine.ui.clickgui.ModuleRenderer; +import net.moran.loratadine.ui.clickgui.values.Component; +import net.moran.loratadine.utils.math.MathUtils; +import net.moran.loratadine.utils.wrapper.Wrapper; + +public class NumberValueComponent extends Component implements Wrapper { + private NumberSetting numValue = (NumberSetting)this.value; + private boolean sliding = false; + + public NumberValueComponent(Setting value, ModuleRenderer parent, int offset) { + super(value, parent, offset); + this.numValue = (NumberSetting)value; + } + + @Override + public void render(PoseStack stack, int mouseX, int mouseY, float delta, int x, int y, int width, int height) { + super.render(stack, mouseX, mouseY, delta, x, y, width, height); + int renderWidth = (int)( + (float)width + * (this.numValue.getValue().floatValue() - this.numValue.getMinValue().floatValue()) + / (this.numValue.getMaxValue().floatValue() - this.numValue.getMinValue().floatValue()) + ); + Gui.fill(stack, x, y + height - 3, x + renderWidth, y + height, Color.WHITE.getRGB()); + if (this.sliding) { + double diff = (double)Math.min(width, Math.max(0, mouseX - x)); + this.numValue + .setValue( + Double.valueOf( + MathUtils.roundToPlace( + diff / (double)width * (double)(this.numValue.getMaxValue().floatValue() - this.numValue.getMinValue().floatValue()) + + (double)this.numValue.getMinValue().floatValue(), + 2 + ) + ) + ); + } + + String text = this.numValue.getName() + ": " + MathUtils.roundToPlace((double)this.numValue.getValue().floatValue(), 2); + mc.font.drawShadow(stack, text, (float)(x + 5), (float)(y + (height / 2 - 9 / 2)), -1); + } + + @Override + public void mouseClicked(double mouseX, double mouseY, int mouseButton) { + if (this.isHovered( + mouseX, mouseY, this.parent.parent.x, this.parent.parent.y + this.parent.offset + this.offset, this.parent.parent.width, this.parent.parent.height + ) + && mouseButton == 0) { + this.sliding = true; + } + } + + @Override + public void mouseReleased(double mouseX, double mouseY, int mouseButton) { + this.sliding = false; + } +} diff --git a/src/main/java/net/moran/loratadine/utils/ByteUtil.java b/src/main/java/net/moran/loratadine/utils/ByteUtil.java new file mode 100644 index 0000000..4ddd8f7 --- /dev/null +++ b/src/main/java/net/moran/loratadine/utils/ByteUtil.java @@ -0,0 +1,90 @@ +package net.moran.loratadine.utils; + +import cn.lzq.injection.Fucker; +import com.google.gson.JsonObject; +import io.netty.buffer.ByteBuf; +import io.netty.channel.Channel; +import java.nio.charset.StandardCharsets; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class ByteUtil { + private static final Logger log = LoggerFactory.getLogger(ByteUtil.class); + private final Channel channel; + public static final String receivePrivateKey = "MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQC4xVR6yFhaTWnfe9SUy2YAIY+SqdB/WOCgsMcN4A0YwbfrZjlvBCRKxlJ32yDTF8tN/HBaOo/lpHX3VRwhpvQ0yL5IFBBSUY4JIc2utIuVdLc3ZaLDuhuh08hOrvrHCWlFi523mJvB4Xzi+6hau6FFs7qfp/SRfGK2tjS7sA7oqky3PVH3nBV+X6f3rI7/a3POFqboSwdm0jnqTvEpNr75H1gy47/V7L2oAgGIBspFvqLj8VgtKNX8clVTva9UTlnLtKG+rDf1nCr6fiRDotXP+QnD1kzVEl6Xndw8pdXpBQo/GsUdIixAdBN5mW/wz/4tdPbK9jmh7CFWqbEM6IPZAgMBAAECggEBAIn0q9LQ60bhLf9y0ZIXG51VcYEr0USD85OG6dhuRNkLKmtT8+XzzbUWxlQ/BA8YYO9lX+2+c9oeJQX6QfrOUN9oUso2UMllowsmdg/PNbjtYC64cAJ7Xk5BdflppEwftr36NFP0Wbc0yK4g/95e4VbNjrXODUji+kE5Yb4RAdCssbzd3Z5ftqK1U9eB5ASKgYuo3w9bkG6du7iFnGI+BeSHOkjVLzY2ETIq9oPknMTQAif1JzXvLGH2OefqTF8To8kkxn17BrJncBzwmExkrCPOxqc2DoMrCeuN/x28GbYxS40f+9cGBC0EtGg0rK7O4uMivAqATA8YBl3p8AMuYUECgYEA2dB227WxQjsoqHhe0qa2Aq1YIJRsFJmfiwW3D8VMAzvJTSmuSjKT2ttHhI7wWVbKxqksugpwsCb0K+omXSPSaqf5MvtXy/4lbWzmfG4bALlDmuu11EDqm8nj6tXzYHuyXBg5Cff+lqmLaEtU0CoArmKFZ0gIeWn57OoxeR0EyG0CgYEA2SneiTH2xO+R3uN+Od/3ukxdSJzZvRzFpCqhBVKeXroGFlYTlBcLwIp+YduLFbSFNCThy1e8YkPj2MT/yYIJXWEA5Cwv4dylKg7ACcnJFHldQTEq4jY6EP6HTnxhrvGAy1UXTJJuVvsfqEm9U5Ar8lfUK+R3uugBKPIQ5E6SXZ0CgYBEfO8SsLPW7oEfUBIIzJDIkLb4L5M4ewGWlip0lAYNsjvevm9mNzcUhwSa4tMiVE8YXlOJAAVk7iqysEJ14PClxsFtzWhS5Uvhd2+Vyo1FEfv294zJ+8uJRtcanUGUofB4UsmEn+z2dMM3/Q/jEIH8U1A9JII9oxwJ6a26tmwtlQKBgCFTLIQvN6gm/2KN1Iv7E5/yIgqHj15W8PltVUJk2Eq/DzoUQXLjSnlkh1pq/1/4UMycsE2tDAqkUm2sZXg9zUQYI7PgGAT4AByBIPUfkwziRu4/Jk6KdcSv2oGv0qmvA82wJCArBGWyqbwAfN467JOG6NdHexwiiDMJWpA+gnV9AoGBAJBk+33lsD9NEyRHdwnTXaoNHreifNux8XdH24YqaAdVCkym1RBtbD4DoNC2aZVFlRfrWP3alQQ98jzqm80HRRic1uqqvdOgAxDzCa+ZOBm4UgiWtbsfDRlZHvuJxd+j0jn0hBbLZJCkUCxBqutTHjnp8lscv2u1Q4nfSftDnKIz"; + private static final String sendPublicKey = "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAnFjDlblXYSsBa5/9XgV3o85V+6k1xdzRgXTuwp7cROwnFOKcZ7uksaxCR5Tu1JmSIpKqVsmAMy64MqrwlC4d1GJyj1AcThixV9s42UH6gkLJiXQKdNUqOtwcSPPVH5ZA01qtMqgCk+7VybXihNCLkAKnhYsoNnKltKcRS43kaJ+POTvNcT07Qh3zNwOCpop+/8DbQHg7GLBK2L5zfJQXwONHpaaJ72L1+z/yu7VHpoCEVBrlHIQBIZ3iwUgD0WQP4wZBMDPT6t1i18YzlDEos2MmQdYXOgFnzj6bnQkfwMrhfnQUwPb6bDLzA14ZEvRrh3cxcVsE9Nlh43BOV5FsQQIDAQAB"; + private static final int SLICE_SIZE = 128; + + public ByteUtil(Channel channel) { + this.channel = channel; + } + + public static String read(Object msg) { + ByteBuf byteBuf = (ByteBuf)msg; + byte[] bytes = new byte[byteBuf.readableBytes()]; + byteBuf.readBytes(bytes); + return CryptUtil.RSA.decryptByPrivateKey( + bytes, + "MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQC4xVR6yFhaTWnfe9SUy2YAIY+SqdB/WOCgsMcN4A0YwbfrZjlvBCRKxlJ32yDTF8tN/HBaOo/lpHX3VRwhpvQ0yL5IFBBSUY4JIc2utIuVdLc3ZaLDuhuh08hOrvrHCWlFi523mJvB4Xzi+6hau6FFs7qfp/SRfGK2tjS7sA7oqky3PVH3nBV+X6f3rI7/a3POFqboSwdm0jnqTvEpNr75H1gy47/V7L2oAgGIBspFvqLj8VgtKNX8clVTva9UTlnLtKG+rDf1nCr6fiRDotXP+QnD1kzVEl6Xndw8pdXpBQo/GsUdIixAdBN5mW/wz/4tdPbK9jmh7CFWqbEM6IPZAgMBAAECggEBAIn0q9LQ60bhLf9y0ZIXG51VcYEr0USD85OG6dhuRNkLKmtT8+XzzbUWxlQ/BA8YYO9lX+2+c9oeJQX6QfrOUN9oUso2UMllowsmdg/PNbjtYC64cAJ7Xk5BdflppEwftr36NFP0Wbc0yK4g/95e4VbNjrXODUji+kE5Yb4RAdCssbzd3Z5ftqK1U9eB5ASKgYuo3w9bkG6du7iFnGI+BeSHOkjVLzY2ETIq9oPknMTQAif1JzXvLGH2OefqTF8To8kkxn17BrJncBzwmExkrCPOxqc2DoMrCeuN/x28GbYxS40f+9cGBC0EtGg0rK7O4uMivAqATA8YBl3p8AMuYUECgYEA2dB227WxQjsoqHhe0qa2Aq1YIJRsFJmfiwW3D8VMAzvJTSmuSjKT2ttHhI7wWVbKxqksugpwsCb0K+omXSPSaqf5MvtXy/4lbWzmfG4bALlDmuu11EDqm8nj6tXzYHuyXBg5Cff+lqmLaEtU0CoArmKFZ0gIeWn57OoxeR0EyG0CgYEA2SneiTH2xO+R3uN+Od/3ukxdSJzZvRzFpCqhBVKeXroGFlYTlBcLwIp+YduLFbSFNCThy1e8YkPj2MT/yYIJXWEA5Cwv4dylKg7ACcnJFHldQTEq4jY6EP6HTnxhrvGAy1UXTJJuVvsfqEm9U5Ar8lfUK+R3uugBKPIQ5E6SXZ0CgYBEfO8SsLPW7oEfUBIIzJDIkLb4L5M4ewGWlip0lAYNsjvevm9mNzcUhwSa4tMiVE8YXlOJAAVk7iqysEJ14PClxsFtzWhS5Uvhd2+Vyo1FEfv294zJ+8uJRtcanUGUofB4UsmEn+z2dMM3/Q/jEIH8U1A9JII9oxwJ6a26tmwtlQKBgCFTLIQvN6gm/2KN1Iv7E5/yIgqHj15W8PltVUJk2Eq/DzoUQXLjSnlkh1pq/1/4UMycsE2tDAqkUm2sZXg9zUQYI7PgGAT4AByBIPUfkwziRu4/Jk6KdcSv2oGv0qmvA82wJCArBGWyqbwAfN467JOG6NdHexwiiDMJWpA+gnV9AoGBAJBk+33lsD9NEyRHdwnTXaoNHreifNux8XdH24YqaAdVCkym1RBtbD4DoNC2aZVFlRfrWP3alQQ98jzqm80HRRic1uqqvdOgAxDzCa+ZOBm4UgiWtbsfDRlZHvuJxd+j0jn0hBbLZJCkUCxBqutTHjnp8lscv2u1Q4nfSftDnKIz" + ); + } + + public void send(String text) { + byte[] textBytes = text.getBytes(StandardCharsets.UTF_8); + int totalLength = textBytes.length; + int offset = 0; + + while (offset < totalLength) { + int sliceLength = Math.min(128, totalLength - offset); + byte[] slice = new byte[sliceLength]; + System.arraycopy(textBytes, offset, slice, 0, sliceLength); + byte[] encryptedSlice = CryptUtil.RSA.encryptByPublicKey( + slice, + "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAnFjDlblXYSsBa5/9XgV3o85V+6k1xdzRgXTuwp7cROwnFOKcZ7uksaxCR5Tu1JmSIpKqVsmAMy64MqrwlC4d1GJyj1AcThixV9s42UH6gkLJiXQKdNUqOtwcSPPVH5ZA01qtMqgCk+7VybXihNCLkAKnhYsoNnKltKcRS43kaJ+POTvNcT07Qh3zNwOCpop+/8DbQHg7GLBK2L5zfJQXwONHpaaJ72L1+z/yu7VHpoCEVBrlHIQBIZ3iwUgD0WQP4wZBMDPT6t1i18YzlDEos2MmQdYXOgFnzj6bnQkfwMrhfnQUwPb6bDLzA14ZEvRrh3cxcVsE9Nlh43BOV5FsQQIDAQAB" + ); + ByteBuf buffer = this.channel.alloc().buffer(); + boolean hasMoreSlices = offset + sliceLength < totalLength; + buffer.writeInt(encryptedSlice.length + 1); + buffer.writeBoolean(hasMoreSlices); + buffer.writeBytes(encryptedSlice); + this.channel.writeAndFlush(buffer); + offset += sliceLength; + } + } + + public void online(String name) { + JsonObject jsonObject = new JsonObject(); + jsonObject.addProperty("Type", "online"); + jsonObject.addProperty("Player", CryptUtil.Base64Crypt.encrypt(name)); + this.send(jsonObject.toString()); + } + + public void jumping() { + JsonObject jsonObject = new JsonObject(); + jsonObject.addProperty("Type", "jumping"); + this.send(jsonObject.toString()); + } + + public void login() { + JsonObject jsonObject = new JsonObject(); + jsonObject.addProperty("Type", "login"); + JsonObject loginRequest = new JsonObject(); + loginRequest.addProperty("a", Fucker.loginUsername); + loginRequest.addProperty("ap", Fucker.loginPassword); + if (Fucker.requestText != null) { + loginRequest.addProperty("aa", Fucker.requestText); + } + + loginRequest.addProperty("ab", "2"); + loginRequest.addProperty("b", HWIDUtil.getUUID()); + jsonObject.addProperty("a", CryptUtil.Base64Crypt.encrypt(loginRequest.toString())); + this.send(jsonObject.toString()); + } + + public void message(String text) { + JsonObject jsonObject = new JsonObject(); + jsonObject.addProperty("Type", "message"); + jsonObject.addProperty("Text", CryptUtil.Base64Crypt.encrypt(text)); + this.send(jsonObject.toString()); + } +} diff --git a/src/main/java/net/moran/loratadine/utils/ClientUtils.java b/src/main/java/net/moran/loratadine/utils/ClientUtils.java new file mode 100644 index 0000000..6617a57 --- /dev/null +++ b/src/main/java/net/moran/loratadine/utils/ClientUtils.java @@ -0,0 +1,17 @@ +package net.moran.loratadine.utils; + +import net.minecraft.network.chat.TextComponent; +import net.moran.loratadine.Loratadine; +import net.moran.loratadine.utils.wrapper.Wrapper; + +public class ClientUtils implements Wrapper { + public static void mc_debugMessage(String debugMessage) { + if (mc.level != null && mc.player != null) { + mc.gui.getChat().addMessage(new TextComponent("§8[§c§l" + Loratadine.CLIENT_NAME + "§8]§c§d" + debugMessage)); + } + } + + public static void displayIRC(String text) { + mc_debugMessage("§l[§bLoratadine§r§l] §r" + text); + } +} diff --git a/src/main/java/net/moran/loratadine/utils/CryptUtil.java b/src/main/java/net/moran/loratadine/utils/CryptUtil.java new file mode 100644 index 0000000..9481277 --- /dev/null +++ b/src/main/java/net/moran/loratadine/utils/CryptUtil.java @@ -0,0 +1,72 @@ +package net.moran.loratadine.utils; + +import java.nio.charset.StandardCharsets; +import java.security.KeyFactory; +import java.security.PrivateKey; +import java.security.PublicKey; +import java.security.spec.PKCS8EncodedKeySpec; +import java.security.spec.X509EncodedKeySpec; +import java.util.Base64; +import javax.crypto.Cipher; + +public class CryptUtil { + public static class Base64Crypt { + public static String decrypt(String message) { + return new String(Base64.getDecoder().decode(message)); + } + + public static String encrypt(String message) { + return Base64.getEncoder().encodeToString(message.getBytes(StandardCharsets.UTF_8)); + } + } + + public static class RSA { + private static final String RSA_KEY_ALGORITHM = "RSA"; + + public static byte[] encryptByPublicKey(byte[] data, String publicKeyStr) { + try { + byte[] pubKey = Base64.getDecoder().decode(publicKeyStr); + X509EncodedKeySpec x509KeySpec = new X509EncodedKeySpec(pubKey); + KeyFactory keyFactory = KeyFactory.getInstance("RSA"); + PublicKey publicKey = keyFactory.generatePublic(x509KeySpec); + Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm()); + cipher.init(1, publicKey); + byte[] encrypt = cipher.doFinal(Base64.getEncoder().encode(data)); + return Base64.getEncoder().encode(encrypt); + } catch (Throwable var8) { + var8.printStackTrace(); + return new byte[0]; + } + } + + public static String decryptByPrivateKey(byte[] data, String privateKeyStr) { + try { + byte[] priKey = Base64.getDecoder().decode(privateKeyStr); + PKCS8EncodedKeySpec pkcs8KeySpec = new PKCS8EncodedKeySpec(priKey); + KeyFactory keyFactory = KeyFactory.getInstance("RSA"); + PrivateKey privateKey = keyFactory.generatePrivate(pkcs8KeySpec); + Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm()); + cipher.init(2, privateKey); + return new String(Base64.getDecoder().decode(cipher.doFinal(Base64.getDecoder().decode(data)))); + } catch (Throwable var7) { + var7.printStackTrace(); + return ""; + } + } + + public static byte[] decryptByPrivateKeyByte(byte[] data, String privateKeyStr) { + try { + byte[] priKey = Base64.getDecoder().decode(privateKeyStr); + PKCS8EncodedKeySpec pkcs8KeySpec = new PKCS8EncodedKeySpec(priKey); + KeyFactory keyFactory = KeyFactory.getInstance("RSA"); + PrivateKey privateKey = keyFactory.generatePrivate(pkcs8KeySpec); + Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm()); + cipher.init(2, privateKey); + return Base64.getDecoder().decode(cipher.doFinal(Base64.getDecoder().decode(data))); + } catch (Throwable var7) { + var7.printStackTrace(); + return new byte[0]; + } + } + } +} diff --git a/src/main/java/net/moran/loratadine/utils/HWIDUtil.java b/src/main/java/net/moran/loratadine/utils/HWIDUtil.java new file mode 100644 index 0000000..34945ae --- /dev/null +++ b/src/main/java/net/moran/loratadine/utils/HWIDUtil.java @@ -0,0 +1,143 @@ +package net.moran.loratadine.utils; + +import dev.annotations.JNICInclude; +import java.io.BufferedReader; +import java.io.InputStream; +import java.io.InputStreamReader; +import java.math.BigInteger; +import java.net.NetworkInterface; +import java.nio.charset.StandardCharsets; +import java.security.MessageDigest; +import java.security.NoSuchAlgorithmException; +import java.util.Enumeration; +import javax.annotation.Nonnull; + +@JNICInclude +public class HWIDUtil { + public static String bytesToHexString(byte[] src) { + StringBuilder stringBuilder = new StringBuilder(); + if (src != null && src.length != 0) { + for (int i = 0; i < src.length; i++) { + int v = src[i] & 255; + String hv = Integer.toHexString(v); + if (hv.length() < 2) { + stringBuilder.append(0); + } + + stringBuilder.append(hv); + } + + return stringBuilder.toString(); + } else { + return null; + } + } + + private static String getSplitString(String str, String split, int length) { + int len = str.length(); + StringBuilder temp = new StringBuilder(); + + for (int i = 0; i < len; i++) { + if (i % length == 0 && i > 0) { + temp.append(split); + } + + temp.append(str.charAt(i)); + } + + String[] attrs = temp.toString().split(split); + StringBuilder finalMachineCode = new StringBuilder(); + + for (String attr : attrs) { + if (attr.length() == length) { + finalMachineCode.append(attr).append(split); + } + } + + return finalMachineCode.substring(0, finalMachineCode.toString().length() - 1); + } + + private static String md5Encoder(String str) { + MessageDigest md = null; + + try { + md = MessageDigest.getInstance("MD5"); + md.update(str.getBytes()); + return getSplitString(new BigInteger(1, md.digest()).toString(16), "-", 5).toUpperCase(); + } catch (NoSuchAlgorithmException var3) { + var3.printStackTrace(); + return str; + } + } + + @Nonnull + public static String getUUID() { + String name = System.getProperty("os.name").toLowerCase(); + + try { + if (name.contains("windows")) { + StringBuilder raw = new StringBuilder(); + String main = System.getenv("PROCESS_IDENTIFIER") + System.getenv("COMPUTERNAME"); + byte[] bytes = main.getBytes(StandardCharsets.UTF_8); + MessageDigest messageDigest = MessageDigest.getInstance("MD5"); + byte[] md5 = messageDigest.digest(bytes); + int i = 0; + + for (byte b : md5) { + raw.append(Integer.toHexString(b & 255 | 768), 0, 3); + if (i != md5.length - 1) { + raw.append(""); + } + + i++; + } + + StringBuilder result = new StringBuilder(raw.substring(raw.length() - 20, raw.length()).toUpperCase()); + + for (int index = 5; index < result.length(); index += 6) { + result.insert(index, '-'); + } + + return md5Encoder(result.toString()); + } + + if (name.contains("mac")) { + Enumeration el = NetworkInterface.getNetworkInterfaces(); + + while (el.hasMoreElements()) { + byte[] mac = el.nextElement().getHardwareAddress(); + if (mac != null) { + String hexStr = bytesToHexString(mac); + if (hexStr == null) { + return ""; + } + + return md5Encoder(getSplitString(hexStr, "-", 2).toUpperCase()); + } + } + + return ""; + } + + if (name.contains("linux")) { + String result = ""; + Process process = Runtime.getRuntime().exec("sudo dmidecode -s system-uuid"); + InputStream in = process.getInputStream(); + BufferedReader br = new BufferedReader(new InputStreamReader(in)); + + while (in.read() != -1) { + result = br.readLine(); + } + + br.close(); + in.close(); + process.destroy(); + return md5Encoder(result); + } + } catch (Exception var11) { + var11.printStackTrace(); + } + + return ""; + } +} diff --git a/src/main/java/net/moran/loratadine/utils/JsonUtil.java b/src/main/java/net/moran/loratadine/utils/JsonUtil.java new file mode 100644 index 0000000..b1468c9 --- /dev/null +++ b/src/main/java/net/moran/loratadine/utils/JsonUtil.java @@ -0,0 +1,27 @@ +package net.moran.loratadine.utils; + +import com.google.gson.JsonObject; + +public class JsonUtil { + private final JsonObject object; + + public JsonUtil(JsonObject object) { + this.object = object; + } + + public String getString(String name, String defaultValue) { + return this.object.has(name) ? this.object.get(name).getAsString() : defaultValue; + } + + public long getLong(String name, long defaultValue) { + return this.object.has(name) ? this.object.get(name).getAsLong() : defaultValue; + } + + public boolean getBoolean(String name, boolean defaultValue) { + return this.object.has(name) ? this.object.get(name).getAsBoolean() : defaultValue; + } + + public int getInt(String name, int defaultValue) { + return this.object.has(name) ? this.object.get(name).getAsInt() : defaultValue; + } +} diff --git a/src/main/java/net/moran/loratadine/utils/NetworkUtils.java b/src/main/java/net/moran/loratadine/utils/NetworkUtils.java new file mode 100644 index 0000000..df73d64 --- /dev/null +++ b/src/main/java/net/moran/loratadine/utils/NetworkUtils.java @@ -0,0 +1,95 @@ +package net.moran.loratadine.utils; + +import io.netty.channel.Channel; +import io.netty.channel.ChannelDuplexHandler; +import io.netty.channel.ChannelHandlerContext; +import io.netty.channel.ChannelPipeline; +import io.netty.channel.ChannelPromise; +import java.lang.reflect.Field; +import java.lang.reflect.Method; +import net.minecraft.client.player.LocalPlayer; +import net.moran.loratadine.Loratadine; +import net.moran.loratadine.event.Event; +import net.moran.loratadine.utils.wrapper.Wrapper; + +public class NetworkUtils implements Wrapper { + public static void init() { + Object handler = Loratadine.INSTANCE.getEventHandler(); + + try { + Class clientPacketListenerClass = Class.forName("net.minecraft.client.multiplayer.ClientPacketListener"); + Class connectionClass = Class.forName("net.minecraft.network.Connection"); + + label44: + for (Field field : LocalPlayer.class.getDeclaredFields()) { + if (field.getType() == clientPacketListenerClass) { + field.setAccessible(true); + Object clientPacketListener = field.get(mc.player); + field.setAccessible(false); + + for (Field innerField : clientPacketListener.getClass().getDeclaredFields()) { + if (innerField.getType() == connectionClass) { + innerField.setAccessible(true); + Object connection = innerField.get(clientPacketListener); + innerField.setAccessible(false); + + for (Field connField : connection.getClass().getDeclaredFields()) { + if (connField.getType() == Channel.class) { + connField.setAccessible(true); + Channel channel = (Channel)connField.get(connection); + ChannelPipeline pipeline = channel.pipeline(); + ChannelDuplexHandler packetHandler = new NetworkUtils.PacketHandler(handler); + pipeline.addBefore("packet_handler", "PacketHandler", packetHandler); + connField.setAccessible(false); + return; + } + } + break label44; + } + } + break; + } + } + } catch (Throwable var20) { + var20.printStackTrace(); + } + } + + private static class PacketHandler extends ChannelDuplexHandler { + private final Object handler; + + public PacketHandler(Object handler) { + this.handler = handler; + } + + public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception { + try { + Method onPacketMethod = this.handler.getClass().getDeclaredMethod("onPacket", Object.class, Event.Side.class); + onPacketMethod.setAccessible(true); + Boolean result = (Boolean)onPacketMethod.invoke(this.handler, msg, Event.Side.PRE); + if (result) { + return; + } + } catch (Exception var5) { + var5.printStackTrace(); + } + + super.channelRead(ctx, msg); + } + + public void write(ChannelHandlerContext ctx, Object msg, ChannelPromise promise) throws Exception { + try { + Method onPacketMethod = this.handler.getClass().getDeclaredMethod("onPacket", Object.class, Event.Side.class); + onPacketMethod.setAccessible(true); + Boolean result = (Boolean)onPacketMethod.invoke(this.handler, msg, Event.Side.POST); + if (result) { + return; + } + } catch (Exception var6) { + var6.printStackTrace(); + } + + super.write(ctx, msg, promise); + } + } +} diff --git a/src/main/java/net/moran/loratadine/utils/PacketUtils.java b/src/main/java/net/moran/loratadine/utils/PacketUtils.java new file mode 100644 index 0000000..0d0f26e --- /dev/null +++ b/src/main/java/net/moran/loratadine/utils/PacketUtils.java @@ -0,0 +1,26 @@ +package net.moran.loratadine.utils; + +import java.util.ArrayList; +import net.minecraft.network.protocol.Packet; +import net.minecraft.network.protocol.game.ServerGamePacketListener; +import net.moran.loratadine.utils.wrapper.Wrapper; + +public class PacketUtils implements Wrapper { + private static final ArrayList> packets = new ArrayList<>(); + + public static boolean handleSendPacket(Packet packet) { + if (packets.contains(packet)) { + packets.remove(packet); + return true; + } else { + return false; + } + } + + public static void sendPacketNoEvent(Packet packet) { + if (mc.player != null) { + packets.add(packet); + mc.player.connection.send(packet); + } + } +} diff --git a/src/main/java/net/moran/loratadine/utils/ReflectionUtil.java b/src/main/java/net/moran/loratadine/utils/ReflectionUtil.java new file mode 100644 index 0000000..3aae098 --- /dev/null +++ b/src/main/java/net/moran/loratadine/utils/ReflectionUtil.java @@ -0,0 +1,31 @@ +package net.moran.loratadine.utils; + +import java.lang.reflect.Field; +import net.minecraft.network.chat.TextComponent; + +public class ReflectionUtil { + public static Field textComponentText; + + public static void init() { + for (Field field : TextComponent.class.getDeclaredFields()) { + if (field.getType() == String.class) { + textComponentText = field; + } + } + } + + public static void set(Field field, Object ins, Object obj) { + try { + boolean canAccess = field.canAccess(ins); + if (!canAccess) { + field.setAccessible(true); + } + + field.set(ins, obj); + if (!canAccess) { + field.setAccessible(false); + } + } catch (Throwable var4) { + } + } +} diff --git a/src/main/java/net/moran/loratadine/utils/RotationUtils.java b/src/main/java/net/moran/loratadine/utils/RotationUtils.java new file mode 100644 index 0000000..e5944e1 --- /dev/null +++ b/src/main/java/net/moran/loratadine/utils/RotationUtils.java @@ -0,0 +1,54 @@ +package net.moran.loratadine.utils; + +import net.minecraft.world.entity.Entity; +import net.minecraft.world.entity.LivingEntity; +import net.minecraft.world.phys.AABB; +import net.minecraft.world.phys.Vec3; +import net.moran.loratadine.utils.vector.Vector3d; +import net.moran.loratadine.utils.wrapper.Wrapper; + +public class RotationUtils implements Wrapper { + public static double getDistanceToEntityBox(Entity target) { + Vec3 eyes = mc.player.getEyePosition(1.0F); + Vec3 pos = getNearestPointBB(eyes, target.getBoundingBox()); + double xDist = Math.abs(pos.x - eyes.x); + double yDist = Math.abs(pos.y - eyes.y); + double zDist = Math.abs(pos.z - eyes.z); + return Math.sqrt(xDist * xDist + yDist * yDist + zDist * zDist); + } + + private static Vec3 getNearestPointBB(Vec3 point, AABB box) { + double x = Math.max(box.minX, Math.min(point.x, box.maxX)); + double y = Math.max(box.minY, Math.min(point.y, box.maxY)); + double z = Math.max(box.minZ, Math.min(point.z, box.maxZ)); + return new Vec3(x, y, z); + } + + public static float[] getRotationFromEyeToPoint(Vector3d point3d) { + return getRotation(new Vector3d(mc.player.getX(), mc.player.getBoundingBox().minY + (double)mc.player.getEyeHeight(), mc.player.getZ()), point3d); + } + + public static float[] getRotation(Vector3d from, Vector3d to) { + double x = to.getX() - from.getX(); + double y = to.getY() - from.getY(); + double z = to.getZ() - from.getZ(); + double sqrt = Math.sqrt(x * x + z * z); + float yaw = (float)Math.toDegrees(Math.atan2(z, x)) - 90.0F; + float pitch = (float)(-Math.toDegrees(Math.atan2(y, sqrt))); + return new float[]{yaw, Math.min(Math.max(pitch, -90.0F), 90.0F)}; + } + + public static float[] getSimpleRotations(LivingEntity target) { + double yDist = target.getY() - mc.player.getY(); + Vector3d targetPos; + if (yDist >= 1.547) { + targetPos = new Vector3d(target.getX(), target.getY(), target.getZ()); + } else if (yDist <= -1.547) { + targetPos = new Vector3d(target.getX(), target.getY() + (double)target.getEyeHeight(), target.getZ()); + } else { + targetPos = new Vector3d(target.getX(), target.getY() + (double)(target.getEyeHeight() / 2.0F), target.getZ()); + } + + return getRotationFromEyeToPoint(targetPos); + } +} diff --git a/src/main/java/net/moran/loratadine/utils/SystemUtils.java b/src/main/java/net/moran/loratadine/utils/SystemUtils.java new file mode 100644 index 0000000..6adb7d1 --- /dev/null +++ b/src/main/java/net/moran/loratadine/utils/SystemUtils.java @@ -0,0 +1,27 @@ +package net.moran.loratadine.utils; + +import dev.annotations.JNICInclude; +import java.io.BufferedReader; +import java.io.IOException; +import java.io.InputStreamReader; + +@JNICInclude +public class SystemUtils { + public static boolean isServiceExist(String serviceName) { + try { + Process process = Runtime.getRuntime().exec("tasklist /SVC"); + BufferedReader reader = new BufferedReader(new InputStreamReader(process.getInputStream())); + + String line; + while ((line = reader.readLine()) != null) { + if (line.contains(serviceName)) { + return true; + } + } + } catch (IOException var4) { + System.out.println("Error executing command."); + } + + return false; + } +} diff --git a/src/main/java/net/moran/loratadine/utils/TimerUtils.java b/src/main/java/net/moran/loratadine/utils/TimerUtils.java new file mode 100644 index 0000000..87dbf17 --- /dev/null +++ b/src/main/java/net/moran/loratadine/utils/TimerUtils.java @@ -0,0 +1,65 @@ +package net.moran.loratadine.utils; + +public class TimerUtils { + public long lastMS = System.currentTimeMillis(); + + public TimerUtils() { + this.reset(); + } + + public void reset() { + this.lastMS = System.currentTimeMillis(); + } + + public void resetMS() { + this.lastMS = System.nanoTime(); + } + + public boolean hasTimeElapsed(long time, boolean reset) { + if (System.currentTimeMillis() - this.lastMS > time) { + if (reset) { + this.reset(); + } + + return true; + } else { + return false; + } + } + + public boolean delay(long time) { + return System.currentTimeMillis() - this.lastMS >= time; + } + + public boolean passedS(double s) { + return this.getMs(System.nanoTime() - this.lastMS) >= (long)(s * 1000.0); + } + + public boolean passedMs(long ms) { + return this.getMs(System.nanoTime() - this.lastMS) >= ms; + } + + public boolean hasTimeElapsed(long time) { + return System.currentTimeMillis() - this.lastMS > time; + } + + public boolean hasTimeElapsed(double time) { + return this.hasTimeElapsed((long)time); + } + + public long getTime() { + return System.currentTimeMillis() - this.lastMS; + } + + public void setTime(long time) { + this.lastMS = time; + } + + public long getPassedTimeMs() { + return this.getMs(System.nanoTime() - this.lastMS); + } + + public long getMs(long time) { + return time / 1000000L; + } +} diff --git a/src/main/java/net/moran/loratadine/utils/helper/ReflectionHelper.java b/src/main/java/net/moran/loratadine/utils/helper/ReflectionHelper.java new file mode 100644 index 0000000..c74ed66 --- /dev/null +++ b/src/main/java/net/moran/loratadine/utils/helper/ReflectionHelper.java @@ -0,0 +1,83 @@ +package net.moran.loratadine.utils.helper; + +import java.lang.reflect.Field; +import java.lang.reflect.Method; +import net.moran.loratadine.utils.unsafe.UnsafeUtils; +import sun.misc.Unsafe; + +public class ReflectionHelper { + public static Field findField(Class clazz, String... fieldNames) { + if (clazz != null && fieldNames != null && fieldNames.length != 0) { + Exception failed = null; + + for (Class currentClass = clazz; currentClass != null; currentClass = currentClass.getSuperclass()) { + for (String fieldName : fieldNames) { + if (fieldName != null) { + try { + Field f = currentClass.getDeclaredField(fieldName); + f.setAccessible(true); + UnsafeUtils.putInt(f, (long)Unsafe.ARRAY_BOOLEAN_BASE_OFFSET, f.getModifiers() & -17); + return f; + } catch (Exception var9) { + failed = var9; + } + } + } + } + + throw new ReflectionHelper.UnableToFindFieldException(failed); + } else { + throw new IllegalArgumentException("Class and fieldNames must not be null or empty"); + } + } + + public static Method findMethod(Class clazz, String obfName, String deobfName, Class... parameterTypes) { + if (clazz != null && (obfName != null || deobfName != null)) { + Exception failed = null; + + for (Class currentClass = clazz; currentClass != null; currentClass = currentClass.getSuperclass()) { + try { + Method m = null; + if (obfName != null) { + try { + m = currentClass.getDeclaredMethod(obfName, parameterTypes); + } catch (NoSuchMethodException var8) { + } + } + + if (m == null && deobfName != null) { + m = currentClass.getDeclaredMethod(deobfName, parameterTypes); + } + + if (m != null) { + m.setAccessible(true); + UnsafeUtils.putInt(m, (long)Unsafe.ARRAY_BOOLEAN_BASE_OFFSET, m.getModifiers() & -17); + return m; + } + } catch (Exception var9) { + failed = var9; + } + } + + throw new ReflectionHelper.UnableToFindMethodException(failed); + } else { + throw new IllegalArgumentException("Class and at least one method name must not be null"); + } + } + + private static class UnableToFindFieldException extends RuntimeException { + private static final long serialVersionUID = 1L; + + public UnableToFindFieldException(Exception e) { + super(e); + } + } + + private static class UnableToFindMethodException extends RuntimeException { + private static final long serialVersionUID = 1L; + + public UnableToFindMethodException(Exception e) { + super(e); + } + } +} diff --git a/src/main/java/net/moran/loratadine/utils/item/InventoryUtils.java b/src/main/java/net/moran/loratadine/utils/item/InventoryUtils.java new file mode 100644 index 0000000..ca83bed --- /dev/null +++ b/src/main/java/net/moran/loratadine/utils/item/InventoryUtils.java @@ -0,0 +1,356 @@ +package net.moran.loratadine.utils.item; + +import com.google.common.collect.Multimap; +import java.util.ArrayList; +import java.util.HashSet; +import java.util.Iterator; +import java.util.List; +import java.util.Set; +import lombok.Generated; +import net.minecraft.world.effect.MobEffect; +import net.minecraft.world.effect.MobEffectInstance; +import net.minecraft.world.effect.MobEffects; +import net.minecraft.world.entity.EquipmentSlot; +import net.minecraft.world.entity.ai.attributes.Attribute; +import net.minecraft.world.entity.ai.attributes.AttributeModifier; +import net.minecraft.world.entity.player.Player; +import net.minecraft.world.food.FoodProperties; +import net.minecraft.world.inventory.AbstractContainerMenu; +import net.minecraft.world.inventory.InventoryMenu; +import net.minecraft.world.inventory.Slot; +import net.minecraft.world.item.ArmorItem; +import net.minecraft.world.item.AxeItem; +import net.minecraft.world.item.BowItem; +import net.minecraft.world.item.CrossbowItem; +import net.minecraft.world.item.DiggerItem; +import net.minecraft.world.item.Item; +import net.minecraft.world.item.ItemStack; +import net.minecraft.world.item.Items; +import net.minecraft.world.item.PickaxeItem; +import net.minecraft.world.item.SwordItem; +import net.minecraft.world.item.alchemy.PotionUtils; +import net.minecraft.world.item.enchantment.Enchantment; +import net.minecraft.world.item.enchantment.EnchantmentHelper; +import net.minecraft.world.item.enchantment.Enchantments; +import net.minecraft.world.level.block.Blocks; +import net.moran.loratadine.utils.wrapper.Wrapper; + +public final class InventoryUtils implements Wrapper { + public static final int INCLUDE_ARMOR_BEGIN = 5; + public static final int EXCLUDE_ARMOR_BEGIN = 9; + public static final int ONLY_HOT_BAR_BEGIN = 36; + public static final int END = 45; + private static final Set GOOD_STATUS_EFFECTS = new HashSet<>( + Set.of( + MobEffects.MOVEMENT_SPEED, + MobEffects.HEAL, + MobEffects.DAMAGE_BOOST, + MobEffects.JUMP, + MobEffects.REGENERATION, + MobEffects.DAMAGE_RESISTANCE, + MobEffects.FIRE_RESISTANCE, + MobEffects.WATER_BREATHING, + MobEffects.NIGHT_VISION, + MobEffects.HEALTH_BOOST, + MobEffects.ABSORPTION, + MobEffects.SATURATION, + MobEffects.LUCK, + MobEffects.SLOW_FALLING, + MobEffects.CONDUIT_POWER, + MobEffects.DOLPHINS_GRACE, + MobEffects.HERO_OF_THE_VILLAGE, + MobEffects.INVISIBILITY + ) + ); + + public static boolean isBestCrossBow(InventoryMenu handler, ItemStack itemStack) { + double bestBowDmg = -1.0; + ItemStack bestBow = ItemStack.EMPTY; + + for (int i = 9; i < 45; i++) { + ItemStack stack = handler.getSlot(i).getItem(); + if (!stack.isEmpty() && stack.getItem() instanceof CrossbowItem) { + double damage = getCrossBowDamage(stack); + if (damage > bestBowDmg) { + bestBow = stack; + bestBowDmg = damage; + } + } + } + + return itemStack.equals(bestBow) || getBowDamage(itemStack) > bestBowDmg; + } + + public static boolean isBestBow(AbstractContainerMenu handler, ItemStack itemStack) { + double bestBowDmg = -1.0; + ItemStack bestBow = ItemStack.EMPTY; + + for (int i = 9; i < 45; i++) { + ItemStack stack = handler.getSlot(i).getItem(); + if (!stack.isEmpty() && stack.getItem() instanceof BowItem) { + double damage = getBowDamage(stack); + if (damage > bestBowDmg) { + bestBow = stack; + bestBowDmg = damage; + } + } + } + + return itemStack.equals(bestBow) || getBowDamage(itemStack) > bestBowDmg; + } + + public static double getCrossBowDamage(ItemStack stack) { + double damage = 0.0; + if (stack.getItem() instanceof CrossbowItem && stack.hasFoil()) { + damage += (double)getLevel(Enchantments.POWER_ARROWS, stack); + } + + return damage; + } + + public static double getBowDamage(ItemStack stack) { + double damage = 0.0; + if (stack.getItem() instanceof BowItem && stack.hasFoil()) { + damage += (double)getLevel(Enchantments.POWER_ARROWS, stack); + } + + return damage; + } + + public static boolean isBuffPotion(ItemStack stack) { + for (MobEffectInstance effect : PotionUtils.getMobEffects(stack)) { + if (!effect.getEffect().isBeneficial()) { + return false; + } + } + + return true; + } + + public static boolean isBestTool(AbstractContainerMenu handler, ItemStack itemStack) { + int type = getToolType(itemStack); + InventoryUtils.Tool bestTool = new InventoryUtils.Tool(-1, -1.0, ItemStack.EMPTY); + + for (int i = 9; i < 45; i++) { + ItemStack stack = handler.getSlot(i).getItem(); + if (!stack.isEmpty() && stack.getItem() instanceof DiggerItem && type == getToolType(stack)) { + double efficiency = (double)getToolScore(stack); + if (efficiency > (double)getToolScore(bestTool.getItem())) { + bestTool = new InventoryUtils.Tool(i, efficiency, stack); + } + } + } + + return bestTool.getItem().equals(itemStack) || getToolScore(itemStack) > getToolScore(bestTool.getItem()); + } + + public static float getToolScore(ItemStack stack) { + float score = 0.0F; + Item item = stack.getItem(); + if (item instanceof DiggerItem tool) { + if (item instanceof PickaxeItem) { + score = tool.getDestroySpeed(stack, Blocks.STONE.defaultBlockState()) - 0.0F; + } else { + if (!(item instanceof AxeItem)) { + return 1.0F; + } + + score = tool.getDestroySpeed(stack, Blocks.DARK_OAK_LOG.defaultBlockState()); + } + + score += (float)getLevel(Enchantments.BLOCK_EFFICIENCY, stack) * 0.0075F; + score += (float)getLevel(Enchantments.BLOCK_EFFICIENCY, stack) / 100.0F; + score += (float)getLevel(Enchantments.SHARPNESS, stack) * 1.0F; + } + + return score; + } + + public static float getToolEfficiency(ItemStack itemStack) { + DiggerItem tool = (DiggerItem)itemStack.getItem(); + float efficiency = tool.getTier().getSpeed(); + int lvl = getLevel(Enchantments.BLOCK_EFFICIENCY, itemStack); + if (efficiency > 1.0F && lvl > 0) { + efficiency += (float)(lvl * lvl + 1); + } + + return efficiency; + } + + public static boolean isGoodFood(ItemStack stack) { + if (stack.getItem() == Items.GOLDEN_APPLE) { + return true; + } else { + FoodProperties component = stack.getItem().getFoodProperties(); + return component.getNutrition() >= 4 && component.getSaturationModifier() >= 0.3F; + } + } + + public static boolean isGoodItem(ItemStack stack) { + Item item = stack.getItem(); + return item == Items.FIRE_CHARGE + || item == Items.ENDER_PEARL + || item == Items.ARROW + || item == Items.WATER_BUCKET + || item == Items.SLIME_BALL + || item == Items.TNT + || item instanceof CrossbowItem && isBestCrossBow(mc.player.inventoryMenu, stack); + } + + public static boolean isBestSword(AbstractContainerMenu c, ItemStack itemStack) { + double damage = 0.0; + ItemStack bestStack = ItemStack.EMPTY; + + for (int i = 9; i < 45; i++) { + ItemStack stack = c.getSlot(i).getItem(); + if (!stack.isEmpty() && stack.getItem() instanceof SwordItem) { + double newDamage = getItemDamage(stack); + if (newDamage > damage) { + damage = newDamage; + bestStack = stack; + } + } + } + + return bestStack.equals(itemStack) || getItemDamage(itemStack) > damage; + } + + public static boolean isBestArmor(AbstractContainerMenu c, ItemStack itemStack) { + ArmorItem itemArmor = (ArmorItem)itemStack.getItem(); + double reduction = 0.0; + ItemStack bestStack = ItemStack.EMPTY; + + for (int i = 5; i < 45; i++) { + ItemStack stack = c.getSlot(i).getItem(); + if (!stack.isEmpty()) { + Item newReduction = stack.getItem(); + if (newReduction instanceof ArmorItem) { + ArmorItem stackArmor = (ArmorItem)newReduction; + if (stackArmor.getSlot().getFilterFlag() - 1 == itemArmor.getSlot().getFilterFlag() - 1) { + double newReductionx = getDamageReduction(stack); + if (newReductionx > reduction) { + reduction = newReductionx; + bestStack = stack; + } + } + } + } + } + + return bestStack.equals(itemStack) || getDamageReduction(itemStack) > reduction; + } + + public static double getDamageReduction(ItemStack stack) { + double reduction = 0.0; + if (!(stack.getItem() instanceof ArmorItem)) { + return 0.0; + } else { + ArmorItem armor = (ArmorItem)stack.getItem(); + reduction += (double)armor.getDefense(); + if (stack.hasFoil()) { + reduction += (double)getLevel(Enchantments.ALL_DAMAGE_PROTECTION, stack) * 0.25; + } + + return reduction; + } + } + + public static double getItemDamage(ItemStack stack) { + double damage = 0.0; + Multimap attributeModifierMap = stack.getAttributeModifiers(EquipmentSlot.MAINHAND); + + for (Attribute attributeName : attributeModifierMap.keySet()) { + if (attributeName.getDescriptionId().equals("attribute.name.generic.attack_damage")) { + Iterator attributeModifiers = attributeModifierMap.get(attributeName).iterator(); + if (attributeModifiers.hasNext()) { + damage += attributeModifiers.next().getAmount(); + } + break; + } + } + + if (stack.hasFoil()) { + damage += (double)EnchantmentHelper.getItemEnchantmentLevel(Enchantments.FIRE_ASPECT, stack); + damage += (double)EnchantmentHelper.getItemEnchantmentLevel(Enchantments.SHARPNESS, stack) * 1.25; + } + + return damage; + } + + private static int getLevel(Enchantment registryKey, ItemStack itemStack) { + return EnchantmentHelper.getItemEnchantmentLevel(registryKey, itemStack); + } + + public static int getToolType(ItemStack stack) { + DiggerItem tool = (DiggerItem)stack.getItem(); + if (tool instanceof PickaxeItem) { + return 0; + } else { + return tool instanceof AxeItem ? 1 : -1; + } + } + + public static List getItemStacks(Player player) { + List result = new ArrayList<>(); + + for (Slot slot : player.inventoryMenu.slots) { + if (!slot.getItem().isEmpty()) { + result.add(slot.getItem()); + } + } + + return result; + } + + public static float getPlayerArmorScore(Player player) { + float score = 0.0F; + + for (int armorSlot = 5; armorSlot < 9; armorSlot++) { + ItemStack stack = player.inventoryMenu.getSlot(armorSlot).getItem(); + if (stack != null) { + score += (float)getDamageReduction(stack); + } + } + + return score; + } + + public static boolean isArmorBetter(Player player) { + return getPlayerArmorScore(player) < getPlayerArmorScore(mc.player); + } + + @Generated + private InventoryUtils() { + throw new UnsupportedOperationException("This is a utility class and cannot be instantiated"); + } + + public static enum BlockAction { + PLACE, + REPLACE, + PLACE_ON; + } + + private static class Tool { + private final int slot; + private final double efficiency; + private final ItemStack stack; + + public Tool(int slot, double efficiency, ItemStack stack) { + this.slot = slot; + this.efficiency = efficiency; + this.stack = stack; + } + + public int getSlot() { + return this.slot; + } + + public double getEfficiency() { + return this.efficiency; + } + + public ItemStack getItem() { + return this.stack; + } + } +} diff --git a/src/main/java/net/moran/loratadine/utils/math/MathUtils.java b/src/main/java/net/moran/loratadine/utils/math/MathUtils.java new file mode 100644 index 0000000..2323f4e --- /dev/null +++ b/src/main/java/net/moran/loratadine/utils/math/MathUtils.java @@ -0,0 +1,124 @@ +package net.moran.loratadine.utils.math; + +import java.math.BigDecimal; +import java.math.RoundingMode; +import java.security.SecureRandom; +import java.text.DecimalFormat; +import java.util.Random; +import lombok.Generated; + +public final class MathUtils { + public static final DecimalFormat DF_0 = new DecimalFormat("0"); + public static final DecimalFormat DF_1 = new DecimalFormat("0.0"); + public static final DecimalFormat DF_2 = new DecimalFormat("0.00"); + public static final float PI = (float) Math.PI; + public static final float TO_RADIANS = (float) (Math.PI / 180.0); + public static final float TO_DEGREES = 180.0F / (float)Math.PI; + + public static boolean approximatelyEquals(float a, float b) { + return Math.abs(b - a) < 1.0E-5F; + } + + public static boolean approximatelyEquals(double a, double b) { + return Math.abs(b - a) < 1.0E-5F; + } + + public static double roundToPlace(double value, int place) { + if (place < 0) { + return value; + } else { + BigDecimal bd = new BigDecimal(value); + bd = bd.setScale(place, RoundingMode.HALF_UP); + return bd.doubleValue(); + } + } + + public static float clamp2(float num, float min, float max) { + return num < min ? min : Math.min(num, max); + } + + public static Double clamp(double num, double min, double max) { + return Math.min(Math.max(num, min), max); + } + + public static double getRandomInRange(double min, double max) { + SecureRandom random = new SecureRandom(); + return min == max ? min : random.nextDouble() * (max - min) + min; + } + + public static int getRandomNumberUsingNextInt(int min, int max) { + Random random = new Random(); + return random.nextInt(max - min) + min; + } + + public static double lerp(double old, double newVal, double amount) { + return (1.0 - amount) * old + amount * newVal; + } + + public static Double interpolate(double oldValue, double newValue, double interpolationValue) { + return oldValue + (newValue - oldValue) * interpolationValue; + } + + public static float interpolateFloat(float oldValue, float newValue, double interpolationValue) { + return interpolate((double)oldValue, (double)newValue, (double)((float)interpolationValue)).floatValue(); + } + + public static int interpolateInt(int oldValue, int newValue, double interpolationValue) { + return interpolate((double)oldValue, (double)newValue, (double)((float)interpolationValue)).intValue(); + } + + public static float calculateGaussianValue(float x, float sigma) { + double output = 1.0 / Math.sqrt((Math.PI * 2) * (double)(sigma * sigma)); + return (float)(output * Math.exp((double)(-(x * x)) / (2.0 * (double)(sigma * sigma)))); + } + + public static double roundToHalf(double d) { + return (double)Math.round(d * 2.0) / 2.0; + } + + public static double round(double num, double increment) { + BigDecimal bd = new BigDecimal(num); + bd = bd.setScale((int)increment, RoundingMode.HALF_UP); + return bd.doubleValue(); + } + + public static double round(double value, int places) { + if (places < 0) { + throw new IllegalArgumentException(); + } else { + BigDecimal bd = new BigDecimal(value); + bd = bd.setScale(places, RoundingMode.HALF_UP); + return bd.doubleValue(); + } + } + + public static String round(String value, int places) { + if (places < 0) { + throw new IllegalArgumentException(); + } else { + BigDecimal bd = new BigDecimal(value); + bd = bd.stripTrailingZeros(); + bd = bd.setScale(places, RoundingMode.HALF_UP); + return bd.toString(); + } + } + + public static float getRandomFloat(float max, float min) { + SecureRandom random = new SecureRandom(); + return random.nextFloat() * (max - min) + min; + } + + public static int getNumberOfDecimalPlace(double value) { + BigDecimal bigDecimal = new BigDecimal(value); + return Math.max(0, bigDecimal.stripTrailingZeros().scale()); + } + + public static boolean equals(float a, float b) { + return (double)Math.abs(a - b) < 1.0E-4; + } + + @Generated + private MathUtils() { + throw new UnsupportedOperationException("This is a utility class and cannot be instantiated"); + } +} diff --git a/src/main/java/net/moran/loratadine/utils/misc/EntityUtils.java b/src/main/java/net/moran/loratadine/utils/misc/EntityUtils.java new file mode 100644 index 0000000..bd4821f --- /dev/null +++ b/src/main/java/net/moran/loratadine/utils/misc/EntityUtils.java @@ -0,0 +1,70 @@ +package net.moran.loratadine.utils.misc; + +import net.minecraft.client.multiplayer.ClientPacketListener; +import net.minecraft.client.multiplayer.PlayerInfo; +import net.minecraft.world.entity.Entity; +import net.minecraft.world.entity.LivingEntity; +import net.minecraft.world.entity.Mob; +import net.minecraft.world.entity.ambient.Bat; +import net.minecraft.world.entity.animal.Animal; +import net.minecraft.world.entity.animal.IronGolem; +import net.minecraft.world.entity.animal.Squid; +import net.minecraft.world.entity.boss.enderdragon.EnderDragon; +import net.minecraft.world.entity.monster.Ghast; +import net.minecraft.world.entity.monster.Shulker; +import net.minecraft.world.entity.monster.Slime; +import net.minecraft.world.entity.npc.Villager; +import net.minecraft.world.entity.player.Player; +import net.moran.loratadine.Loratadine; +import net.moran.loratadine.modules.impl.misc.Teams; +import net.moran.loratadine.utils.wrapper.Wrapper; + +public final class EntityUtils implements Wrapper { + public static boolean isSelected( + Entity entity, boolean targetPlayer, boolean targetMobs, boolean targetAnimals, boolean targetDead, boolean targetInvisible, boolean canAttackCheck + ) { + if (entity instanceof LivingEntity && (targetDead || entity.isAlive()) && !entity.equals(mc.player) && (targetInvisible || !entity.isInvisible())) { + if (targetPlayer && entity instanceof Player entityPlayer) { + if (!canAttackCheck) { + return true; + } else if (entityPlayer.isSpectator()) { + return false; + } else { + Teams teams = (Teams)Loratadine.INSTANCE.getModuleManager().getModule(Teams.class); + return !teams.isEnabled() || !teams.isSameTeam(entityPlayer); + } + } else { + return targetMobs && isMob(entity) || targetAnimals && isAnimal(entity); + } + } else { + return false; + } + } + + public static boolean isAnimal(Entity entity) { + return entity instanceof Animal || entity instanceof Squid || entity instanceof IronGolem || entity instanceof Bat; + } + + public static boolean isMob(Entity entity) { + return entity instanceof Mob + || entity instanceof Villager + || entity instanceof Slime + || entity instanceof Ghast + || entity instanceof EnderDragon + || entity instanceof Shulker; + } + + public static int getPing(Player entityPlayer) { + if (entityPlayer == null) { + return 0; + } else { + ClientPacketListener connection = mc.getConnection(); + if (connection == null) { + return 0; + } else { + PlayerInfo networkPlayerInfo = connection.getPlayerInfo(entityPlayer.getUUID()); + return networkPlayerInfo == null ? 0 : networkPlayerInfo.getLatency(); + } + } + } +} diff --git a/src/main/java/net/moran/loratadine/utils/misc/WebUtils.java b/src/main/java/net/moran/loratadine/utils/misc/WebUtils.java new file mode 100644 index 0000000..8a6d91b --- /dev/null +++ b/src/main/java/net/moran/loratadine/utils/misc/WebUtils.java @@ -0,0 +1,61 @@ +package net.moran.loratadine.utils.misc; + +import dev.annotations.JNICInclude; +import java.io.BufferedReader; +import java.io.IOException; +import java.io.InputStreamReader; +import java.net.HttpURLConnection; +import java.net.URL; +import java.net.URLConnection; + +@JNICInclude +public class WebUtils { + public static String get(String url, boolean preventRedirect) throws IOException { + HttpURLConnection con = (HttpURLConnection)new URL(url).openConnection(); + con.setRequestMethod("GET"); + con.setRequestProperty("User-Agent", "Mozilla/5.0"); + con.setInstanceFollowRedirects(!preventRedirect); + BufferedReader in = new BufferedReader(new InputStreamReader(con.getInputStream())); + StringBuilder response = new StringBuilder(); + + String inputLine; + while ((inputLine = in.readLine()) != null) { + response.append(inputLine); + response.append("\n"); + } + + in.close(); + return response.toString(); + } + + public static String readContent(String stringURL) throws IOException { + HttpURLConnection httpConnection = (HttpURLConnection)new URL(stringURL).openConnection(); + httpConnection.setConnectTimeout(10000); + httpConnection.setReadTimeout(10000); + httpConnection.setRequestMethod("GET"); + httpConnection.setRequestProperty("User-Agent", "Mozilla/5.0 (Windows NT 6.1; WOW64; rv:25.0) Gecko/20100101 Firefox/25.0"); + HttpURLConnection.setFollowRedirects(true); + httpConnection.setDoOutput(true); + BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(httpConnection.getInputStream())); + StringBuilder stringBuilder = new StringBuilder(); + + String line; + while ((line = bufferedReader.readLine()) != null) { + stringBuilder.append(line).append("\n"); + } + + bufferedReader.close(); + return stringBuilder.toString(); + } + + public static boolean isNetworkConnected() { + try { + URL url = new URL("https://www.baidu.com"); + URLConnection connection = url.openConnection(); + connection.connect(); + return true; + } catch (IOException var2) { + return false; + } + } +} diff --git a/src/main/java/net/moran/loratadine/utils/player/BlockUtils.java b/src/main/java/net/moran/loratadine/utils/player/BlockUtils.java new file mode 100644 index 0000000..46b2269 --- /dev/null +++ b/src/main/java/net/moran/loratadine/utils/player/BlockUtils.java @@ -0,0 +1,41 @@ +package net.moran.loratadine.utils.player; + +import lombok.Generated; +import net.minecraft.core.BlockPos; +import net.minecraft.world.level.block.AirBlock; +import net.minecraft.world.level.block.Block; +import net.minecraft.world.level.block.ChestBlock; +import net.minecraft.world.level.block.FurnaceBlock; +import net.minecraft.world.level.block.LadderBlock; +import net.minecraft.world.level.block.LiquidBlock; +import net.minecraft.world.level.block.TntBlock; +import net.moran.loratadine.utils.wrapper.Wrapper; + +public final class BlockUtils implements Wrapper { + public static boolean isAirBlock(BlockPos blockPos) { + Block block = mc.level.getBlockState(blockPos).getBlock(); + return block instanceof AirBlock; + } + + public static boolean isValidBlock(BlockPos blockPos) { + return isValidBlock(mc.level.getBlockState(blockPos).getBlock()); + } + + public static boolean isValidBlock(Block block) { + return !(block instanceof LiquidBlock) + && !(block instanceof AirBlock) + && !(block instanceof ChestBlock) + && !(block instanceof FurnaceBlock) + && !(block instanceof LadderBlock) + && !(block instanceof TntBlock); + } + + public static Block getBlock(BlockPos blockPos) { + return mc.level.getBlockState(blockPos).getBlock(); + } + + @Generated + private BlockUtils() { + throw new UnsupportedOperationException("This is a utility class and cannot be instantiated"); + } +} diff --git a/src/main/java/net/moran/loratadine/utils/player/MoveUtils.java b/src/main/java/net/moran/loratadine/utils/player/MoveUtils.java new file mode 100644 index 0000000..036601d --- /dev/null +++ b/src/main/java/net/moran/loratadine/utils/player/MoveUtils.java @@ -0,0 +1,41 @@ +package net.moran.loratadine.utils.player; + +import lombok.Generated; +import net.moran.loratadine.utils.wrapper.Wrapper; + +public final class MoveUtils implements Wrapper { + public static boolean isMoving() { + return mc.player != null + && mc.level != null + && mc.player.input != null + && ((double)mc.player.input.forwardImpulse != 0.0 || (double)mc.player.input.leftImpulse != 0.0); + } + + public static double direction(float rotationYaw, double moveForward, double moveStrafing) { + if (moveForward < 0.0) { + rotationYaw += 180.0F; + } + + float forward = 1.0F; + if (moveForward < 0.0) { + forward = -0.5F; + } else if (moveForward > 0.0) { + forward = 0.5F; + } + + if (moveStrafing > 0.0) { + rotationYaw -= 90.0F * forward; + } + + if (moveStrafing < 0.0) { + rotationYaw += 90.0F * forward; + } + + return Math.toRadians((double)rotationYaw); + } + + @Generated + private MoveUtils() { + throw new UnsupportedOperationException("This is a utility class and cannot be instantiated"); + } +} diff --git a/src/main/java/net/moran/loratadine/utils/render/ColorUtils.java b/src/main/java/net/moran/loratadine/utils/render/ColorUtils.java new file mode 100644 index 0000000..3e55787 --- /dev/null +++ b/src/main/java/net/moran/loratadine/utils/render/ColorUtils.java @@ -0,0 +1,52 @@ +package net.moran.loratadine.utils.render; + +import java.awt.Color; +import lombok.Generated; + +public final class ColorUtils { + public static Color rainbow(int speed, int index) { + int angle = (int)((System.currentTimeMillis() / (long)speed + (long)index) % 360L); + float hue = (float)angle / 360.0F; + return new Color(Color.HSBtoRGB(hue, 0.7F, 1.0F)); + } + + public static int alpha(int hex) { + return hex >> 24 & 0xFF; + } + + public static int red(int hex) { + return hex >> 16 & 0xFF; + } + + public static int green(int hex) { + return hex >> 8 & 0xFF; + } + + public static int blue(int hex) { + return hex & 0xFF; + } + + public static Color getBlack(float opacity) { + opacity = Math.min(1.0F, Math.max(0.0F, opacity)); + return new Color(0.0F, 0.0F, 0.0F, opacity); + } + + public static int applyOpacity(int color, float opacity) { + Color old = new Color(color); + return applyOpacity(old, opacity).getRGB(); + } + + public static Color applyOpacity(Color color, float opacity) { + opacity = Math.min(1.0F, Math.max(0.0F, opacity)); + return new Color(color.getRed(), color.getGreen(), color.getBlue(), (int)((float)color.getAlpha() * opacity)); + } + + public static int color(int r, int g, int b, int a) { + return (a & 0xFF) << 24 | (r & 0xFF) << 16 | (g & 0xFF) << 8 | b & 0xFF; + } + + @Generated + private ColorUtils() { + throw new UnsupportedOperationException("This is a utility class and cannot be instantiated"); + } +} diff --git a/src/main/java/net/moran/loratadine/utils/render/GLUtils.java b/src/main/java/net/moran/loratadine/utils/render/GLUtils.java new file mode 100644 index 0000000..c4827cc --- /dev/null +++ b/src/main/java/net/moran/loratadine/utils/render/GLUtils.java @@ -0,0 +1,35 @@ +package net.moran.loratadine.utils.render; + +import com.mojang.blaze3d.platform.NativeImage; +import com.mojang.blaze3d.systems.RenderSystem; +import java.awt.image.BufferedImage; +import lombok.Generated; +import net.minecraft.client.renderer.texture.DynamicTexture; + +public final class GLUtils { + public static void color(int r, int g, int b, int a) { + RenderSystem.setShaderColor((float)r / 255.0F, (float)g / 255.0F, (float)b / 255.0F, (float)a / 255.0F); + } + + public static void color(int hex) { + color(ColorUtils.red(hex), ColorUtils.green(hex), ColorUtils.blue(hex), ColorUtils.alpha(hex)); + } + + public static int uploadTexture(BufferedImage image) { + NativeImage nativeImage = new NativeImage(image.getWidth(), image.getHeight(), false); + + for (int x = 0; x < image.getWidth(); x++) { + for (int y = 0; y < image.getHeight(); y++) { + nativeImage.setPixelRGBA(x, y, image.getRGB(x, y)); + } + } + + DynamicTexture texture = new DynamicTexture(nativeImage); + return texture.getId(); + } + + @Generated + private GLUtils() { + throw new UnsupportedOperationException("This is a utility class and cannot be instantiated"); + } +} diff --git a/src/main/java/net/moran/loratadine/utils/render/RenderUtils.java b/src/main/java/net/moran/loratadine/utils/render/RenderUtils.java new file mode 100644 index 0000000..66d8835 --- /dev/null +++ b/src/main/java/net/moran/loratadine/utils/render/RenderUtils.java @@ -0,0 +1,133 @@ +package net.moran.loratadine.utils.render; + +import com.mojang.blaze3d.systems.RenderSystem; +import com.mojang.blaze3d.vertex.BufferBuilder; +import com.mojang.blaze3d.vertex.DefaultVertexFormat; +import com.mojang.blaze3d.vertex.PoseStack; +import com.mojang.blaze3d.vertex.Tesselator; +import com.mojang.blaze3d.vertex.VertexFormat.Mode; +import com.mojang.math.Matrix4f; +import com.mojang.math.Quaternion; +import java.awt.Color; +import java.util.function.Supplier; +import net.minecraft.client.renderer.GameRenderer; +import net.minecraft.client.renderer.ShaderInstance; +import net.minecraft.client.renderer.entity.EntityRenderDispatcher; +import net.minecraft.world.entity.Entity; +import net.minecraft.world.entity.LivingEntity; +import net.minecraft.world.entity.player.Player; +import net.moran.loratadine.utils.wrapper.Wrapper; + +public class RenderUtils implements Wrapper { + public static void renderEntityBoundingBox(PoseStack poseStack, int type, Entity entity, int color, boolean damage) { + if (entity instanceof LivingEntity) { + EntityRenderDispatcher renderManager = mc.getEntityRenderDispatcher(); + double x = entity.xOld + (entity.getX() - entity.xOld) * (double)mc.getFrameTime() - renderManager.camera.getPosition().x(); + double y = entity.yOld + (entity.getY() - entity.yOld) * (double)mc.getFrameTime() - renderManager.camera.getPosition().y(); + double z = entity.zOld + (entity.getZ() - entity.zOld) * (double)mc.getFrameTime() - renderManager.camera.getPosition().z(); + float scale = 0.03F; + if (entity instanceof Player && damage && ((Player)entity).hurtTime > 0) { + color = Color.RED.getRGB(); + } + + RenderSystem.disableDepthTest(); + switch (type) { + case 0: + poseStack.pushPose(); + poseStack.translate(x, y, z); + poseStack.mulPose(new Quaternion(0.0F, -renderManager.camera.getYRot(), 0.0F, true)); + poseStack.scale(scale, scale, scale); + int outline = Color.BLACK.getRGB(); + drawRect(poseStack, -20, -1, -26, 75, outline); + drawRect(poseStack, 20, -1, 26, 75, outline); + drawRect(poseStack, -20, -1, 21, 5, outline); + drawRect(poseStack, -20, 70, 21, 75, outline); + if (color != 0) { + drawRect(poseStack, -21, 0, -25, 74, color); + drawRect(poseStack, 21, 0, 25, 74, color); + drawRect(poseStack, -21, 0, 24, 4, color); + drawRect(poseStack, -21, 71, 25, 74, color); + } else { + int startColor = rainbowDraw(2L, 0L); + int endColor = rainbowDraw(2L, 1000L); + drawGradientRect(poseStack, -21, 0, -25, 74, startColor, endColor); + drawGradientRect(poseStack, 21, 0, 25, 74, startColor, endColor); + drawRect(poseStack, -21, 0, 21, 4, endColor); + drawRect(poseStack, -21, 71, 21, 74, startColor); + } + + RenderSystem.enableDepthTest(); + poseStack.popPose(); + } + } + } + + public static int rainbowDraw(long speed, long... delay) { + long time = System.currentTimeMillis() + (delay.length > 0 ? delay[0] : 0L); + return Color.getHSBColor((float)(time % (15000L / speed)) / (15000.0F / (float)speed), 1.0F, 1.0F).getRGB(); + } + + public static void drawRect(PoseStack poseStack, int left, int top, int right, int bottom, int color) { + if (left < right) { + int j = left; + left = right; + right = j; + } + + if (top < bottom) { + int j = top; + top = bottom; + bottom = j; + } + + Matrix4f matrix = poseStack.last().pose(); + Tesselator tessellator = Tesselator.getInstance(); + BufferBuilder bufferbuilder = tessellator.getBuilder(); + RenderSystem.setShader(new Supplier() { + public ShaderInstance get() { + return GameRenderer.getPositionColorShader(); + } + }); + RenderSystem.setShaderColor(1.0F, 1.0F, 1.0F, 1.0F); + RenderSystem.disableTexture(); + bufferbuilder.begin(Mode.QUADS, DefaultVertexFormat.POSITION_COLOR); + bufferbuilder.vertex(matrix, (float)left, (float)bottom, 0.0F).color(color >> 16 & 0xFF, color >> 8 & 0xFF, color & 0xFF, color >> 24 & 0xFF).endVertex(); + bufferbuilder.vertex(matrix, (float)right, (float)bottom, 0.0F) + .color(color >> 16 & 0xFF, color >> 8 & 0xFF, color & 0xFF, color >> 24 & 0xFF) + .endVertex(); + bufferbuilder.vertex(matrix, (float)right, (float)top, 0.0F).color(color >> 16 & 0xFF, color >> 8 & 0xFF, color & 0xFF, color >> 24 & 0xFF).endVertex(); + bufferbuilder.vertex(matrix, (float)left, (float)top, 0.0F).color(color >> 16 & 0xFF, color >> 8 & 0xFF, color & 0xFF, color >> 24 & 0xFF).endVertex(); + tessellator.end(); + RenderSystem.enableTexture(); + } + + public static void drawGradientRect(PoseStack poseStack, int left, int top, int right, int bottom, int startColor, int endColor) { + Matrix4f matrix = poseStack.last().pose(); + Tesselator tessellator = Tesselator.getInstance(); + BufferBuilder bufferbuilder = tessellator.getBuilder(); + RenderSystem.setShader(new Supplier() { + public ShaderInstance get() { + return GameRenderer.getPositionColorShader(); + } + }); + RenderSystem.disableTexture(); + RenderSystem.enableBlend(); + RenderSystem.defaultBlendFunc(); + float startAlpha = (float)(startColor >> 24 & 0xFF) / 255.0F; + float startRed = (float)(startColor >> 16 & 0xFF) / 255.0F; + float startGreen = (float)(startColor >> 8 & 0xFF) / 255.0F; + float startBlue = (float)(startColor & 0xFF) / 255.0F; + float endAlpha = (float)(endColor >> 24 & 0xFF) / 255.0F; + float endRed = (float)(endColor >> 16 & 0xFF) / 255.0F; + float endGreen = (float)(endColor >> 8 & 0xFF) / 255.0F; + float endBlue = (float)(endColor & 0xFF) / 255.0F; + bufferbuilder.begin(Mode.QUADS, DefaultVertexFormat.POSITION_COLOR); + bufferbuilder.vertex(matrix, (float)right, (float)top, 0.0F).color(startRed, startGreen, startBlue, startAlpha).endVertex(); + bufferbuilder.vertex(matrix, (float)left, (float)top, 0.0F).color(startRed, startGreen, startBlue, startAlpha).endVertex(); + bufferbuilder.vertex(matrix, (float)left, (float)bottom, 0.0F).color(endRed, endGreen, endBlue, endAlpha).endVertex(); + bufferbuilder.vertex(matrix, (float)right, (float)bottom, 0.0F).color(endRed, endGreen, endBlue, endAlpha).endVertex(); + tessellator.end(); + RenderSystem.disableBlend(); + RenderSystem.enableTexture(); + } +} diff --git a/src/main/java/net/moran/loratadine/utils/unsafe/UnsafeUtils.java b/src/main/java/net/moran/loratadine/utils/unsafe/UnsafeUtils.java new file mode 100644 index 0000000..7c163e8 --- /dev/null +++ b/src/main/java/net/moran/loratadine/utils/unsafe/UnsafeUtils.java @@ -0,0 +1,92 @@ +package net.moran.loratadine.utils.unsafe; + +import java.lang.reflect.Field; +import lombok.Generated; +import sun.misc.Unsafe; + +public class UnsafeUtils { + private static final Unsafe unsafe; + + private static Unsafe getUnsafeInstance() throws NoSuchFieldException, IllegalAccessException, ClassNotFoundException { + Class unsafeClass = Class.forName("sun.misc.Unsafe"); + Field theUnsafeField = unsafeClass.getDeclaredField("theUnsafe"); + theUnsafeField.setAccessible(true); + return (Unsafe)theUnsafeField.get(null); + } + + public static long allocateMemory(long size) { + return unsafe.allocateMemory(size); + } + + public static void freeMemory(long address) { + unsafe.freeMemory(address); + } + + public static void putLong(long address, long value) { + unsafe.putLong(address, value); + } + + public static void putInt(long address, int value) { + unsafe.putInt(address, value); + } + + public static void putInt(Object object, long offset, int value) { + unsafe.putInt(object, offset, value); + } + + public static int getInt(long address) { + return unsafe.getInt(address); + } + + public static int getInt(Object object, long offset) { + return unsafe.getInt(object, offset); + } + + public static long getLong(long address) { + return unsafe.getLong(address); + } + + public static Object getObject(Object object, long offset) { + return unsafe.getObject(object, offset); + } + + public static void putObject(Object object, long offset, Object value) { + unsafe.putObject(object, offset, value); + } + + public static long getFieldOffset(Field field) { + return unsafe.objectFieldOffset(field); + } + + public static Object createInstance(Class clazz) throws InstantiationException { + return unsafe.allocateInstance(clazz); + } + + public static void loadClass(Class clazz) { + unsafe.ensureClassInitialized(clazz); + } + + public static long getArrayBaseOffset(Class clazz) { + return (long)unsafe.arrayBaseOffset(clazz); + } + + public static long getArrayIndexScale(Class clazz) { + return (long)unsafe.arrayIndexScale(clazz); + } + + @Generated + public static Unsafe getUnsafe() { + return unsafe; + } + + static { + try { + unsafe = getUnsafeInstance(); + if (unsafe == null) { + throw new RuntimeException("Unable to get Unsafe instance"); + } + } catch (Exception var1) { + throw new RuntimeException("Unable to get Unsafe instance", var1); + } + } +} diff --git a/src/main/java/net/moran/loratadine/utils/vector/Vector3d.java b/src/main/java/net/moran/loratadine/utils/vector/Vector3d.java new file mode 100644 index 0000000..4b13525 --- /dev/null +++ b/src/main/java/net/moran/loratadine/utils/vector/Vector3d.java @@ -0,0 +1,77 @@ +package net.moran.loratadine.utils.vector; + +import lombok.Generated; + +public class Vector3d { + public double x; + public double y; + public double z; + + public Vector3d(double x, double y, double z) { + this.x = x; + this.y = y; + this.z = z; + } + + public Vector3d add(double x, double y, double z) { + return new Vector3d(this.x + x, this.y + y, this.z + z); + } + + public Vector3d add(Vector3d vector) { + return this.add(vector.x, vector.y, vector.z); + } + + public Vector3d subtract(double x, double y, double z) { + return this.add(-x, -y, -z); + } + + public Vector3d subtract(Vector3d vector) { + return this.add(-vector.x, -vector.y, -vector.z); + } + + public double length() { + return Math.sqrt(this.x * this.x + this.y * this.y + this.z * this.z); + } + + public double getX() { + return this.x; + } + + public double getY() { + return this.y; + } + + public double getZ() { + return this.z; + } + + public Vector3d multiply(double v) { + return new Vector3d(this.x * v, this.y * v, this.z * v); + } + + public double distance(Vector3d vector3d) { + return Math.sqrt(Math.pow(vector3d.x - this.x, 2.0) + Math.pow(vector3d.y - this.y, 2.0) + Math.pow(vector3d.z - this.z, 2.0)); + } + + @Override + public boolean equals(Object obj) { + return !(obj instanceof Vector3d vector) + ? false + : Math.floor(this.x) == Math.floor(vector.x) && Math.floor(this.y) == Math.floor(vector.y) && Math.floor(this.z) == Math.floor(vector.z); + } + + @Generated + public void setX(double x) { + this.x = x; + } + + @Generated + public void setY(double y) { + this.y = y; + } + + @Generated + public void setZ(double z) { + this.z = z; + } +} diff --git a/src/main/java/net/moran/loratadine/utils/wrapper/Wrapper.java b/src/main/java/net/moran/loratadine/utils/wrapper/Wrapper.java new file mode 100644 index 0000000..2f907cd --- /dev/null +++ b/src/main/java/net/moran/loratadine/utils/wrapper/Wrapper.java @@ -0,0 +1,8 @@ +package net.moran.loratadine.utils.wrapper; + +import net.minecraft.client.Minecraft; +import net.moran.loratadine.Loratadine; + +public interface Wrapper { + Minecraft mc = Loratadine.INSTANCE.getMinecraft(); +} diff --git a/src/main/resources/META-INF/mods.toml b/src/main/resources/META-INF/mods.toml new file mode 100644 index 0000000..05e001d --- /dev/null +++ b/src/main/resources/META-INF/mods.toml @@ -0,0 +1,55 @@ +# This is an example mods.toml file. It contains the data relating to the loading mods. +# There are several mandatory fields (#mandatory), and many more that are optional (#optional). +# The overall format is standard TOML format, v0.5.0. +# Note that there are a couple of TOML lists in this file. +# Find more information on toml format here: https://github.com/toml-lang/toml +# The name of the mod loader type to load - for regular FML @Mod mods it should be javafml +modLoader="javafml" #mandatory +# A version range to match for said mod loader - for regular FML @Mod it will be the forge version +loaderVersion="${loader_version_range}" #mandatory This is typically bumped every Minecraft version by Forge. See our download page for lists of versions. +# The license for you mod. This is mandatory metadata and allows for easier comprehension of your redistributive properties. +# Review your options at https://choosealicense.com/. All rights reserved is the default copyright stance, and is thus the default here. +license="${mod_license}" +# A URL to refer people to when problems occur with this mod +#issueTrackerURL="https://change.me.to.your.issue.tracker.example.invalid/" #optional +# A list of mods - how many allowed here is determined by the individual mod loader +[[mods]] #mandatory +# The modid of the mod +modId="${mod_id}" #mandatory +# The version number of the mod +version="${mod_version}" #mandatory +# A display name for the mod +displayName="${mod_name}" #mandatory +# A URL to query for updates for this mod. See the JSON update specification https://docs.minecraftforge.net/en/latest/misc/updatechecker/ +#updateJSONURL="https://change.me.example.invalid/updates.json" #optional +# A URL for the "homepage" for this mod, displayed in the mod UI +#displayURL="https://change.me.to.your.mods.homepage.example.invalid/" #optional +# A file name (in the root of the mod JAR) containing a logo for display +#logoFile="loratadine.png" #optional +# A text field displayed in the mod UI +#credits="Thanks for this example mod goes to Java" #optional +# A text field displayed in the mod UI +authors="${mod_authors}" #optional +# The description text for the mod (multi line!) (#mandatory) +description='''${mod_description}''' +# A dependency - use the . to indicate dependency for a specific modid. Dependencies are optional. +[[dependencies."${mod_id}"]] #optional + # the modid of the dependency + modId="forge" #mandatory + # Does this dependency have to exist - if not, ordering below must be specified + mandatory=true #mandatory + # The version range of the dependency + versionRange="${forge_version_range}" #mandatory + # An ordering relationship for the dependency - BEFORE or AFTER required if the dependency is not mandatory + # BEFORE - This mod is loaded BEFORE the dependency + # AFTER - This mod is loaded AFTER the dependency + ordering="NONE" + # Side this dependency is applied on - BOTH, CLIENT, or SERVER + side="BOTH"# Here's another dependency +[[dependencies."${mod_id}"]] + modId="minecraft" + mandatory=true + # This version range declares a minimum of the current minecraft version up to but not including the next major version + versionRange="${minecraft_version_range}" + ordering="NONE" + side="BOTH" diff --git a/src/main/resources/pack.mcmeta b/src/main/resources/pack.mcmeta new file mode 100644 index 0000000..20bf29f --- /dev/null +++ b/src/main/resources/pack.mcmeta @@ -0,0 +1,8 @@ +{ + "pack": { + "description": "loratadine resources", + "pack_format": 8, + "forge:resource_pack_format": 8, + "forge:data_pack_format": 9 + } +}