├── .editorconfig ├── .github ├── CONTRIBUTING │ └── CONTRIBUTING_GUIDELINES.md ├── IMAGES │ ├── crystalAura.png │ ├── downloading.png │ ├── gui.png │ └── shulkerChat.png ├── ISSUE_TEMPLATE │ ├── bug-report.md │ └── feature_request.md └── workflows │ └── fabricmod.yml ├── .gitignore ├── .travis.yml ├── LICENSE.md ├── README.md ├── autocopy.bat ├── build.gradle.kts ├── gradle.properties ├── gradle └── wrapper │ ├── gradle-wrapper.jar │ └── gradle-wrapper.properties ├── gradlew ├── gradlew.bat ├── settings.gradle └── src └── main ├── java └── me │ └── zeroeightsix │ └── kami │ ├── feature │ └── module │ │ ├── Module.java │ │ ├── combat │ │ ├── Auto32k.java │ │ └── AutoLog.java │ │ ├── misc │ │ ├── AntiAFK.java │ │ ├── AntiRain.java │ │ ├── AutoRespawn.java │ │ ├── ChatEncryption.java │ │ └── SkinFlicker.java │ │ ├── movement │ │ ├── AntiHunger.java │ │ ├── ElytraFlight.java │ │ ├── Flight.java │ │ ├── Sprint.java │ │ └── Velocity.java │ │ ├── player │ │ ├── AntiForceLook.java │ │ ├── AutoFish.java │ │ ├── AutoJump.java │ │ ├── AutoWalk.java │ │ ├── Blink.java │ │ ├── Fastbreak.java │ │ ├── Fastplace.java │ │ ├── NoFall.java │ │ ├── PitchLock.java │ │ ├── TpsSync.java │ │ └── YawLock.java │ │ └── render │ │ ├── AntiFog.java │ │ ├── ArmourHUD.java │ │ ├── BossStack.java │ │ ├── ChunkFinder.java │ │ └── NoHurtCam.java │ ├── mixin │ ├── client │ │ ├── IBackedConfigLeaf.java │ │ ├── IBlockModelRenderer.java │ │ ├── ICamera.java │ │ ├── IChatMessageC2SPacket.java │ │ ├── IChatMessageS2CPacket.java │ │ ├── IChunkData.java │ │ ├── IClientPlayerInteractionManager.java │ │ ├── IDimensionType.java │ │ ├── IDisconnectedScreen.java │ │ ├── IEntity.java │ │ ├── IEntitySelector.java │ │ ├── IEntityVelocityUpdateS2CPacket.java │ │ ├── IExplosionS2CPacket.java │ │ ├── IGameRenderer.java │ │ ├── IInputUtilType.java │ │ ├── IKeyBinding.java │ │ ├── IMatrix4f.java │ │ ├── IMatrixStack$Entry.java │ │ ├── IMatrixStack.java │ │ ├── IMinecraftClient.java │ │ ├── IMiningToolItem.java │ │ ├── IPlayerMoveC2SPacket.java │ │ ├── IPlayerPositionLookS2CPacket.java │ │ ├── IShulkerBoxBlockEntity.java │ │ ├── MixinBackedConfigLeaf.java │ │ ├── MixinBackgroundRenderer.java │ │ ├── MixinBeaconBlockEntity.java │ │ ├── MixinBlockBufferBuilderStorage.java │ │ ├── MixinBlockEntityRenderDispatcher.java │ │ ├── MixinBossBarHud.java │ │ ├── MixinBuiltChunk.java │ │ ├── MixinCamera.java │ │ ├── MixinChatScreen.java │ │ ├── MixinClientChunkManager.java │ │ ├── MixinClientConnection.java │ │ ├── MixinClientPlayNetworkHandler.java │ │ ├── MixinClientPlayerEntity.java │ │ ├── MixinClientPlayerInteractionManager.java │ │ ├── MixinClientWorld.java │ │ ├── MixinComeCommand.java │ │ ├── MixinCommandSuggestor.java │ │ ├── MixinConfigType.java │ │ ├── MixinDecoderHandler.java │ │ ├── MixinEntity.java │ │ ├── MixinEntityRenderer.java │ │ ├── MixinGameRenderer.java │ │ ├── MixinHandledScreen.java │ │ ├── MixinHorseBaseEntity.java │ │ ├── MixinInGameHud.java │ │ ├── MixinInGameOverlayRenderer.java │ │ ├── MixinInput.java │ │ ├── MixinKeyboard.java │ │ ├── MixinLightmapTextureManager.java │ │ ├── MixinLivingEntityRenderer.java │ │ ├── MixinMinecraftClient.java │ │ ├── MixinMouse.java │ │ ├── MixinNetHandlerPlayClient.java │ │ ├── MixinPigEntity.java │ │ ├── MixinPlayerEntity.java │ │ ├── MixinPlayerListHud.java │ │ ├── MixinPojoMemberProcessorImpl.java │ │ ├── MixinRebuildTask.java │ │ ├── MixinRenderPlayer.java │ │ ├── MixinRenderTickCounter.java │ │ ├── MixinStateImplementation.java │ │ ├── MixinStriderEntity.java │ │ └── MixinWorldRenderer.java │ ├── duck │ │ ├── CanDisableCaching.java │ │ ├── HasSettingInterface.java │ │ └── HotSwappable.java │ └── extend │ │ ├── ExtendedInput.java │ │ └── Extensions.kt │ └── util │ ├── Bind.java │ ├── EntityUtil.java │ ├── GeometryMasks.java │ ├── KamiTessellator.java │ ├── ShulkerBoxCommon.java │ ├── Texts.java │ └── Wrapper.java ├── kotlin └── me │ └── zeroeightsix │ └── kami │ ├── BaritoneIntegration.kt │ ├── KamiMod.kt │ ├── KotlinTypeMagic.kt │ ├── Utils.kt │ ├── event │ ├── Events.kt │ └── KamiEvent.kt │ ├── feature │ ├── Feature.kt │ ├── FeatureManager.kt │ ├── FindFeature.kt │ ├── FullFeature.kt │ ├── HasBind.kt │ ├── command │ │ ├── BindArgumentType.kt │ │ ├── BindCommand.kt │ │ ├── BrigadierDsl.kt │ │ ├── Command.kt │ │ ├── ConfigCommand.kt │ │ ├── DependantArgumentType.kt │ │ ├── FeatureArgumentType.kt │ │ ├── FriendCommand.kt │ │ ├── GiveCommand.kt │ │ ├── HClipCommand.kt │ │ ├── KamiCommandSource.kt │ │ ├── NbtCommand.kt │ │ ├── PeekCommand.kt │ │ ├── PluginArgumentType.kt │ │ ├── PluginCommand.kt │ │ ├── SayCommand.kt │ │ ├── SettingArgumentType.kt │ │ ├── SettingValueArgumentType.kt │ │ ├── SettingsCommand.kt │ │ ├── ToggleCommand.kt │ │ └── VClipCommand.kt │ ├── hidden │ │ ├── ClickGui.kt │ │ ├── KamiPrefixChat.kt │ │ ├── PlayerMovementSpoofer.kt │ │ ├── PrepHandler.kt │ │ └── TickSpeedMeter.kt │ ├── module │ │ ├── Aura.kt │ │ ├── AutoArmour.kt │ │ ├── AutoEat.kt │ │ ├── AutoGG.kt │ │ ├── AutoReconnect.kt │ │ ├── AutoTool.kt │ │ ├── AutoTotem.kt │ │ ├── BaritonePause.kt │ │ ├── Breadcrumbs.kt │ │ ├── Brightness.kt │ │ ├── Chams.kt │ │ ├── CustomChat.kt │ │ ├── DiscordStatus.kt │ │ ├── ESP.kt │ │ ├── EntitySpeed.kt │ │ ├── ExtraTab.kt │ │ ├── Freecam.kt │ │ ├── ItemHighlight.kt │ │ ├── Jesus.kt │ │ ├── ModuleCamera.kt │ │ ├── MountBypass.kt │ │ ├── MurderMysteries.kt │ │ ├── Nametags.kt │ │ ├── NoEntityTrace.kt │ │ ├── NoPacketKick.kt │ │ ├── NoRender.kt │ │ ├── NoSlowDown.kt │ │ ├── Notebot.kt │ │ ├── Nuker.kt │ │ ├── PortalChat.kt │ │ ├── PortalGodMode.kt │ │ ├── SafeWalk.kt │ │ ├── Scaffold.kt │ │ ├── SignSpammer.kt │ │ ├── Timer.kt │ │ ├── Tracers.kt │ │ └── Trajectories.kt │ └── plugin │ │ └── Plugin.kt │ ├── gui │ ├── ImGuiScreen.kt │ ├── ImguiDSL.kt │ ├── KImGui.kt │ ├── KamiGuiScreen.kt │ ├── KamiHud.kt │ ├── KamiImgui.kt │ ├── MenuBar.kt │ ├── Themes.kt │ ├── text │ │ ├── CompiledText.kt │ │ └── VarMap.kt │ ├── widgets │ │ ├── ActiveModules.kt │ │ ├── Coordinates.kt │ │ ├── EnabledWidgets.kt │ │ ├── GraphPinnableWidget.kt │ │ ├── Information.kt │ │ ├── InventoryPinnableWidget.kt │ │ ├── PinnableWidget.kt │ │ ├── PlayerPinnableWidget.kt │ │ └── TextPinnableWidget.kt │ ├── windows │ │ ├── Settings.kt │ │ └── modules │ │ │ ├── ModuleWindowsEditor.kt │ │ │ ├── Modules.kt │ │ │ └── Payloads.kt │ └── wizard │ │ └── Wizard.kt │ ├── setting │ ├── AnnotationProcessors.kt │ ├── FiberController.kt │ ├── GenerateType.kt │ ├── InvalidValueException.kt │ ├── KamiConfig.kt │ ├── KamiFiberSerialization.kt │ ├── ProperCaseConvention.kt │ └── SettingInterface.kt │ ├── target │ ├── CategorisedTargets.kt │ └── TargetSupplier.kt │ ├── util │ ├── Friends.kt │ ├── InstrumentMap.kt │ ├── MidiParser.kt │ ├── OutlineVertexConsumer.kt │ ├── ResettableLazy.kt │ ├── TextsDSL.kt │ ├── VectorMath.kt │ └── Viewblock.kt │ └── world │ └── KamiRenderLayers.kt └── resources ├── assets └── kami │ ├── Minecraftia.ttf │ ├── kamired_square.png │ └── shaders │ ├── post │ ├── entity_blur_outline.json │ └── entity_sharp_outline.json │ └── program │ ├── entity_sharp_outline.json │ └── entity_sharp_sobel.fsh ├── fabric.mod.json ├── kami.mixins.json └── minify-all.sh /.github/CONTRIBUTING/CONTRIBUTING_GUIDELINES.md: -------------------------------------------------------------------------------- 1 | # Contributing Guidelines 2 | 3 | ## Creating a pull request 4 | If you are proposing a pull request, please make sure the change won't interfere with anything current, and that it is useful. 5 | ## Creating an issue 6 | If you want to request a feature use the Feature Issue template, and the Bug Report template for reporting a bug or crash. 7 | 8 | #### Please be respectful of others, and use a polite tone 9 | -------------------------------------------------------------------------------- /.github/IMAGES/crystalAura.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zeroeightysix/KAMI/7195851c1c319cdd0b79ff5618fde7e2f1b7ab5a/.github/IMAGES/crystalAura.png -------------------------------------------------------------------------------- /.github/IMAGES/downloading.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zeroeightysix/KAMI/7195851c1c319cdd0b79ff5618fde7e2f1b7ab5a/.github/IMAGES/downloading.png -------------------------------------------------------------------------------- /.github/IMAGES/gui.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zeroeightysix/KAMI/7195851c1c319cdd0b79ff5618fde7e2f1b7ab5a/.github/IMAGES/gui.png -------------------------------------------------------------------------------- /.github/IMAGES/shulkerChat.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zeroeightysix/KAMI/7195851c1c319cdd0b79ff5618fde7e2f1b7ab5a/.github/IMAGES/shulkerChat.png -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/bug-report.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Bug report 3 | about: Create a report to help us improve 4 | title: '' 5 | labels: bug 6 | assignees: '' 7 | 8 | --- 9 | 10 | **Describe the bug** 11 | A clear and concise description of what the bug is. 12 | 13 | **To Reproduce** 14 | Steps to reproduce the behavior: 15 | 1. Go to '...' 16 | 2. Click on '....' 17 | 3. Scroll down to '....' 18 | 4. See error 19 | 20 | **Expected behavior** 21 | A clear and concise description of what you expected to happen. 22 | 23 | **Screenshots** 24 | If applicable, add screenshots to help explain your problem. 25 | 26 | **Environment** 27 | Did you build KAMI yourself? If so, on what commit? If not, which release did you download? 28 | What operating operating system? 29 | What version of java? 30 | 31 | **Additional context** 32 | Add any other context about the problem here. 33 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/feature_request.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Feature request 3 | about: Suggest an idea for this project 4 | title: '' 5 | labels: '' 6 | assignees: '' 7 | 8 | --- 9 | 10 | **Is your feature request related to a problem? Please describe.** 11 | A clear and concise description of what the problem is. Ex. I'm always frustrated when [...] 12 | 13 | **Describe the solution you'd like** 14 | A clear and concise description of what you want to happen. 15 | 16 | **Describe alternatives you've considered** 17 | A clear and concise description of any alternative solutions or features you've considered. 18 | 19 | **Additional context** 20 | Add any other context or screenshots about the feature request here. 21 | -------------------------------------------------------------------------------- /.github/workflows/fabricmod.yml: -------------------------------------------------------------------------------- 1 | # This is a basic workflow to help you get started with Actions 2 | name: Fabric mod jar build 3 | 4 | # Controls when the action will run. Triggers the workflow on push or pull request 5 | # events but only for the fabric branch 6 | on: 7 | push: 8 | branches: [ fabric ] 9 | pull_request: 10 | branches: [ fabric ] 11 | 12 | # A workflow run is made up of one or more jobs that can run sequentially or in parallel 13 | jobs: 14 | # This workflow contains a single job called "build" 15 | build: 16 | # The type of runner that the job will run on 17 | runs-on: ubuntu-latest 18 | 19 | # Steps represent a sequence of tasks that will be executed as part of the job 20 | steps: 21 | # Checks-out your repository under $GITHUB_WORKSPACE, so your job can access it 22 | - uses: actions/checkout@v2 23 | 24 | # Set up the compiler 25 | - name: Set up JDK 8 26 | uses: actions/setup-java@v1 27 | with: 28 | java-version: 1.8 29 | 30 | - name: Cache Gradle packages 31 | uses: actions/cache@v2 32 | with: 33 | path: | 34 | ~/.gradle/caches 35 | ~/.gradle/wrapper 36 | key: ${{ runner.os }}-gradle-${{ hashFiles('**/*.gradle') }} 37 | restore-keys: ${{ runner.os }}-gradle 38 | 39 | # Runs a single command using the runners shell 40 | - name: Build using gradle 41 | run: ./gradlew --build-cache build 42 | 43 | - uses: actions/upload-artifact@v2 44 | with: 45 | name: KAMI Artifacts archive 46 | path: "./build/libs/KAMI-*.jar" 47 | 48 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: java 2 | jdk: 3 | - openjdk8 4 | before_install: 5 | - chmod +x gradlew 6 | deploy: 7 | provider: releases 8 | api_key: 9 | secure: GV6VEpKw8t5MyHVnv7PJqlIVXxXLmwTmMY9LMKRkCo475/SPC9R1JGR9awudpHlJSJWenaGyDRBCQpnbK4K/LeJHRByvTjBbZHQ5ZYELgwmwjG3L8W4dLgjEhltbJdvVChezEA4b8W3IFYr2K0vt8N9JUceIAUVmDA6X81e3boe99qyX8AOg0qXUIjVEWj0hgaXTe66Z7cylVe2po5LMO3Ke+gsdgRV2WZorX4Bc+DlYmdTXaOkGeUTZgOmju3Hv0LL6cezf/YZ2bV2d3+ZNgJc5nOaSxaE+LRP9MXn8oP7rqIxFWQU13AV24vwcK4L6EYpQ8eSDOXg4/DY13vHRNpdQHyb3Bqt6oDw86cD0wBEaZzG8tXlPYxxGsB99DvcVAUEFQSwCdQplS7Vidh29cEwl06olDVfjLfsaMxTceZ/iQLZgBCgVcDHJNo18/GkKiW5ut6lIPeNxV2S8aAmcQO57Ko0e3jhGgMe7JX/itdZIVDqM37maNVFJkczLsl0RuQGKRGBjNFxOgd/wHQsUKHXzbVbq4PjzzPbTwVWu6tzcpSoA7ZYVToyfoJ+jBogc3mZ0Khb/8BpVHu4aBQyI1rTdnV44v6GaMNrBUyT/yzpgScRYz1yC+4d8TM7CWgbWaOPYdq7jYIX6LMRx2tXDRu3oGdJvUrn/Plx5Upb6wYw= 10 | file: build/libs/KAMI-*-release.jar 11 | file_glob: true 12 | skip_cleanup: true 13 | on: 14 | repo: zeroeightysix/KAMI 15 | tags: true 16 | -------------------------------------------------------------------------------- /autocopy.bat: -------------------------------------------------------------------------------- 1 | del %appdata%\.minecraft\mods\1.12.2\Kami*.jar 2 | xcopy %~dp0build\libs\*-release.jar %appdata%\.minecraft\mods\1.12.2\ 3 | -------------------------------------------------------------------------------- /gradle.properties: -------------------------------------------------------------------------------- 1 | # Sets default memory used for gradle commands. Can be overridden by user or command line properties. 2 | # This is required to provide enough memory for the Minecraft decompilation process. 3 | kotlin.code.style=official 4 | org.gradle.jvmargs=-Xmx3G 5 | # Fabric 6 | minecraft_version=1.16.5 7 | yarn_mappings=1.16.5+build.4:v2 8 | loader_version=0.11.1 9 | api_version=0.1.3+12a8474cfa 10 | resource_loader_version=0.2.9+e5d3217f4e 11 | loom_version=0.6-SNAPSHOT 12 | # KAMI 13 | mod_version=mar 14 | maven_group=me.zeroeightsix 15 | archives_base_name=kami 16 | # Dependencies 17 | kotlin_version=1.4.30 18 | fiber_version=fix~undetected-mutation-SNAPSHOT 19 | imgui_version=1.80-1.5.0 20 | satin_version=1.5.0 21 | reflections_version=0.9.12 22 | alpine_version=1.9 23 | fuzzywuzzy_version=1.3.1 -------------------------------------------------------------------------------- /gradle/wrapper/gradle-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zeroeightysix/KAMI/7195851c1c319cdd0b79ff5618fde7e2f1b7ab5a/gradle/wrapper/gradle-wrapper.jar -------------------------------------------------------------------------------- /gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | #Wed Dec 18 21:16:04 CET 2019 2 | distributionUrl=https\://services.gradle.org/distributions/gradle-6.8.1-bin.zip 3 | distributionBase=GRADLE_USER_HOME 4 | distributionPath=wrapper/dists 5 | zipStorePath=wrapper/dists 6 | zipStoreBase=GRADLE_USER_HOME 7 | -------------------------------------------------------------------------------- /gradlew.bat: -------------------------------------------------------------------------------- 1 | @if "%DEBUG%" == "" @echo off 2 | @rem ########################################################################## 3 | @rem 4 | @rem Gradle startup script for Windows 5 | @rem 6 | @rem ########################################################################## 7 | 8 | @rem Set local scope for the variables with windows NT shell 9 | if "%OS%"=="Windows_NT" setlocal 10 | 11 | set DIRNAME=%~dp0 12 | if "%DIRNAME%" == "" set DIRNAME=. 13 | set APP_BASE_NAME=%~n0 14 | set APP_HOME=%DIRNAME% 15 | 16 | @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. 17 | set DEFAULT_JVM_OPTS= 18 | 19 | @rem Find java.exe 20 | if defined JAVA_HOME goto findJavaFromJavaHome 21 | 22 | set JAVA_EXE=java.exe 23 | %JAVA_EXE% -version >NUL 2>&1 24 | if "%ERRORLEVEL%" == "0" goto init 25 | 26 | echo. 27 | echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 28 | echo. 29 | echo Please set the JAVA_HOME variable in your environment to match the 30 | echo location of your Java installation. 31 | 32 | goto fail 33 | 34 | :findJavaFromJavaHome 35 | set JAVA_HOME=%JAVA_HOME:"=% 36 | set JAVA_EXE=%JAVA_HOME%/bin/java.exe 37 | 38 | if exist "%JAVA_EXE%" goto init 39 | 40 | echo. 41 | echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% 42 | echo. 43 | echo Please set the JAVA_HOME variable in your environment to match the 44 | echo location of your Java installation. 45 | 46 | goto fail 47 | 48 | :init 49 | @rem Get command-line arguments, handling Windows variants 50 | 51 | if not "%OS%" == "Windows_NT" goto win9xME_args 52 | if "%@eval[2+2]" == "4" goto 4NT_args 53 | 54 | :win9xME_args 55 | @rem Slurp the command line arguments. 56 | set CMD_LINE_ARGS= 57 | set _SKIP=2 58 | 59 | :win9xME_args_slurp 60 | if "x%~1" == "x" goto execute 61 | 62 | set CMD_LINE_ARGS=%* 63 | goto execute 64 | 65 | :4NT_args 66 | @rem Get arguments from the 4NT Shell from JP Software 67 | set CMD_LINE_ARGS=%$ 68 | 69 | :execute 70 | @rem Setup the command line 71 | 72 | set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar 73 | 74 | @rem Execute Gradle 75 | "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS% 76 | 77 | :end 78 | @rem End local scope for the variables with windows NT shell 79 | if "%ERRORLEVEL%"=="0" goto mainEnd 80 | 81 | :fail 82 | rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of 83 | rem the _cmd.exe /c_ return code! 84 | if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 85 | exit /b 1 86 | 87 | :mainEnd 88 | if "%OS%"=="Windows_NT" endlocal 89 | 90 | :omega 91 | -------------------------------------------------------------------------------- /settings.gradle: -------------------------------------------------------------------------------- 1 | pluginManagement { 2 | repositories { 3 | jcenter() 4 | maven { 5 | name = 'Fabric' 6 | url = 'https://maven.fabricmc.net/' 7 | } 8 | gradlePluginPortal() 9 | } 10 | 11 | plugins { 12 | id 'fabric-loom' version loom_version 13 | id "org.jetbrains.kotlin.jvm" version kotlin_version 14 | } 15 | } -------------------------------------------------------------------------------- /src/main/java/me/zeroeightsix/kami/feature/module/Module.java: -------------------------------------------------------------------------------- 1 | package me.zeroeightsix.kami.feature.module; 2 | 3 | import io.github.fablabsmc.fablabs.api.fiber.v1.annotation.Setting; 4 | import me.zeroeightsix.kami.feature.FindFeature; 5 | import me.zeroeightsix.kami.feature.FullFeature; 6 | import me.zeroeightsix.kami.setting.SettingVisibility; 7 | import net.minecraft.client.MinecraftClient; 8 | 9 | import java.lang.annotation.Retention; 10 | import java.lang.annotation.RetentionPolicy; 11 | 12 | @FindFeature(findDescendants = true) 13 | public class Module extends FullFeature { 14 | 15 | private final Category category = getAnnotation().category(); 16 | protected static final MinecraftClient mc = MinecraftClient.getInstance(); 17 | 18 | @Setting(name = "Show in active modules") 19 | @SettingVisibility.Constant(false) 20 | public boolean showInActiveModules = true; 21 | 22 | public Module() { 23 | Info annotation = getAnnotation(); 24 | setName(annotation.name()); 25 | setDisplayName(annotation.name()); 26 | setDescription(annotation.description()); 27 | } 28 | 29 | @Override 30 | public void init() { 31 | super.init(); 32 | setAlwaysListening(getAnnotation().alwaysListening()); 33 | } 34 | 35 | private Info getAnnotation() { 36 | if (getClass().isAnnotationPresent(Info.class)) { 37 | return getClass().getAnnotation(Info.class); 38 | } 39 | throw new IllegalStateException("No Annotation on class " + this.getClass().getCanonicalName() + "!"); 40 | } 41 | 42 | public enum Category { 43 | COMBAT("Combat", false), 44 | RENDER("Render", false), 45 | MISC("Misc", false), 46 | PLAYER("Player", false), 47 | MOVEMENT("Movement", false), 48 | HIDDEN("Hidden", true); 49 | 50 | boolean hidden; 51 | String name; 52 | 53 | Category(String name, boolean hidden) { 54 | this.name = name; 55 | this.hidden = hidden; 56 | } 57 | 58 | public boolean isHidden() { 59 | return hidden; 60 | } 61 | 62 | public String getName() { 63 | return name; 64 | } 65 | } 66 | 67 | @Retention(RetentionPolicy.RUNTIME) 68 | public @interface Info 69 | { 70 | String name(); 71 | 72 | String description() default "Descriptionless"; 73 | 74 | Category category(); 75 | 76 | boolean alwaysListening() default false; 77 | } 78 | 79 | public Category getCategory() { 80 | return category; 81 | } 82 | 83 | } 84 | -------------------------------------------------------------------------------- /src/main/java/me/zeroeightsix/kami/feature/module/combat/AutoLog.java: -------------------------------------------------------------------------------- 1 | package me.zeroeightsix.kami.feature.module.combat; 2 | 3 | import io.github.fablabsmc.fablabs.api.fiber.v1.annotation.Setting; 4 | import me.zero.alpine.listener.EventHandler; 5 | import me.zero.alpine.listener.Listener; 6 | import me.zeroeightsix.kami.event.EntityEvent; 7 | import me.zeroeightsix.kami.event.TickEvent; 8 | import me.zeroeightsix.kami.feature.module.AutoReconnect; 9 | import me.zeroeightsix.kami.feature.module.Module; 10 | import net.minecraft.client.MinecraftClient; 11 | import net.minecraft.network.packet.s2c.play.DisconnectS2CPacket; 12 | import net.minecraft.text.LiteralText; 13 | 14 | import java.util.Objects; 15 | 16 | @Module.Info(name = "AutoLog", description = "Automatically log when in danger or on low health", category = Module.Category.COMBAT) 17 | public class AutoLog extends Module { 18 | 19 | @Setting(name = "Health") 20 | private @Setting.Constrain.Range(min = 0, max = 36) int health = 6; 21 | private boolean shouldLog = false; 22 | long lastLog = System.currentTimeMillis(); 23 | 24 | @EventHandler 25 | private Listener livingDamageEventListener = new Listener<>(event -> { 26 | if (mc.player == null) return; 27 | if (event.getHealth() > 0f && event.getEntity() == mc.player && event.getHealth() < health) { 28 | log(); 29 | } 30 | }); 31 | 32 | /*@EventHandler 33 | private Listener entityJoinWorldEventListener = new Listener<>(event -> { 34 | if (mc.player == null) return; 35 | if (event.getEntity() instanceof EnderCrystalEntity) { 36 | if (mc.player.getHealth() - CrystalAura.calculateDamage((EnderCrystalEntity) event.getEntity(), mc.player) < health) { 37 | log(); 38 | } 39 | } 40 | });*/ //TODO 41 | 42 | @EventHandler 43 | private Listener updateListener = new Listener<>(event -> { 44 | if (shouldLog) { 45 | shouldLog = false; 46 | if (System.currentTimeMillis() - lastLog < 2000) return; 47 | Objects.requireNonNull(MinecraftClient.getInstance().getNetworkHandler()).onDisconnect(new DisconnectS2CPacket(new LiteralText("AutoLogged"))); 48 | } 49 | }); 50 | 51 | private void log() { 52 | AutoReconnect.INSTANCE.disable(); 53 | shouldLog = true; 54 | lastLog = System.currentTimeMillis(); 55 | } 56 | 57 | } 58 | -------------------------------------------------------------------------------- /src/main/java/me/zeroeightsix/kami/feature/module/misc/AntiAFK.java: -------------------------------------------------------------------------------- 1 | package me.zeroeightsix.kami.feature.module.misc; 2 | 3 | import io.github.fablabsmc.fablabs.api.fiber.v1.annotation.Setting; 4 | import me.zero.alpine.listener.EventHandler; 5 | import me.zero.alpine.listener.Listener; 6 | import me.zeroeightsix.kami.event.TickEvent; 7 | import me.zeroeightsix.kami.feature.module.Module; 8 | import net.minecraft.client.network.ClientPlayerEntity; 9 | import net.minecraft.network.packet.c2s.play.PlayerInteractItemC2SPacket; 10 | import net.minecraft.util.Hand; 11 | 12 | import java.util.Objects; 13 | import java.util.Random; 14 | 15 | @Module.Info(name = "AntiAFK", category = Module.Category.MISC, description = "Moves in order not to get kicked. (May be invisible client-sided)") 16 | public class AntiAFK extends Module { 17 | 18 | @Setting(name = "Swing") 19 | private boolean swing = true; 20 | @Setting(name = "Turn") 21 | private boolean turn = true; 22 | 23 | private Random random = new Random(); 24 | 25 | @EventHandler 26 | private Listener updateListener = new Listener<>(event -> { 27 | assert mc.interactionManager != null; 28 | if (mc.interactionManager.isBreakingBlock()) return; 29 | 30 | ClientPlayerEntity player = event.getPlayer(); 31 | 32 | if (player.age % 40 == 0 && swing) 33 | Objects.requireNonNull(mc.getNetworkHandler()).getConnection().send(new PlayerInteractItemC2SPacket(Hand.MAIN_HAND)); 34 | if (player.age % 15 == 0 && turn) 35 | player.yaw = random.nextFloat() * 360f - 180f; 36 | 37 | if (!(swing || turn) && player.age % 80 == 0) { 38 | player.jump(); 39 | } 40 | }); 41 | 42 | } 43 | -------------------------------------------------------------------------------- /src/main/java/me/zeroeightsix/kami/feature/module/misc/AntiRain.java: -------------------------------------------------------------------------------- 1 | package me.zeroeightsix.kami.feature.module.misc; 2 | 3 | import me.zero.alpine.listener.EventHandler; 4 | import me.zero.alpine.listener.Listener; 5 | import me.zeroeightsix.kami.event.RenderWeatherEvent; 6 | import me.zeroeightsix.kami.feature.module.Module; 7 | 8 | @Module.Info(name = "AntiRain", description = "Removes rain from your world", category = Module.Category.MISC) 9 | public class AntiRain extends Module { 10 | 11 | @EventHandler 12 | private Listener renderWeatherEventListener = new Listener<>(event -> { 13 | event.cancel(); 14 | }); 15 | 16 | } 17 | -------------------------------------------------------------------------------- /src/main/java/me/zeroeightsix/kami/feature/module/misc/AutoRespawn.java: -------------------------------------------------------------------------------- 1 | package me.zeroeightsix.kami.feature.module.misc; 2 | 3 | import io.github.fablabsmc.fablabs.api.fiber.v1.annotation.Setting; 4 | import me.zero.alpine.listener.EventHandler; 5 | import me.zero.alpine.listener.Listener; 6 | import me.zeroeightsix.kami.event.ScreenEvent; 7 | import me.zeroeightsix.kami.feature.module.Module; 8 | import me.zeroeightsix.kami.util.Texts; 9 | import me.zeroeightsix.kami.util.Wrapper; 10 | import net.minecraft.client.gui.screen.DeathScreen; 11 | import net.minecraft.util.Formatting; 12 | 13 | import java.text.SimpleDateFormat; 14 | import java.util.Calendar; 15 | 16 | @Module.Info(name = "AutoRespawn", description = "Respawn utility", category = Module.Category.MISC) 17 | public class AutoRespawn extends Module { 18 | 19 | @Setting(name = "Respawn") 20 | private boolean respawn = true; 21 | @Setting(name = "DeathCoords") 22 | private boolean deathCoords = false; 23 | @Setting(name = "Anti Glitch Screen") 24 | private boolean antiGlitchScreen = true; 25 | 26 | @EventHandler 27 | public Listener listener = new Listener<>(event -> { 28 | 29 | if (!(event.getScreen() instanceof DeathScreen)) { 30 | return; 31 | } 32 | 33 | if (respawn || (antiGlitchScreen && mc.player.getHealth() > 0)) { 34 | if (deathCoords) { 35 | Calendar cal = Calendar.getInstance(); 36 | SimpleDateFormat sdf = new SimpleDateFormat("HH:mm:ss"); 37 | 38 | Wrapper.getPlayer().sendSystemMessage(Texts.f(Formatting.GOLD, Texts.append( 39 | Texts.lit("You died at "), 40 | Texts.flit(Formatting.YELLOW, "x " + Math.floor(mc.player.getX())), 41 | Texts.lit(", "), 42 | Texts.flit(Formatting.YELLOW, "y " + Math.floor(mc.player.getY())), 43 | Texts.lit(", "), 44 | Texts.flit(Formatting.YELLOW, "z " + Math.floor(mc.player.getZ())), 45 | Texts.lit(" ("), 46 | Texts.flit(Formatting.AQUA, sdf.format(cal.getTime())), 47 | Texts.lit(").") 48 | )), null); 49 | } 50 | mc.player.requestRespawn(); 51 | mc.openScreen(null); 52 | } 53 | 54 | }); 55 | 56 | } 57 | -------------------------------------------------------------------------------- /src/main/java/me/zeroeightsix/kami/feature/module/misc/SkinFlicker.java: -------------------------------------------------------------------------------- 1 | package me.zeroeightsix.kami.feature.module.misc; 2 | 3 | import io.github.fablabsmc.fablabs.api.fiber.v1.annotation.Setting; 4 | import me.zero.alpine.listener.EventHandler; 5 | import me.zero.alpine.listener.Listener; 6 | import me.zeroeightsix.kami.event.TickEvent; 7 | import me.zeroeightsix.kami.feature.module.Module; 8 | import net.minecraft.client.network.ClientPlayerEntity; 9 | import net.minecraft.client.render.entity.PlayerModelPart; 10 | 11 | import java.util.Random; 12 | 13 | @Module.Info(name = "SkinFlicker", description = "Toggle the jacket layer rapidly for a cool skin effect", category = Module.Category.MISC) 14 | public class SkinFlicker extends Module { 15 | 16 | @Setting(name = "Mode") 17 | private FlickerMode mode = FlickerMode.HORIZONTAL; 18 | @Setting(name = "Slowness") 19 | private @Setting.Constrain.Range(min = 1) int slowness = 2; 20 | 21 | private final static PlayerModelPart[] PARTS_HORIZONTAL = new PlayerModelPart[]{ 22 | PlayerModelPart.LEFT_SLEEVE, 23 | PlayerModelPart.JACKET, 24 | PlayerModelPart.HAT, 25 | PlayerModelPart.LEFT_PANTS_LEG, 26 | PlayerModelPart.RIGHT_PANTS_LEG, 27 | PlayerModelPart.RIGHT_SLEEVE 28 | }; 29 | 30 | private final static PlayerModelPart[] PARTS_VERTICAL = new PlayerModelPart[]{ 31 | PlayerModelPart.HAT, 32 | PlayerModelPart.JACKET, 33 | PlayerModelPart.LEFT_SLEEVE, 34 | PlayerModelPart.RIGHT_SLEEVE, 35 | PlayerModelPart.LEFT_PANTS_LEG, 36 | PlayerModelPart.RIGHT_PANTS_LEG, 37 | }; 38 | 39 | private Random r = new Random(); 40 | private int len = PlayerModelPart.values().length; 41 | 42 | @EventHandler 43 | private Listener updateListener = new Listener<>(event -> { 44 | ClientPlayerEntity player = event.getPlayer(); 45 | 46 | switch (mode) { 47 | case RANDOM: 48 | if (player.age % slowness != 0) return; 49 | mc.options.togglePlayerModelPart(PlayerModelPart.values()[r.nextInt(len)]); 50 | break; 51 | case VERTICAL: 52 | case HORIZONTAL: 53 | int i = (player.age / slowness) % (PARTS_HORIZONTAL.length * 2); // *2 for on/off 54 | boolean on = false; 55 | if (i >= PARTS_HORIZONTAL.length) { 56 | on = true; 57 | i -= PARTS_HORIZONTAL.length; 58 | } 59 | mc.options.setPlayerModelPart(mode == FlickerMode.VERTICAL ? PARTS_VERTICAL[i] : PARTS_HORIZONTAL[i], on); 60 | } 61 | }); 62 | 63 | public enum FlickerMode { 64 | HORIZONTAL, VERTICAL, RANDOM 65 | } 66 | 67 | } 68 | -------------------------------------------------------------------------------- /src/main/java/me/zeroeightsix/kami/feature/module/movement/AntiHunger.java: -------------------------------------------------------------------------------- 1 | package me.zeroeightsix.kami.feature.module.movement; 2 | 3 | import me.zero.alpine.listener.EventHandler; 4 | import me.zero.alpine.listener.Listener; 5 | import me.zeroeightsix.kami.event.PacketEvent; 6 | import me.zeroeightsix.kami.feature.module.Module; 7 | import me.zeroeightsix.kami.mixin.client.IPlayerMoveC2SPacket; 8 | import net.minecraft.network.packet.c2s.play.PlayerMoveC2SPacket; 9 | 10 | @Module.Info(name = "AntiHunger", category = Module.Category.MOVEMENT, description = "Lose hunger less fast. Might cause ghostblocks.") 11 | public class AntiHunger extends Module { 12 | 13 | @EventHandler 14 | public Listener packetListener = new Listener<>(event -> { 15 | if (event.getPacket() instanceof PlayerMoveC2SPacket) { 16 | ((IPlayerMoveC2SPacket) event.getPacket()).setOnGround(false); 17 | } 18 | }); 19 | 20 | } 21 | -------------------------------------------------------------------------------- /src/main/java/me/zeroeightsix/kami/feature/module/movement/ElytraFlight.java: -------------------------------------------------------------------------------- 1 | package me.zeroeightsix.kami.feature.module.movement; 2 | 3 | import io.github.fablabsmc.fablabs.api.fiber.v1.annotation.Setting; 4 | import me.zero.alpine.listener.EventHandler; 5 | import me.zero.alpine.listener.Listener; 6 | import me.zeroeightsix.kami.event.TickEvent; 7 | import me.zeroeightsix.kami.feature.module.Module; 8 | import me.zeroeightsix.kami.util.EntityUtil; 9 | import net.minecraft.client.network.ClientPlayerEntity; 10 | import net.minecraft.network.packet.c2s.play.ClientCommandC2SPacket; 11 | import net.minecraft.util.math.MathHelper; 12 | 13 | import java.util.Optional; 14 | 15 | @Module.Info(name = "ElytraFlight", description = "Allows infinite elytra flying", category = Module.Category.MOVEMENT) 16 | public class ElytraFlight extends Module { 17 | 18 | @Setting(name = "Mode") 19 | private ElytraFlightMode mode = ElytraFlightMode.BOOST; 20 | 21 | @EventHandler 22 | private Listener updateListener = new Listener<>(event -> { 23 | ClientPlayerEntity player = event.getPlayer(); 24 | if (!player.isFallFlying()) return; 25 | switch (mode) { 26 | case BOOST: 27 | if (player.isSubmergedInWater()) { 28 | Optional.ofNullable(mc.getNetworkHandler()).ifPresent(handler -> handler.sendPacket(new ClientCommandC2SPacket(player, ClientCommandC2SPacket.Mode.START_FALL_FLYING))); 29 | return; 30 | } 31 | 32 | if (mc.options.keyJump.isPressed()) { 33 | EntityUtil.updateVelocityY(player, player.getVelocity().y + 0.08); 34 | } else if (mc.options.keySneak.isPressed()) { 35 | EntityUtil.updateVelocityY(player, player.getVelocity().y - 0.04); 36 | } 37 | 38 | if (mc.options.keyForward.isPressed()) { 39 | float yaw = (float) Math.toRadians(player.yaw); 40 | player.addVelocity(MathHelper.sin(yaw) * -0.05F, 0, MathHelper.cos(yaw) * 0.05F); 41 | } else if (mc.options.keyBack.isPressed()) { 42 | float yaw = (float) Math.toRadians(player.yaw); 43 | player.addVelocity(MathHelper.sin(yaw) * 0.05F, 0, MathHelper.cos(yaw) * -0.05F); 44 | } 45 | break; 46 | case FLY: 47 | player.abilities.flying = true; 48 | } 49 | }); 50 | 51 | @Override 52 | public void onDisable() { 53 | assert mc.player != null; 54 | if (mc.player.abilities.creativeMode) return; 55 | mc.player.abilities.flying = false; 56 | } 57 | 58 | private enum ElytraFlightMode { 59 | BOOST, FLY, 60 | } 61 | 62 | } 63 | -------------------------------------------------------------------------------- /src/main/java/me/zeroeightsix/kami/feature/module/movement/Sprint.java: -------------------------------------------------------------------------------- 1 | package me.zeroeightsix.kami.feature.module.movement; 2 | 3 | import me.zero.alpine.listener.EventHandler; 4 | import me.zero.alpine.listener.Listener; 5 | import me.zeroeightsix.kami.event.TickEvent; 6 | import me.zeroeightsix.kami.feature.module.Module; 7 | import net.minecraft.client.network.ClientPlayerEntity; 8 | 9 | @Module.Info(name = "Sprint", description = "Automatically makes the player sprint", category = Module.Category.MOVEMENT) 10 | public class Sprint extends Module { 11 | 12 | @EventHandler 13 | private Listener updateListener = new Listener<>(event -> { 14 | ClientPlayerEntity player = event.getPlayer(); 15 | player.setSprinting(!player.horizontalCollision && player.forwardSpeed > 0); 16 | }); 17 | 18 | } 19 | -------------------------------------------------------------------------------- /src/main/java/me/zeroeightsix/kami/feature/module/player/AntiForceLook.java: -------------------------------------------------------------------------------- 1 | package me.zeroeightsix.kami.feature.module.player; 2 | 3 | import me.zero.alpine.listener.EventHandler; 4 | import me.zero.alpine.listener.Listener; 5 | import me.zeroeightsix.kami.event.PacketEvent; 6 | import me.zeroeightsix.kami.feature.module.Module; 7 | import me.zeroeightsix.kami.mixin.client.IPlayerPositionLookS2CPacket; 8 | import net.minecraft.network.packet.s2c.play.PlayerPositionLookS2CPacket; 9 | 10 | @Module.Info(name = "AntiForceLook", category = Module.Category.PLAYER) 11 | public class AntiForceLook extends Module { 12 | 13 | @EventHandler 14 | Listener receiveListener = new Listener<>(event -> { 15 | if (mc.player == null) return; 16 | if (event.getPacket() instanceof PlayerPositionLookS2CPacket) { 17 | IPlayerPositionLookS2CPacket yawPitch = (IPlayerPositionLookS2CPacket) event.getPacket(); 18 | yawPitch.setYaw(mc.player.yaw); 19 | yawPitch.setPitch(mc.player.pitch); 20 | } 21 | }); 22 | 23 | } 24 | -------------------------------------------------------------------------------- /src/main/java/me/zeroeightsix/kami/feature/module/player/AutoFish.java: -------------------------------------------------------------------------------- 1 | package me.zeroeightsix.kami.feature.module.player; 2 | 3 | import me.zero.alpine.listener.EventHandler; 4 | import me.zero.alpine.listener.Listener; 5 | import me.zeroeightsix.kami.event.PacketEvent; 6 | import me.zeroeightsix.kami.feature.module.Module; 7 | import me.zeroeightsix.kami.mixin.client.IMinecraftClient; 8 | import net.minecraft.item.Items; 9 | import net.minecraft.network.packet.s2c.play.PlaySoundS2CPacket; 10 | import net.minecraft.sound.SoundEvents; 11 | 12 | @Module.Info(name = "AutoFish", category = Module.Category.MISC, description = "Automatically catch fish") 13 | public class AutoFish extends Module { 14 | 15 | @EventHandler 16 | private Listener receiveListener = new Listener<>(event -> { 17 | if (mc.player != null && (mc.player.getMainHandStack().getItem() == Items.FISHING_ROD || mc.player.getOffHandStack().getItem() == Items.FISHING_ROD) && event.getPacket() instanceof PlaySoundS2CPacket && SoundEvents.ENTITY_FISHING_BOBBER_SPLASH.equals(((PlaySoundS2CPacket) event.getPacket()).getSound())) { 18 | new Thread(() -> { 19 | try { 20 | Thread.sleep(200); 21 | } catch (InterruptedException e) { 22 | e.printStackTrace(); 23 | } 24 | ((IMinecraftClient) mc).callDoItemUse(); 25 | try { 26 | Thread.sleep(500); 27 | } catch (InterruptedException e) { 28 | e.printStackTrace(); 29 | } 30 | ((IMinecraftClient) mc).callDoItemUse(); 31 | }).start(); 32 | } 33 | }); 34 | 35 | } 36 | -------------------------------------------------------------------------------- /src/main/java/me/zeroeightsix/kami/feature/module/player/AutoJump.java: -------------------------------------------------------------------------------- 1 | package me.zeroeightsix.kami.feature.module.player; 2 | 3 | import me.zero.alpine.listener.EventHandler; 4 | import me.zero.alpine.listener.Listener; 5 | import me.zeroeightsix.kami.event.TickEvent; 6 | import me.zeroeightsix.kami.feature.module.Module; 7 | import me.zeroeightsix.kami.util.EntityUtil; 8 | import net.minecraft.client.network.ClientPlayerEntity; 9 | 10 | @Module.Info(name = "AutoJump", category = Module.Category.PLAYER, description = "Automatically jumps if possible") 11 | public class AutoJump extends Module { 12 | 13 | @EventHandler 14 | private Listener updateListener = new Listener<>(event -> { 15 | ClientPlayerEntity player = event.getPlayer(); 16 | 17 | if (player.isSubmergedInWater() || player.isInLava()) { 18 | EntityUtil.updateVelocityY(player, 0.1); 19 | } else if (player.isOnGround()) player.jump(); 20 | }); 21 | 22 | } 23 | -------------------------------------------------------------------------------- /src/main/java/me/zeroeightsix/kami/feature/module/player/AutoWalk.java: -------------------------------------------------------------------------------- 1 | package me.zeroeightsix.kami.feature.module.player; 2 | 3 | import io.github.fablabsmc.fablabs.api.fiber.v1.annotation.Setting; 4 | import me.zero.alpine.listener.EventHandler; 5 | import me.zero.alpine.listener.Listener; 6 | import me.zeroeightsix.kami.event.TickEvent; 7 | import me.zeroeightsix.kami.feature.module.Module; 8 | 9 | @Module.Info(name = "AutoWalk", category = Module.Category.PLAYER) 10 | public class AutoWalk extends Module { 11 | 12 | @Setting(name = "Mode") 13 | private AutoWalkMode mode = AutoWalkMode.FORWARD; 14 | 15 | @EventHandler 16 | private Listener tickListener = new Listener<>(event -> { 17 | assert mc.player != null; 18 | mc.player.input.movementForward = mode.forward; 19 | }); 20 | 21 | private enum AutoWalkMode { 22 | FORWARD(1), BACKWARDS(-1); 23 | final int forward; 24 | 25 | AutoWalkMode(int forward) { 26 | this.forward = forward; 27 | } 28 | } 29 | 30 | } 31 | -------------------------------------------------------------------------------- /src/main/java/me/zeroeightsix/kami/feature/module/player/Fastbreak.java: -------------------------------------------------------------------------------- 1 | package me.zeroeightsix.kami.feature.module.player; 2 | 3 | import me.zero.alpine.listener.EventHandler; 4 | import me.zero.alpine.listener.Listener; 5 | import me.zeroeightsix.kami.event.TickEvent; 6 | import me.zeroeightsix.kami.feature.module.Module; 7 | import me.zeroeightsix.kami.mixin.client.IClientPlayerInteractionManager; 8 | 9 | @Module.Info(name = "Fastbreak", category = Module.Category.PLAYER, description = "Nullifies block hit delay") 10 | public class Fastbreak extends Module { 11 | 12 | @EventHandler 13 | private Listener updateListener = new Listener<>(event -> { 14 | assert mc.interactionManager != null; 15 | ((IClientPlayerInteractionManager) mc.interactionManager).setBlockBreakingCooldown(0); 16 | }); 17 | 18 | } 19 | -------------------------------------------------------------------------------- /src/main/java/me/zeroeightsix/kami/feature/module/player/Fastplace.java: -------------------------------------------------------------------------------- 1 | package me.zeroeightsix.kami.feature.module.player; 2 | 3 | import me.zero.alpine.listener.EventHandler; 4 | import me.zero.alpine.listener.Listener; 5 | import me.zeroeightsix.kami.event.TickEvent; 6 | import me.zeroeightsix.kami.feature.module.Module; 7 | import me.zeroeightsix.kami.mixin.client.IMinecraftClient; 8 | 9 | @Module.Info(name = "Fastplace", category = Module.Category.PLAYER, description = "Nullifies block place delay") 10 | public class Fastplace extends Module { 11 | 12 | @EventHandler 13 | private Listener updateListener = new Listener<>(event -> { 14 | ((IMinecraftClient) mc).setItemUseCooldown(0); 15 | }); 16 | 17 | } 18 | -------------------------------------------------------------------------------- /src/main/java/me/zeroeightsix/kami/feature/module/player/PitchLock.java: -------------------------------------------------------------------------------- 1 | package me.zeroeightsix.kami.feature.module.player; 2 | 3 | import io.github.fablabsmc.fablabs.api.fiber.v1.annotation.Setting; 4 | import me.zero.alpine.listener.EventHandler; 5 | import me.zero.alpine.listener.Listener; 6 | import me.zeroeightsix.kami.event.TickEvent; 7 | import me.zeroeightsix.kami.feature.module.Module; 8 | import net.minecraft.client.network.ClientPlayerEntity; 9 | import net.minecraft.entity.Entity; 10 | import net.minecraft.util.math.MathHelper; 11 | 12 | @Module.Info(name = "PitchLock", category = Module.Category.PLAYER) 13 | public class PitchLock extends Module { 14 | 15 | @Setting(name = "Auto") 16 | private boolean auto = true; 17 | @Setting(name = "Pitch") 18 | private float pitch = 180f; 19 | @Setting(name = "Slice") 20 | private int slice = 8; 21 | 22 | @EventHandler 23 | private Listener updateListener = new Listener<>(event -> { 24 | ClientPlayerEntity player = event.getPlayer(); 25 | if (slice == 0) return; 26 | if (auto) { 27 | int angle = 360 / slice; 28 | float pitch = player.pitch; 29 | pitch = Math.round(pitch / angle) * angle; 30 | player.pitch = pitch; 31 | Entity vehicle = player.getVehicle(); 32 | if (player.isRiding() && vehicle != null) vehicle.pitch = pitch; 33 | } else { 34 | player.pitch = MathHelper.clamp(pitch - 180, -180, 180); 35 | } 36 | }); 37 | 38 | } 39 | -------------------------------------------------------------------------------- /src/main/java/me/zeroeightsix/kami/feature/module/player/TpsSync.java: -------------------------------------------------------------------------------- 1 | package me.zeroeightsix.kami.feature.module.player; 2 | 3 | import me.zeroeightsix.kami.feature.module.Module; 4 | 5 | @Module.Info(name = "TpsSync", description = "Synchronizes some actions with the server TPS", category = Module.Category.PLAYER) 6 | public class TpsSync extends Module { 7 | 8 | private static TpsSync INSTANCE; 9 | 10 | public TpsSync() { 11 | INSTANCE = this; 12 | } 13 | 14 | public static boolean isSync() { 15 | return INSTANCE.getEnabled(); 16 | } 17 | 18 | } 19 | -------------------------------------------------------------------------------- /src/main/java/me/zeroeightsix/kami/feature/module/player/YawLock.java: -------------------------------------------------------------------------------- 1 | package me.zeroeightsix.kami.feature.module.player; 2 | 3 | import io.github.fablabsmc.fablabs.api.fiber.v1.annotation.Setting; 4 | import me.zero.alpine.listener.EventHandler; 5 | import me.zero.alpine.listener.Listener; 6 | import me.zeroeightsix.kami.event.TickEvent; 7 | import me.zeroeightsix.kami.feature.module.Module; 8 | import net.minecraft.client.network.ClientPlayerEntity; 9 | import net.minecraft.entity.Entity; 10 | import net.minecraft.util.math.MathHelper; 11 | 12 | @Module.Info(name = "YawLock", category = Module.Category.PLAYER) 13 | public class YawLock extends Module { 14 | 15 | @Setting(name = "Auto") 16 | private boolean auto = true; 17 | @Setting(name = "Yaw") 18 | private float yaw = 180f; 19 | @Setting(name = "Slice") 20 | private int slice = 8; 21 | 22 | @EventHandler 23 | private Listener updateListener = new Listener<>(event -> { 24 | ClientPlayerEntity player = event.getPlayer(); 25 | 26 | if (slice == 0) return; 27 | if (auto) { 28 | int angle = 360 / slice; 29 | float yaw = player.yaw; 30 | yaw = Math.round(yaw / angle) * angle; 31 | player.yaw = yaw; 32 | Entity vehicle = player.getVehicle(); 33 | if (player.isRiding() && vehicle != null) vehicle.yaw = yaw; 34 | } else { 35 | player.yaw = MathHelper.clamp(yaw - 180, -180, 180); 36 | } 37 | }); 38 | } 39 | -------------------------------------------------------------------------------- /src/main/java/me/zeroeightsix/kami/feature/module/render/AntiFog.java: -------------------------------------------------------------------------------- 1 | package me.zeroeightsix.kami.feature.module.render; 2 | 3 | import me.zero.alpine.listener.EventHandler; 4 | import me.zero.alpine.listener.Listener; 5 | import me.zeroeightsix.kami.event.ApplyFogEvent; 6 | import me.zeroeightsix.kami.feature.module.Module; 7 | 8 | @Module.Info(name = "AntiFog", description = "Disables or reduces fog", category = Module.Category.RENDER) 9 | public class AntiFog extends Module { 10 | 11 | @EventHandler 12 | public Listener applyFogListener = new Listener<>(event -> { 13 | event.cancel(); 14 | }); 15 | 16 | } 17 | -------------------------------------------------------------------------------- /src/main/java/me/zeroeightsix/kami/feature/module/render/ArmourHUD.java: -------------------------------------------------------------------------------- 1 | package me.zeroeightsix.kami.feature.module.render; 2 | 3 | import com.mojang.blaze3d.platform.GlStateManager; 4 | import io.github.fablabsmc.fablabs.api.fiber.v1.annotation.Setting; 5 | import me.zero.alpine.listener.EventHandler; 6 | import me.zero.alpine.listener.Listener; 7 | import me.zeroeightsix.kami.event.RenderGuiEvent; 8 | import me.zeroeightsix.kami.feature.module.Module; 9 | import me.zeroeightsix.kami.util.Wrapper; 10 | import net.minecraft.client.MinecraftClient; 11 | import net.minecraft.client.render.item.ItemRenderer; 12 | import net.minecraft.item.ItemStack; 13 | 14 | @Module.Info(name = "ArmourHUD", category = Module.Category.RENDER) 15 | public class ArmourHUD extends Module { 16 | 17 | private static ItemRenderer itemRender = MinecraftClient.getInstance().getItemRenderer(); 18 | 19 | @Setting(name = "Damage") 20 | private boolean damage = false; 21 | 22 | @EventHandler 23 | public Listener renderListener = new Listener<>(event -> { 24 | ItemRenderer itemRenderer = Wrapper.getMinecraft().getItemRenderer(); 25 | 26 | GlStateManager.enableTexture(); 27 | 28 | int i = MinecraftClient.getInstance().getWindow().getScaledWidth() / 2; 29 | int iteration = 0; 30 | int y = MinecraftClient.getInstance().getWindow().getScaledHeight() - 55 - (mc.player.isSubmergedInWater() ? 10 : 0); 31 | for (ItemStack is : mc.player.inventory.armor) { 32 | iteration++; 33 | if (is.isEmpty()) continue; 34 | int x = i - 90 + (9 - iteration) * 20 + 2; 35 | GlStateManager.enableDepthTest(); 36 | 37 | itemRenderer.zOffset = 200F; 38 | itemRenderer.renderInGuiWithOverrides(is, x, y); 39 | itemRenderer.renderGuiItemOverlay(mc.textRenderer, is, x, y); 40 | itemRenderer.zOffset = 0F; 41 | 42 | GlStateManager.enableTexture(); 43 | GlStateManager.disableLighting(); 44 | GlStateManager.disableDepthTest(); 45 | 46 | String s = is.getCount() > 1 ? is.getCount() + "" : ""; 47 | mc.textRenderer.drawWithShadow(event.getMatrixStack(), s, x + 19 - 2 - mc.textRenderer.getWidth(s), y + 9, 0xffffff); 48 | 49 | if (damage) { 50 | int green = (int) ((((float) is.getMaxDamage() - (float) is.getDamage()) / (float) is.getMaxDamage()) * 255); 51 | int red = 255 - green; 52 | int dmg = 100 - (int) (red / 255f * 100); 53 | int colour = (0xFF << 24) | (red << 16) | (green << 8); 54 | mc.textRenderer.drawWithShadow(event.getMatrixStack(), dmg + "", x + 8 - mc.textRenderer.getWidth(dmg + "") / 2, y - 11, colour); 55 | } 56 | } 57 | 58 | GlStateManager.enableDepthTest(); 59 | GlStateManager.disableLighting(); 60 | }); 61 | 62 | } 63 | -------------------------------------------------------------------------------- /src/main/java/me/zeroeightsix/kami/feature/module/render/BossStack.java: -------------------------------------------------------------------------------- 1 | package me.zeroeightsix.kami.feature.module.render; 2 | 3 | import io.github.fablabsmc.fablabs.api.fiber.v1.annotation.Setting; 4 | import me.zero.alpine.listener.EventHandler; 5 | import me.zero.alpine.listener.Listener; 6 | import me.zeroeightsix.kami.event.RenderBossBarEvent; 7 | import me.zeroeightsix.kami.feature.module.Module; 8 | import me.zeroeightsix.kami.setting.SettingVisibility; 9 | import net.minecraft.client.gui.hud.ClientBossBar; 10 | 11 | import java.util.HashMap; 12 | import java.util.WeakHashMap; 13 | 14 | @Module.Info(name = "BossStack", description = "Modify the boss health GUI to take up less space", category = Module.Category.MISC) 15 | public class BossStack extends Module { 16 | 17 | @Setting(name = "Hide boss bars") 18 | private boolean remove = false; 19 | @Setting 20 | @SettingVisibility.Method("ifNotRemove") 21 | private boolean fold = true; 22 | @Setting 23 | @SettingVisibility.Method("ifNotRemoveNotFold") 24 | private int spacing = 10; 25 | 26 | public boolean ifNotRemove() { 27 | return !remove; 28 | } 29 | 30 | public boolean ifNotRemoveNotFold() { 31 | return !remove && !fold; 32 | } 33 | 34 | public static final WeakHashMap barMap = new WeakHashMap<>(); 35 | 36 | @EventHandler 37 | private Listener getIteratorListener = new Listener<>(event -> { 38 | if (remove) { 39 | event.cancel(); 40 | return; 41 | } 42 | 43 | if (fold) { 44 | HashMap chosenBarMap = new HashMap<>(); 45 | event.getIterator().forEachRemaining(bar -> { 46 | String name = bar.getName().asString(); 47 | if (chosenBarMap.containsKey(name)) { 48 | barMap.compute(chosenBarMap.get(name), (clientBossBar, integer) -> (integer == null) ? 2 : integer + 1); 49 | } else { 50 | chosenBarMap.put(name, bar); 51 | } 52 | }); 53 | event.setIterator(chosenBarMap.values().iterator()); 54 | } 55 | }); 56 | 57 | @EventHandler 58 | private Listener getTextListener = new Listener<>(event -> { 59 | if (BossStack.barMap.isEmpty()) return; 60 | ClientBossBar bar = event.getBossBar(); 61 | Integer integer = barMap.get(bar); 62 | barMap.remove(bar); 63 | if (integer != null) { 64 | event.setText(event.getText().copy().append(" x" + integer)); 65 | } 66 | }); 67 | 68 | @EventHandler 69 | private Listener spacingListener = new Listener<>(event -> event.setSpacing(event.getSpacing() - spacing)); 70 | 71 | 72 | } 73 | -------------------------------------------------------------------------------- /src/main/java/me/zeroeightsix/kami/feature/module/render/NoHurtCam.java: -------------------------------------------------------------------------------- 1 | package me.zeroeightsix.kami.feature.module.render; 2 | 3 | import me.zero.alpine.listener.EventHandler; 4 | import me.zero.alpine.listener.Listener; 5 | import me.zeroeightsix.kami.event.CameraHurtEvent; 6 | import me.zeroeightsix.kami.feature.module.Module; 7 | 8 | @Module.Info(name = "NoHurtCam", category = Module.Category.RENDER, description = "Disables the 'hurt' camera effect") 9 | public class NoHurtCam extends Module { 10 | 11 | @EventHandler 12 | public Listener eventListener = new Listener<>(cameraHurtEvent -> cameraHurtEvent.cancel()); 13 | 14 | } 15 | -------------------------------------------------------------------------------- /src/main/java/me/zeroeightsix/kami/mixin/client/IBackedConfigLeaf.java: -------------------------------------------------------------------------------- 1 | package me.zeroeightsix.kami.mixin.client; 2 | 3 | import io.github.fablabsmc.fablabs.api.fiber.v1.schema.type.derived.ConfigType; 4 | import io.github.fablabsmc.fablabs.impl.fiber.annotation.BackedConfigLeaf; 5 | import org.spongepowered.asm.mixin.Mixin; 6 | import org.spongepowered.asm.mixin.gen.Accessor; 7 | 8 | import java.lang.reflect.Field; 9 | 10 | @Mixin(value = BackedConfigLeaf.class, remap = false) 11 | public interface IBackedConfigLeaf { 12 | 13 | @Accessor 14 | ConfigType getType(); 15 | 16 | @Accessor 17 | Field getBackingField(); 18 | 19 | @Accessor 20 | Object getPojo(); 21 | 22 | } 23 | -------------------------------------------------------------------------------- /src/main/java/me/zeroeightsix/kami/mixin/client/IBlockModelRenderer.java: -------------------------------------------------------------------------------- 1 | package me.zeroeightsix.kami.mixin.client; 2 | 3 | import net.minecraft.block.BlockState; 4 | import net.minecraft.client.render.VertexConsumer; 5 | import net.minecraft.client.render.block.BlockModelRenderer; 6 | import net.minecraft.client.render.block.BlockRenderManager; 7 | import net.minecraft.client.render.model.BakedQuad; 8 | import net.minecraft.client.util.math.MatrixStack; 9 | import net.minecraft.util.math.BlockPos; 10 | import net.minecraft.world.BlockRenderView; 11 | import org.spongepowered.asm.mixin.Mixin; 12 | import org.spongepowered.asm.mixin.gen.Invoker; 13 | 14 | import java.util.BitSet; 15 | import java.util.List; 16 | 17 | @Mixin(BlockModelRenderer.class) 18 | public interface IBlockModelRenderer { 19 | 20 | @Invoker 21 | void callRenderQuad(BlockRenderView blockRenderView, BlockState blockState, BlockPos blockPos, VertexConsumer vertexConsumer, MatrixStack.Entry entry, BakedQuad bakedQuad, float f, float g, float h, float i, int j, int k, int l, int m, int n); 22 | 23 | } 24 | -------------------------------------------------------------------------------- /src/main/java/me/zeroeightsix/kami/mixin/client/ICamera.java: -------------------------------------------------------------------------------- 1 | package me.zeroeightsix.kami.mixin.client; 2 | 3 | import net.minecraft.client.render.Camera; 4 | import net.minecraft.util.math.Vec3d; 5 | import org.spongepowered.asm.mixin.Mixin; 6 | import org.spongepowered.asm.mixin.gen.Accessor; 7 | import org.spongepowered.asm.mixin.gen.Invoker; 8 | 9 | @Mixin(Camera.class) 10 | public interface ICamera { 11 | 12 | @Invoker 13 | void callSetPos(Vec3d pos); 14 | 15 | @Invoker 16 | void callSetRotation(float yaw, float pitch); 17 | 18 | @Accessor 19 | float getYaw(); 20 | 21 | @Accessor 22 | float getPitch(); 23 | 24 | } 25 | -------------------------------------------------------------------------------- /src/main/java/me/zeroeightsix/kami/mixin/client/IChatMessageC2SPacket.java: -------------------------------------------------------------------------------- 1 | package me.zeroeightsix.kami.mixin.client; 2 | 3 | import net.minecraft.network.packet.c2s.play.ChatMessageC2SPacket; 4 | import org.spongepowered.asm.mixin.Mixin; 5 | import org.spongepowered.asm.mixin.gen.Accessor; 6 | 7 | @Mixin(ChatMessageC2SPacket.class) 8 | public interface IChatMessageC2SPacket { 9 | 10 | @Accessor 11 | String getChatMessage(); 12 | 13 | @Accessor 14 | void setChatMessage(String newMessage); 15 | 16 | } 17 | -------------------------------------------------------------------------------- /src/main/java/me/zeroeightsix/kami/mixin/client/IChatMessageS2CPacket.java: -------------------------------------------------------------------------------- 1 | package me.zeroeightsix.kami.mixin.client; 2 | 3 | import net.minecraft.network.packet.s2c.play.GameMessageS2CPacket; 4 | import net.minecraft.text.Text; 5 | import org.spongepowered.asm.mixin.Mixin; 6 | import org.spongepowered.asm.mixin.gen.Accessor; 7 | 8 | @Mixin(GameMessageS2CPacket.class) 9 | public interface IChatMessageS2CPacket { 10 | 11 | @Accessor 12 | void setMessage(Text text); 13 | @Accessor 14 | Text getMessage(); 15 | 16 | } 17 | -------------------------------------------------------------------------------- /src/main/java/me/zeroeightsix/kami/mixin/client/IChunkData.java: -------------------------------------------------------------------------------- 1 | package me.zeroeightsix.kami.mixin.client; 2 | 3 | import net.minecraft.client.render.RenderLayer; 4 | import net.minecraft.client.render.chunk.ChunkBuilder; 5 | import org.spongepowered.asm.mixin.Mixin; 6 | import org.spongepowered.asm.mixin.gen.Accessor; 7 | 8 | import java.util.Set; 9 | 10 | @Mixin(ChunkBuilder.ChunkData.class) 11 | public interface IChunkData { 12 | 13 | @Accessor 14 | Set getInitializedLayers(); 15 | 16 | @Accessor 17 | void setEmpty(boolean empty); 18 | 19 | @Accessor 20 | Set getNonEmptyLayers(); 21 | 22 | } 23 | -------------------------------------------------------------------------------- /src/main/java/me/zeroeightsix/kami/mixin/client/IClientPlayerInteractionManager.java: -------------------------------------------------------------------------------- 1 | package me.zeroeightsix.kami.mixin.client; 2 | 3 | import net.minecraft.client.network.ClientPlayerInteractionManager; 4 | import org.spongepowered.asm.mixin.Mixin; 5 | import org.spongepowered.asm.mixin.gen.Accessor; 6 | import org.spongepowered.asm.mixin.gen.Invoker; 7 | 8 | @Mixin(ClientPlayerInteractionManager.class) 9 | public interface IClientPlayerInteractionManager { 10 | 11 | @Invoker 12 | void invokeSyncSelectedSlot(); 13 | 14 | @Accessor 15 | void setBlockBreakingCooldown(int blockBreakingCooldown); 16 | 17 | } 18 | -------------------------------------------------------------------------------- /src/main/java/me/zeroeightsix/kami/mixin/client/IDimensionType.java: -------------------------------------------------------------------------------- 1 | package me.zeroeightsix.kami.mixin.client; 2 | 3 | import net.minecraft.world.dimension.DimensionType; 4 | import org.spongepowered.asm.mixin.Mixin; 5 | import org.spongepowered.asm.mixin.gen.Accessor; 6 | 7 | @Mixin(DimensionType.class) 8 | public interface IDimensionType { 9 | 10 | @Accessor("OVERWORLD") 11 | static DimensionType getOverworld() { 12 | throw new UnsupportedOperationException("Untransformed mixin!"); 13 | } 14 | 15 | } 16 | -------------------------------------------------------------------------------- /src/main/java/me/zeroeightsix/kami/mixin/client/IDisconnectedScreen.java: -------------------------------------------------------------------------------- 1 | package me.zeroeightsix.kami.mixin.client; 2 | 3 | import net.minecraft.client.gui.screen.DisconnectedScreen; 4 | import net.minecraft.client.gui.screen.Screen; 5 | import net.minecraft.text.Text; 6 | import org.spongepowered.asm.mixin.Mixin; 7 | import org.spongepowered.asm.mixin.gen.Accessor; 8 | 9 | @Mixin(DisconnectedScreen.class) 10 | public interface IDisconnectedScreen { 11 | 12 | @Accessor 13 | Screen getParent(); 14 | @Accessor 15 | Text getReason(); 16 | 17 | } 18 | -------------------------------------------------------------------------------- /src/main/java/me/zeroeightsix/kami/mixin/client/IEntity.java: -------------------------------------------------------------------------------- 1 | package me.zeroeightsix.kami.mixin.client; 2 | 3 | import net.minecraft.entity.Entity; 4 | import net.minecraft.util.math.Vec3d; 5 | import org.spongepowered.asm.mixin.Mixin; 6 | import org.spongepowered.asm.mixin.gen.Invoker; 7 | 8 | @Mixin(Entity.class) 9 | public interface IEntity { 10 | 11 | @Invoker("movementInputToVelocity") 12 | static Vec3d movementInputToVelocity(Vec3d movementInput, float speed, float yaw) { 13 | throw new UnsupportedOperationException("Untransformed mixin!"); 14 | } 15 | 16 | } 17 | -------------------------------------------------------------------------------- /src/main/java/me/zeroeightsix/kami/mixin/client/IEntitySelector.java: -------------------------------------------------------------------------------- 1 | package me.zeroeightsix.kami.mixin.client; 2 | 3 | import net.minecraft.command.EntitySelector; 4 | import org.spongepowered.asm.mixin.Mixin; 5 | import org.spongepowered.asm.mixin.gen.Accessor; 6 | 7 | import java.util.UUID; 8 | 9 | @Mixin(EntitySelector.class) 10 | public interface IEntitySelector { 11 | 12 | @Accessor 13 | String getPlayerName(); 14 | @Accessor 15 | UUID getUuid(); 16 | 17 | } 18 | -------------------------------------------------------------------------------- /src/main/java/me/zeroeightsix/kami/mixin/client/IEntityVelocityUpdateS2CPacket.java: -------------------------------------------------------------------------------- 1 | package me.zeroeightsix.kami.mixin.client; 2 | 3 | import net.minecraft.network.packet.s2c.play.EntityVelocityUpdateS2CPacket; 4 | import org.spongepowered.asm.mixin.Mixin; 5 | import org.spongepowered.asm.mixin.gen.Accessor; 6 | 7 | @Mixin(EntityVelocityUpdateS2CPacket.class) 8 | public interface IEntityVelocityUpdateS2CPacket { 9 | 10 | @Accessor 11 | int getID(); 12 | @Accessor 13 | void setID(int id); 14 | 15 | @Accessor 16 | int getVelocityX(); 17 | @Accessor 18 | int getVelocityY(); 19 | @Accessor 20 | int getVelocityZ(); 21 | 22 | @Accessor 23 | void setVelocityX(int x); 24 | @Accessor 25 | void setVelocityY(int y); 26 | @Accessor 27 | void setVelocityZ(int z); 28 | 29 | } 30 | -------------------------------------------------------------------------------- /src/main/java/me/zeroeightsix/kami/mixin/client/IExplosionS2CPacket.java: -------------------------------------------------------------------------------- 1 | package me.zeroeightsix.kami.mixin.client; 2 | 3 | import net.minecraft.network.packet.s2c.play.ExplosionS2CPacket; 4 | import org.spongepowered.asm.mixin.Mixin; 5 | import org.spongepowered.asm.mixin.gen.Accessor; 6 | 7 | @Mixin(ExplosionS2CPacket.class) 8 | public interface IExplosionS2CPacket { 9 | 10 | @Accessor 11 | float getPlayerVelocityX(); 12 | 13 | @Accessor 14 | void setPlayerVelocityX(float playerVelocityX); 15 | 16 | @Accessor 17 | float getPlayerVelocityY(); 18 | 19 | @Accessor 20 | void setPlayerVelocityY(float playerVelocityY); 21 | 22 | @Accessor 23 | float getPlayerVelocityZ(); 24 | 25 | @Accessor 26 | void setPlayerVelocityZ(float playerVelocityZ); 27 | 28 | } 29 | -------------------------------------------------------------------------------- /src/main/java/me/zeroeightsix/kami/mixin/client/IGameRenderer.java: -------------------------------------------------------------------------------- 1 | package me.zeroeightsix.kami.mixin.client; 2 | 3 | import net.minecraft.client.render.GameRenderer; 4 | import org.spongepowered.asm.mixin.Mixin; 5 | import org.spongepowered.asm.mixin.gen.Accessor; 6 | 7 | @Mixin(GameRenderer.class) 8 | public interface IGameRenderer { 9 | 10 | @Accessor 11 | void setRenderHand(boolean renderHand); 12 | 13 | } 14 | -------------------------------------------------------------------------------- /src/main/java/me/zeroeightsix/kami/mixin/client/IInputUtilType.java: -------------------------------------------------------------------------------- 1 | package me.zeroeightsix.kami.mixin.client; 2 | 3 | import it.unimi.dsi.fastutil.ints.Int2ObjectMap; 4 | import net.minecraft.client.util.InputUtil; 5 | import org.spongepowered.asm.mixin.Mixin; 6 | import org.spongepowered.asm.mixin.gen.Accessor; 7 | 8 | @Mixin(InputUtil.Type.class) 9 | public interface IInputUtilType { 10 | 11 | @Accessor 12 | Int2ObjectMap getMap(); 13 | 14 | } 15 | -------------------------------------------------------------------------------- /src/main/java/me/zeroeightsix/kami/mixin/client/IKeyBinding.java: -------------------------------------------------------------------------------- 1 | package me.zeroeightsix.kami.mixin.client; 2 | 3 | import net.minecraft.client.options.KeyBinding; 4 | import net.minecraft.client.util.InputUtil; 5 | import org.spongepowered.asm.mixin.Mixin; 6 | import org.spongepowered.asm.mixin.gen.Accessor; 7 | 8 | @Mixin(KeyBinding.class) 9 | public interface IKeyBinding { 10 | 11 | @Accessor 12 | InputUtil.Key getBoundKey(); 13 | @Accessor 14 | void setPressed(boolean pressed); 15 | 16 | } 17 | -------------------------------------------------------------------------------- /src/main/java/me/zeroeightsix/kami/mixin/client/IMatrix4f.java: -------------------------------------------------------------------------------- 1 | package me.zeroeightsix.kami.mixin.client; 2 | 3 | import net.minecraft.util.math.Matrix4f; 4 | import org.spongepowered.asm.mixin.Mixin; 5 | import org.spongepowered.asm.mixin.gen.Accessor; 6 | 7 | @Mixin(Matrix4f.class) 8 | public interface IMatrix4f { 9 | 10 | @Accessor 11 | float getA00(); 12 | 13 | @Accessor 14 | float getA01(); 15 | 16 | @Accessor 17 | float getA02(); 18 | 19 | @Accessor 20 | float getA03(); 21 | 22 | @Accessor 23 | float getA10(); 24 | 25 | @Accessor 26 | float getA11(); 27 | 28 | @Accessor 29 | float getA12(); 30 | 31 | @Accessor 32 | float getA13(); 33 | 34 | @Accessor 35 | float getA20(); 36 | 37 | @Accessor 38 | float getA21(); 39 | 40 | @Accessor 41 | float getA22(); 42 | 43 | @Accessor 44 | float getA23(); 45 | 46 | @Accessor 47 | float getA30(); 48 | 49 | @Accessor 50 | float getA31(); 51 | 52 | @Accessor 53 | float getA32(); 54 | 55 | @Accessor 56 | float getA33(); 57 | 58 | } 59 | -------------------------------------------------------------------------------- /src/main/java/me/zeroeightsix/kami/mixin/client/IMatrixStack$Entry.java: -------------------------------------------------------------------------------- 1 | package me.zeroeightsix.kami.mixin.client; 2 | 3 | import net.minecraft.client.util.math.MatrixStack; 4 | import net.minecraft.util.math.Matrix3f; 5 | import net.minecraft.util.math.Matrix4f; 6 | import org.spongepowered.asm.mixin.Mixin; 7 | import org.spongepowered.asm.mixin.gen.Invoker; 8 | 9 | @Mixin(MatrixStack.Entry.class) 10 | public interface IMatrixStack$Entry { 11 | 12 | @Invoker("") 13 | static MatrixStack.Entry create(Matrix4f model, Matrix3f normal) { 14 | throw new UnsupportedOperationException("Untransformed Accessor!"); 15 | } 16 | 17 | } 18 | -------------------------------------------------------------------------------- /src/main/java/me/zeroeightsix/kami/mixin/client/IMatrixStack.java: -------------------------------------------------------------------------------- 1 | package me.zeroeightsix.kami.mixin.client; 2 | 3 | import net.minecraft.client.util.math.MatrixStack; 4 | import org.spongepowered.asm.mixin.Mixin; 5 | import org.spongepowered.asm.mixin.gen.Accessor; 6 | 7 | import java.util.Deque; 8 | 9 | @Mixin(MatrixStack.class) 10 | public interface IMatrixStack { 11 | 12 | @Accessor 13 | Deque getStack(); 14 | 15 | } 16 | -------------------------------------------------------------------------------- /src/main/java/me/zeroeightsix/kami/mixin/client/IMinecraftClient.java: -------------------------------------------------------------------------------- 1 | package me.zeroeightsix.kami.mixin.client; 2 | 3 | import net.minecraft.client.MinecraftClient; 4 | import org.spongepowered.asm.mixin.Mixin; 5 | import org.spongepowered.asm.mixin.gen.Accessor; 6 | import org.spongepowered.asm.mixin.gen.Invoker; 7 | 8 | @Mixin(MinecraftClient.class) 9 | public interface IMinecraftClient { 10 | 11 | @Accessor 12 | void setItemUseCooldown(int itemUseCooldown); 13 | 14 | @Accessor 15 | int getItemUseCooldown(); 16 | 17 | @Invoker 18 | void callDoAttack(); 19 | 20 | @Invoker 21 | void callDoItemUse(); 22 | 23 | @Invoker 24 | void callOpenChatScreen(String text); 25 | 26 | @Accessor 27 | static int getCurrentFps() { 28 | throw new UnsupportedOperationException("Untransformed mixin!"); 29 | } 30 | 31 | } 32 | -------------------------------------------------------------------------------- /src/main/java/me/zeroeightsix/kami/mixin/client/IMiningToolItem.java: -------------------------------------------------------------------------------- 1 | package me.zeroeightsix.kami.mixin.client; 2 | 3 | import net.minecraft.item.MiningToolItem; 4 | import org.spongepowered.asm.mixin.Mixin; 5 | import org.spongepowered.asm.mixin.gen.Accessor; 6 | 7 | @Mixin(MiningToolItem.class) 8 | public interface IMiningToolItem { 9 | 10 | @Accessor 11 | float getAttackDamage(); 12 | 13 | } 14 | -------------------------------------------------------------------------------- /src/main/java/me/zeroeightsix/kami/mixin/client/IPlayerMoveC2SPacket.java: -------------------------------------------------------------------------------- 1 | package me.zeroeightsix.kami.mixin.client; 2 | 3 | import net.minecraft.network.packet.c2s.play.PlayerMoveC2SPacket; 4 | import org.spongepowered.asm.mixin.Mixin; 5 | import org.spongepowered.asm.mixin.gen.Accessor; 6 | 7 | @Mixin(PlayerMoveC2SPacket.class) 8 | public interface IPlayerMoveC2SPacket { 9 | 10 | @Accessor 11 | void setOnGround(boolean onGround); 12 | 13 | @Accessor 14 | double getX(); 15 | 16 | @Accessor 17 | double getY(); 18 | 19 | @Accessor 20 | double getZ(); 21 | 22 | @Accessor 23 | void setX(double x); 24 | 25 | @Accessor 26 | void setY(double y); 27 | 28 | @Accessor 29 | void setZ(double z); 30 | 31 | @Accessor 32 | void setYaw(float yaw); 33 | 34 | @Accessor 35 | void setPitch(float pitch); 36 | 37 | @Accessor 38 | void setChangePosition(boolean changePosition); 39 | 40 | @Accessor 41 | void setChangeLook(boolean changeLook); 42 | 43 | } 44 | -------------------------------------------------------------------------------- /src/main/java/me/zeroeightsix/kami/mixin/client/IPlayerPositionLookS2CPacket.java: -------------------------------------------------------------------------------- 1 | package me.zeroeightsix.kami.mixin.client; 2 | 3 | import net.minecraft.network.packet.s2c.play.PlayerPositionLookS2CPacket; 4 | import org.spongepowered.asm.mixin.Mixin; 5 | import org.spongepowered.asm.mixin.gen.Accessor; 6 | 7 | @Mixin(PlayerPositionLookS2CPacket.class) 8 | public interface IPlayerPositionLookS2CPacket { 9 | 10 | @Accessor 11 | float getYaw(); 12 | @Accessor 13 | float getPitch(); 14 | 15 | @Accessor 16 | void setYaw(float yaw); 17 | @Accessor 18 | void setPitch(float pitch); 19 | 20 | } 21 | -------------------------------------------------------------------------------- /src/main/java/me/zeroeightsix/kami/mixin/client/IShulkerBoxBlockEntity.java: -------------------------------------------------------------------------------- 1 | package me.zeroeightsix.kami.mixin.client; 2 | 3 | import net.minecraft.block.entity.ShulkerBoxBlockEntity; 4 | import net.minecraft.entity.player.PlayerInventory; 5 | import net.minecraft.screen.ScreenHandler; 6 | import org.spongepowered.asm.mixin.Mixin; 7 | import org.spongepowered.asm.mixin.gen.Invoker; 8 | 9 | @Mixin(ShulkerBoxBlockEntity.class) 10 | public interface IShulkerBoxBlockEntity { 11 | 12 | @Invoker 13 | ScreenHandler invokeCreateScreenHandler(int syncId, PlayerInventory playerInventory); 14 | 15 | } 16 | -------------------------------------------------------------------------------- /src/main/java/me/zeroeightsix/kami/mixin/client/MixinBackedConfigLeaf.java: -------------------------------------------------------------------------------- 1 | package me.zeroeightsix.kami.mixin.client; 2 | 3 | import io.github.fablabsmc.fablabs.impl.fiber.annotation.BackedConfigLeaf; 4 | import me.zeroeightsix.kami.mixin.duck.CanDisableCaching; 5 | import org.spongepowered.asm.mixin.Mixin; 6 | import org.spongepowered.asm.mixin.Shadow; 7 | import org.spongepowered.asm.mixin.injection.At; 8 | import org.spongepowered.asm.mixin.injection.Inject; 9 | import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; 10 | 11 | @Mixin(value = BackedConfigLeaf.class, remap = false) 12 | public class MixinBackedConfigLeaf implements CanDisableCaching { 13 | 14 | @Shadow 15 | private R cachedValue; 16 | private boolean cachingDisabled = false; 17 | 18 | @Override 19 | public boolean isCachingDisabled() { 20 | return this.cachingDisabled; 21 | } 22 | 23 | @Override 24 | public void setCachingDisabled(boolean disabled) { 25 | this.cachingDisabled = disabled; 26 | } 27 | 28 | @Inject(method = "getValue", at = @At("RETURN")) 29 | public void onReturnGetValue(CallbackInfoReturnable returnable) { 30 | if (cachingDisabled) 31 | this.cachedValue = null; 32 | } 33 | 34 | } 35 | -------------------------------------------------------------------------------- /src/main/java/me/zeroeightsix/kami/mixin/client/MixinBackgroundRenderer.java: -------------------------------------------------------------------------------- 1 | package me.zeroeightsix.kami.mixin.client; 2 | 3 | import me.zeroeightsix.kami.KamiMod; 4 | import me.zeroeightsix.kami.event.ApplyFogEvent; 5 | import net.minecraft.client.render.BackgroundRenderer; 6 | import net.minecraft.client.render.Camera; 7 | import org.spongepowered.asm.mixin.Mixin; 8 | import org.spongepowered.asm.mixin.injection.At; 9 | import org.spongepowered.asm.mixin.injection.Inject; 10 | import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; 11 | 12 | @Mixin(BackgroundRenderer.class) 13 | public class MixinBackgroundRenderer { 14 | 15 | @Inject(method = "applyFog", at = @At("HEAD"), cancellable = true) 16 | private static void onApplyFog(Camera camera, BackgroundRenderer.FogType fogType, float viewDistance, boolean thickFog, CallbackInfo ci) { 17 | ApplyFogEvent event = new ApplyFogEvent(); 18 | KamiMod.EVENT_BUS.post(event); 19 | if (event.isCancelled()) ci.cancel(); 20 | } 21 | 22 | } 23 | -------------------------------------------------------------------------------- /src/main/java/me/zeroeightsix/kami/mixin/client/MixinBeaconBlockEntity.java: -------------------------------------------------------------------------------- 1 | package me.zeroeightsix.kami.mixin.client; 2 | 3 | import com.google.common.collect.ImmutableList; 4 | import me.zeroeightsix.kami.feature.module.NoRender; 5 | import net.minecraft.block.entity.BeaconBlockEntity; 6 | import org.spongepowered.asm.mixin.Mixin; 7 | import org.spongepowered.asm.mixin.injection.At; 8 | import org.spongepowered.asm.mixin.injection.Inject; 9 | import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; 10 | 11 | import java.util.List; 12 | 13 | @Mixin(BeaconBlockEntity.class) 14 | public class MixinBeaconBlockEntity { 15 | @Inject(method = "getBeamSegments", at = @At("RETURN"), cancellable = true) 16 | public void shouldBeamRender(CallbackInfoReturnable> cir) { 17 | if (NoRender.INSTANCE.getEnabled() && NoRender.INSTANCE.getBeaconBeams()) { 18 | cir.setReturnValue(ImmutableList.of()); 19 | } 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /src/main/java/me/zeroeightsix/kami/mixin/client/MixinBlockBufferBuilderStorage.java: -------------------------------------------------------------------------------- 1 | package me.zeroeightsix.kami.mixin.client; 2 | 3 | import me.zeroeightsix.kami.world.KamiRenderLayers; 4 | import net.minecraft.client.render.BufferBuilder; 5 | import net.minecraft.client.render.RenderLayer; 6 | import net.minecraft.client.render.chunk.BlockBufferBuilderStorage; 7 | import org.spongepowered.asm.mixin.Final; 8 | import org.spongepowered.asm.mixin.Mixin; 9 | import org.spongepowered.asm.mixin.Shadow; 10 | import org.spongepowered.asm.mixin.injection.At; 11 | import org.spongepowered.asm.mixin.injection.Inject; 12 | import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; 13 | 14 | import java.util.Map; 15 | import java.util.stream.Collectors; 16 | 17 | @Mixin(BlockBufferBuilderStorage.class) 18 | public class MixinBlockBufferBuilderStorage { 19 | 20 | @Shadow @Final private Map builders; 21 | 22 | @Inject(method = "", at = @At("TAIL")) 23 | public void onInit(CallbackInfo ci) { 24 | this.builders.putAll(KamiRenderLayers.INSTANCE.getLayers().entrySet().stream().collect(Collectors.toMap(Map.Entry::getKey, entry -> new BufferBuilder(entry.getKey().getExpectedBufferSize())))); 25 | } 26 | 27 | } 28 | -------------------------------------------------------------------------------- /src/main/java/me/zeroeightsix/kami/mixin/client/MixinBlockEntityRenderDispatcher.java: -------------------------------------------------------------------------------- 1 | package me.zeroeightsix.kami.mixin.client; 2 | 3 | import me.zeroeightsix.kami.Colour; 4 | import me.zeroeightsix.kami.feature.module.ESP; 5 | import me.zeroeightsix.kami.mixin.duck.HotSwappable; 6 | import net.minecraft.block.entity.BlockEntity; 7 | import net.minecraft.client.MinecraftClient; 8 | import net.minecraft.client.render.OutlineVertexConsumerProvider; 9 | import net.minecraft.client.render.VertexConsumerProvider; 10 | import net.minecraft.client.render.block.entity.BlockEntityRenderDispatcher; 11 | import net.minecraft.client.render.block.entity.BlockEntityRenderer; 12 | import net.minecraft.client.util.math.MatrixStack; 13 | import org.spongepowered.asm.mixin.Mixin; 14 | import org.spongepowered.asm.mixin.Shadow; 15 | import org.spongepowered.asm.mixin.injection.At; 16 | import org.spongepowered.asm.mixin.injection.Redirect; 17 | 18 | @Mixin(BlockEntityRenderDispatcher.class) 19 | public abstract class MixinBlockEntityRenderDispatcher { 20 | @Redirect(method = "net/minecraft/client/render/block/entity/BlockEntityRenderDispatcher.method_23081(Lnet/minecraft/client/render/block/entity/BlockEntityRenderer;Lnet/minecraft/block/entity/BlockEntity;FLnet/minecraft/client/util/math/MatrixStack;Lnet/minecraft/client/render/VertexConsumerProvider;)V", 21 | at = @At(value = "INVOKE", 22 | target = "Lnet/minecraft/client/render/block/entity/BlockEntityRenderDispatcher;render(Lnet/minecraft/client/render/block/entity/BlockEntityRenderer;Lnet/minecraft/block/entity/BlockEntity;FLnet/minecraft/client/util/math/MatrixStack;Lnet/minecraft/client/render/VertexConsumerProvider;)V") 23 | ) 24 | private static void onRender(BlockEntityRenderer renderer, E blockEntity, float tickDelta, MatrixStack matrices, VertexConsumerProvider vertexConsumers) { 25 | if (ESP.INSTANCE.getEnabled()) { 26 | Colour colour = ESP.INSTANCE.getBlockEntityTargets().get(blockEntity); 27 | if (colour != null) { 28 | ((HotSwappable) MinecraftClient.getInstance().worldRenderer).swapWhile(() -> { 29 | OutlineVertexConsumerProvider provider = ESP.INSTANCE.getEntityOutlineVertexConsumerProvider(); 30 | provider.setColor((int) (colour.getR() * 255), (int) (colour.getG() * 255), (int) (colour.getB() * 255), (int) (colour.getA() * 255)); 31 | render(renderer, blockEntity, tickDelta, matrices, provider); 32 | }); 33 | return; 34 | } 35 | } 36 | render(renderer, blockEntity, tickDelta, matrices, vertexConsumers); 37 | } 38 | 39 | @Shadow 40 | private static void render(BlockEntityRenderer renderer, T blockEntity, float tickDelta, MatrixStack matrices, VertexConsumerProvider vertexConsumers) { 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /src/main/java/me/zeroeightsix/kami/mixin/client/MixinBossBarHud.java: -------------------------------------------------------------------------------- 1 | package me.zeroeightsix.kami.mixin.client; 2 | 3 | import me.zeroeightsix.kami.KamiMod; 4 | import me.zeroeightsix.kami.event.RenderBossBarEvent; 5 | import net.minecraft.client.gui.hud.BossBarHud; 6 | import net.minecraft.client.gui.hud.ClientBossBar; 7 | import net.minecraft.text.Text; 8 | import org.spongepowered.asm.mixin.Mixin; 9 | import org.spongepowered.asm.mixin.injection.At; 10 | import org.spongepowered.asm.mixin.injection.Constant; 11 | import org.spongepowered.asm.mixin.injection.ModifyConstant; 12 | import org.spongepowered.asm.mixin.injection.Redirect; 13 | 14 | import java.util.Collection; 15 | import java.util.Collections; 16 | import java.util.Iterator; 17 | 18 | @Mixin(BossBarHud.class) 19 | public class MixinBossBarHud { 20 | 21 | @Redirect(method = "render", at = @At(value = "INVOKE", target = "Ljava/util/Collection;iterator()Ljava/util/Iterator;")) 22 | public Iterator onRender(Collection collection) { 23 | RenderBossBarEvent.GetIterator event = new RenderBossBarEvent.GetIterator(collection.iterator()); 24 | KamiMod.EVENT_BUS.post(event); 25 | if (event.isCancelled()) { 26 | return Collections.emptyIterator(); 27 | } 28 | return event.getIterator(); 29 | } 30 | 31 | @Redirect(method = "render", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/gui/hud/ClientBossBar;getName()Lnet/minecraft/text/Text;")) 32 | public Text onAsFormattedString(ClientBossBar clientBossBar) { 33 | RenderBossBarEvent.GetText event = new RenderBossBarEvent.GetText(clientBossBar, clientBossBar.getName()); 34 | KamiMod.EVENT_BUS.post(event); 35 | return event.getText(); 36 | } 37 | 38 | @ModifyConstant(method = "render", constant = @Constant(intValue = 9, ordinal = 1)) 39 | public int modifySpacingConstant(int j) { 40 | RenderBossBarEvent.Spacing spacing = new RenderBossBarEvent.Spacing(j); 41 | KamiMod.EVENT_BUS.post(spacing); 42 | return spacing.getSpacing(); 43 | } 44 | 45 | } 46 | -------------------------------------------------------------------------------- /src/main/java/me/zeroeightsix/kami/mixin/client/MixinBuiltChunk.java: -------------------------------------------------------------------------------- 1 | package me.zeroeightsix.kami.mixin.client; 2 | 3 | import me.zeroeightsix.kami.world.KamiRenderLayers; 4 | import net.minecraft.client.gl.VertexBuffer; 5 | import net.minecraft.client.render.RenderLayer; 6 | import net.minecraft.client.render.chunk.ChunkBuilder; 7 | import org.spongepowered.asm.mixin.Final; 8 | import org.spongepowered.asm.mixin.Mixin; 9 | import org.spongepowered.asm.mixin.Shadow; 10 | import org.spongepowered.asm.mixin.injection.At; 11 | import org.spongepowered.asm.mixin.injection.Inject; 12 | import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; 13 | 14 | import java.util.Map; 15 | import java.util.stream.Collectors; 16 | 17 | @Mixin(ChunkBuilder.BuiltChunk.class) 18 | public class MixinBuiltChunk { 19 | 20 | @Shadow @Final private Map buffers; 21 | 22 | @Inject(method = "", at = @At("TAIL")) 23 | public void onInit(ChunkBuilder outer, CallbackInfo ci) { 24 | this.buffers.putAll(KamiRenderLayers.INSTANCE.getLayers().entrySet().stream().collect(Collectors.toMap(Map.Entry::getKey, entry -> new VertexBuffer(entry.getValue())))); 25 | } 26 | 27 | } 28 | -------------------------------------------------------------------------------- /src/main/java/me/zeroeightsix/kami/mixin/client/MixinCamera.java: -------------------------------------------------------------------------------- 1 | package me.zeroeightsix.kami.mixin.client; 2 | 3 | import me.zeroeightsix.kami.KamiMod; 4 | import me.zeroeightsix.kami.event.CameraUpdateEvent; 5 | import me.zeroeightsix.kami.feature.module.ModuleCamera; 6 | import net.minecraft.client.render.Camera; 7 | import net.minecraft.entity.Entity; 8 | import net.minecraft.world.BlockView; 9 | import org.spongepowered.asm.mixin.Mixin; 10 | import org.spongepowered.asm.mixin.Shadow; 11 | import org.spongepowered.asm.mixin.injection.At; 12 | import org.spongepowered.asm.mixin.injection.Inject; 13 | import org.spongepowered.asm.mixin.injection.Redirect; 14 | import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; 15 | 16 | @Mixin(Camera.class) 17 | public abstract class MixinCamera { 18 | 19 | @Shadow protected abstract double clipToSpace(double desiredCameraDistance); 20 | 21 | @Redirect(method = "update", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/render/Camera;clipToSpace(D)D")) 22 | private double redirectClipToSpace(Camera camera, double desiredCameraDistance) { 23 | if (ModuleCamera.INSTANCE.getEnabled()) { 24 | desiredCameraDistance = ModuleCamera.INSTANCE.getDesiredDistance(); 25 | if (ModuleCamera.INSTANCE.getClip()) return desiredCameraDistance; 26 | } 27 | return clipToSpace(desiredCameraDistance); 28 | } 29 | 30 | @Inject(method = "update", at = @At("TAIL")) 31 | public void onUpdate(BlockView area, Entity focusedEntity, boolean thirdPerson, boolean inverseView, float tickDelta, CallbackInfo ci) { 32 | CameraUpdateEvent event = new CameraUpdateEvent((Camera) (Object) this, area, focusedEntity, thirdPerson, inverseView, tickDelta); 33 | KamiMod.EVENT_BUS.post(event); 34 | } 35 | 36 | } 37 | -------------------------------------------------------------------------------- /src/main/java/me/zeroeightsix/kami/mixin/client/MixinChatScreen.java: -------------------------------------------------------------------------------- 1 | package me.zeroeightsix.kami.mixin.client; 2 | 3 | import com.mojang.brigadier.CommandDispatcher; 4 | import com.mojang.brigadier.ParseResults; 5 | import com.mojang.brigadier.StringReader; 6 | import com.mojang.brigadier.exceptions.CommandSyntaxException; 7 | import com.mojang.brigadier.suggestion.Suggestions; 8 | import me.zeroeightsix.kami.feature.command.Command; 9 | import me.zeroeightsix.kami.feature.command.KamiCommandSource; 10 | import me.zeroeightsix.kami.gui.windows.Settings; 11 | import me.zeroeightsix.kami.util.Wrapper; 12 | import net.minecraft.client.gui.screen.ChatScreen; 13 | import net.minecraft.client.gui.widget.TextFieldWidget; 14 | import net.minecraft.command.CommandSource; 15 | import net.minecraft.text.LiteralText; 16 | import net.minecraft.text.Style; 17 | import net.minecraft.util.Formatting; 18 | import org.spongepowered.asm.mixin.Mixin; 19 | import org.spongepowered.asm.mixin.Shadow; 20 | import org.spongepowered.asm.mixin.injection.At; 21 | import org.spongepowered.asm.mixin.injection.Inject; 22 | import org.spongepowered.asm.mixin.injection.Redirect; 23 | import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; 24 | import org.spongepowered.asm.mixin.injection.callback.LocalCapture; 25 | 26 | import java.util.UUID; 27 | import java.util.concurrent.CompletableFuture; 28 | 29 | @Mixin(ChatScreen.class) 30 | public abstract class MixinChatScreen { 31 | 32 | @Redirect(method = "keyPressed", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/gui/screen/ChatScreen;sendMessage(Ljava/lang/String;)V")) 33 | public void sendMessage(ChatScreen screen, String message) { 34 | if (message.startsWith(String.valueOf(Settings.INSTANCE.getCommandPrefix()))) { 35 | Wrapper.getMinecraft().inGameHud.getChatHud().addToMessageHistory(message); 36 | 37 | message = message.substring(1); // cut off command prefix 38 | 39 | try { 40 | Command.dispatcher.execute(message, new KamiCommandSource(Wrapper.getMinecraft().getNetworkHandler(), Wrapper.getMinecraft())); 41 | } catch (CommandSyntaxException e) { 42 | Wrapper.getPlayer().sendSystemMessage(new LiteralText(e.getMessage()).setStyle(Style.EMPTY.withColor(Formatting.RED)), UUID.randomUUID()); 43 | } 44 | } else { 45 | screen.sendMessage(message); 46 | } 47 | } 48 | 49 | } 50 | -------------------------------------------------------------------------------- /src/main/java/me/zeroeightsix/kami/mixin/client/MixinClientChunkManager.java: -------------------------------------------------------------------------------- 1 | package me.zeroeightsix.kami.mixin.client; 2 | 3 | import me.zeroeightsix.kami.KamiMod; 4 | import me.zeroeightsix.kami.event.ChunkEvent; 5 | import net.minecraft.client.world.ClientChunkManager; 6 | import net.minecraft.world.chunk.WorldChunk; 7 | import org.spongepowered.asm.mixin.Mixin; 8 | import org.spongepowered.asm.mixin.injection.At; 9 | import org.spongepowered.asm.mixin.injection.Inject; 10 | import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; 11 | import org.spongepowered.asm.mixin.injection.callback.LocalCapture; 12 | 13 | @Mixin(ClientChunkManager.class) 14 | public class MixinClientChunkManager { 15 | 16 | @Inject( 17 | method = "unload", 18 | at = @At(value = "INVOKE", target = "Lnet/minecraft/client/world/ClientChunkManager;positionEquals(Lnet/minecraft/world/chunk/WorldChunk;II)Z"), 19 | locals = LocalCapture.CAPTURE_FAILHARD, 20 | cancellable = true 21 | ) 22 | public void onUnload(int chunkX, int chunkZ, CallbackInfo ci, int i, WorldChunk worldChunk) { 23 | ChunkEvent.Unload unload = new ChunkEvent.Unload(worldChunk); 24 | KamiMod.EVENT_BUS.post(unload); 25 | if (unload.isCancelled()) ci.cancel(); 26 | } 27 | 28 | } 29 | -------------------------------------------------------------------------------- /src/main/java/me/zeroeightsix/kami/mixin/client/MixinClientConnection.java: -------------------------------------------------------------------------------- 1 | package me.zeroeightsix.kami.mixin.client; 2 | 3 | import io.netty.channel.ChannelHandlerContext; 4 | import io.netty.util.concurrent.Future; 5 | import io.netty.util.concurrent.GenericFutureListener; 6 | import me.zeroeightsix.kami.KamiMod; 7 | import me.zeroeightsix.kami.event.PacketEvent; 8 | import me.zeroeightsix.kami.feature.module.NoPacketKick; 9 | import net.minecraft.network.ClientConnection; 10 | import net.minecraft.network.NetworkSide; 11 | import net.minecraft.network.Packet; 12 | import org.spongepowered.asm.mixin.Final; 13 | import org.spongepowered.asm.mixin.Mixin; 14 | import org.spongepowered.asm.mixin.Shadow; 15 | import org.spongepowered.asm.mixin.injection.At; 16 | import org.spongepowered.asm.mixin.injection.Inject; 17 | import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; 18 | 19 | import java.io.IOException; 20 | 21 | @Mixin(ClientConnection.class) 22 | public class MixinClientConnection { 23 | 24 | @Shadow @Final private NetworkSide side; 25 | 26 | @Inject(method = "channelRead0", at = @At("HEAD"), cancellable = true) 27 | protected void onChannelRead0(ChannelHandlerContext channelHandlerContext, Packet packet, CallbackInfo info) { 28 | if (this.side != NetworkSide.CLIENTBOUND) 29 | return; // Don't post a packet event from the server thread 30 | PacketEvent.Receive receive = new PacketEvent.Receive(packet); 31 | KamiMod.EVENT_BUS.post(receive); 32 | if (receive.isCancelled()) 33 | info.cancel(); 34 | } 35 | 36 | @Inject(method = "sendImmediately", at = @At("HEAD"), cancellable = true) 37 | private void sendImmediately(Packet packet, GenericFutureListener> listener, CallbackInfo info) { 38 | if (this.side != NetworkSide.CLIENTBOUND) 39 | return; // Don't post a packet event from the server thread 40 | PacketEvent.Send event = new PacketEvent.Send(packet); 41 | KamiMod.EVENT_BUS.post(event); 42 | if (event.isCancelled()) 43 | info.cancel(); 44 | } 45 | 46 | @Inject(method = "exceptionCaught", at = @At("HEAD"), cancellable = true) 47 | private void exceptionCaught(ChannelHandlerContext context, Throwable throwable, CallbackInfo ci) { 48 | if (throwable instanceof IOException && NoPacketKick.INSTANCE.getEnabled()) ci.cancel(); 49 | } 50 | 51 | } 52 | -------------------------------------------------------------------------------- /src/main/java/me/zeroeightsix/kami/mixin/client/MixinClientPlayNetworkHandler.java: -------------------------------------------------------------------------------- 1 | package me.zeroeightsix.kami.mixin.client; 2 | 3 | import me.zeroeightsix.kami.feature.module.SignSpammer; 4 | import net.minecraft.block.entity.BlockEntity; 5 | import net.minecraft.client.network.ClientPlayNetworkHandler; 6 | import net.minecraft.network.Packet; 7 | import net.minecraft.network.packet.c2s.play.UpdateSignC2SPacket; 8 | import net.minecraft.network.packet.s2c.play.SignEditorOpenS2CPacket; 9 | import org.spongepowered.asm.mixin.Mixin; 10 | import org.spongepowered.asm.mixin.Shadow; 11 | import org.spongepowered.asm.mixin.injection.At; 12 | import org.spongepowered.asm.mixin.injection.Inject; 13 | import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; 14 | import org.spongepowered.asm.mixin.injection.callback.LocalCapture; 15 | 16 | @Mixin(ClientPlayNetworkHandler.class) 17 | public abstract class MixinClientPlayNetworkHandler { 18 | @Shadow 19 | public abstract void sendPacket(Packet packet); 20 | 21 | @Inject( 22 | method = "onSignEditorOpen", 23 | at = @At( 24 | value = "INVOKE", 25 | target = "Lnet/minecraft/client/network/ClientPlayerEntity;openEditSignScreen(Lnet/minecraft/block/entity/SignBlockEntity;)V" 26 | ), 27 | cancellable = true, 28 | locals = LocalCapture.CAPTURE_FAILSOFT 29 | ) 30 | private void onSignEditorOpen(SignEditorOpenS2CPacket packet, CallbackInfo ci, BlockEntity blockEntity) { 31 | // this variable is just here for some deduplication 32 | SignSpammer spammer = SignSpammer.INSTANCE; 33 | if (spammer.getEnabled()) { 34 | this.sendPacket( 35 | new UpdateSignC2SPacket( 36 | packet.getPos(), 37 | spammer.getLine1(), 38 | spammer.getLine2(), 39 | spammer.getLine3(), 40 | spammer.getLine4() 41 | ) 42 | ); 43 | blockEntity.markDirty(); 44 | // cancel to not open edit screen 45 | ci.cancel(); 46 | } 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /src/main/java/me/zeroeightsix/kami/mixin/client/MixinClientPlayerInteractionManager.java: -------------------------------------------------------------------------------- 1 | package me.zeroeightsix.kami.mixin.client; 2 | 3 | import me.zeroeightsix.kami.KamiMod; 4 | import me.zeroeightsix.kami.event.PlayerAttackBlockEvent; 5 | import me.zeroeightsix.kami.feature.module.player.TpsSync; 6 | import me.zeroeightsix.kami.feature.hidden.TickSpeedMeter; 7 | import net.minecraft.block.BlockState; 8 | import net.minecraft.client.network.ClientPlayerInteractionManager; 9 | import net.minecraft.entity.player.PlayerEntity; 10 | import net.minecraft.util.math.BlockPos; 11 | import net.minecraft.util.math.Direction; 12 | import net.minecraft.world.BlockView; 13 | import org.spongepowered.asm.mixin.Mixin; 14 | import org.spongepowered.asm.mixin.injection.At; 15 | import org.spongepowered.asm.mixin.injection.Inject; 16 | import org.spongepowered.asm.mixin.injection.Redirect; 17 | import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; 18 | 19 | @Mixin(ClientPlayerInteractionManager.class) 20 | public class MixinClientPlayerInteractionManager { 21 | 22 | @Inject(method = "attackBlock", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/world/ClientWorld;getBlockState(Lnet/minecraft/util/math/BlockPos;)Lnet/minecraft/block/BlockState;", ordinal = 1)) 23 | public void attackBlock(BlockPos position, Direction facing, CallbackInfoReturnable info) { 24 | PlayerAttackBlockEvent event = new PlayerAttackBlockEvent(position, facing); 25 | KamiMod.EVENT_BUS.post(event); 26 | } 27 | 28 | @Redirect(method = "updateBlockBreakingProgress", at = @At(value = "INVOKE", target = "Lnet/minecraft/block/BlockState;calcBlockBreakingDelta(Lnet/minecraft/entity/player/PlayerEntity;Lnet/minecraft/world/BlockView;Lnet/minecraft/util/math/BlockPos;)F")) 29 | public float calcBlockBreakingDelta(BlockState state, PlayerEntity player, BlockView view, BlockPos pos) { 30 | return state.calcBlockBreakingDelta(player, view, pos) * (TpsSync.isSync() ? (TickSpeedMeter.INSTANCE.getTickRate() / 20f) : 1); 31 | } 32 | 33 | } 34 | -------------------------------------------------------------------------------- /src/main/java/me/zeroeightsix/kami/mixin/client/MixinClientWorld.java: -------------------------------------------------------------------------------- 1 | package me.zeroeightsix.kami.mixin.client; 2 | 3 | import me.zeroeightsix.kami.KamiMod; 4 | import me.zeroeightsix.kami.event.EntityJoinWorldEvent; 5 | import net.minecraft.client.world.ClientWorld; 6 | import net.minecraft.entity.Entity; 7 | import org.spongepowered.asm.mixin.Mixin; 8 | import org.spongepowered.asm.mixin.injection.At; 9 | import org.spongepowered.asm.mixin.injection.Inject; 10 | import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; 11 | 12 | @Mixin(ClientWorld.class) 13 | public class MixinClientWorld { 14 | 15 | @Inject(method = "addEntity", at = @At("HEAD"), cancellable = true) 16 | public void addEntity(int id, Entity entity, CallbackInfo info) { 17 | EntityJoinWorldEvent event = new EntityJoinWorldEvent(id, entity); 18 | KamiMod.EVENT_BUS.post(event); 19 | if (event.isCancelled()) info.cancel(); 20 | } 21 | 22 | } 23 | -------------------------------------------------------------------------------- /src/main/java/me/zeroeightsix/kami/mixin/client/MixinComeCommand.java: -------------------------------------------------------------------------------- 1 | package me.zeroeightsix.kami.mixin.client; 2 | 3 | import baritone.api.IBaritone; 4 | import baritone.api.command.Command; 5 | import baritone.api.command.argument.IArgConsumer; 6 | import baritone.api.pathing.goals.GoalBlock; 7 | import baritone.command.defaults.ComeCommand; 8 | import me.zeroeightsix.kami.feature.module.Freecam; 9 | import net.minecraft.util.math.Vec3d; 10 | import org.spongepowered.asm.mixin.Mixin; 11 | import org.spongepowered.asm.mixin.injection.At; 12 | import org.spongepowered.asm.mixin.injection.Inject; 13 | import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; 14 | 15 | // If baritone is not present at runtime, this will just produce a harmless error in console. 16 | @Mixin(value = ComeCommand.class, remap = false) 17 | public abstract class MixinComeCommand extends Command { 18 | 19 | protected MixinComeCommand(IBaritone baritone, String... names) { 20 | super(baritone, names); 21 | } 22 | 23 | @Inject(method = "execute", at = @At(value = "INVOKE", target = "Lbaritone/api/process/ICustomGoalProcess;setGoalAndPath(Lbaritone/api/pathing/goals/Goal;)V"), cancellable = true) 24 | public void onSetGoalAndPath(String label, IArgConsumer args, CallbackInfo ci) { 25 | if (Freecam.INSTANCE.getEnabled()) { 26 | ci.cancel(); 27 | Vec3d pos = Freecam.INSTANCE.getPos(); 28 | baritone.getCustomGoalProcess().setGoalAndPath(new GoalBlock((int) pos.x, (int) pos.y - 1, (int) pos.z)); 29 | logDirect("Coming (to KAMI freecam)"); 30 | } 31 | } 32 | 33 | } 34 | -------------------------------------------------------------------------------- /src/main/java/me/zeroeightsix/kami/mixin/client/MixinCommandSuggestor.java: -------------------------------------------------------------------------------- 1 | package me.zeroeightsix.kami.mixin.client; 2 | 3 | import com.mojang.brigadier.CommandDispatcher; 4 | import com.mojang.brigadier.ParseResults; 5 | import com.mojang.brigadier.StringReader; 6 | import com.mojang.brigadier.suggestion.Suggestions; 7 | import me.zeroeightsix.kami.feature.command.Command; 8 | import me.zeroeightsix.kami.gui.windows.Settings; 9 | import me.zeroeightsix.kami.util.Wrapper; 10 | import net.minecraft.client.gui.screen.CommandSuggestor; 11 | import net.minecraft.client.gui.widget.TextFieldWidget; 12 | import net.minecraft.command.CommandSource; 13 | import org.spongepowered.asm.mixin.Final; 14 | import org.spongepowered.asm.mixin.Mixin; 15 | import org.spongepowered.asm.mixin.Shadow; 16 | import org.spongepowered.asm.mixin.injection.At; 17 | import org.spongepowered.asm.mixin.injection.Inject; 18 | import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; 19 | import org.spongepowered.asm.mixin.injection.callback.LocalCapture; 20 | 21 | import java.util.concurrent.CompletableFuture; 22 | 23 | @Mixin(CommandSuggestor.class) 24 | public abstract class MixinCommandSuggestor { 25 | 26 | @Shadow 27 | @Final 28 | private boolean slashOptional; 29 | 30 | @Shadow 31 | private ParseResults parse; 32 | 33 | @Shadow 34 | @Final 35 | private TextFieldWidget textField; 36 | 37 | @Shadow 38 | private boolean completingSuggestions; 39 | 40 | @Shadow 41 | private CompletableFuture pendingSuggestions; 42 | 43 | @Shadow 44 | public abstract void show(); 45 | 46 | @Inject(method = "refresh", 47 | at = @At(value = "INVOKE", target = "Lcom/mojang/brigadier/StringReader;canRead()Z"), 48 | cancellable = true, 49 | locals = LocalCapture.CAPTURE_FAILHARD) 50 | public void refresh(CallbackInfo ci, String string, StringReader stringReader) { 51 | if (slashOptional) return; // Command block 52 | 53 | int i; 54 | if (stringReader.canRead() && stringReader.peek() == Settings.INSTANCE.getCommandPrefix()) { 55 | stringReader.skip(); 56 | CommandDispatcher commandDispatcher = Command.dispatcher; 57 | if (this.parse == null) { 58 | this.parse = commandDispatcher.parse(stringReader, Wrapper.getPlayer().networkHandler.getCommandSource()); 59 | } 60 | 61 | i = this.textField.getCursor(); 62 | if (i >= 1 && (!this.completingSuggestions)) { 63 | this.pendingSuggestions = commandDispatcher.getCompletionSuggestions(this.parse, i); 64 | this.pendingSuggestions.thenRun(() -> { 65 | if (this.pendingSuggestions.isDone()) { 66 | this.show(); 67 | } 68 | }); 69 | } 70 | 71 | ci.cancel(); 72 | } 73 | } 74 | 75 | } 76 | -------------------------------------------------------------------------------- /src/main/java/me/zeroeightsix/kami/mixin/client/MixinConfigType.java: -------------------------------------------------------------------------------- 1 | package me.zeroeightsix.kami.mixin.client; 2 | 3 | import io.github.fablabsmc.fablabs.api.fiber.v1.schema.type.derived.ConfigType; 4 | import me.zeroeightsix.kami.mixin.duck.HasSettingInterface; 5 | import me.zeroeightsix.kami.setting.SettingInterface; 6 | import org.spongepowered.asm.mixin.Mixin; 7 | 8 | @Mixin(value = ConfigType.class, remap = false) 9 | public class MixinConfigType implements HasSettingInterface { 10 | SettingInterface settingInterface; 11 | 12 | @Override 13 | public SettingInterface getSettingInterface() { 14 | return settingInterface; 15 | } 16 | 17 | @Override 18 | public void setSettingInterface(SettingInterface settingInterface) { 19 | this.settingInterface = settingInterface; 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /src/main/java/me/zeroeightsix/kami/mixin/client/MixinDecoderHandler.java: -------------------------------------------------------------------------------- 1 | package me.zeroeightsix.kami.mixin.client; 2 | 3 | import me.zeroeightsix.kami.KamiMod; 4 | import me.zeroeightsix.kami.event.PacketEvent; 5 | import net.minecraft.network.DecoderHandler; 6 | import net.minecraft.network.Packet; 7 | import net.minecraft.network.PacketByteBuf; 8 | import org.spongepowered.asm.mixin.Mixin; 9 | import org.spongepowered.asm.mixin.injection.At; 10 | import org.spongepowered.asm.mixin.injection.Redirect; 11 | 12 | import java.io.IOException; 13 | 14 | @Mixin(DecoderHandler.class) 15 | public class MixinDecoderHandler { 16 | 17 | @Redirect(method = "decode", at = @At(value = "INVOKE", target = "Lnet/minecraft/network/Packet;read(Lnet/minecraft/network/PacketByteBuf;)V")) 18 | void read(Packet packet, PacketByteBuf buf) throws IOException { 19 | packet.read(buf); 20 | PacketEvent.Receive receive = new PacketEvent.Receive(packet); 21 | KamiMod.EVENT_BUS.post(receive); 22 | } 23 | 24 | } 25 | -------------------------------------------------------------------------------- /src/main/java/me/zeroeightsix/kami/mixin/client/MixinEntityRenderer.java: -------------------------------------------------------------------------------- 1 | package me.zeroeightsix.kami.mixin.client; 2 | 3 | import me.zeroeightsix.kami.feature.module.Nametags; 4 | import net.minecraft.client.render.VertexConsumerProvider; 5 | import net.minecraft.client.render.entity.EntityRenderer; 6 | import net.minecraft.client.util.math.MatrixStack; 7 | import net.minecraft.entity.Entity; 8 | import net.minecraft.text.Text; 9 | import org.spongepowered.asm.mixin.Mixin; 10 | import org.spongepowered.asm.mixin.injection.At; 11 | import org.spongepowered.asm.mixin.injection.Inject; 12 | import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; 13 | 14 | @Mixin(EntityRenderer.class) 15 | public class MixinEntityRenderer { 16 | 17 | @Inject(method = "renderLabelIfPresent", at = @At("HEAD"), cancellable = true) 18 | public void onRenderLabelIfPresent(T entity, Text text, MatrixStack matrices, VertexConsumerProvider vertexConsumers, int light, CallbackInfo ci) { 19 | if (Nametags.INSTANCE.getEnabled() && Nametags.INSTANCE.getTargets().get(entity) != null) 20 | ci.cancel(); 21 | } 22 | 23 | } 24 | -------------------------------------------------------------------------------- /src/main/java/me/zeroeightsix/kami/mixin/client/MixinHandledScreen.java: -------------------------------------------------------------------------------- 1 | package me.zeroeightsix.kami.mixin.client; 2 | 3 | import me.zeroeightsix.kami.Colour; 4 | import me.zeroeightsix.kami.feature.module.ItemHighlight; 5 | import net.minecraft.client.gui.DrawableHelper; 6 | import net.minecraft.client.gui.screen.ingame.HandledScreen; 7 | import net.minecraft.client.util.math.MatrixStack; 8 | import net.minecraft.screen.slot.Slot; 9 | import org.spongepowered.asm.mixin.Mixin; 10 | import org.spongepowered.asm.mixin.injection.At; 11 | import org.spongepowered.asm.mixin.injection.Inject; 12 | import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; 13 | 14 | @Mixin(HandledScreen.class) 15 | public abstract class MixinHandledScreen extends DrawableHelper { 16 | @Inject(method = "drawSlot", at = @At("HEAD")) 17 | private void onDrawSlot(MatrixStack matrices, Slot slot, CallbackInfo info) { 18 | if (ItemHighlight.INSTANCE.getEnabled()) { 19 | Colour c = ItemHighlight.INSTANCE.getHighlightedItems().get(slot.getStack().getItem()); 20 | if (c != null) { 21 | fill(matrices, slot.x, slot.y, slot.x + 16, slot.y + 16, c.asARGB()); 22 | } 23 | } 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /src/main/java/me/zeroeightsix/kami/mixin/client/MixinHorseBaseEntity.java: -------------------------------------------------------------------------------- 1 | package me.zeroeightsix.kami.mixin.client; 2 | 3 | import me.zeroeightsix.kami.KamiMod; 4 | import me.zeroeightsix.kami.event.CanBeControlledEvent; 5 | import net.minecraft.entity.mob.MobEntity; 6 | import net.minecraft.entity.passive.HorseBaseEntity; 7 | import org.spongepowered.asm.mixin.Mixin; 8 | import org.spongepowered.asm.mixin.injection.At; 9 | import org.spongepowered.asm.mixin.injection.Inject; 10 | import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; 11 | 12 | @Mixin(HorseBaseEntity.class) 13 | public class MixinHorseBaseEntity { 14 | 15 | @Inject(method = "canBeControlledByRider", at = @At("TAIL"), cancellable = true) 16 | public void onCanBeControlledByRider(CallbackInfoReturnable cir) { 17 | CanBeControlledEvent event = new CanBeControlledEvent((MobEntity) (Object) this, null); 18 | KamiMod.EVENT_BUS.post(event); 19 | Boolean b = event.getCanBeSteered(); 20 | if (!event.isCancelled() && b != null) { 21 | cir.setReturnValue(b); 22 | } 23 | } 24 | 25 | } 26 | -------------------------------------------------------------------------------- /src/main/java/me/zeroeightsix/kami/mixin/client/MixinInGameHud.java: -------------------------------------------------------------------------------- 1 | package me.zeroeightsix.kami.mixin.client; 2 | 3 | import com.mojang.blaze3d.systems.RenderSystem; 4 | import me.zeroeightsix.kami.KamiMod; 5 | import me.zeroeightsix.kami.event.RenderGuiEvent; 6 | import net.minecraft.client.MinecraftClient; 7 | import net.minecraft.client.gui.hud.InGameHud; 8 | import net.minecraft.client.util.math.MatrixStack; 9 | import org.spongepowered.asm.mixin.Final; 10 | import org.spongepowered.asm.mixin.Mixin; 11 | import org.spongepowered.asm.mixin.Shadow; 12 | import org.spongepowered.asm.mixin.injection.At; 13 | import org.spongepowered.asm.mixin.injection.Inject; 14 | import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; 15 | 16 | @Mixin(InGameHud.class) 17 | public class MixinInGameHud { 18 | 19 | @Shadow 20 | @Final 21 | private MinecraftClient client; 22 | 23 | // This inject targets a point after vignette is rendered, but before any other GUI element. 24 | @Inject(method = "render", at = @At(value = "INVOKE", target = "Lnet/minecraft/entity/player/PlayerInventory;getArmorStack(I)Lnet/minecraft/item/ItemStack;")) 25 | public void onGetArmorStack(MatrixStack matrices, float tickDelta, CallbackInfo ci) { 26 | RenderGuiEvent event = new RenderGuiEvent(MinecraftClient.getInstance().getWindow(), matrices); 27 | client.getProfiler().push("kamiGuiRender"); 28 | KamiMod.EVENT_BUS.post(event); 29 | client.getProfiler().pop(); 30 | if (event.isCancelled()) { 31 | ci.cancel(); 32 | } else { 33 | // Listeners for RenderGuiEvent draw text.https://i.redd.it/ofdlip89ixh51.jpg 34 | // It looks like drawing text disables blend sometimes, 35 | // making the hotbar (first thing rendered after this), look opaque. 36 | // We make sure it's enabled back here. 37 | RenderSystem.enableBlend(); 38 | } 39 | } 40 | 41 | } 42 | -------------------------------------------------------------------------------- /src/main/java/me/zeroeightsix/kami/mixin/client/MixinInGameOverlayRenderer.java: -------------------------------------------------------------------------------- 1 | package me.zeroeightsix.kami.mixin.client; 2 | 3 | import me.zeroeightsix.kami.feature.module.NoRender; 4 | import net.minecraft.client.gui.hud.InGameOverlayRenderer; 5 | import org.spongepowered.asm.mixin.Mixin; 6 | import org.spongepowered.asm.mixin.injection.At; 7 | import org.spongepowered.asm.mixin.injection.Inject; 8 | import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; 9 | 10 | @Mixin(InGameOverlayRenderer.class) 11 | public class MixinInGameOverlayRenderer { 12 | @Inject(method = "renderFireOverlay", at = @At("HEAD"), cancellable = true) 13 | private static void renderFireOverlay(CallbackInfo ci) { 14 | if (NoRender.INSTANCE.getEnabled() && NoRender.INSTANCE.getFire()) { 15 | ci.cancel(); 16 | } 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /src/main/java/me/zeroeightsix/kami/mixin/client/MixinInput.java: -------------------------------------------------------------------------------- 1 | package me.zeroeightsix.kami.mixin.client; 2 | 3 | import me.zeroeightsix.kami.mixin.extend.ExtendedInput; 4 | import net.minecraft.client.input.Input; 5 | import org.spongepowered.asm.mixin.Mixin; 6 | import org.spongepowered.asm.mixin.Shadow; 7 | 8 | @Mixin(Input.class) 9 | public class MixinInput implements ExtendedInput { 10 | 11 | @Shadow 12 | public float movementSideways; 13 | @Shadow 14 | public float movementForward; 15 | @Shadow 16 | public boolean pressingForward; 17 | @Shadow 18 | public boolean pressingBack; 19 | @Shadow 20 | public boolean pressingLeft; 21 | @Shadow 22 | public boolean pressingRight; 23 | @Shadow 24 | public boolean jumping; 25 | @Shadow 26 | public boolean sneaking; 27 | 28 | @Override 29 | public Input copy() { 30 | Input copy = new Input(); 31 | ((ExtendedInput) copy).update(movementSideways, movementForward, pressingForward, pressingBack, pressingLeft, pressingRight, jumping, sneaking); 32 | return copy; 33 | } 34 | 35 | @Override 36 | public void update(Input from) { 37 | this.update(from.movementSideways, from.movementForward, from.pressingForward, from.pressingBack, from.pressingLeft, from.pressingRight, from.jumping, from.sneaking); 38 | } 39 | 40 | @Override 41 | public void update(float movementSideways, float movementForward, boolean pressingForward, boolean pressingBack, boolean pressingLeft, boolean pressingRight, boolean jumping, boolean sneaking) { 42 | this.movementForward = movementForward; 43 | this.movementSideways = movementSideways; 44 | this.pressingForward = pressingForward; 45 | this.pressingBack = pressingBack; 46 | this.pressingLeft = pressingLeft; 47 | this.pressingRight = pressingRight; 48 | this.jumping = jumping; 49 | this.sneaking = sneaking; 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /src/main/java/me/zeroeightsix/kami/mixin/client/MixinKeyboard.java: -------------------------------------------------------------------------------- 1 | package me.zeroeightsix.kami.mixin.client; 2 | 3 | import me.zeroeightsix.kami.KamiMod; 4 | import me.zeroeightsix.kami.event.BindEvent; 5 | import me.zeroeightsix.kami.event.CharTypedEvent; 6 | import net.minecraft.client.Keyboard; 7 | import org.spongepowered.asm.mixin.Mixin; 8 | import org.spongepowered.asm.mixin.injection.At; 9 | import org.spongepowered.asm.mixin.injection.Inject; 10 | import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; 11 | 12 | @Mixin(Keyboard.class) 13 | public class MixinKeyboard { 14 | 15 | @Inject(method = "onKey", at = @At(value = "RETURN", ordinal = 4), require = 1, cancellable = true) 16 | public void onKey(long window, int key, int scancode, int i, int j, CallbackInfo info) { 17 | BindEvent event = new BindEvent(key, scancode, i); 18 | KamiMod.EVENT_BUS.post(event); 19 | if (event.isCancelled()) { 20 | info.cancel(); 21 | } 22 | } 23 | 24 | @Inject(method = "onChar", at = @At(value = "FIELD", target = "Lnet/minecraft/client/MinecraftClient;currentScreen:Lnet/minecraft/client/gui/screen/Screen;"), cancellable = true) 25 | public void onOneChar(long window, int i, int j, CallbackInfo ci) { 26 | boolean consumed = false; 27 | if (Character.charCount(i) == 1) 28 | consumed = publishCharEvent((char) i); 29 | else { 30 | for (char c : Character.toChars(i)) { 31 | consumed = consumed || publishCharEvent(c); 32 | } 33 | } 34 | 35 | if (consumed) 36 | ci.cancel(); 37 | } 38 | 39 | private static boolean publishCharEvent(char c) { 40 | CharTypedEvent event = new CharTypedEvent(c); 41 | KamiMod.EVENT_BUS.post(event); 42 | return event.isCancelled(); 43 | } 44 | 45 | } 46 | -------------------------------------------------------------------------------- /src/main/java/me/zeroeightsix/kami/mixin/client/MixinLightmapTextureManager.java: -------------------------------------------------------------------------------- 1 | package me.zeroeightsix.kami.mixin.client; 2 | 3 | import me.zeroeightsix.kami.feature.module.Brightness; 4 | import net.minecraft.client.network.ClientPlayerEntity; 5 | import net.minecraft.client.render.GameRenderer; 6 | import net.minecraft.client.render.LightmapTextureManager; 7 | import net.minecraft.entity.LivingEntity; 8 | import net.minecraft.entity.effect.StatusEffect; 9 | import org.spongepowered.asm.mixin.Mixin; 10 | import org.spongepowered.asm.mixin.injection.At; 11 | import org.spongepowered.asm.mixin.injection.Redirect; 12 | 13 | @Mixin(LightmapTextureManager.class) 14 | public class MixinLightmapTextureManager { 15 | 16 | private boolean nightVision; 17 | 18 | @Redirect(method = "update", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/render/GameRenderer;getNightVisionStrength(Lnet/minecraft/entity/LivingEntity;F)F")) 19 | public float getNightVisionStrength(LivingEntity entity, float tickDelta) { 20 | return nightVision ? Brightness.getCurrentBrightness() : GameRenderer.getNightVisionStrength(entity, tickDelta); 21 | } 22 | 23 | @Redirect(method = "update", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/network/ClientPlayerEntity;hasStatusEffect(Lnet/minecraft/entity/effect/StatusEffect;)Z", ordinal = 0)) 24 | public boolean hasStatusEffect(ClientPlayerEntity entity, StatusEffect statusEffect) { 25 | return (nightVision = Brightness.shouldBeActive()) || entity.hasStatusEffect(statusEffect); 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /src/main/java/me/zeroeightsix/kami/mixin/client/MixinLivingEntityRenderer.java: -------------------------------------------------------------------------------- 1 | package me.zeroeightsix.kami.mixin.client; 2 | 3 | import me.zeroeightsix.kami.feature.module.Chams; 4 | import net.minecraft.client.render.RenderLayer; 5 | import net.minecraft.client.render.VertexConsumerProvider; 6 | import net.minecraft.client.render.entity.EntityRenderDispatcher; 7 | import net.minecraft.client.render.entity.EntityRenderer; 8 | import net.minecraft.client.render.entity.LivingEntityRenderer; 9 | import net.minecraft.client.util.math.MatrixStack; 10 | import net.minecraft.entity.LivingEntity; 11 | import org.lwjgl.opengl.GL11; 12 | import org.spongepowered.asm.mixin.Mixin; 13 | import org.spongepowered.asm.mixin.Shadow; 14 | import org.spongepowered.asm.mixin.injection.At; 15 | import org.spongepowered.asm.mixin.injection.Inject; 16 | import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; 17 | 18 | @Mixin(LivingEntityRenderer.class) 19 | public abstract class MixinLivingEntityRenderer extends EntityRenderer { 20 | 21 | protected MixinLivingEntityRenderer(EntityRenderDispatcher dispatcher) { 22 | super(dispatcher); 23 | } 24 | 25 | @Shadow 26 | protected abstract RenderLayer getRenderLayer(T entity, boolean showBody, boolean translucent, boolean showOutline); 27 | 28 | @Inject(method = "render", at = @At("HEAD")) 29 | private void injectChamsPre(T livingEntity, float f, float g, MatrixStack matrixStack, VertexConsumerProvider vertexConsumerProvider, int i, CallbackInfo ci) { 30 | if (Chams.INSTANCE.getEnabled() && Chams.INSTANCE.renderChams(livingEntity)) { 31 | GL11.glEnable(32823); 32 | GL11.glPolygonOffset(1.0f, -1000000.0f); 33 | } 34 | } 35 | 36 | @Inject(method = "render", at = @At("RETURN")) 37 | private void injectChamsPost(T livingEntity, float f, float g, MatrixStack matrixStack, VertexConsumerProvider vertexConsumerProvider, int i, CallbackInfo ci) { 38 | if (Chams.INSTANCE.getEnabled() && Chams.INSTANCE.renderChams(livingEntity)) { 39 | GL11.glPolygonOffset(1.0f, 1000000.0f); 40 | GL11.glDisable(32823); 41 | } 42 | } 43 | 44 | } 45 | -------------------------------------------------------------------------------- /src/main/java/me/zeroeightsix/kami/mixin/client/MixinMouse.java: -------------------------------------------------------------------------------- 1 | package me.zeroeightsix.kami.mixin.client; 2 | 3 | import me.zeroeightsix.kami.gui.KamiHud; 4 | import me.zeroeightsix.kami.gui.KamiImgui; 5 | import me.zeroeightsix.kami.util.Wrapper; 6 | import net.minecraft.client.Mouse; 7 | import org.spongepowered.asm.mixin.Mixin; 8 | import org.spongepowered.asm.mixin.injection.At; 9 | import org.spongepowered.asm.mixin.injection.Inject; 10 | import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; 11 | 12 | @Mixin(Mouse.class) 13 | public class MixinMouse { 14 | 15 | @Inject(method = "onMouseScroll", at = @At("HEAD")) 16 | private void onMouseScroll(long window, double d, double e, CallbackInfo info) { 17 | if (window == Wrapper.getMinecraft().getWindow().getHandle()) { 18 | KamiImgui.INSTANCE.mouseScroll(d, e); 19 | } 20 | } 21 | 22 | } 23 | -------------------------------------------------------------------------------- /src/main/java/me/zeroeightsix/kami/mixin/client/MixinNetHandlerPlayClient.java: -------------------------------------------------------------------------------- 1 | package me.zeroeightsix.kami.mixin.client; 2 | 3 | import me.zeroeightsix.kami.KamiMod; 4 | import me.zeroeightsix.kami.event.ChunkEvent; 5 | import net.minecraft.client.network.ClientPlayNetworkHandler; 6 | import net.minecraft.network.packet.s2c.play.ChunkDataS2CPacket; 7 | import net.minecraft.world.biome.source.BiomeArray; 8 | import net.minecraft.world.chunk.WorldChunk; 9 | import org.spongepowered.asm.mixin.Mixin; 10 | import org.spongepowered.asm.mixin.injection.At; 11 | import org.spongepowered.asm.mixin.injection.Inject; 12 | import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; 13 | import org.spongepowered.asm.mixin.injection.callback.LocalCapture; 14 | 15 | @Mixin(ClientPlayNetworkHandler.class) 16 | public class MixinNetHandlerPlayClient { 17 | 18 | @Inject(method = "onChunkData", 19 | at = @At(value = "INVOKE_ASSIGN", target = "Lnet/minecraft/client/world/ClientChunkManager;loadChunkFromPacket(IILnet/minecraft/world/biome/source/BiomeArray;Lnet/minecraft/network/PacketByteBuf;Lnet/minecraft/nbt/CompoundTag;IZ)Lnet/minecraft/world/chunk/WorldChunk;"), 20 | locals = LocalCapture.CAPTURE_FAILHARD) 21 | private void read(ChunkDataS2CPacket packet, CallbackInfo ci, int i, int j, BiomeArray biomeArray, WorldChunk worldChunk) { 22 | KamiMod.EVENT_BUS.post(new ChunkEvent.Load(worldChunk, packet)); 23 | } 24 | 25 | } 26 | -------------------------------------------------------------------------------- /src/main/java/me/zeroeightsix/kami/mixin/client/MixinPigEntity.java: -------------------------------------------------------------------------------- 1 | package me.zeroeightsix.kami.mixin.client; 2 | 3 | import me.zeroeightsix.kami.KamiMod; 4 | import me.zeroeightsix.kami.event.CanBeControlledEvent; 5 | import net.minecraft.entity.mob.MobEntity; 6 | import net.minecraft.entity.passive.PigEntity; 7 | import org.spongepowered.asm.mixin.Mixin; 8 | import org.spongepowered.asm.mixin.injection.At; 9 | import org.spongepowered.asm.mixin.injection.Inject; 10 | import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; 11 | 12 | @Mixin(PigEntity.class) 13 | public class MixinPigEntity { 14 | 15 | @Inject(method = "canBeControlledByRider", at = @At("TAIL"), cancellable = true) 16 | public void onCanBeControlledByRider(CallbackInfoReturnable cir) { 17 | CanBeControlledEvent event = new CanBeControlledEvent((MobEntity) (Object) this, null); 18 | KamiMod.EVENT_BUS.post(event); 19 | Boolean b = event.getCanBeSteered(); 20 | if (!event.isCancelled() && b != null) { 21 | cir.setReturnValue(b); 22 | } 23 | } 24 | 25 | } 26 | -------------------------------------------------------------------------------- /src/main/java/me/zeroeightsix/kami/mixin/client/MixinPlayerEntity.java: -------------------------------------------------------------------------------- 1 | package me.zeroeightsix.kami.mixin.client; 2 | 3 | import me.zeroeightsix.kami.KamiMod; 4 | import me.zeroeightsix.kami.event.ClipAtLedgeEvent; 5 | import me.zeroeightsix.kami.event.EntityEvent; 6 | import me.zeroeightsix.kami.event.PlayerAttackEntityEvent; 7 | import net.minecraft.entity.Entity; 8 | import net.minecraft.entity.player.PlayerEntity; 9 | import org.spongepowered.asm.mixin.Mixin; 10 | import org.spongepowered.asm.mixin.injection.At; 11 | import org.spongepowered.asm.mixin.injection.Inject; 12 | import org.spongepowered.asm.mixin.injection.ModifyVariable; 13 | import org.spongepowered.asm.mixin.injection.Slice; 14 | import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; 15 | import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; 16 | 17 | @Mixin(PlayerEntity.class) 18 | public class MixinPlayerEntity { 19 | 20 | @Inject(method = "attack", at = @At("HEAD"), cancellable = true) 21 | public void attack(Entity entity, CallbackInfo info) { 22 | PlayerAttackEntityEvent event = new PlayerAttackEntityEvent(entity); 23 | KamiMod.EVENT_BUS.post(event); 24 | if (info.isCancelled()) { 25 | info.cancel(); 26 | } 27 | } 28 | 29 | @Inject(method = "clipAtLedge", at = @At("HEAD"), cancellable = true) 30 | public void onClipAtLedge(CallbackInfoReturnable cir) { 31 | ClipAtLedgeEvent event = new ClipAtLedgeEvent((PlayerEntity) (Object) this, null); 32 | KamiMod.EVENT_BUS.post(event); 33 | if (event.getClip() != null) cir.setReturnValue(event.getClip()); 34 | } 35 | 36 | } 37 | -------------------------------------------------------------------------------- /src/main/java/me/zeroeightsix/kami/mixin/client/MixinPlayerListHud.java: -------------------------------------------------------------------------------- 1 | package me.zeroeightsix.kami.mixin.client; 2 | 3 | import me.zeroeightsix.kami.feature.module.ExtraTab; 4 | import net.minecraft.client.gui.hud.PlayerListHud; 5 | import net.minecraft.client.network.PlayerListEntry; 6 | import net.minecraft.text.Text; 7 | import org.spongepowered.asm.mixin.Mixin; 8 | import org.spongepowered.asm.mixin.injection.At; 9 | import org.spongepowered.asm.mixin.injection.Inject; 10 | import org.spongepowered.asm.mixin.injection.Redirect; 11 | import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; 12 | 13 | import java.util.List; 14 | 15 | @Mixin(PlayerListHud.class) 16 | public class MixinPlayerListHud { 17 | 18 | @Redirect(method = "render", at = @At(value = "INVOKE", target = "Ljava/util/List;subList(II)Ljava/util/List;")) 19 | public List subList(List list, int fromIndex, int toIndex) { 20 | return list.subList(fromIndex, ExtraTab.INSTANCE.getEnabled() ? Math.min(ExtraTab.tabSize, list.size()) : toIndex); 21 | } 22 | 23 | @Inject(method = "getPlayerName", at = @At("HEAD"), cancellable = true) 24 | public void getPlayerName(PlayerListEntry networkPlayerInfoIn, CallbackInfoReturnable returnable) { 25 | if (ExtraTab.INSTANCE.getEnabled()) { 26 | returnable.cancel(); 27 | returnable.setReturnValue(ExtraTab.getPlayerName(networkPlayerInfoIn)); 28 | } 29 | } 30 | 31 | } 32 | -------------------------------------------------------------------------------- /src/main/java/me/zeroeightsix/kami/mixin/client/MixinRenderPlayer.java: -------------------------------------------------------------------------------- 1 | package me.zeroeightsix.kami.mixin.client; 2 | 3 | import me.zeroeightsix.kami.KamiMod; 4 | import me.zeroeightsix.kami.event.RenderPlayerNametagEvent; 5 | import net.minecraft.client.network.AbstractClientPlayerEntity; 6 | import net.minecraft.client.render.VertexConsumerProvider; 7 | import net.minecraft.client.render.entity.PlayerEntityRenderer; 8 | import net.minecraft.client.util.math.MatrixStack; 9 | import net.minecraft.text.Text; 10 | import org.spongepowered.asm.mixin.Mixin; 11 | import org.spongepowered.asm.mixin.injection.At; 12 | import org.spongepowered.asm.mixin.injection.Inject; 13 | import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; 14 | 15 | @Mixin(PlayerEntityRenderer.class) 16 | public class MixinRenderPlayer { 17 | 18 | @Inject(method = "renderLabelIfPresent", at = @At("HEAD"), cancellable = true) 19 | public void renderLivingLabel(AbstractClientPlayerEntity entityIn, Text text, MatrixStack matrixStack, VertexConsumerProvider vertexConsumerProvider, int i, CallbackInfo ci) { 20 | RenderPlayerNametagEvent event = new RenderPlayerNametagEvent(entityIn); 21 | KamiMod.EVENT_BUS.post(event); 22 | if (event.isCancelled()) { 23 | ci.cancel(); 24 | } 25 | } 26 | 27 | } 28 | -------------------------------------------------------------------------------- /src/main/java/me/zeroeightsix/kami/mixin/client/MixinRenderTickCounter.java: -------------------------------------------------------------------------------- 1 | package me.zeroeightsix.kami.mixin.client; 2 | 3 | import me.zeroeightsix.kami.feature.module.Timer; 4 | import net.minecraft.client.render.RenderTickCounter; 5 | import org.spongepowered.asm.mixin.Mixin; 6 | import org.spongepowered.asm.mixin.Shadow; 7 | import org.spongepowered.asm.mixin.injection.At; 8 | import org.spongepowered.asm.mixin.injection.Inject; 9 | import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; 10 | 11 | @Mixin(RenderTickCounter.class) 12 | public class MixinRenderTickCounter { 13 | 14 | @Shadow 15 | public float lastFrameDuration; 16 | 17 | @Inject(method = "beginRenderTick", at = @At(value = "FIELD", target = "Lnet/minecraft/client/render/RenderTickCounter;lastFrameDuration:F")) 18 | public void onBeginRenderTick(long timeMillis, CallbackInfoReturnable cir) { 19 | lastFrameDuration *= Timer.INSTANCE.getSpeedModifier(); 20 | } 21 | 22 | } 23 | -------------------------------------------------------------------------------- /src/main/java/me/zeroeightsix/kami/mixin/client/MixinStateImplementation.java: -------------------------------------------------------------------------------- 1 | package me.zeroeightsix.kami.mixin.client; 2 | 3 | //@Mixin(BlockStateContainer.StateImplementation.class) 4 | public class MixinStateImplementation { 5 | 6 | /*@Shadow @Final private Block block; 7 | 8 | @Redirect(method = "addCollisionBoxToList", at = @At(value="INVOKE", target = "Lnet/minecraft/block/Block;addCollisionBoxToList(Lnet/minecraft/block/state/IBlockState;Lnet/minecraft/world/World;Lnet/minecraft/util/math/BlockPos;Lnet/minecraft/util/math/AxisAlignedBB;Ljava/util/List;Lnet/minecraft/entity/Entity;Z)V")) 9 | public void addCollisionBoxToList(Block b, IBlockState state, World worldIn, BlockPos pos, AxisAlignedBB entityBox, List collidingBoxes, @Nullable Entity entityIn, boolean isActualState) { 10 | AddCollisionBoxToListEvent event = new AddCollisionBoxToListEvent(b, state, worldIn, pos, entityBox, collidingBoxes, entityIn, isActualState); 11 | KamiMod.EVENT_BUS.post(event); 12 | if (!event.isCancelled()) 13 | block.addCollisionBoxToList(state, worldIn, pos, entityBox, collidingBoxes, entityIn, isActualState); 14 | }*/ //TODO 15 | 16 | } 17 | -------------------------------------------------------------------------------- /src/main/java/me/zeroeightsix/kami/mixin/client/MixinStriderEntity.java: -------------------------------------------------------------------------------- 1 | package me.zeroeightsix.kami.mixin.client; 2 | 3 | import me.zeroeightsix.kami.KamiMod; 4 | import me.zeroeightsix.kami.event.CanBeControlledEvent; 5 | import net.minecraft.entity.mob.MobEntity; 6 | import net.minecraft.entity.passive.StriderEntity; 7 | import org.spongepowered.asm.mixin.Mixin; 8 | import org.spongepowered.asm.mixin.injection.At; 9 | import org.spongepowered.asm.mixin.injection.Inject; 10 | import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; 11 | 12 | @Mixin(StriderEntity.class) 13 | public class MixinStriderEntity { 14 | 15 | @Inject(method = "canBeControlledByRider", at = @At("TAIL"), cancellable = true) 16 | public void onCanBeControlledByRider(CallbackInfoReturnable cir) { 17 | CanBeControlledEvent event = new CanBeControlledEvent((MobEntity) (Object) this, null); 18 | KamiMod.EVENT_BUS.post(event); 19 | Boolean b = event.getCanBeSteered(); 20 | if (!event.isCancelled() && b != null) { 21 | cir.setReturnValue(b); 22 | } 23 | } 24 | 25 | } 26 | -------------------------------------------------------------------------------- /src/main/java/me/zeroeightsix/kami/mixin/duck/CanDisableCaching.java: -------------------------------------------------------------------------------- 1 | package me.zeroeightsix.kami.mixin.duck; 2 | 3 | public interface CanDisableCaching { 4 | 5 | boolean isCachingDisabled(); 6 | 7 | void setCachingDisabled(boolean disabled); 8 | 9 | } 10 | -------------------------------------------------------------------------------- /src/main/java/me/zeroeightsix/kami/mixin/duck/HasSettingInterface.java: -------------------------------------------------------------------------------- 1 | package me.zeroeightsix.kami.mixin.duck; 2 | 3 | import me.zeroeightsix.kami.setting.SettingInterface; 4 | 5 | public interface HasSettingInterface { 6 | 7 | SettingInterface getSettingInterface(); 8 | 9 | void setSettingInterface(SettingInterface settingInterface); 10 | 11 | } 12 | -------------------------------------------------------------------------------- /src/main/java/me/zeroeightsix/kami/mixin/duck/HotSwappable.java: -------------------------------------------------------------------------------- 1 | package me.zeroeightsix.kami.mixin.duck; 2 | 3 | /** 4 | * Indicates that the class can swap something for the duration of a function passed to it. 5 | *

6 | * What is being swapped depends on the implementation. 7 | */ 8 | public interface HotSwappable { 9 | 10 | void swapWhile(Runnable runnable); 11 | 12 | } 13 | -------------------------------------------------------------------------------- /src/main/java/me/zeroeightsix/kami/mixin/extend/ExtendedInput.java: -------------------------------------------------------------------------------- 1 | package me.zeroeightsix.kami.mixin.extend; 2 | 3 | import net.minecraft.client.input.Input; 4 | 5 | public interface ExtendedInput { 6 | 7 | Input copy(); 8 | void update(Input from); 9 | void update(float movementSideways, float movementForward, boolean pressingForward, boolean pressingBack, boolean pressingLeft, boolean pressingRight, boolean jumping, boolean sneaking); 10 | 11 | } 12 | -------------------------------------------------------------------------------- /src/main/java/me/zeroeightsix/kami/util/GeometryMasks.java: -------------------------------------------------------------------------------- 1 | package me.zeroeightsix.kami.util; 2 | 3 | import net.minecraft.util.math.Direction; 4 | 5 | import java.util.HashMap; 6 | 7 | public final class GeometryMasks { 8 | 9 | public static final HashMap FACEMAP = new HashMap<>(); 10 | static { 11 | FACEMAP.put(Direction.DOWN, Quad.DOWN); 12 | FACEMAP.put(Direction.WEST, Quad.WEST); 13 | FACEMAP.put(Direction.NORTH, Quad.NORTH); 14 | FACEMAP.put(Direction.SOUTH, Quad.SOUTH); 15 | FACEMAP.put(Direction.EAST, Quad.EAST); 16 | FACEMAP.put(Direction.UP, Quad.UP); 17 | } 18 | 19 | public static final class Quad { 20 | public static final int DOWN = 0x01; 21 | public static final int UP = 0x02; 22 | public static final int NORTH = 0x04; 23 | public static final int SOUTH = 0x08; 24 | public static final int WEST = 0x10; 25 | public static final int EAST = 0x20; 26 | public static final int ALL = DOWN | UP | NORTH | SOUTH | WEST | EAST; 27 | } 28 | 29 | public static final class Line { 30 | public static final int DOWN_WEST = 0x11; 31 | public static final int UP_WEST = 0x12; 32 | public static final int DOWN_EAST = 0x21; 33 | public static final int UP_EAST = 0x22; 34 | public static final int DOWN_NORTH = 0x05; 35 | public static final int UP_NORTH = 0x06; 36 | public static final int DOWN_SOUTH = 0x09; 37 | public static final int UP_SOUTH = 0x0A; 38 | public static final int NORTH_WEST = 0x14; 39 | public static final int NORTH_EAST = 0x24; 40 | public static final int SOUTH_WEST = 0x18; 41 | public static final int SOUTH_EAST = 0x28; 42 | public static final int ALL = DOWN_WEST | UP_WEST | DOWN_EAST | UP_EAST | DOWN_NORTH | UP_NORTH | DOWN_SOUTH | UP_SOUTH | NORTH_WEST | NORTH_EAST | SOUTH_WEST | SOUTH_EAST; 43 | } 44 | } -------------------------------------------------------------------------------- /src/main/java/me/zeroeightsix/kami/util/ShulkerBoxCommon.java: -------------------------------------------------------------------------------- 1 | package me.zeroeightsix.kami.util; 2 | 3 | import net.minecraft.block.Block; 4 | import net.minecraft.block.Blocks; 5 | import net.minecraft.item.BlockItem; 6 | import net.minecraft.item.Item; 7 | 8 | import java.util.Arrays; 9 | import java.util.List; 10 | 11 | public class ShulkerBoxCommon { 12 | 13 | private static final List shulkerList = Arrays.asList( 14 | Blocks.SHULKER_BOX, 15 | Blocks.WHITE_SHULKER_BOX, 16 | Blocks.ORANGE_SHULKER_BOX, 17 | Blocks.MAGENTA_SHULKER_BOX, 18 | Blocks.LIGHT_BLUE_SHULKER_BOX, 19 | Blocks.YELLOW_SHULKER_BOX, 20 | Blocks.LIME_SHULKER_BOX, 21 | Blocks.PINK_SHULKER_BOX, 22 | Blocks.GRAY_SHULKER_BOX, 23 | Blocks.LIGHT_GRAY_SHULKER_BOX, 24 | Blocks.CYAN_SHULKER_BOX, 25 | Blocks.PURPLE_SHULKER_BOX, 26 | Blocks.BLUE_SHULKER_BOX, 27 | Blocks.BROWN_SHULKER_BOX, 28 | Blocks.GREEN_SHULKER_BOX, 29 | Blocks.RED_SHULKER_BOX, 30 | Blocks.BLACK_SHULKER_BOX 31 | ); 32 | 33 | public static boolean isShulkerBox(Item item) { 34 | return item instanceof BlockItem && isShulkerBox(((BlockItem) item).getBlock()); 35 | } 36 | 37 | public static boolean isShulkerBox(Block block) { 38 | return shulkerList.contains(block); 39 | } 40 | 41 | } 42 | -------------------------------------------------------------------------------- /src/main/java/me/zeroeightsix/kami/util/Texts.java: -------------------------------------------------------------------------------- 1 | package me.zeroeightsix.kami.util; 2 | 3 | import net.minecraft.text.LiteralText; 4 | import net.minecraft.text.MutableText; 5 | import net.minecraft.text.Text; 6 | import net.minecraft.util.Formatting; 7 | 8 | import java.util.Arrays; 9 | import java.util.Iterator; 10 | 11 | /** 12 | * A helper class for condensed, formatted literal {@link Text} creation. 13 | */ 14 | @Deprecated 15 | public class Texts { 16 | 17 | /** 18 | * Produces a {@link LiteralText} from the given string 19 | * @param string 20 | * @return 21 | */ 22 | public static LiteralText lit(String string) { 23 | return new LiteralText(string); 24 | } 25 | 26 | public static MutableText i(MutableText text) { 27 | return f(Formatting.ITALIC, text); 28 | } 29 | 30 | public static MutableText b(MutableText text) { 31 | return f(Formatting.BOLD, text); 32 | } 33 | 34 | public static MutableText obf(MutableText text) { 35 | return f(Formatting.OBFUSCATED, text); 36 | } 37 | 38 | public static MutableText strike(MutableText text) { 39 | return f(Formatting.STRIKETHROUGH, text); 40 | } 41 | 42 | public static MutableText r(MutableText text) { 43 | return f(Formatting.RESET, text); 44 | } 45 | 46 | /** 47 | * Produces a formatted version of the provided text 48 | * @param formatting 49 | * @param text 50 | * @return 51 | */ 52 | public static MutableText f(Formatting formatting, MutableText text) { 53 | return text.formatted(formatting); 54 | } 55 | 56 | /** 57 | * Produces a formatted, literal text 58 | * @param formatting the formatting to use 59 | * @param string the string to use 60 | * @return the created text 61 | */ 62 | public static MutableText flit(Formatting formatting, String string) { 63 | return f(formatting, lit(string)); 64 | } 65 | 66 | public static MutableText append(MutableText... texts) { 67 | Iterator iterator = Arrays.stream(texts).iterator(); 68 | MutableText text = iterator.next(); 69 | while (iterator.hasNext()) { 70 | //Text no longer has an append function 71 | text = text.append(iterator.next()); 72 | } 73 | return text; 74 | } 75 | 76 | } 77 | -------------------------------------------------------------------------------- /src/main/java/me/zeroeightsix/kami/util/Wrapper.java: -------------------------------------------------------------------------------- 1 | package me.zeroeightsix.kami.util; 2 | 3 | import net.minecraft.client.MinecraftClient; 4 | import net.minecraft.client.network.ClientPlayerEntity; 5 | import net.minecraft.world.World; 6 | 7 | public class Wrapper { 8 | 9 | public static MinecraftClient getMinecraft() { 10 | return MinecraftClient.getInstance(); 11 | } 12 | public static ClientPlayerEntity getPlayer() { 13 | return getMinecraft().player; 14 | } 15 | public static World getWorld() { 16 | return getMinecraft().world; 17 | } 18 | 19 | } 20 | -------------------------------------------------------------------------------- /src/main/kotlin/me/zeroeightsix/kami/KamiMod.kt: -------------------------------------------------------------------------------- 1 | package me.zeroeightsix.kami 2 | 3 | import me.zero.alpine.bus.EventBus 4 | import me.zero.alpine.bus.EventManager 5 | import me.zeroeightsix.kami.feature.FeatureManager 6 | import me.zeroeightsix.kami.setting.KamiConfig 7 | import net.fabricmc.api.ModInitializer 8 | import org.apache.logging.log4j.LogManager 9 | 10 | // We use a class instead of an object so we don't need to use the kotlin language adapter just to initialise KAMI 11 | class KamiMod : ModInitializer { 12 | companion object { 13 | const val MODNAME = "KAMI" 14 | const val MODVER = "fabric-1.16.5-mar" 15 | const val KAMI_KANJI = "\u795E" 16 | 17 | @JvmStatic 18 | val log = LogManager.getLogger("KAMI") 19 | 20 | @JvmField 21 | val EVENT_BUS: EventBus = EventManager() 22 | var rainbow = Colour(1.0f, 1.0f, 1.0f, 1.0f) // This will be updated every tick 23 | } 24 | 25 | override fun onInitialize() { 26 | log.info("Initialising $MODNAME $MODVER") 27 | 28 | FeatureManager // Initialises FeatureManager, which finds & initialises ALL features 29 | KamiConfig // Initialises KamiConfig, which constructs & loads config 30 | 31 | log.info("$MODNAME initialised") 32 | } 33 | } -------------------------------------------------------------------------------- /src/main/kotlin/me/zeroeightsix/kami/KotlinTypeMagic.kt: -------------------------------------------------------------------------------- 1 | package me.zeroeightsix.kami 2 | 3 | import java.lang.reflect.AnnotatedArrayType 4 | import java.lang.reflect.AnnotatedParameterizedType 5 | import java.lang.reflect.AnnotatedType 6 | import java.lang.reflect.Field 7 | import kotlin.reflect.KMutableProperty 8 | 9 | object KotlinTypeMagic { 10 | @JvmStatic 11 | fun getKotlinAnnotatedType(pojo: Any, setting: Field): AnnotatedType { 12 | val annotations = ( 13 | pojo::class.members.find { 14 | it.name == setting.name && it is KMutableProperty 15 | } ?: return setting.annotatedType 16 | ).returnType.annotations.toMutableList() 17 | 18 | val type = setting.annotatedType 19 | annotations.addAll(type.annotations) 20 | 21 | val arrayOfAnnotations = annotations.toTypedArray() 22 | 23 | return when (type) { 24 | is AnnotatedArrayType -> { 25 | object : AnnotatedArrayType by type { 26 | override fun getAnnotations(): Array = arrayOfAnnotations 27 | } 28 | } 29 | is AnnotatedParameterizedType -> { 30 | object : AnnotatedParameterizedType by type { 31 | override fun getAnnotations(): Array = arrayOfAnnotations 32 | } 33 | } 34 | else -> { 35 | object : AnnotatedType by type { 36 | override fun getAnnotations(): Array = arrayOfAnnotations 37 | } 38 | } 39 | } 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /src/main/kotlin/me/zeroeightsix/kami/event/KamiEvent.kt: -------------------------------------------------------------------------------- 1 | package me.zeroeightsix.kami.event 2 | 3 | import me.zero.alpine.event.type.Cancellable 4 | import me.zeroeightsix.kami.util.Wrapper 5 | 6 | open class KamiEvent : Cancellable() { 7 | var era = Era.PRE 8 | protected set 9 | val partialTicks: Float = Wrapper.getMinecraft().tickDelta 10 | 11 | enum class Era { 12 | PRE, POST 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /src/main/kotlin/me/zeroeightsix/kami/feature/Feature.kt: -------------------------------------------------------------------------------- 1 | package me.zeroeightsix.kami.feature 2 | 3 | interface Feature { 4 | 5 | var name: String 6 | var hidden: Boolean 7 | 8 | /** 9 | * Called once when the module is initialised. 10 | * 11 | * Preferred over running code in the constructor (or kotlin `init`, which is the same) as it assures all fields are initialised by the JVM. 12 | */ 13 | fun init() {} 14 | } -------------------------------------------------------------------------------- /src/main/kotlin/me/zeroeightsix/kami/feature/FindFeature.kt: -------------------------------------------------------------------------------- 1 | package me.zeroeightsix.kami.feature 2 | 3 | @Target(AnnotationTarget.CLASS) 4 | @Retention(AnnotationRetention.RUNTIME) 5 | annotation class FindFeature( 6 | /** 7 | * Find *only* the subtypes of this class. The annotated class itself will not be registered as a feature. 8 | */ 9 | val findDescendants: Boolean = false 10 | ) -------------------------------------------------------------------------------- /src/main/kotlin/me/zeroeightsix/kami/feature/HasBind.kt: -------------------------------------------------------------------------------- 1 | package me.zeroeightsix.kami.feature 2 | 3 | import me.zeroeightsix.kami.util.Bind 4 | 5 | interface HasBind { 6 | 7 | var bind: Bind 8 | } 9 | -------------------------------------------------------------------------------- /src/main/kotlin/me/zeroeightsix/kami/feature/command/BindArgumentType.kt: -------------------------------------------------------------------------------- 1 | package me.zeroeightsix.kami.feature.command 2 | 3 | import com.mojang.brigadier.StringReader 4 | import com.mojang.brigadier.arguments.ArgumentType 5 | import com.mojang.brigadier.context.CommandContext 6 | import com.mojang.brigadier.suggestion.Suggestions 7 | import com.mojang.brigadier.suggestion.SuggestionsBuilder 8 | import me.zeroeightsix.kami.setting.KamiConfig 9 | import me.zeroeightsix.kami.setting.settingInterface 10 | import me.zeroeightsix.kami.util.Bind 11 | import java.util.concurrent.CompletableFuture 12 | 13 | class BindArgumentType private constructor() : ArgumentType { 14 | companion object { 15 | fun bind(): BindArgumentType = BindArgumentType() 16 | } 17 | 18 | override fun parse(reader: StringReader?): Bind? = 19 | KamiConfig.bindType.settingInterface?.valueFromString(reader!!.readUnquotedString()) 20 | 21 | override fun listSuggestions( 22 | context: CommandContext, 23 | builder: SuggestionsBuilder, 24 | ): CompletableFuture = 25 | KamiConfig.bindType.settingInterface?.listSuggestions(context, builder) ?: builder.buildFuture() 26 | } 27 | -------------------------------------------------------------------------------- /src/main/kotlin/me/zeroeightsix/kami/feature/command/BindCommand.kt: -------------------------------------------------------------------------------- 1 | package me.zeroeightsix.kami.feature.command 2 | 3 | import com.mojang.brigadier.CommandDispatcher 4 | import me.zeroeightsix.kami.feature.Feature 5 | import me.zeroeightsix.kami.feature.FullFeature 6 | import me.zeroeightsix.kami.feature.HasBind 7 | import me.zeroeightsix.kami.util.Bind 8 | import me.zeroeightsix.kami.util.text 9 | import net.minecraft.command.CommandSource 10 | import net.minecraft.util.Formatting.GOLD 11 | import net.minecraft.util.Formatting.LIGHT_PURPLE 12 | import net.minecraft.util.Formatting.YELLOW 13 | 14 | object BindCommand : Command() { 15 | override fun register(dispatcher: CommandDispatcher) { 16 | dispatcher register rootLiteral("bind") { 17 | argument("feature", FeatureArgumentType.boundFeature()) { 18 | argument("bind", BindArgumentType.bind()) { 19 | does { ctx -> 20 | val feature: HasBind = "feature" from ctx 21 | val bind: Bind = "bind" from ctx 22 | feature.bind = bind 23 | sendFeedback(ctx.source as KamiCommandSource, (feature as Feature).name, " bound to ", bind) 24 | 0 25 | } 26 | } 27 | does { 28 | val feature: FullFeature = "feature" from it 29 | val bind = feature.bind 30 | val featureName = feature.displayName 31 | sendFeedback(it.source as KamiCommandSource, featureName, " is bound to ", bind) 32 | 0 33 | } 34 | } 35 | } 36 | } 37 | 38 | private fun sendFeedback( 39 | source: KamiCommandSource, 40 | name: String, 41 | infix: String, 42 | bind: Bind 43 | ) { 44 | source replyWith text(GOLD) { 45 | +"Feature " 46 | +name(YELLOW) 47 | +infix 48 | +bind.toString()(LIGHT_PURPLE) 49 | +"!" 50 | } 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /src/main/kotlin/me/zeroeightsix/kami/feature/command/Command.kt: -------------------------------------------------------------------------------- 1 | package me.zeroeightsix.kami.feature.command 2 | 3 | import com.mojang.brigadier.CommandDispatcher 4 | import com.mojang.brigadier.context.CommandContext 5 | import me.zeroeightsix.kami.KamiMod 6 | import me.zeroeightsix.kami.feature.Feature 7 | import me.zeroeightsix.kami.feature.FindFeature 8 | import me.zeroeightsix.kami.mc 9 | import net.minecraft.command.CommandSource 10 | import net.minecraft.text.LiteralText 11 | import net.minecraft.text.MutableText 12 | import java.util.regex.Pattern 13 | 14 | @FindFeature(findDescendants = true) 15 | abstract class Command : Feature { 16 | 17 | override var hidden: Boolean = true 18 | override var name: String = javaClass.simpleName 19 | 20 | abstract fun register(dispatcher: CommandDispatcher) 21 | 22 | @Deprecated("") 23 | class ChatMessage(text: String?) : LiteralText(text) { 24 | var text: String 25 | override fun copy(): LiteralText? { 26 | return ChatMessage(text) 27 | } 28 | 29 | init { 30 | val p = Pattern.compile("&[0123456789abcdefrlonmk]") 31 | val m = p.matcher(text) 32 | val sb = StringBuffer() 33 | while (m.find()) { 34 | val replacement = "\u00A7" + m.group().substring(1) 35 | m.appendReplacement(sb, replacement) 36 | } 37 | m.appendTail(sb) 38 | this.text = sb.toString() 39 | } 40 | } 41 | 42 | protected infix fun CommandSource.replyWith(with: MutableText) = (this as? KamiCommandSource)?.sendFeedback(with) 43 | protected infix fun CommandContext.replyWith(with: MutableText) = this.source replyWith with 44 | 45 | companion object { 46 | @JvmField 47 | var dispatcher = CommandDispatcher() 48 | 49 | @JvmField 50 | var SECTION_SIGN = '\u00A7' 51 | 52 | @JvmStatic 53 | @Deprecated("") 54 | fun sendChatMessage(message: String) { 55 | sendRawChatMessage("&7[&a" + KamiMod.KAMI_KANJI + "&7] &r" + message) 56 | } 57 | 58 | @Deprecated("") 59 | fun sendRawChatMessage(message: String?) { 60 | mc.player?.sendMessage(ChatMessage(message), false) 61 | } 62 | } 63 | } 64 | -------------------------------------------------------------------------------- /src/main/kotlin/me/zeroeightsix/kami/feature/command/ConfigCommand.kt: -------------------------------------------------------------------------------- 1 | package me.zeroeightsix.kami.feature.command 2 | 3 | import com.mojang.brigadier.CommandDispatcher 4 | import com.mojang.brigadier.exceptions.DynamicCommandExceptionType 5 | import java.util.function.Function 6 | import me.zeroeightsix.kami.setting.KamiConfig 7 | import me.zeroeightsix.kami.util.text 8 | import net.minecraft.command.CommandSource 9 | import net.minecraft.text.LiteralText 10 | import net.minecraft.util.Formatting.GOLD 11 | import net.minecraft.util.Formatting.YELLOW 12 | 13 | object ConfigCommand : Command() { 14 | private val FAILED_EXCEPTION = 15 | DynamicCommandExceptionType( 16 | Function { o: Any -> 17 | LiteralText(o.toString()) 18 | } 19 | ) 20 | 21 | override fun register(dispatcher: CommandDispatcher) { 22 | dispatcher register rootLiteral("config") { 23 | literal("reload") { 24 | does { 25 | try { 26 | KamiConfig.loadAll() 27 | } catch (e: Exception) { 28 | throw FAILED_EXCEPTION.create(e.message) 29 | } 30 | it replyWith text(GOLD, "Reloaded configuration!") 31 | 0 32 | } 33 | } 34 | literal("save") { 35 | does { 36 | KamiConfig.saveAll() 37 | it replyWith text(GOLD, "Saved configuration!") 38 | 0 39 | } 40 | } 41 | literal("where") { 42 | does { 43 | it replyWith text { 44 | +"The configuration file is at "(GOLD) 45 | +KamiConfig.rootPath.toAbsolutePath().toString()(YELLOW) 46 | } 47 | 0 48 | } 49 | } 50 | } 51 | } 52 | } -------------------------------------------------------------------------------- /src/main/kotlin/me/zeroeightsix/kami/feature/command/DependantArgumentType.kt: -------------------------------------------------------------------------------- 1 | package me.zeroeightsix.kami.feature.command 2 | 3 | import com.mojang.brigadier.StringReader 4 | import com.mojang.brigadier.arguments.ArgumentType 5 | import com.mojang.brigadier.context.CommandContext 6 | import com.mojang.brigadier.exceptions.CommandSyntaxException 7 | 8 | abstract class DependantArgumentType( 9 | private val dependantType: ArgumentType, 10 | private val dependantArgument: String, 11 | private val shiftWords: Int 12 | ) : ArgumentType { 13 | @Throws(CommandSyntaxException::class) 14 | protected fun findDependencyValue(reader: StringReader?): D { 15 | val copy = StringReader(reader) 16 | rewind(copy, shiftWords) 17 | return dependantType.parse(copy) 18 | } 19 | 20 | protected fun findDependencyValue(context: CommandContext, clazz: Class): D { 21 | return context.getArgument(dependantArgument, clazz) 22 | } 23 | 24 | private fun rewind(reader: StringReader, words: Int, readQuotes: Boolean = true) { 25 | var words = words 26 | reader.cursor = 0.coerceAtLeast(reader.cursor - 1) 27 | while (words > 0) { 28 | reader.cursor = 0.coerceAtLeast(reader.cursor - 1) // Move to the end of the previous argument 29 | var quoted = reader.peek() == '"' 30 | // Move to the front of the previous argument 31 | while (reader.cursor > 0) { 32 | reader.cursor = reader.cursor - 1 33 | val prev = reader.peek() 34 | if (quoted && prev == '"' && reader.cursor > 0) { // Unescaped quote found 35 | reader.cursor-- 36 | if (reader.peek() != '\\') break 37 | } else if (!quoted && prev == ' ') break 38 | } 39 | words-- 40 | } 41 | reader.skip() // We just found a space; skip it. 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /src/main/kotlin/me/zeroeightsix/kami/feature/command/FeatureArgumentType.kt: -------------------------------------------------------------------------------- 1 | package me.zeroeightsix.kami.feature.command 2 | 3 | import com.mojang.brigadier.StringReader 4 | import com.mojang.brigadier.arguments.ArgumentType 5 | import com.mojang.brigadier.context.CommandContext 6 | import com.mojang.brigadier.exceptions.CommandSyntaxException 7 | import com.mojang.brigadier.exceptions.DynamicCommandExceptionType 8 | import com.mojang.brigadier.suggestion.Suggestions 9 | import com.mojang.brigadier.suggestion.SuggestionsBuilder 10 | import me.zeroeightsix.kami.feature.FeatureManager.features 11 | import me.zeroeightsix.kami.feature.FullFeature 12 | import me.zeroeightsix.kami.feature.HasBind 13 | import net.minecraft.command.CommandSource 14 | import net.minecraft.text.LiteralText 15 | import java.util.NoSuchElementException 16 | import java.util.concurrent.CompletableFuture 17 | 18 | class FeatureArgumentType(val clazz: Class) : ArgumentType { 19 | @Throws(CommandSyntaxException::class) 20 | override fun parse(reader: StringReader): T { 21 | val string = reader.readUnquotedString() 22 | try { 23 | return clazz.cast( 24 | features.filter { clazz.isInstance(it) } 25 | .first { it.name.equals(string, ignoreCase = true) } 26 | ) 27 | } catch (e: NoSuchElementException) { 28 | throw INVALID_MODULE_EXCEPTION.create(string) 29 | } 30 | } 31 | 32 | override fun listSuggestions( 33 | context: CommandContext, 34 | builder: SuggestionsBuilder 35 | ): CompletableFuture { 36 | return CommandSource.suggestMatching( 37 | features.filter { clazz.isInstance(it) }.map { it.name }, 38 | builder 39 | ) 40 | } 41 | 42 | override fun getExamples(): Collection { 43 | return EXAMPLES 44 | } 45 | 46 | companion object { 47 | private val EXAMPLES: Collection = listOf("Aura", "CameraClip", "Flight") 48 | val INVALID_MODULE_EXCEPTION = 49 | DynamicCommandExceptionType { obj -> 50 | LiteralText("Unknown feature '$obj'") 51 | } 52 | 53 | fun fullFeature(): FeatureArgumentType = FeatureArgumentType(FullFeature::class.java) 54 | fun boundFeature() = FeatureArgumentType(HasBind::class.java) 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /src/main/kotlin/me/zeroeightsix/kami/feature/command/GiveCommand.kt: -------------------------------------------------------------------------------- 1 | package me.zeroeightsix.kami.feature.command 2 | 3 | import com.mojang.brigadier.CommandDispatcher 4 | import com.mojang.brigadier.exceptions.DynamicCommandExceptionType 5 | import me.zeroeightsix.kami.mc 6 | import net.minecraft.command.CommandSource 7 | import net.minecraft.command.argument.ItemStackArgument 8 | import net.minecraft.command.argument.ItemStackArgumentType 9 | import net.minecraft.item.ItemStack 10 | import net.minecraft.text.LiteralText 11 | 12 | object GiveCommand : Command() { 13 | 14 | private val FAILED_EXCEPTION = 15 | DynamicCommandExceptionType { LiteralText(it.toString()) } 16 | 17 | override fun register(dispatcher: CommandDispatcher) { 18 | dispatcher register rootLiteral("give") { 19 | argument("item", ItemStackArgumentType.itemStack()) { 20 | does { ctx -> 21 | give("item" from ctx, 1) 22 | 0 23 | } 24 | 25 | integer("count") { 26 | does { ctx -> 27 | give("item" from ctx, "count" from ctx) 28 | 0 29 | } 30 | } 31 | } 32 | } 33 | } 34 | 35 | private fun give(itemArgument: ItemStackArgument, count: Int) { 36 | val player = mc.player ?: return 37 | 38 | if (!player.isCreative) { 39 | throw FAILED_EXCEPTION.create("You must be in creative mode to use this command") 40 | } 41 | 42 | val stack: ItemStack = itemArgument.createStack(count, false) 43 | 44 | if (player.mainHandStack?.isEmpty == true) { 45 | mc.interactionManager?.clickCreativeStack(stack, 36 + player.inventory?.selectedSlot!!) 46 | } else { 47 | val emptySlot: Int? = player.inventory?.emptySlot 48 | 49 | if (emptySlot!! < 9) { 50 | mc.interactionManager?.clickCreativeStack(stack, 36 + emptySlot) 51 | } else { 52 | mc.interactionManager?.clickCreativeStack(stack, 36 + player.inventory?.selectedSlot!!) 53 | } 54 | } 55 | } 56 | } -------------------------------------------------------------------------------- /src/main/kotlin/me/zeroeightsix/kami/feature/command/HClipCommand.kt: -------------------------------------------------------------------------------- 1 | package me.zeroeightsix.kami.feature.command 2 | 3 | import com.mojang.brigadier.CommandDispatcher 4 | import me.zeroeightsix.kami.mc 5 | import net.minecraft.command.CommandSource 6 | import net.minecraft.util.math.Vec3d 7 | 8 | object HClipCommand : Command() { 9 | override fun register(dispatcher: CommandDispatcher) { 10 | dispatcher register rootLiteral("hclip") { 11 | float("distance") { 12 | does { ctx -> 13 | mc.player?.let { 14 | val direction = Vec3d.fromPolar(0f, it.yaw) 15 | val distance: Float = "distance" from ctx 16 | it.updatePosition( 17 | it.x + direction.x * distance, 18 | it.y, 19 | it.z + direction.z * distance 20 | ) 21 | } 22 | 0 23 | } 24 | } 25 | } 26 | } 27 | } -------------------------------------------------------------------------------- /src/main/kotlin/me/zeroeightsix/kami/feature/command/KamiCommandSource.kt: -------------------------------------------------------------------------------- 1 | package me.zeroeightsix.kami.feature.command 2 | 3 | import me.zeroeightsix.kami.mc 4 | import net.minecraft.client.MinecraftClient 5 | import net.minecraft.client.network.ClientCommandSource 6 | import net.minecraft.client.network.ClientPlayNetworkHandler 7 | import net.minecraft.text.Text 8 | 9 | class KamiCommandSource(client: ClientPlayNetworkHandler?, minecraftClient: MinecraftClient?) : 10 | ClientCommandSource(client, minecraftClient) { 11 | fun sendFeedback(text: Text?) { 12 | mc.player?.sendMessage(text, false) 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /src/main/kotlin/me/zeroeightsix/kami/feature/command/PluginArgumentType.kt: -------------------------------------------------------------------------------- 1 | package me.zeroeightsix.kami.feature.command 2 | 3 | import com.mojang.brigadier.StringReader 4 | import com.mojang.brigadier.arguments.ArgumentType 5 | import com.mojang.brigadier.context.CommandContext 6 | import com.mojang.brigadier.exceptions.DynamicCommandExceptionType 7 | import com.mojang.brigadier.suggestion.Suggestions 8 | import com.mojang.brigadier.suggestion.SuggestionsBuilder 9 | import me.zeroeightsix.kami.feature.FeatureManager 10 | import me.zeroeightsix.kami.feature.FeatureManager.getByName 11 | import me.zeroeightsix.kami.feature.plugin.Plugin 12 | import net.minecraft.command.CommandSource 13 | import net.minecraft.text.LiteralText 14 | import java.util.concurrent.CompletableFuture 15 | import java.util.function.Function 16 | 17 | class PluginArgumentType : ArgumentType { 18 | 19 | private val examples: MutableCollection = mutableListOf("Aura", "CameraClip", "Flight") 20 | private val invalidPluginException = DynamicCommandExceptionType( 21 | Function { `object`: Any -> LiteralText("Unknown module '$`object`'") } 22 | ) 23 | 24 | companion object { 25 | fun plugin(): PluginArgumentType { 26 | return PluginArgumentType() 27 | } 28 | } 29 | 30 | override fun parse(reader: StringReader?): Plugin { 31 | val reader: StringReader = reader!! 32 | val str = reader.readUnquotedString() 33 | FeatureManager.plugins.getByName(str)?.let { 34 | return@let it 35 | } 36 | throw invalidPluginException.create(str) 37 | } 38 | 39 | override fun listSuggestions( 40 | context: CommandContext?, 41 | builder: SuggestionsBuilder? 42 | ): CompletableFuture? { 43 | return CommandSource.suggestMatching( 44 | FeatureManager.plugins.stream().map { obj: Plugin -> obj.name }, 45 | builder 46 | ) 47 | } 48 | 49 | override fun getExamples(): MutableCollection { 50 | return examples 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /src/main/kotlin/me/zeroeightsix/kami/feature/command/PluginCommand.kt: -------------------------------------------------------------------------------- 1 | package me.zeroeightsix.kami.feature.command 2 | 3 | import com.mojang.brigadier.CommandDispatcher 4 | import com.mojang.brigadier.exceptions.DynamicCommandExceptionType 5 | import me.zeroeightsix.kami.feature.plugin.Plugin 6 | import me.zeroeightsix.kami.util.text 7 | import net.minecraft.command.CommandSource 8 | import net.minecraft.text.LiteralText 9 | import net.minecraft.util.Formatting.GOLD 10 | import net.minecraft.util.Formatting.YELLOW 11 | 12 | object PluginCommand : Command() { 13 | 14 | private val failedException = DynamicCommandExceptionType { o: Any -> LiteralText(o.toString()) } 15 | 16 | override fun register(dispatcher: CommandDispatcher) { 17 | dispatcher register rootLiteral("plugins") { 18 | literal("enable") { 19 | argument("plugin", PluginArgumentType.plugin()) { 20 | does { ctx -> 21 | toggle( 22 | "enable", 23 | ctx.source as KamiCommandSource, 24 | "plugin" from ctx, 25 | true 26 | ) 27 | 0 28 | } 29 | } 30 | } 31 | literal("disable") { 32 | argument("plugin", PluginArgumentType.plugin()) { 33 | does { ctx -> 34 | toggle( 35 | "disable", 36 | ctx.source as KamiCommandSource, 37 | "plugin" from ctx, 38 | false 39 | ) 40 | 0 41 | } 42 | } 43 | } 44 | } 45 | } 46 | 47 | private fun toggle(word: String, source: KamiCommandSource, plugin: Plugin, enable: Boolean) { 48 | if (plugin.enabled != enable) { 49 | plugin.enabled = enable 50 | source replyWith text(GOLD) { 51 | +"${word.capitalize()}d plugin " 52 | +plugin.name(YELLOW) 53 | } 54 | } else 55 | source replyWith text(GOLD) { 56 | +plugin.name(YELLOW) 57 | +"is already ${word}d." 58 | } 59 | } 60 | } 61 | -------------------------------------------------------------------------------- /src/main/kotlin/me/zeroeightsix/kami/feature/command/SayCommand.kt: -------------------------------------------------------------------------------- 1 | package me.zeroeightsix.kami.feature.command 2 | 3 | import com.mojang.brigadier.CommandDispatcher 4 | import me.zeroeightsix.kami.mc 5 | import net.minecraft.command.CommandSource 6 | 7 | object SayCommand : Command() { 8 | override fun register(dispatcher: CommandDispatcher) { 9 | dispatcher register rootLiteral("say") { 10 | greedyString("message") { 11 | does { 12 | mc.player?.sendChatMessage("message" from it) 13 | 0 14 | } 15 | } 16 | } 17 | } 18 | } 19 | 20 | -------------------------------------------------------------------------------- /src/main/kotlin/me/zeroeightsix/kami/feature/command/SettingValueArgumentType.kt: -------------------------------------------------------------------------------- 1 | package me.zeroeightsix.kami.feature.command 2 | 3 | import com.mojang.brigadier.StringReader 4 | import com.mojang.brigadier.arguments.ArgumentType 5 | import com.mojang.brigadier.context.CommandContext 6 | import com.mojang.brigadier.exceptions.CommandSyntaxException 7 | import com.mojang.brigadier.exceptions.DynamicCommandExceptionType 8 | import com.mojang.brigadier.suggestion.Suggestions 9 | import com.mojang.brigadier.suggestion.SuggestionsBuilder 10 | import io.github.fablabsmc.fablabs.api.fiber.v1.tree.ConfigLeaf 11 | import me.zeroeightsix.kami.setting.getAnyInterface 12 | import net.minecraft.text.LiteralText 13 | import java.util.concurrent.CompletableFuture 14 | import java.util.function.Function 15 | 16 | class SettingValueArgumentType( 17 | dependantType: ArgumentType>, 18 | dependantArgument: String, 19 | shift: Int 20 | ) : DependantArgumentType>( 21 | dependantType, 22 | dependantArgument, 23 | shift 24 | ) { 25 | @Throws(CommandSyntaxException::class) 26 | override fun parse(reader: StringReader): String { 27 | val setting = findDependencyValue(reader) 28 | val string = reader.readUnquotedString() 29 | return if (setting.getAnyInterface()?.canFromString(string) == true) { 30 | string 31 | } else { 32 | throw INVALID_VALUE_EXCEPTION.create( 33 | arrayOf( 34 | string, 35 | setting.name 36 | ) 37 | ) 38 | } 39 | } 40 | 41 | override fun listSuggestions( 42 | context: CommandContext, 43 | builder: SuggestionsBuilder 44 | ): CompletableFuture { 45 | return findDependencyValue(context, ConfigLeaf::class.java).getAnyInterface()?.listSuggestions( 46 | context, 47 | builder 48 | ) ?: builder.buildFuture() 49 | } 50 | 51 | companion object { 52 | val INVALID_VALUE_EXCEPTION = 53 | DynamicCommandExceptionType( 54 | Function { `object`: Any -> 55 | LiteralText( 56 | "Invalid value '" + (`object` as Array)[0] + "' for property '" + `object`[1] + "'" 57 | ) 58 | } 59 | ) 60 | 61 | fun value( 62 | dependantType: ArgumentType>, 63 | dependantArgument: String, 64 | shift: Int 65 | ): SettingValueArgumentType { 66 | return SettingValueArgumentType(dependantType, dependantArgument, shift) 67 | } 68 | } 69 | } 70 | -------------------------------------------------------------------------------- /src/main/kotlin/me/zeroeightsix/kami/feature/command/ToggleCommand.kt: -------------------------------------------------------------------------------- 1 | package me.zeroeightsix.kami.feature.command 2 | 3 | import com.mojang.brigadier.CommandDispatcher 4 | import me.zeroeightsix.kami.feature.FullFeature 5 | import me.zeroeightsix.kami.util.text 6 | import net.minecraft.command.CommandSource 7 | import net.minecraft.util.Formatting 8 | import net.minecraft.util.Formatting.GOLD 9 | import net.minecraft.util.Formatting.YELLOW 10 | 11 | object ToggleCommand : Command() { 12 | override fun register(dispatcher: CommandDispatcher) { 13 | dispatcher register rootLiteral("toggle") { 14 | argument("feature", FeatureArgumentType.fullFeature()) { 15 | does { ctx -> 16 | val f: FullFeature = "feature" from ctx 17 | f.enabled = !f.enabled 18 | ctx replyWith text(GOLD) { 19 | +"Toggled feature " 20 | +f.name(YELLOW) 21 | +", now " 22 | +(if (f.enabled) "ON" else "OFF")(if (f.enabled) Formatting.GREEN else Formatting.RED) 23 | } 24 | 0 25 | } 26 | } 27 | } 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /src/main/kotlin/me/zeroeightsix/kami/feature/command/VClipCommand.kt: -------------------------------------------------------------------------------- 1 | package me.zeroeightsix.kami.feature.command 2 | 3 | import com.mojang.brigadier.CommandDispatcher 4 | import me.zeroeightsix.kami.mc 5 | import net.minecraft.command.CommandSource 6 | 7 | object VClipCommand : Command() { 8 | override fun register(dispatcher: CommandDispatcher) { 9 | dispatcher register rootLiteral("vclip") { 10 | float("height") { 11 | does { ctx -> 12 | mc.player?.let { 13 | it.updatePosition( 14 | it.x, 15 | it.y + ("height".from(ctx)), 16 | it.z 17 | ) 18 | } 19 | 0 20 | } 21 | } 22 | } 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /src/main/kotlin/me/zeroeightsix/kami/feature/hidden/ClickGui.kt: -------------------------------------------------------------------------------- 1 | package me.zeroeightsix.kami.feature.hidden 2 | 3 | import io.github.fablabsmc.fablabs.api.fiber.v1.annotation.Setting 4 | import me.zero.alpine.listener.EventHandler 5 | import me.zero.alpine.listener.EventHook 6 | import me.zero.alpine.listener.Listenable 7 | import me.zero.alpine.listener.Listener 8 | import me.zeroeightsix.kami.KamiMod 9 | import me.zeroeightsix.kami.event.BindEvent 10 | import me.zeroeightsix.kami.expectingInput 11 | import me.zeroeightsix.kami.feature.Feature 12 | import me.zeroeightsix.kami.feature.FindFeature 13 | import me.zeroeightsix.kami.feature.HasBind 14 | import me.zeroeightsix.kami.gui.KamiGuiScreen 15 | import me.zeroeightsix.kami.gui.KamiHud 16 | import me.zeroeightsix.kami.gui.windows.Settings 17 | import me.zeroeightsix.kami.mc 18 | import me.zeroeightsix.kami.util.Bind 19 | import net.minecraft.client.util.InputUtil 20 | 21 | @FindFeature 22 | object ClickGui : Feature, Listenable, HasBind { 23 | 24 | @Setting 25 | override var bind: Bind = Bind(false, false, false, Bind.Code(InputUtil.fromTranslationKey("key.keyboard.y"))) 26 | 27 | @EventHandler 28 | val bindListener = Listener( 29 | EventHook { 30 | bind.update(it.key, it.scancode, it.pressed) 31 | if (bind.isDown && (it.ingame || (Settings.openGuiAnywhere && mc.currentScreen?.expectingInput != true && mc.currentScreen !is KamiGuiScreen))) { 32 | KamiHud // In case imgui was not yet initialised, it gets initialised here. (Kotlin `init` block) 33 | mc.openScreen(KamiGuiScreen(mc.currentScreen)) 34 | it.cancel() 35 | } 36 | } 37 | ) 38 | 39 | override var name: String = "ClickGui" 40 | override var hidden: Boolean = false 41 | 42 | override fun init() { 43 | super.init() 44 | KamiMod.EVENT_BUS.subscribe(bindListener) 45 | } 46 | } -------------------------------------------------------------------------------- /src/main/kotlin/me/zeroeightsix/kami/feature/hidden/KamiPrefixChat.kt: -------------------------------------------------------------------------------- 1 | package me.zeroeightsix.kami.feature.hidden 2 | 3 | import me.zero.alpine.listener.Listener 4 | import me.zeroeightsix.kami.KamiMod 5 | import me.zeroeightsix.kami.event.CharTypedEvent 6 | import me.zeroeightsix.kami.feature.Feature 7 | import me.zeroeightsix.kami.feature.FindFeature 8 | import me.zeroeightsix.kami.gui.windows.Settings 9 | import me.zeroeightsix.kami.mc 10 | import me.zeroeightsix.kami.mixin.extend.openChatScreen 11 | 12 | @FindFeature 13 | object KamiPrefixChat : Feature { 14 | override var name: String = "Kami prefix chat opener" 15 | override var hidden: Boolean = true 16 | 17 | override fun init() { 18 | super.init() 19 | KamiMod.EVENT_BUS.subscribe( 20 | Listener({ event: CharTypedEvent -> 21 | if (Settings.openChatWhenCommandPrefixPressed && mc.currentScreen === null && event.char == Settings.commandPrefix) { 22 | mc.openChatScreen(event.char.toString()) 23 | event.cancel() 24 | } 25 | }) 26 | ) 27 | } 28 | } -------------------------------------------------------------------------------- /src/main/kotlin/me/zeroeightsix/kami/feature/hidden/TickSpeedMeter.kt: -------------------------------------------------------------------------------- 1 | package me.zeroeightsix.kami.feature.hidden 2 | 3 | import java.util.Arrays 4 | import me.zero.alpine.listener.Listenable 5 | import me.zero.alpine.listener.Listener 6 | import me.zeroeightsix.kami.KamiMod 7 | import me.zeroeightsix.kami.event.PacketEvent.Receive 8 | import me.zeroeightsix.kami.feature.Feature 9 | import me.zeroeightsix.kami.feature.FindFeature 10 | import net.minecraft.network.packet.s2c.play.WorldTimeUpdateS2CPacket 11 | import net.minecraft.util.math.MathHelper 12 | 13 | @FindFeature 14 | object TickSpeedMeter : Listenable, Feature { 15 | override var name = "TPS meter" 16 | override var hidden = true 17 | 18 | private val tickRates = FloatArray(20) 19 | private var nextIndex = 0 20 | private var timeLastTimeUpdate: Long = 0 21 | 22 | val tickRate: Float 23 | get() { 24 | var numTicks = 0.0f 25 | var sumTickRates = 0.0f 26 | for (tickRate in tickRates) { 27 | if (tickRate > 0.0f) { 28 | sumTickRates += tickRate 29 | numTicks += 1.0f 30 | } 31 | } 32 | return MathHelper.clamp(sumTickRates / numTicks, 0.0f, 20.0f) 33 | } 34 | 35 | fun reset() { 36 | nextIndex = 0 37 | timeLastTimeUpdate = -1L 38 | Arrays.fill(tickRates, 0.0f) 39 | } 40 | 41 | private fun onTimeUpdate() { 42 | if (timeLastTimeUpdate != -1L) { 43 | val timeElapsed = (System.currentTimeMillis() - timeLastTimeUpdate).toFloat() / 1000.0f 44 | tickRates[nextIndex % tickRates.size] = MathHelper.clamp(20.0f / timeElapsed, 0.0f, 20.0f) 45 | nextIndex += 1 46 | } 47 | timeLastTimeUpdate = System.currentTimeMillis() 48 | } 49 | 50 | override fun init() { 51 | super.init() 52 | KamiMod.EVENT_BUS.subscribe( 53 | Listener({ event -> 54 | if (event.packet is WorldTimeUpdateS2CPacket) { 55 | onTimeUpdate() 56 | } 57 | }) 58 | ) 59 | reset() 60 | } 61 | } -------------------------------------------------------------------------------- /src/main/kotlin/me/zeroeightsix/kami/feature/module/AutoGG.kt: -------------------------------------------------------------------------------- 1 | package me.zeroeightsix.kami.feature.module 2 | 3 | import io.github.fablabsmc.fablabs.api.fiber.v1.annotation.Setting 4 | import java.util.UUID 5 | import me.zero.alpine.listener.EventHandler 6 | import me.zero.alpine.listener.Listener 7 | import me.zeroeightsix.kami.event.PacketEvent 8 | import me.zeroeightsix.kami.gui.ImguiDSL.imgui 9 | import me.zeroeightsix.kami.gui.text.CompiledText 10 | import net.minecraft.network.packet.s2c.play.GameMessageS2CPacket 11 | 12 | @Module.Info( 13 | name = "AutoGG", 14 | category = Module.Category.MISC, 15 | description = "Says GG or a custom message at the end of a match" 16 | ) 17 | object AutoGG : Module() { 18 | @Setting 19 | var ggMessage = CompiledText( 20 | mutableListOf( 21 | CompiledText.LiteralPart("gg".imgui) 22 | ) 23 | ) 24 | 25 | private const val updateLimit: Long = 7000 // 7 Seconds 26 | private var lastUpdate: Long = 0L 27 | private final val emptyUuid = UUID(0, 0) // Nil UUID 28 | 29 | private val triggers = listOf( 30 | "1st Killer - ", 31 | "1st Place - ", 32 | " - Damage Dealt - ", 33 | "Winning Team -", 34 | "1st - ", 35 | "Winners:", 36 | "Winner:", 37 | "Winning Team:", 38 | " won the game!", 39 | "Top Seeker:", 40 | "1st Place:", 41 | "Last team standing!", 42 | "Winner #1 (", 43 | "Top Survivors", 44 | "Winners - ", 45 | "Sumo Duel - ", 46 | " WINNER!" 47 | ) 48 | 49 | @EventHandler 50 | private val listener = Listener({ event: PacketEvent.Receive -> 51 | if (lastUpdate + updateLimit <= System.currentTimeMillis() && 52 | event.packet is GameMessageS2CPacket && 53 | event.packet.senderUuid == emptyUuid 54 | ) { 55 | val chatMessage = event.packet.message.string 56 | if (triggers.any { chatMessage.contains(it, ignoreCase = false) }) { 57 | mc.player?.sendChatMessage(ggMessage.toString()) 58 | lastUpdate = System.currentTimeMillis() 59 | } 60 | } 61 | }) 62 | } -------------------------------------------------------------------------------- /src/main/kotlin/me/zeroeightsix/kami/feature/module/BaritonePause.kt: -------------------------------------------------------------------------------- 1 | package me.zeroeightsix.kami.feature.module 2 | 3 | import baritone.api.BaritoneAPI 4 | import baritone.api.process.IBaritoneProcess 5 | import baritone.api.process.PathingCommand 6 | import baritone.api.process.PathingCommandType 7 | import me.zero.alpine.listener.Listener 8 | import me.zeroeightsix.kami.BaritoneIntegration 9 | import me.zeroeightsix.kami.KamiMod 10 | import me.zeroeightsix.kami.event.TickEvent 11 | 12 | @Module.Info( 13 | name = "BaritonePause", 14 | category = Module.Category.MISC, 15 | description = "Pauses Baritone" 16 | ) 17 | object BaritonePause : Module() { 18 | var process: BaritoneWrapper? = null 19 | 20 | init { 21 | hidden = true 22 | BaritoneIntegration { 23 | hidden = false 24 | process = BaritoneWrapper(BaritoneWrapper.PauseBaritoneProcess("${KamiMod.MODNAME} Pause Module")) 25 | var listener: Listener? = null 26 | listener = Listener({ 27 | BaritoneIntegration { 28 | val mngr = BaritoneAPI.getProvider()?.primaryBaritone?.pathingControlManager 29 | mngr?.let { 30 | it.registerProcess(process?.process) 31 | KamiMod.EVENT_BUS.unsubscribe(listener) 32 | } 33 | } 34 | }) 35 | KamiMod.EVENT_BUS.subscribe(listener) 36 | } 37 | } 38 | 39 | override fun onDisable() { 40 | process?.process?.isPaused = false 41 | } 42 | 43 | override fun onEnable() { 44 | process?.process?.isPaused = true 45 | } 46 | } 47 | 48 | // this wrapper is required in order to keep kami from crashing without baritone 49 | class BaritoneWrapper(val process: PauseBaritoneProcess) { 50 | class PauseBaritoneProcess( 51 | val displayName: String, 52 | var isPaused: Boolean = false 53 | ) : IBaritoneProcess { 54 | override fun isActive(): Boolean = isPaused 55 | 56 | override fun onTick(p0: Boolean, p1: Boolean) = 57 | PathingCommand(null, PathingCommandType.REQUEST_PAUSE) 58 | 59 | override fun isTemporary() = true 60 | 61 | override fun onLostControl() {} 62 | 63 | override fun displayName0() = displayName 64 | } 65 | } 66 | -------------------------------------------------------------------------------- /src/main/kotlin/me/zeroeightsix/kami/feature/module/Chams.kt: -------------------------------------------------------------------------------- 1 | package me.zeroeightsix.kami.feature.module 2 | 3 | import io.github.fablabsmc.fablabs.api.fiber.v1.annotation.Setting 4 | import me.zeroeightsix.kami.util.EntityUtil 5 | import net.minecraft.entity.Entity 6 | import net.minecraft.entity.player.PlayerEntity 7 | 8 | @Module.Info( 9 | name = "Chams", 10 | category = Module.Category.RENDER, 11 | description = "See entities through walls" 12 | ) 13 | object Chams : Module() { 14 | @Setting 15 | private var players = true 16 | 17 | @Setting 18 | private var animals = false 19 | 20 | @Setting 21 | private var mobs = false 22 | 23 | fun renderChams(entity: Entity?): Boolean { 24 | return if (entity is PlayerEntity) players else if (EntityUtil.isPassive(entity)) animals else mobs 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /src/main/kotlin/me/zeroeightsix/kami/feature/module/CustomChat.kt: -------------------------------------------------------------------------------- 1 | package me.zeroeightsix.kami.feature.module 2 | 3 | import io.github.fablabsmc.fablabs.api.fiber.v1.annotation.Setting 4 | import me.zero.alpine.listener.EventHandler 5 | import me.zero.alpine.listener.Listener 6 | import me.zeroeightsix.kami.event.PacketEvent.Send 7 | import me.zeroeightsix.kami.mixin.client.IChatMessageC2SPacket 8 | import me.zeroeightsix.kami.setting.SettingVisibility 9 | import net.minecraft.network.packet.c2s.play.ChatMessageC2SPacket 10 | 11 | @Module.Info(name = "CustomChat", category = Module.Category.MISC, description = "Modifies your chat messages") 12 | object CustomChat : Module() { 13 | @Setting(name = "Commands") 14 | private var commands = false 15 | 16 | // Of course we could omit this setting and just have the default value for the custom suffix be KAMI_SUFFIX. 17 | // Though, in reality, we _do_ want to promote KAMI - and one way to do that is by making it as easy as possible to fallback to the default one (through this setting). 18 | @Setting(name = "Custom suffix", comment = "Whether or not to use the default KAMI suffix, or the custom one.") 19 | private var customSuffix = false 20 | 21 | @Setting(name = "uwuify", comment = "uwuify the chat message") 22 | private var uwu = false 23 | 24 | @Setting(name = "Suffix") 25 | @SettingVisibility.Method("ifCustomSuffix") 26 | private var suffix = " | KAMI" 27 | 28 | fun ifCustomSuffix() = customSuffix 29 | fun uwuify(t: String): String = t.replace('r', 'w').replace('R', 'W').replace('l', 'w').replace('L', 'W').replace("th", "d").replace("Th", "D").replace("tH", "d").replace("TH", "D") 30 | 31 | private const val KAMI_SUFFIX = " \u23D0 \u1D0B\u1D00\u1D0D\u026A" 32 | 33 | @EventHandler 34 | var listener = Listener({ event: Send -> 35 | if (event.packet is ChatMessageC2SPacket) { 36 | var s = (event.packet as IChatMessageC2SPacket).chatMessage 37 | if (s.startsWith("/") && !commands) return@Listener 38 | s = if (uwu) uwuify(s) else s 39 | s += if (customSuffix) suffix else KAMI_SUFFIX 40 | if (s.length >= 256) s = s.substring(0, 256) 41 | (event.packet as IChatMessageC2SPacket).chatMessage = s 42 | } 43 | }) 44 | } 45 | -------------------------------------------------------------------------------- /src/main/kotlin/me/zeroeightsix/kami/feature/module/ExtraTab.kt: -------------------------------------------------------------------------------- 1 | package me.zeroeightsix.kami.feature.module 2 | 3 | import io.github.fablabsmc.fablabs.api.fiber.v1.annotation.Setting 4 | import me.zeroeightsix.kami.util.Friends.isFriend 5 | import net.minecraft.client.network.PlayerListEntry 6 | import net.minecraft.scoreboard.Team 7 | import net.minecraft.text.LiteralText 8 | import net.minecraft.text.Text 9 | import net.minecraft.util.Formatting 10 | 11 | @Module.Info(name = "ExtraTab", description = "Expands the player tab menu", category = Module.Category.RENDER) 12 | object ExtraTab : Module() { 13 | @JvmField 14 | @Setting 15 | var tabSize = 80 16 | 17 | @Setting 18 | var highlightFriends = true 19 | 20 | @JvmStatic 21 | fun getPlayerName(networkPlayerInfoIn: PlayerListEntry): Text? { 22 | val dname = 23 | if (networkPlayerInfoIn.displayName != null) networkPlayerInfoIn.displayName else Team.modifyText( 24 | networkPlayerInfoIn.scoreboardTeam, 25 | LiteralText(networkPlayerInfoIn.profile.name) 26 | ) 27 | return if (highlightFriends && isFriend(dname!!.string)) dname.shallowCopy() 28 | .formatted(Formatting.GREEN) else dname 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /src/main/kotlin/me/zeroeightsix/kami/feature/module/ItemHighlight.kt: -------------------------------------------------------------------------------- 1 | package me.zeroeightsix.kami.feature.module 2 | 3 | import io.github.fablabsmc.fablabs.api.fiber.v1.annotation.Setting 4 | import me.zeroeightsix.kami.Colour 5 | import me.zeroeightsix.kami.target.ItemCategory 6 | import me.zeroeightsix.kami.target.ItemSupplier 7 | 8 | @Module.Info( 9 | name = "ItemHighlight", 10 | category = Module.Category.RENDER, 11 | description = "Highlights certain Item Slots" 12 | ) 13 | /** 14 | * @see me.zeroeightsix.kami.mixin.client.MixinHandledScreen 15 | */ 16 | object ItemHighlight: Module() { 17 | @Setting 18 | var highlightedItems = ItemSupplier( 19 | mapOf( 20 | ItemCategory.FOOD to Colour(1f, 1f, 1f, 0f) 21 | ), 22 | mapOf() 23 | ) 24 | } -------------------------------------------------------------------------------- /src/main/kotlin/me/zeroeightsix/kami/feature/module/ModuleCamera.kt: -------------------------------------------------------------------------------- 1 | package me.zeroeightsix.kami.feature.module 2 | 3 | import io.github.fablabsmc.fablabs.api.fiber.v1.annotation.Setting 4 | import me.zero.alpine.listener.EventHandler 5 | import me.zero.alpine.listener.Listener 6 | import me.zeroeightsix.kami.event.CameraUpdateEvent 7 | import me.zeroeightsix.kami.mixin.extend.ipos 8 | import me.zeroeightsix.kami.util.plus 9 | import net.minecraft.util.math.Vec3d 10 | 11 | @Module.Info( 12 | name = "Camera", 13 | category = Module.Category.RENDER, 14 | description = "Allows modification of the camera behaviour while in 3rd person mode" 15 | ) 16 | object ModuleCamera : Module() { 17 | 18 | @Setting(name = "Distance from player") 19 | var desiredDistance: @Setting.Constrain.Range( 20 | min = 0.0, 21 | max = 50.0, 22 | step = 0.1 23 | ) Double = 4.0 24 | 25 | @Setting(name = "Shift Y") 26 | var shiftY: @Setting.Constrain.Range( 27 | min = -5.0, 28 | max = 10.0, 29 | step = 0.01 30 | ) Double = 0.0 31 | 32 | @Setting(name = "Clip through blocks") 33 | var clip: Boolean = true 34 | 35 | @EventHandler 36 | val updateCameraListener = Listener({ 37 | with(it.camera) { 38 | if (!isThirdPerson) return@Listener 39 | ipos += Vec3d(0.0, shiftY, 0.0) 40 | } 41 | }) 42 | } 43 | -------------------------------------------------------------------------------- /src/main/kotlin/me/zeroeightsix/kami/feature/module/MountBypass.kt: -------------------------------------------------------------------------------- 1 | package me.zeroeightsix.kami.feature.module 2 | 3 | import me.zero.alpine.listener.EventHandler 4 | import me.zero.alpine.listener.Listener 5 | import me.zeroeightsix.kami.event.PacketEvent 6 | import net.minecraft.entity.passive.AbstractDonkeyEntity 7 | import net.minecraft.network.packet.c2s.play.PlayerInteractEntityC2SPacket 8 | 9 | @Module.Info( 10 | name = "MountBypass", 11 | category = Module.Category.PLAYER, 12 | description = "Forcefully allows mounting donkeys with chests" 13 | ) 14 | object MountBypass : Module() { 15 | @EventHandler 16 | private val listener = Listener({ event: PacketEvent.Send -> 17 | if (mc.player == null || mc.world == null || event.packet !is PlayerInteractEntityC2SPacket) return@Listener 18 | if (event.packet.getEntity(mc.world) is AbstractDonkeyEntity) event.cancel() 19 | }) 20 | } -------------------------------------------------------------------------------- /src/main/kotlin/me/zeroeightsix/kami/feature/module/NoEntityTrace.kt: -------------------------------------------------------------------------------- 1 | package me.zeroeightsix.kami.feature.module 2 | 3 | import io.github.fablabsmc.fablabs.api.fiber.v1.annotation.Setting 4 | import me.zero.alpine.listener.EventHandler 5 | import me.zero.alpine.listener.EventHook 6 | import me.zero.alpine.listener.Listener 7 | import me.zeroeightsix.kami.event.TargetEntityEvent 8 | 9 | @Module.Info( 10 | name = "NoEntityTrace", 11 | category = Module.Category.MISC, 12 | description = "Blocks entities from stopping you from mining" 13 | ) 14 | object NoEntityTrace : Module() { 15 | @Setting 16 | var traceMode = TraceMode.DYNAMIC 17 | 18 | enum class TraceMode { 19 | STATIC, DYNAMIC 20 | } 21 | 22 | @EventHandler 23 | val targetListener = Listener( 24 | EventHook { 25 | if (traceMode == TraceMode.STATIC || mc.interactionManager?.isBreakingBlock == true) 26 | it.trace = null 27 | } 28 | ) 29 | } 30 | -------------------------------------------------------------------------------- /src/main/kotlin/me/zeroeightsix/kami/feature/module/NoPacketKick.kt: -------------------------------------------------------------------------------- 1 | package me.zeroeightsix.kami.feature.module 2 | 3 | /** 4 | * @see me.zeroeightsix.kami.mixin.client.MixinClientConnection 5 | */ 6 | @Module.Info( 7 | name = "NoPacketKick", 8 | category = Module.Category.MISC, 9 | description = "Prevent large packets from kicking you" 10 | ) 11 | object NoPacketKick : Module() 12 | -------------------------------------------------------------------------------- /src/main/kotlin/me/zeroeightsix/kami/feature/module/NoRender.kt: -------------------------------------------------------------------------------- 1 | package me.zeroeightsix.kami.feature.module 2 | 3 | import io.github.fablabsmc.fablabs.api.fiber.v1.annotation.Setting 4 | import me.zero.alpine.listener.EventHandler 5 | import me.zero.alpine.listener.Listener 6 | import me.zeroeightsix.kami.event.PacketEvent 7 | import net.minecraft.network.packet.s2c.play.EntitySpawnS2CPacket 8 | import net.minecraft.network.packet.s2c.play.ExperienceOrbSpawnS2CPacket 9 | import net.minecraft.network.packet.s2c.play.ExplosionS2CPacket 10 | import net.minecraft.network.packet.s2c.play.LightUpdateS2CPacket 11 | import net.minecraft.network.packet.s2c.play.MobSpawnS2CPacket 12 | 13 | @Module.Info( 14 | name = "NoRender", 15 | category = Module.Category.RENDER, 16 | description = "Prevent rendering of certain things" 17 | ) 18 | object NoRender : Module() { 19 | @Setting 20 | private var mobs = false 21 | 22 | @Setting 23 | private var objects = false 24 | 25 | @Setting 26 | private var experienceOrbs = true 27 | 28 | @Setting 29 | var fire = true 30 | 31 | @Setting 32 | private var explosions = true 33 | 34 | @Setting 35 | var beaconBeams = false 36 | 37 | @Setting 38 | private var skyLightUpdates = true 39 | 40 | @EventHandler 41 | private val receiveListener = Listener({ event: PacketEvent.Receive -> 42 | val packet = event.packet 43 | when { 44 | packet is MobSpawnS2CPacket && mobs -> event.cancel() 45 | packet is EntitySpawnS2CPacket && objects -> event.cancel() 46 | packet is ExperienceOrbSpawnS2CPacket && experienceOrbs -> event.cancel() 47 | packet is ExplosionS2CPacket && explosions -> event.cancel() 48 | packet is LightUpdateS2CPacket && skyLightUpdates -> event.cancel() 49 | } 50 | }) 51 | } 52 | -------------------------------------------------------------------------------- /src/main/kotlin/me/zeroeightsix/kami/feature/module/NoSlowDown.kt: -------------------------------------------------------------------------------- 1 | package me.zeroeightsix.kami.feature.module 2 | 3 | import me.zero.alpine.listener.EventHandler 4 | import me.zero.alpine.listener.Listener 5 | import me.zeroeightsix.kami.event.EntityVelocityMultiplierEvent 6 | 7 | @Module.Info( 8 | name = "NoSlowDown", 9 | category = Module.Category.MOVEMENT 10 | ) 11 | object NoSlowDown : Module() { 12 | @EventHandler 13 | private val entityVelocityMultiplierEventListener = 14 | Listener( 15 | { event: EntityVelocityMultiplierEvent -> 16 | if (event.entity === mc.player) event.multiplier = 1f 17 | } 18 | ) 19 | } 20 | -------------------------------------------------------------------------------- /src/main/kotlin/me/zeroeightsix/kami/feature/module/PortalChat.kt: -------------------------------------------------------------------------------- 1 | package me.zeroeightsix.kami.feature.module 2 | 3 | import me.zero.alpine.listener.EventHandler 4 | import me.zero.alpine.listener.Listener 5 | import me.zeroeightsix.kami.event.CloseScreenInPortalEvent 6 | 7 | /** 8 | * @see me.zeroeightsix.kami.mixin.client.MixinClientPlayerEntity 9 | */ 10 | @Module.Info(name = "PortalChat", category = Module.Category.MISC, description = "Allows you to open GUIs in portals") 11 | class PortalChat : Module() { 12 | @EventHandler 13 | var portalEventListener = Listener( 14 | { event -> event.cancel() }) 15 | } -------------------------------------------------------------------------------- /src/main/kotlin/me/zeroeightsix/kami/feature/module/PortalGodMode.kt: -------------------------------------------------------------------------------- 1 | package me.zeroeightsix.kami.feature.module 2 | 3 | import me.zero.alpine.listener.EventHandler 4 | import me.zero.alpine.listener.Listener 5 | import me.zeroeightsix.kami.event.PacketEvent.Send 6 | import net.minecraft.network.packet.c2s.play.TeleportConfirmC2SPacket 7 | 8 | @Module.Info(name = "PortalGodMode", category = Module.Category.PLAYER) 9 | object PortalGodMode : Module() { 10 | var sent: TeleportConfirmC2SPacket? = null 11 | 12 | override fun onEnable() { 13 | sent = null 14 | } 15 | 16 | override fun onDisable() { 17 | sent?.let { 18 | mc.networkHandler?.sendPacket(sent) 19 | } 20 | } 21 | 22 | @EventHandler 23 | var listener = Listener({ event: Send -> 24 | if (event.packet is TeleportConfirmC2SPacket) { 25 | event.cancel() 26 | sent = event.packet 27 | } 28 | }) 29 | } 30 | -------------------------------------------------------------------------------- /src/main/kotlin/me/zeroeightsix/kami/feature/module/SafeWalk.kt: -------------------------------------------------------------------------------- 1 | package me.zeroeightsix.kami.feature.module 2 | 3 | import me.zero.alpine.listener.EventHandler 4 | import me.zero.alpine.listener.Listener 5 | import me.zeroeightsix.kami.event.ClipAtLedgeEvent 6 | 7 | @Module.Info( 8 | name = "SafeWalk", 9 | category = Module.Category.MOVEMENT, 10 | description = "Keeps you from walking off edges" 11 | ) 12 | object SafeWalk : Module() { 13 | 14 | @EventHandler 15 | val clipListener = Listener({ 16 | it.clip = true 17 | }) 18 | } 19 | -------------------------------------------------------------------------------- /src/main/kotlin/me/zeroeightsix/kami/feature/module/SignSpammer.kt: -------------------------------------------------------------------------------- 1 | package me.zeroeightsix.kami.feature.module 2 | 3 | import io.github.fablabsmc.fablabs.api.fiber.v1.annotation.Setting 4 | 5 | /** 6 | * @see me.zeroeightsix.kami.mixin.client.MixinClientPlayNetworkHandler 7 | */ 8 | @Module.Info( 9 | name = "SignSpammer", 10 | category = Module.Category.MISC, 11 | description = "Automatically fills newly placed signs" 12 | ) 13 | object SignSpammer : Module() { 14 | @Setting 15 | var line1 = "" 16 | @Setting 17 | var line2 = "" 18 | @Setting 19 | var line3 = "" 20 | @Setting 21 | var line4 = "" 22 | } -------------------------------------------------------------------------------- /src/main/kotlin/me/zeroeightsix/kami/feature/module/Timer.kt: -------------------------------------------------------------------------------- 1 | package me.zeroeightsix.kami.feature.module 2 | 3 | import io.github.fablabsmc.fablabs.api.fiber.v1.annotation.Setting 4 | import me.zeroeightsix.kami.mixin.client.MixinRenderTickCounter 5 | 6 | /** 7 | * @see MixinRenderTickCounter 8 | */ 9 | @Module.Info(name = "Timer", category = Module.Category.MISC, description = "Modifies the speed the game runs at") 10 | object Timer : Module() { 11 | 12 | @Setting 13 | private var speed: @Setting.Constrain.Range(min = 0.1, max = 10.0, step = 0.1) Float = 2f 14 | 15 | fun getSpeedModifier() = if (enabled) { 16 | speed 17 | } else { 18 | 1f 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /src/main/kotlin/me/zeroeightsix/kami/feature/plugin/Plugin.kt: -------------------------------------------------------------------------------- 1 | package me.zeroeightsix.kami.feature.plugin 2 | 3 | import me.zeroeightsix.kami.feature.Feature 4 | import me.zeroeightsix.kami.feature.FeatureManager 5 | import me.zeroeightsix.kami.feature.FullFeature 6 | 7 | open class Plugin( 8 | name: String, 9 | description: String, 10 | hidden: Boolean = false, 11 | alwaysListening: Boolean = true, 12 | val features: List = listOf() 13 | ) : 14 | FullFeature(name, description, hidden, alwaysListening) { 15 | 16 | override fun onEnable() { 17 | super.onEnable() 18 | features.forEach { FeatureManager.addFeature(it) } 19 | } 20 | 21 | override fun onDisable() { 22 | super.onDisable() 23 | features.forEach { FeatureManager.removeFeature(it) } 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /src/main/kotlin/me/zeroeightsix/kami/gui/ImGuiScreen.kt: -------------------------------------------------------------------------------- 1 | package me.zeroeightsix.kami.gui 2 | 3 | import imgui.ImGui 4 | import imgui.flag.ImGuiConfigFlags 5 | import me.zeroeightsix.kami.gui.ImguiDSL.without 6 | import me.zeroeightsix.kami.mc 7 | import me.zeroeightsix.kami.util.Bind 8 | import net.minecraft.client.gui.screen.Screen 9 | import net.minecraft.client.util.InputUtil 10 | import net.minecraft.text.Text 11 | import org.lwjgl.glfw.GLFW 12 | 13 | /** 14 | * class for a screen for which input should be handled. 15 | * includes callback handlers 16 | */ 17 | abstract class ImGuiScreen(title: Text) : Screen(title) { 18 | 19 | override fun onClose() { 20 | ImGui.getIO().configFlags = ImGui.getIO().configFlags or ImGuiConfigFlags.NoMouse 21 | super.onClose() 22 | } 23 | 24 | override fun init() { 25 | super.init() 26 | ImGui.getIO().configFlags = ImGui.getIO().configFlags without ImGuiConfigFlags.NoMouse 27 | } 28 | 29 | override fun keyPressed(keyCode: Int, scanCode: Int, modifiers: Int): Boolean { 30 | val returned = super.keyPressed(keyCode, scanCode, modifiers) 31 | if (!returned) { 32 | KamiImgui.imguiGlfw.keyCallback(mc.window.handle, keyCode, scanCode, GLFW.GLFW_PRESS, modifiers) 33 | 34 | KamiImgui.keyQueue.add(Bind.Code(InputUtil.fromKeyCode(keyCode, scanCode))) 35 | } 36 | return returned 37 | } 38 | 39 | override fun keyReleased(keyCode: Int, scanCode: Int, modifiers: Int): Boolean { 40 | val returned = super.keyReleased(keyCode, scanCode, modifiers) 41 | if (!returned) { 42 | KamiImgui.imguiGlfw.keyCallback(mc.window.handle, keyCode, scanCode, GLFW.GLFW_RELEASE, modifiers) 43 | } 44 | return returned 45 | } 46 | 47 | override fun charTyped(chr: Char, keyCode: Int): Boolean { 48 | val returned = super.charTyped(chr, keyCode) 49 | if (!returned) { 50 | KamiImgui.imguiGlfw.charCallback(mc.window.handle, chr.toInt()) 51 | KamiImgui.charQueue.add(chr to keyCode) 52 | } 53 | return returned 54 | } 55 | } -------------------------------------------------------------------------------- /src/main/kotlin/me/zeroeightsix/kami/gui/KImGui.kt: -------------------------------------------------------------------------------- 1 | package me.zeroeightsix.kami.gui 2 | 3 | import imgui.ImGui 4 | import imgui.flag.ImGuiCol 5 | import kotlin.reflect.KMutableProperty0 6 | import me.zeroeightsix.kami.gui.ImguiDSL.addFrame 7 | import me.zeroeightsix.kami.gui.ImguiDSL.calcTextSize 8 | import me.zeroeightsix.kami.gui.ImguiDSL.colour 9 | import me.zeroeightsix.kami.gui.ImguiDSL.cursorPosX 10 | import me.zeroeightsix.kami.gui.ImguiDSL.get 11 | import me.zeroeightsix.kami.gui.ImguiDSL.plus 12 | import me.zeroeightsix.kami.gui.windows.Settings 13 | import me.zeroeightsix.kami.util.Bind 14 | 15 | private fun inputButton(text: String, value: T, hoverText: String?, width: Float? = null, onHover: () -> R): R? { 16 | val frameHeight = ImGui.getFrameHeight() 17 | val framePaddingY = ImGui.getStyle().framePaddingY 18 | val drawList = ImGui.getWindowDrawList() 19 | @Suppress("NAME_SHADOWING") val width = width ?: frameHeight 20 | 21 | val cursorPos = ImguiDSL.cursorPos 22 | val (x, y) = ImguiDSL.windowPos + cursorPos 23 | cursorPosX += (width - calcTextSize(value.toString()).x) / 2f 24 | ImGui.text(value.toString()) 25 | var hovered = ImGui.isItemHovered() 26 | ImguiDSL.cursorPos = cursorPos 27 | 28 | ImguiDSL.invisibleButton(value.toString(), width, frameHeight) {} 29 | 30 | hovered = hovered || ImGui.isItemHovered() 31 | drawList.addFrame( 32 | x, 33 | y, 34 | x + width, 35 | y + frameHeight, 36 | (if (hovered) ImGui.getStyle()[ImGuiCol.FrameBgHovered] else ImGui.getStyle()[ImGuiCol.FrameBg]).colour 37 | ) 38 | 39 | ImGui.sameLine(0f, ImGui.getStyle().itemInnerSpacingX) 40 | ImguiDSL.cursorPosY += (framePaddingY / 2f) 41 | ImGui.text(if (hovered) hoverText else text) 42 | ImguiDSL.cursorPosY -= (framePaddingY / 2f) 43 | 44 | return if (hovered) onHover() else null 45 | } 46 | 47 | fun charButton(text: String, char: KMutableProperty0, pressText: String? = "Type a character") { 48 | inputButton(text, char.get(), pressText) { 49 | ImGui.captureKeyboardFromApp() 50 | 51 | char.set((KamiImgui.charQueue.removeFirstOrNull() ?: return@inputButton).first) 52 | } 53 | } 54 | 55 | fun bindButton(text: String, bind: Bind, pressText: String? = "Press a key"): Bind? { 56 | val width = calcTextSize(bind.toString()).x.coerceAtLeast(20f) 57 | return inputButton(text, bind, pressText, width + ImGui.getStyle().framePaddingX * 2f) { 58 | ImGui.captureKeyboardFromApp() 59 | val c = KamiImgui.keyQueue.removeFirstOrNull() ?: return@inputButton null 60 | val modifiers = Settings.modifiersEnabled 61 | return@inputButton Bind( 62 | ImGui.getIO().keyCtrl && modifiers, 63 | ImGui.getIO().keyAlt && modifiers, 64 | ImGui.getIO().keyShift && modifiers, 65 | c 66 | ) 67 | } 68 | } -------------------------------------------------------------------------------- /src/main/kotlin/me/zeroeightsix/kami/gui/KamiHud.kt: -------------------------------------------------------------------------------- 1 | package me.zeroeightsix.kami.gui 2 | 3 | import me.zeroeightsix.kami.gui.widgets.EnabledWidgets 4 | import me.zeroeightsix.kami.gui.widgets.PinnableWidget 5 | import me.zeroeightsix.kami.mc 6 | import me.zeroeightsix.kami.tempSet 7 | import net.minecraft.client.util.math.MatrixStack 8 | 9 | object KamiHud { 10 | 11 | fun renderHud(matrixStack: MatrixStack) { 12 | if (mc.options.hudHidden) return 13 | KamiImgui.frame(matrixStack) { 14 | if (!EnabledWidgets.hideAll) { 15 | PinnableWidget.Companion::drawFadedBackground.tempSet(false) { 16 | EnabledWidgets.widgets.removeAll { widget -> 17 | widget.open && widget.pinned && widget.showWindow(false) 18 | } 19 | } 20 | } 21 | } 22 | } 23 | 24 | fun getScale() = mc.window.scaleFactor.toFloat() 25 | } 26 | -------------------------------------------------------------------------------- /src/main/kotlin/me/zeroeightsix/kami/gui/widgets/ActiveModules.kt: -------------------------------------------------------------------------------- 1 | package me.zeroeightsix.kami.gui.widgets 2 | 3 | import imgui.ImGui 4 | import me.zeroeightsix.kami.feature.FeatureManager 5 | import me.zeroeightsix.kami.gui.ImguiDSL.button 6 | import me.zeroeightsix.kami.gui.ImguiDSL.child 7 | import me.zeroeightsix.kami.gui.ImguiDSL.imgui 8 | import me.zeroeightsix.kami.gui.ImguiDSL.menuItem 9 | import me.zeroeightsix.kami.gui.text.CompiledText 10 | 11 | val modulesVariable = object : CompiledText.StringVariable( 12 | "modules", 13 | true, 14 | { 15 | FeatureManager.modules.filter { it.enabled && it.showInActiveModules }.joinToString("\n") { it.name } 16 | } 17 | ) { 18 | var filter = "".imgui 19 | override var editLabel: String = "(active modules)" 20 | 21 | override fun edit(variableMap: Map CompiledText.Variable>) { 22 | ImGui.separator() 23 | ImGui.text("Show the following modules in the list:") 24 | ImGui.inputText("Filter##active-modules-filter", filter) 25 | child("active-modules-show-list", -1f, 60.0f) { 26 | FeatureManager.modules.filter { 27 | !it.hidden && it.name.toLowerCase().contains(filter.get().toLowerCase()) 28 | }.forEach { 29 | menuItem(it.name, selected = it.showInActiveModules) { 30 | it.showInActiveModules = !it.showInActiveModules 31 | } 32 | } 33 | } 34 | button("Check all") { 35 | FeatureManager.modules.filter { !it.hidden }.forEach { it.showInActiveModules = true } 36 | } 37 | ImGui.sameLine() 38 | button("Uncheck all") { 39 | FeatureManager.modules.filter { !it.hidden }.forEach { it.showInActiveModules = false } 40 | } 41 | ImGui.separator() 42 | } 43 | } 44 | 45 | object ActiveModules : TextPinnableWidget( 46 | "Active modules", 47 | text = mutableListOf( 48 | CompiledText( 49 | mutableListOf( 50 | CompiledText.VariablePart(modulesVariable, extraSpace = false) 51 | ) 52 | ) 53 | ), 54 | position = Position.TOP_RIGHT, 55 | alignment = Alignment.RIGHT 56 | ) -------------------------------------------------------------------------------- /src/main/kotlin/me/zeroeightsix/kami/gui/widgets/Coordinates.kt: -------------------------------------------------------------------------------- 1 | package me.zeroeightsix.kami.gui.widgets 2 | 3 | import me.zeroeightsix.kami.Colour 4 | import me.zeroeightsix.kami.gui.text.CompiledText 5 | import me.zeroeightsix.kami.gui.text.VarMap 6 | 7 | object Coordinates : TextPinnableWidget( 8 | "Coordinates", 9 | text = mutableListOf( 10 | CompiledText( 11 | mutableListOf( 12 | CompiledText.VariablePart(VarMap["facing_axis"]!!()), 13 | CompiledText.VariablePart(VarMap["x"]!!()).also { 14 | it.colour = Colour(0.64f, 1f, 1f, 1f) 15 | }, 16 | CompiledText.VariablePart(VarMap["y"]!!()).also { 17 | it.colour = Colour(0.64f, 1f, 1f, 1f) 18 | }, 19 | CompiledText.VariablePart(VarMap["z"]!!()).also { 20 | it.colour = Colour(0.64f, 1f, 1f, 1f) 21 | } 22 | ) 23 | ) 24 | ), 25 | position = Position.BOTTOM_LEFT 26 | ) 27 | -------------------------------------------------------------------------------- /src/main/kotlin/me/zeroeightsix/kami/gui/widgets/Information.kt: -------------------------------------------------------------------------------- 1 | package me.zeroeightsix.kami.gui.widgets 2 | 3 | import me.zeroeightsix.kami.Colour 4 | import me.zeroeightsix.kami.gui.ImguiDSL.imgui 5 | import me.zeroeightsix.kami.gui.text.CompiledText 6 | import me.zeroeightsix.kami.gui.text.VarMap 7 | 8 | object Information : TextPinnableWidget( 9 | "Information", 10 | mutableListOf( 11 | CompiledText( 12 | mutableListOf( 13 | CompiledText.VariablePart(VarMap["client"]!!()), 14 | CompiledText.VariablePart(VarMap["version"]!!(), extraSpace = false) 15 | ) 16 | ), 17 | CompiledText( 18 | mutableListOf( 19 | CompiledText.VariablePart(VarMap["fps"]!!()), 20 | CompiledText.LiteralPart("fps".imgui).also { 21 | it.colour = Colour(0.64f, 1f, 1f, 1f) 22 | }, 23 | CompiledText.VariablePart(VarMap["tps"]!!()), 24 | CompiledText.LiteralPart("tps".imgui, extraSpace = false).also { 25 | it.colour = Colour(0.64f, 1f, 1f, 1f) 26 | } 27 | ) 28 | ) 29 | ), 30 | position = Position.TOP_LEFT 31 | ) -------------------------------------------------------------------------------- /src/main/kotlin/me/zeroeightsix/kami/gui/windows/modules/Payloads.kt: -------------------------------------------------------------------------------- 1 | package me.zeroeightsix.kami.gui.windows.modules 2 | 3 | import me.zeroeightsix.kami.feature.module.Module 4 | 5 | internal data class ModulePayload(val modules: MutableSet, val source: Modules.ModuleWindow, val groupName: String? = null) { 6 | fun moveTo(target: Modules.ModuleWindow, targetGroup: String) { 7 | // Start by removing the module(s) from the payload's source 8 | val newSourceGroups = mutableMapOf>() 9 | for ((group, list) in source.groups) { 10 | val newList = list.filter { !this.modules.contains(it) }.toMutableList() 11 | if (newList.isNotEmpty()) { 12 | newSourceGroups[group] = newList 13 | } 14 | } 15 | source.groups = newSourceGroups 16 | 17 | // Add the modules to target window 18 | val newTargetGroups = target.groups.toMutableMap() 19 | val list = (newTargetGroups[targetGroup] ?: mutableListOf()).toMutableList() 20 | list.addAll(modules) 21 | newTargetGroups[targetGroup] = list 22 | target.groups = newTargetGroups 23 | } 24 | 25 | /** 26 | * Generate a window title based on this payload's contents 27 | */ 28 | fun inventName(): String { 29 | if (groupName != null) 30 | return groupName 31 | return when (modules.size) { 32 | 1 -> modules.find { true }!!.name 33 | else -> "${modules.size} modules" 34 | } 35 | } 36 | } 37 | 38 | internal object Payloads { 39 | 40 | const val KAMI_MODULE_PAYLOAD = "KAMI_MODS" 41 | } 42 | -------------------------------------------------------------------------------- /src/main/kotlin/me/zeroeightsix/kami/setting/InvalidValueException.kt: -------------------------------------------------------------------------------- 1 | package me.zeroeightsix.kami.setting 2 | 3 | class InvalidValueException(val reason: String) : RuntimeException() 4 | -------------------------------------------------------------------------------- /src/main/kotlin/me/zeroeightsix/kami/setting/ProperCaseConvention.kt: -------------------------------------------------------------------------------- 1 | package me.zeroeightsix.kami.setting 2 | 3 | import io.github.fablabsmc.fablabs.api.fiber.v1.annotation.SettingNamingConvention 4 | 5 | object ProperCaseConvention : SettingNamingConvention { 6 | override fun name(name: String?): String = name!!.replace("_|-", " ").capitalize() 7 | } 8 | -------------------------------------------------------------------------------- /src/main/kotlin/me/zeroeightsix/kami/util/Friends.kt: -------------------------------------------------------------------------------- 1 | package me.zeroeightsix.kami.util 2 | 3 | import com.mojang.authlib.GameProfile 4 | import io.github.fablabsmc.fablabs.api.fiber.v1.annotation.Setting 5 | import io.github.fablabsmc.fablabs.api.fiber.v1.tree.PropertyMirror 6 | import me.zeroeightsix.kami.setting.KamiConfig 7 | import me.zeroeightsix.kami.setting.internalService 8 | 9 | object Friends { 10 | 11 | private var mirror = PropertyMirror.create(KamiConfig.friendsType) 12 | 13 | @Setting 14 | var friends = mutableListOf() 15 | 16 | init { 17 | KamiConfig.register(internalService("friends"), this).run { 18 | lookupAndBind("Friends", mirror) 19 | } 20 | } 21 | 22 | @JvmStatic 23 | fun isFriend(name: String?): Boolean { 24 | return friends.stream().anyMatch { 25 | it.name.equals(name, ignoreCase = true) 26 | } 27 | } 28 | 29 | fun addFriend(profile: GameProfile) { 30 | if (!isFriend(profile.name)) { 31 | val list = friends.toMutableList() 32 | list.add(profile) 33 | mirror.value = list 34 | } 35 | } 36 | 37 | fun removeFriend(profile: GameProfile) { 38 | if (isFriend(profile.name)) { 39 | val list = friends.toMutableList() 40 | list.removeIf { it == profile } 41 | mirror.value = list 42 | } 43 | } 44 | } -------------------------------------------------------------------------------- /src/main/kotlin/me/zeroeightsix/kami/util/InstrumentMap.kt: -------------------------------------------------------------------------------- 1 | package me.zeroeightsix.kami.util 2 | 3 | import net.minecraft.block.enums.Instrument 4 | import net.minecraft.util.math.BlockPos 5 | import java.util.EnumMap 6 | 7 | class InstrumentMap { 8 | private val instruments = EnumMap>(Instrument::class.java) 9 | 10 | operator fun get(instrument: Instrument): Array { 11 | return instruments.getOrPut(instrument) { arrayOfNulls(25) } 12 | } 13 | 14 | fun add(instrument: Instrument, note: Int, pos: BlockPos?) { 15 | this[instrument][note] = pos 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /src/main/kotlin/me/zeroeightsix/kami/util/OutlineVertexConsumer.kt: -------------------------------------------------------------------------------- 1 | package me.zeroeightsix.kami.util 2 | 3 | import net.fabricmc.api.EnvType 4 | import net.fabricmc.api.Environment 5 | import net.minecraft.client.render.FixedColorVertexConsumer 6 | import net.minecraft.client.render.VertexConsumer 7 | 8 | @Environment(EnvType.CLIENT) 9 | class OutlineVertexConsumer( 10 | private val delegate: VertexConsumer, 11 | i: Int, 12 | j: Int, 13 | k: Int, 14 | l: Int 15 | ) : FixedColorVertexConsumer() { 16 | private var x = 0.0 17 | private var y = 0.0 18 | private var z = 0.0 19 | private var u = 0f 20 | private var v = 0f 21 | override fun fixedColor(i: Int, j: Int, k: Int, l: Int) {} 22 | override fun vertex(d: Double, e: Double, f: Double): VertexConsumer { 23 | x = d 24 | y = e 25 | z = f 26 | return this 27 | } 28 | 29 | override fun color(i: Int, j: Int, k: Int, l: Int): VertexConsumer { 30 | return this 31 | } 32 | 33 | override fun texture(f: Float, g: Float): VertexConsumer { 34 | u = f 35 | v = g 36 | return this 37 | } 38 | 39 | override fun overlay(i: Int, j: Int): VertexConsumer { 40 | return this 41 | } 42 | 43 | override fun light(i: Int, j: Int): VertexConsumer { 44 | return this 45 | } 46 | 47 | override fun normal(f: Float, g: Float, h: Float): VertexConsumer { 48 | return this 49 | } 50 | 51 | override fun vertex( 52 | f: Float, 53 | g: Float, 54 | h: Float, 55 | i: Float, 56 | j: Float, 57 | k: Float, 58 | l: Float, 59 | m: Float, 60 | n: Float, 61 | o: Int, 62 | p: Int, 63 | q: Float, 64 | r: Float, 65 | s: Float 66 | ) { 67 | delegate.vertex(f.toDouble(), g.toDouble(), h.toDouble()).color(fixedRed, fixedGreen, fixedBlue, fixedAlpha) 68 | .texture(m, n).next() 69 | } 70 | 71 | override fun next() { 72 | delegate.vertex(x, y, z).color(fixedRed, fixedGreen, fixedBlue, fixedAlpha).texture(u, v).next() 73 | } 74 | 75 | init { 76 | super.fixedColor(i, j, k, l) 77 | } 78 | } -------------------------------------------------------------------------------- /src/main/kotlin/me/zeroeightsix/kami/util/ResettableLazy.kt: -------------------------------------------------------------------------------- 1 | package me.zeroeightsix.kami.util 2 | 3 | class ResettableLazy(private var initializer: () -> T) : Lazy { 4 | 5 | private var inner = Inner() 6 | 7 | override val value: T 8 | get() = inner.value.value 9 | 10 | override fun isInitialized(): Boolean = inner.value.isInitialized() 11 | 12 | fun invalidate() { 13 | // No need to create a new Inner if no value has been calculated yet 14 | if (isInitialized()) 15 | inner = Inner() 16 | } 17 | 18 | private inner class Inner { 19 | val value = lazy(initializer) 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /src/main/kotlin/me/zeroeightsix/kami/util/TextsDSL.kt: -------------------------------------------------------------------------------- 1 | package me.zeroeightsix.kami.util 2 | 3 | import me.zeroeightsix.kami.unreachable 4 | import net.minecraft.text.LiteralText 5 | import net.minecraft.text.MutableText 6 | import net.minecraft.util.Formatting 7 | 8 | // Required to scope the LiteralText in the String.invoke extension function 9 | class TextBuilder(string: String) : LiteralText(string) { 10 | /** 11 | * Creates a formatted [MutableText] from `this` String, but does not append it to this [TextBuilder] 12 | */ 13 | operator fun String.invoke( 14 | formatting: Formatting? = null, 15 | block: TextBuilder.() -> Unit = {} 16 | ): MutableText = TextBuilder(this).also { 17 | formatting?.let { f -> it.formatted = f } 18 | }.also(block) 19 | 20 | /** 21 | * Calls the invocation operator overload on this string with no parameters, and adds it to this [TextBuilder]. 22 | */ 23 | operator fun String.unaryPlus() = +this() 24 | 25 | /** 26 | * Adds `this` [MutableText] to the scoped [TextBuilder] 27 | */ 28 | operator fun MutableText.unaryPlus(): MutableText = this@TextBuilder.append(this) 29 | 30 | var formatted: Formatting 31 | get() = unreachable() 32 | set(value) { 33 | this.formatted(value) 34 | } 35 | } 36 | 37 | fun text( 38 | formatting: Formatting? = null, 39 | root: String = "", 40 | block: TextBuilder.() -> Unit = {} 41 | ) = TextBuilder(root).also { 42 | formatting?.let { f -> it.formatted = f } 43 | }.also(block) 44 | -------------------------------------------------------------------------------- /src/main/kotlin/me/zeroeightsix/kami/util/Viewblock.kt: -------------------------------------------------------------------------------- 1 | package me.zeroeightsix.kami.util 2 | 3 | import me.zeroeightsix.kami.feature.module.Module 4 | import me.zeroeightsix.kami.feature.module.Scaffold.eyesPos 5 | import net.minecraft.client.MinecraftClient 6 | import net.minecraft.client.network.ClientPlayerEntity 7 | import net.minecraft.client.world.ClientWorld 8 | import net.minecraft.network.packet.c2s.play.PlayerMoveC2SPacket 9 | import net.minecraft.util.math.BlockPos 10 | import net.minecraft.util.math.Direction 11 | import net.minecraft.util.math.MathHelper 12 | import net.minecraft.util.math.Vec3d 13 | import net.minecraft.world.World 14 | import kotlin.math.atan2 15 | import kotlin.math.sqrt 16 | 17 | object Viewblock { 18 | @JvmStatic 19 | fun getNeededRotations(player: ClientPlayerEntity, vec: Vec3d): FloatArray { 20 | val eyesPos = player.eyesPos 21 | val diffX = vec.x - eyesPos.x 22 | val diffY = vec.y - eyesPos.y 23 | val diffZ = vec.z - eyesPos.z 24 | val diffXZ = sqrt(diffX * diffX + diffZ * diffZ) 25 | val yaw = Math.toDegrees(atan2(diffZ, diffX)).toFloat() - 90f 26 | val pitch = (-Math.toDegrees(atan2(diffY, diffXZ))).toFloat() 27 | return floatArrayOf( 28 | Wrapper.getPlayer().yaw + 29 | MathHelper.wrapDegrees(yaw - Wrapper.getPlayer().yaw), 30 | Wrapper.getPlayer().pitch + MathHelper 31 | .wrapDegrees(pitch - Wrapper.getPlayer().pitch) 32 | ) 33 | } 34 | 35 | @JvmStatic 36 | fun faceVectorPacketInstant(player: ClientPlayerEntity, vec: Vec3d, mc: MinecraftClient) { 37 | val rotations = getNeededRotations(player, vec) 38 | mc.networkHandler!!.sendPacket( 39 | PlayerMoveC2SPacket.LookOnly( 40 | rotations[0], 41 | rotations[1], 42 | Wrapper.getPlayer().isOnGround 43 | ) 44 | ) 45 | } 46 | 47 | @JvmStatic 48 | fun getIrreplaceableNeighbour(world: World, blockPos: BlockPos?): Pair? { 49 | if (blockPos == null) return blockPos 50 | for (side in Direction.values()) { 51 | val neighbour = blockPos.offset(side) 52 | if (world.getBlockState(neighbour)?.material?.isReplaceable == false) return neighbour to side.opposite 53 | } 54 | return null 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /src/main/kotlin/me/zeroeightsix/kami/world/KamiRenderLayers.kt: -------------------------------------------------------------------------------- 1 | package me.zeroeightsix.kami.world 2 | 3 | import me.zeroeightsix.kami.mc 4 | import net.minecraft.client.MinecraftClient.IS_SYSTEM_MAC 5 | import net.minecraft.client.gl.Framebuffer 6 | import net.minecraft.client.render.RenderLayer 7 | import net.minecraft.client.render.RenderPhase 8 | import net.minecraft.client.render.VertexFormats 9 | import net.minecraft.client.texture.SpriteAtlasTexture 10 | import org.lwjgl.opengl.GL11 11 | 12 | object KamiRenderLayers { 13 | private val smoothModel = RenderPhase.ShadeModel(true) 14 | private val disableLightmap = RenderPhase.Lightmap(false) 15 | private val mipmapTexture = RenderPhase.Texture(SpriteAtlasTexture.BLOCK_ATLAS_TEXTURE, false, true) 16 | 17 | @Suppress("INACCESSIBLE_TYPE") 18 | val solidFiltered: RenderLayer = RenderLayer.of( 19 | "kami_solid_filtered", 20 | VertexFormats.POSITION_COLOR_TEXTURE_LIGHT_NORMAL, 21 | GL11.GL_QUADS, 22 | 2097152 / 2, 23 | true, 24 | false, 25 | RenderLayer.MultiPhaseParameters.builder() 26 | .shadeModel(smoothModel) 27 | .lightmap(disableLightmap) 28 | .texture(mipmapTexture) 29 | .build(false) 30 | ) 31 | 32 | @Suppress("INACCESSIBLE_TYPE") 33 | val solidFilteredOutline: RenderLayer = RenderLayer.of( 34 | "kami_solid_filtered_outline", 35 | VertexFormats.POSITION_COLOR_TEXTURE, 36 | GL11.GL_QUADS, 37 | 2097152 / 4, 38 | true, 39 | false, 40 | RenderLayer.MultiPhaseParameters.builder() 41 | .lightmap(disableLightmap) 42 | .texture(mipmapTexture) 43 | .build(false) 44 | ) 45 | 46 | val layers = mapOf( 47 | solidFiltered to VertexFormats.POSITION_COLOR_TEXTURE_LIGHT_NORMAL, 48 | solidFilteredOutline to VertexFormats.POSITION_COLOR_TEXTURE 49 | ) 50 | 51 | val filteredFramebuffer by lazy { 52 | Framebuffer(mc.window.framebufferWidth, mc.window.framebufferHeight, true, IS_SYSTEM_MAC) 53 | } 54 | } -------------------------------------------------------------------------------- /src/main/resources/assets/kami/Minecraftia.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zeroeightysix/KAMI/7195851c1c319cdd0b79ff5618fde7e2f1b7ab5a/src/main/resources/assets/kami/Minecraftia.ttf -------------------------------------------------------------------------------- /src/main/resources/assets/kami/kamired_square.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zeroeightysix/KAMI/7195851c1c319cdd0b79ff5618fde7e2f1b7ab5a/src/main/resources/assets/kami/kamired_square.png -------------------------------------------------------------------------------- /src/main/resources/assets/kami/shaders/post/entity_blur_outline.json: -------------------------------------------------------------------------------- 1 | { 2 | "targets": [ 3 | "swap", 4 | "final" 5 | ], 6 | "passes": [ 7 | { 8 | "name": "kami:entity_sharp_outline", 9 | "intarget": "final", 10 | "outtarget": "swap" 11 | }, 12 | { 13 | "name": "blur", 14 | "intarget": "swap", 15 | "outtarget": "final", 16 | "uniforms": [ 17 | { 18 | "name": "BlurDir", 19 | "values": [ 1.0, 0.0 ] 20 | }, 21 | { 22 | "name": "Radius", 23 | "values": [ 1.0 ] 24 | } 25 | ] 26 | }, 27 | { 28 | "name": "blur", 29 | "intarget": "final", 30 | "outtarget": "swap", 31 | "uniforms": [ 32 | { 33 | "name": "BlurDir", 34 | "values": [ 0.0, 1.0 ] 35 | }, 36 | { 37 | "name": "Radius", 38 | "values": [ 1.0 ] 39 | } 40 | ] 41 | }, 42 | { 43 | "name": "blit", 44 | "intarget": "swap", 45 | "outtarget": "final" 46 | } 47 | ] 48 | } 49 | -------------------------------------------------------------------------------- /src/main/resources/assets/kami/shaders/post/entity_sharp_outline.json: -------------------------------------------------------------------------------- 1 | { 2 | "targets": [ 3 | "swap", 4 | "final" 5 | ], 6 | "passes": [ 7 | { 8 | "name": "kami:entity_sharp_outline", 9 | "intarget": "final", 10 | "outtarget": "swap" 11 | }, 12 | { 13 | "name": "blit", 14 | "intarget": "swap", 15 | "outtarget": "final" 16 | } 17 | ] 18 | } 19 | -------------------------------------------------------------------------------- /src/main/resources/assets/kami/shaders/program/entity_sharp_outline.json: -------------------------------------------------------------------------------- 1 | { 2 | "blend": { 3 | "func": "add", 4 | "srcrgb": "srcalpha", 5 | "dstrgb": "1-srcalpha" 6 | }, 7 | "vertex": "sobel", 8 | "fragment": "kami:entity_sharp_sobel", 9 | "attributes": [ 10 | "Position" 11 | ], 12 | "samplers": [ 13 | { 14 | "name": "DiffuseSampler" 15 | } 16 | ], 17 | "uniforms": [ 18 | { 19 | "name": "ProjMat", 20 | "type": "matrix4x4", 21 | "count": 16, 22 | "values": [ 23 | 1.0, 24 | 0.0, 25 | 0.0, 26 | 0.0, 27 | 0.0, 28 | 1.0, 29 | 0.0, 30 | 0.0, 31 | 0.0, 32 | 0.0, 33 | 1.0, 34 | 0.0, 35 | 0.0, 36 | 0.0, 37 | 0.0, 38 | 1.0 39 | ] 40 | }, 41 | { 42 | "name": "InSize", 43 | "type": "float", 44 | "count": 2, 45 | "values": [ 46 | 1.0, 47 | 1.0 48 | ] 49 | }, 50 | { 51 | "name": "OutSize", 52 | "type": "float", 53 | "count": 2, 54 | "values": [ 55 | 1.0, 56 | 1.0 57 | ] 58 | } 59 | ] 60 | } 61 | -------------------------------------------------------------------------------- /src/main/resources/assets/kami/shaders/program/entity_sharp_sobel.fsh: -------------------------------------------------------------------------------- 1 | #version 110 2 | 3 | uniform sampler2D DiffuseSampler; 4 | 5 | varying vec2 texCoord; 6 | varying vec2 oneTexel; 7 | 8 | void main(){ 9 | vec4 center = texture2D(DiffuseSampler, texCoord); 10 | vec4 left = texture2D(DiffuseSampler, texCoord - vec2(oneTexel.x, 0.0)); 11 | vec4 right = texture2D(DiffuseSampler, texCoord + vec2(oneTexel.x, 0.0)); 12 | vec4 up = texture2D(DiffuseSampler, texCoord - vec2(0.0, oneTexel.y)); 13 | vec4 down = texture2D(DiffuseSampler, texCoord + vec2(0.0, oneTexel.y)); 14 | float leftDiff = left.a - center.a; 15 | float rightDiff = right.a - center.a; 16 | float upDiff = up.a - center.a; 17 | float downDiff = down.a - center.a; 18 | float total = leftDiff + rightDiff + downDiff + upDiff; 19 | vec3 outColor = center.rgb * center.a + left.rgb * left.a + right.rgb * right.a + up.rgb * up.a + down.rgb * down.a; 20 | gl_FragColor = vec4(outColor / total, clamp(total, 0.0, 1.0)); 21 | } 22 | -------------------------------------------------------------------------------- /src/main/resources/fabric.mod.json: -------------------------------------------------------------------------------- 1 | { 2 | "schemaVersion": 1, 3 | "id": "kami", 4 | "version": "${version}", 5 | "name": "KAMI", 6 | "description": "KAMI [神]: A minecraft utility mod", 7 | "authors": [ 8 | "zeroeightysix", 9 | "nopjmp", 10 | "l1ving", 11 | "humboldt123", 12 | "nothub", 13 | "LordMZTE", 14 | "zfih" 15 | ], 16 | "contact": { 17 | "sources": "https://github.com/zeroeightysix/kami/" 18 | }, 19 | "license": "LGPL-3.0", 20 | "icon": "assets/kami/kamired_square.png", 21 | "environment": "*", 22 | "entrypoints": { 23 | "main": [ 24 | "me.zeroeightsix.kami.KamiMod" 25 | ] 26 | }, 27 | "mixins": [ 28 | "kami.mixins.json" 29 | ], 30 | "depends": { 31 | "fabricloader": ">=0.4.0", 32 | "minecraft": "1.16.5" 33 | }, 34 | "suggests": { 35 | "fabritone": ">=1.6.2" 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /src/main/resources/kami.mixins.json: -------------------------------------------------------------------------------- 1 | { 2 | "required": true, 3 | "compatibilityLevel": "JAVA_8", 4 | "package": "me.zeroeightsix.kami.mixin.client", 5 | "client": [ 6 | "IBackedConfigLeaf", 7 | "IBlockModelRenderer", 8 | "ICamera", 9 | "IChatMessageC2SPacket", 10 | "IChatMessageS2CPacket", 11 | "IChunkData", 12 | "IClientPlayerInteractionManager", 13 | "IDimensionType", 14 | "IDisconnectedScreen", 15 | "IEntity", 16 | "IEntitySelector", 17 | "IEntityVelocityUpdateS2CPacket", 18 | "IExplosionS2CPacket", 19 | "IGameRenderer", 20 | "IInputUtilType", 21 | "IKeyBinding", 22 | "IMatrix4f", 23 | "IMatrixStack", 24 | "IMatrixStack$Entry", 25 | "IMinecraftClient", 26 | "IMiningToolItem", 27 | "IPlayerMoveC2SPacket", 28 | "IPlayerPositionLookS2CPacket", 29 | "IShulkerBoxBlockEntity", 30 | "MixinBackedConfigLeaf", 31 | "MixinBackgroundRenderer", 32 | "MixinBeaconBlockEntity", 33 | "MixinBlockBufferBuilderStorage", 34 | "MixinBlockEntityRenderDispatcher", 35 | "MixinBossBarHud", 36 | "MixinBuiltChunk", 37 | "MixinCamera", 38 | "MixinChatScreen", 39 | "MixinClientChunkManager", 40 | "MixinClientConnection", 41 | "MixinClientPlayerEntity", 42 | "MixinClientPlayerInteractionManager", 43 | "MixinClientPlayNetworkHandler", 44 | "MixinClientWorld", 45 | "MixinComeCommand", 46 | "MixinCommandSuggestor", 47 | "MixinConfigType", 48 | "MixinDecoderHandler", 49 | "MixinEntity", 50 | "MixinEntityRenderer", 51 | "MixinGameRenderer", 52 | "MixinHandledScreen", 53 | "MixinHorseBaseEntity", 54 | "MixinInGameHud", 55 | "MixinInGameOverlayRenderer", 56 | "MixinInput", 57 | "MixinKeyboard", 58 | "MixinLightmapTextureManager", 59 | "MixinLivingEntityRenderer", 60 | "MixinMinecraftClient", 61 | "MixinMouse", 62 | "MixinNetHandlerPlayClient", 63 | "MixinPigEntity", 64 | "MixinPlayerEntity", 65 | "MixinPlayerListHud", 66 | "MixinPojoMemberProcessorImpl", 67 | "MixinRebuildTask", 68 | "MixinRenderPlayer", 69 | "MixinRenderTickCounter", 70 | "MixinStriderEntity", 71 | "MixinWorldRenderer" 72 | ] 73 | } 74 | -------------------------------------------------------------------------------- /src/main/resources/minify-all.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # This script depends on json-minify 4 | # https://www.npmjs.com/package/json-minify 5 | 6 | # Copyright (c) DaPorkchop_ 7 | # 17/6/2017 8 | 9 | file_list=() 10 | while IFS= read -d $'\0' -r file ; do 11 | file_list=("${file_list[@]}" "$file") 12 | done < <(find "." -type f -name "*.json" -print0) 13 | 14 | # echo "${file_list[@]}" 15 | 16 | for i in "${file_list[@]}" 17 | do 18 | : 19 | echo $i 20 | temp=$( json-minify $i ) 21 | echo $temp > $i 22 | done 23 | 24 | echo "Done!" 25 | echo "Minified ${#file_list[@]} files!" 26 | --------------------------------------------------------------------------------