From f462e3394eb1c75c04727c24fcaf6f38f34ecae2 Mon Sep 17 00:00:00 2001 From: Saereth Date: Tue, 7 Apr 2026 20:29:24 -0700 Subject: [PATCH 1/4] initial 26.1.1 multiloader port --- .gitignore | 8 +- README.md | 25 +- build.gradle | 66 +--- buildSrc/build.gradle | 3 + .../src/main/groovy/multiloader-common.gradle | 99 ++++++ .../src/main/groovy/multiloader-loader.gradle | 95 ++++++ changes.md | 58 ++-- common/build.gradle | 41 +-- .../com/irtimaled/bbor/client/Camera.java | 2 +- .../client/renderers/AbstractRenderer.java | 16 - .../bbor/client/renderers/Renderer.java | 17 +- .../specialeffect/eyemine/EyeMineClient.java | 20 +- .../eyemine/client/CreativeClientHelper.java | 4 +- .../eyemine/client/EyeMineRenderType.java | 55 +--- .../eyemine/client/Keybindings.java | 11 + .../eyemine/client/MainClientHandler.java | 18 +- .../client/gui/CustomCreateWorldScreen.java | 10 +- .../gui/crosshair/ICrosshairOverlay.java | 4 +- .../client/gui/crosshair/IconOverlay.java | 52 ++-- .../gui/crosshair/JoystickControlOverlay.java | 28 +- .../client/gui/crosshair/StateOverlay.java | 97 ++---- .../eyemine/event/BlockOutlineEvent.java | 18 +- .../eyemine/event/EventHolder.java | 16 + .../eyemine/event/EventResult.java | 12 + .../eyemine/event/EyeMineEvents.java | 77 +++++ .../eyemine/event/ScreenSetResult.java | 8 + .../eyemine/mixin/KeyboardInputMixin.java | 58 ++-- .../eyemine/mixin/LivingEntityMixin.java | 38 +-- .../eyemine/mixin/MouseHandlerMixin.java | 10 +- .../eyemine/mixin/TitleScreenMixin.java | 31 +- .../eyemine/packets/NetworkService.java | 25 ++ .../eyemine/packets/PacketHandler.java | 44 +-- .../messages/ActivateBlockAtPosition.java | 19 +- .../packets/messages/AddItemToHotbar.java | 10 +- .../messages/ChangeFlyingStateMessage.java | 8 +- .../packets/messages/GatherBlockMessage.java | 10 +- .../packets/messages/SendCommandMessage.java | 10 +- .../TeleportPlayerToSpawnPointMessage.java | 61 ++-- .../eyemine/platform/EyeMineConfig.java | 225 ++------------ .../eyemine/platform/InventoryConfig.java | 176 ++--------- .../eyemine/platform/Services.java | 27 ++ .../services/IEyeMineConfigService.java | 36 +++ .../services/IInventoryConfigService.java | 29 ++ .../platform/services/IPlatformHelper.java | 7 + .../submod/mining/ContinuouslyMine.java | 28 +- .../eyemine/submod/mining/DwellMine.java | 19 +- .../eyemine/submod/mining/GatherDrops.java | 17 +- .../eyemine/submod/mining/MineOne.java | 19 +- .../eyemine/submod/misc/AutoOpenDoors.java | 10 +- .../eyemine/submod/misc/AutoPillar.java | 27 +- .../submod/misc/ContinuouslyAttack.java | 38 +-- .../submod/misc/DefaultConfigForNewWorld.java | 57 ++-- .../eyemine/submod/misc/DwellBuild.java | 23 +- .../eyemine/submod/misc/IronSights.java | 12 +- .../submod/misc/NightVisionHelper.java | 30 +- .../eyemine/submod/misc/OpenChat.java | 12 +- .../eyemine/submod/misc/OpenTablesChests.java | 22 +- .../eyemine/submod/misc/PickBlock.java | 12 +- .../eyemine/submod/misc/QuickCommands.java | 50 ++-- .../eyemine/submod/misc/SwapMinePlace.java | 27 +- .../eyemine/submod/misc/UseItem.java | 46 +-- .../eyemine/submod/mouse/MouseHandlerMod.java | 39 ++- .../eyemine/submod/movement/AutoFly.java | 34 +-- .../eyemine/submod/movement/AutoJump.java | 15 +- .../submod/movement/BoatController.java | 4 +- .../eyemine/submod/movement/Dismount.java | 31 +- .../submod/movement/EasyLadderClimb.java | 8 +- .../eyemine/submod/movement/MoveWithGaze.java | 38 +-- .../submod/movement/MoveWithGaze2.java | 17 +- .../eyemine/submod/movement/Sneak.java | 15 +- .../eyemine/submod/movement/Swim.java | 15 +- .../eyemine/submod/utils/DebugAverageFps.java | 4 +- .../eyemine/submod/utils/DwellAction.java | 14 +- .../eyemine/utils/MouseHelper.java | 8 +- .../manager/ChestInventoryManager.java | 2 +- .../manager/CreativeInventoryManager.java | 4 +- .../manager/SurvivalInventoryManager.java | 10 +- .../com/specialeffect/utils/ModUtils.java | 30 +- .../resources/META-INF/accesstransformer.cfg | 3 + .../main/resources/eyemine-common.mixins.json | 2 +- .../src/main/resources/eyemine.accesswidener | 6 +- common/src/main/resources/eyemine.common.json | 3 - common/src/main/resources/pack.mcmeta | 2 +- fabric/build.gradle | 107 ++----- .../eyemine/EyeMineClientFabric.java | 104 +++++-- .../config/EyeMineModMenuIntegration.java | 24 +- .../mixin/FabricKeyboardHandlerMixin.java | 33 ++ .../eyemine/mixin/FabricSetScreenMixin.java | 26 ++ .../platform/fabric/EyeMineConfigImpl.java | 198 +++--------- .../platform/fabric/FabricNetworkService.java | 41 +++ .../platform/fabric/FabricPlatformHelper.java | 21 ++ .../platform/fabric/InventoryConfigImpl.java | 156 ++-------- ...ecialeffect.eyemine.packets.NetworkService | 1 + ...ne.platform.services.IEyeMineConfigService | 1 + ....platform.services.IInventoryConfigService | 1 + ....eyemine.platform.services.IPlatformHelper | 1 + .../main/resources/eyemine.fabric.mixins.json | 13 + fabric/src/main/resources/fabric.mod.json | 25 +- forge/build.gradle | 91 ------ forge/gradle.properties | 1 - .../com/inventory/config/InventoryConfig.java | 136 --------- .../eyemine/client/forge/ClientHandler.java | 28 -- .../eyemine/config/EyeMineConfig.java | 281 ------------------ .../eyemine/forge/EyeMineForge.java | 53 ---- .../platform/forge/EyeMineConfigImpl.java | 133 --------- .../platform/forge/InventoryConfigImpl.java | 105 ------- forge/src/main/resources/META-INF/mods.toml | 42 --- forge/src/main/resources/eyemine_logo.png | Bin 6320 -> 0 bytes gradle.properties | 35 ++- gradle/wrapper/gradle-wrapper.jar | Bin 43453 -> 48966 bytes gradle/wrapper/gradle-wrapper.properties | 2 +- neoforge/build.gradle | 106 ++----- .../client/neoforge/ClientHandler.java | 112 ++++++- .../eyemine/neoforge/EyeMineNeoForge.java | 66 ++-- .../platform/neoforge/EyeMineConfigImpl.java | 164 +++------- .../neoforge/InventoryConfigImpl.java | 129 ++------ .../neoforge/NeoForgeNetworkService.java | 57 ++++ .../neoforge/NeoForgePlatformHelper.java | 22 ++ .../resources/META-INF/neoforge.mods.toml | 53 ++-- ...ecialeffect.eyemine.packets.NetworkService | 1 + ...ne.platform.services.IEyeMineConfigService | 1 + ....platform.services.IInventoryConfigService | 1 + ....eyemine.platform.services.IPlatformHelper | 1 + settings.gradle | 29 +- 124 files changed, 1918 insertions(+), 2920 deletions(-) create mode 100644 buildSrc/build.gradle create mode 100644 buildSrc/src/main/groovy/multiloader-common.gradle create mode 100644 buildSrc/src/main/groovy/multiloader-loader.gradle create mode 100644 common/src/main/java/com/specialeffect/eyemine/event/EventHolder.java create mode 100644 common/src/main/java/com/specialeffect/eyemine/event/EventResult.java create mode 100644 common/src/main/java/com/specialeffect/eyemine/event/EyeMineEvents.java create mode 100644 common/src/main/java/com/specialeffect/eyemine/event/ScreenSetResult.java create mode 100644 common/src/main/java/com/specialeffect/eyemine/packets/NetworkService.java create mode 100644 common/src/main/java/com/specialeffect/eyemine/platform/Services.java create mode 100644 common/src/main/java/com/specialeffect/eyemine/platform/services/IEyeMineConfigService.java create mode 100644 common/src/main/java/com/specialeffect/eyemine/platform/services/IInventoryConfigService.java create mode 100644 common/src/main/java/com/specialeffect/eyemine/platform/services/IPlatformHelper.java create mode 100644 common/src/main/resources/META-INF/accesstransformer.cfg delete mode 100644 common/src/main/resources/eyemine.common.json create mode 100644 fabric/src/main/java/com/specialeffect/eyemine/mixin/FabricKeyboardHandlerMixin.java create mode 100644 fabric/src/main/java/com/specialeffect/eyemine/mixin/FabricSetScreenMixin.java create mode 100644 fabric/src/main/java/com/specialeffect/eyemine/platform/fabric/FabricNetworkService.java create mode 100644 fabric/src/main/java/com/specialeffect/eyemine/platform/fabric/FabricPlatformHelper.java create mode 100644 fabric/src/main/resources/META-INF/services/com.specialeffect.eyemine.packets.NetworkService create mode 100644 fabric/src/main/resources/META-INF/services/com.specialeffect.eyemine.platform.services.IEyeMineConfigService create mode 100644 fabric/src/main/resources/META-INF/services/com.specialeffect.eyemine.platform.services.IInventoryConfigService create mode 100644 fabric/src/main/resources/META-INF/services/com.specialeffect.eyemine.platform.services.IPlatformHelper create mode 100644 fabric/src/main/resources/eyemine.fabric.mixins.json delete mode 100644 forge/build.gradle delete mode 100644 forge/gradle.properties delete mode 100644 forge/src/main/java/com/inventory/config/InventoryConfig.java delete mode 100644 forge/src/main/java/com/specialeffect/eyemine/client/forge/ClientHandler.java delete mode 100644 forge/src/main/java/com/specialeffect/eyemine/config/EyeMineConfig.java delete mode 100644 forge/src/main/java/com/specialeffect/eyemine/forge/EyeMineForge.java delete mode 100644 forge/src/main/java/com/specialeffect/eyemine/platform/forge/EyeMineConfigImpl.java delete mode 100644 forge/src/main/java/com/specialeffect/eyemine/platform/forge/InventoryConfigImpl.java delete mode 100644 forge/src/main/resources/META-INF/mods.toml delete mode 100644 forge/src/main/resources/eyemine_logo.png create mode 100644 neoforge/src/main/java/com/specialeffect/eyemine/platform/neoforge/NeoForgeNetworkService.java create mode 100644 neoforge/src/main/java/com/specialeffect/eyemine/platform/neoforge/NeoForgePlatformHelper.java create mode 100644 neoforge/src/main/resources/META-INF/services/com.specialeffect.eyemine.packets.NetworkService create mode 100644 neoforge/src/main/resources/META-INF/services/com.specialeffect.eyemine.platform.services.IEyeMineConfigService create mode 100644 neoforge/src/main/resources/META-INF/services/com.specialeffect.eyemine.platform.services.IInventoryConfigService create mode 100644 neoforge/src/main/resources/META-INF/services/com.specialeffect.eyemine.platform.services.IPlatformHelper diff --git a/.gitignore b/.gitignore index 1f117399..65148347 100644 --- a/.gitignore +++ b/.gitignore @@ -17,4 +17,10 @@ classes/ .vscode .settings *.launch -.architectury-transformer +runs/ + +# Ignore markdown files except the ones we want tracked +*.md +!README.md +!LICENSE.md +!CHANGES.md diff --git a/README.md b/README.md index e61c1de8..4c401320 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,5 @@ -# EyeMineArchitectury -A version of [EyeMineMods](https://github.com/SpecialEffect/EyeMineMods) that is build upon the [Architectury API](https://github.com/architectury/architectury-api) allowing it to work on either NeoForge, Forge or Fabric. +# EyeMineMods +A version of [EyeMineMods](https://github.com/SpecialEffect/EyeMineMods) using Jared's [MultiLoader Template](https://github.com/jaredlll08/MultiLoader-Template) to support both NeoForge and Fabric. This repository contains the Minecraft mods used with [EyeMine](https://github.com/SpecialEffect/EyeMine), which provides a gaze-controlled keyboard for in-game actions. @@ -21,18 +21,19 @@ A version of the mod ported by [Mrbysco](https://github.com/Mrbysco) supports ** ## Information for developers -Code for different versions of Minecraft Forge can be found on different branches: +Code for different versions of Minecraft can be found on different branches: - Minecraft Forge v1.11.2 (via the [eyemineClassic_mc1_11_2 branch](https://github.com/SpecialEffect/EyeMineMods/tree/eyemineClassic_mc1_11_2)) - Minecraft Forge v1.14.4 (via the [eyemineV2_mc1_14_4 branch](https://github.com/SpecialEffect/EyeMineMods/tree/eyemineV2_mc1_14_4)). - Minecraft Forge v1.16.5 (via the [eyemineV2_mc1_16_5 branch](https://github.com/SpecialEffect/EyeMineMods/tree/eyemineV2_mc1_16_5)). +- Minecraft 1.21.1 NeoForge + Fabric via Architectury (via the [architectury_1.21 branch](https://github.com/SpecialEffect/EyeMineMods/tree/architectury_1.21)). +- Minecraft 26.1.1 NeoForge + Fabric via MultiLoader (via the [multiloader_26.1.1 branch](https://github.com/SpecialEffect/EyeMineMods/tree/multiloader_26.1.1)). All the code comprising EyeMine is GPL3 licensed. We would love contributions to port to other versions of Minecraft. If you're interested in doing this, please email eyemine@specialeffect.org.uk to let us know what you're working on! ## Dev setup -These instructions are based on Windows 10 and using Eclipse as an IDE. If you are using a different setup, some details may vary. ### Pre-requisites -- Java SDK ("JDK") +- Java 25 JDK ### Instructions Get the code. @@ -41,17 +42,13 @@ git clone git@github.com:SpecialEffect/EyeMineMods.git cd EyeMineMods ``` -Build the code. The built mod file will be found in the `build/libs` directory. +Build the code. Output JARs will be in `neoforge/build/libs/` and `fabric/build/libs/`. ``` -gradlew build +./gradlew build ``` -Optionally set up to build and run from Eclipse: +Run the client in dev: ``` -gradlew genEclipseRuns -gradlew eclipse +./gradlew :neoforge:runClient +./gradlew :fabric:runClient ``` -Now you can open the project in Eclipse: -File -> Import -> Gradle -> Existing Gradle project -> Set Project Root Directory to the EyeMineMods folder -> Finish -Once the project is loaded, select the project in Package Explorer, hit the green "Run" or "Debug" button and select "runClient" as the configuration to run. - diff --git a/build.gradle b/build.gradle index 9c42df26..b8465aed 100644 --- a/build.gradle +++ b/build.gradle @@ -1,64 +1,6 @@ plugins { - id "architectury-plugin" version "3.4-SNAPSHOT" - id "dev.architectury.loom" version "1.9-SNAPSHOT" apply false + // https://fabricmc.net/develop/ + id 'net.fabricmc.fabric-loom' version '1.16.1' apply false + // https://projects.neoforged.net/neoforged/moddevgradle + id 'net.neoforged.moddev' version '2.0.141' apply false } - -architectury { - minecraft = rootProject.minecraft_version -} - -subprojects { - apply plugin: "dev.architectury.loom" - - loom { - silentMojangMappingsLicense() - } - - dependencies { - minecraft "com.mojang:minecraft:${rootProject.minecraft_version}" - // The following line declares the mojmap mappings, you may use other mappings as well - mappings loom.officialMojangMappings() - // The following line declares the yarn mappings you may select this one as well. - // mappings "net.fabricmc:yarn:1.19.4+build.2:v2" - } -} - -allprojects { - apply plugin: "java" - apply plugin: "architectury-plugin" - apply plugin: "maven-publish" - - base { - archivesName = rootProject.archives_base_name - } - version = rootProject.mod_version - group = rootProject.maven_group - - repositories { - mavenCentral() - maven { - url "https://maven.neoforged.net/releases/" - } - maven { - url "https://maven.terraformersmc.com/" - content { - includeGroup "com.terraformersmc" - } - } - maven { - url "https://cursemaven.com" - content { - includeGroup "curse.maven" - } - } - } - - tasks.withType(JavaCompile).configureEach { - it.options.encoding = 'UTF-8' - it.options.getRelease().set(21) - } - - java { - withSourcesJar() - } -} \ No newline at end of file diff --git a/buildSrc/build.gradle b/buildSrc/build.gradle new file mode 100644 index 00000000..67840524 --- /dev/null +++ b/buildSrc/build.gradle @@ -0,0 +1,3 @@ +plugins { + id 'groovy-gradle-plugin' +} diff --git a/buildSrc/src/main/groovy/multiloader-common.gradle b/buildSrc/src/main/groovy/multiloader-common.gradle new file mode 100644 index 00000000..9aee2054 --- /dev/null +++ b/buildSrc/src/main/groovy/multiloader-common.gradle @@ -0,0 +1,99 @@ +plugins { + id 'java-library' + id 'maven-publish' +} + +base { + archivesName = "${mod_id}-${project.name}-${minecraft_version}" +} + +java { + toolchain.languageVersion = JavaLanguageVersion.of(java_version) + withSourcesJar() + withJavadocJar() +} + +repositories { + mavenCentral() + exclusiveContent { + forRepository { + maven { + name = 'Sponge' + url = 'https://repo.spongepowered.org/repository/maven-public' + } + } + filter { includeGroupAndSubgroups('org.spongepowered') } + } +} + +sourcesJar { + from(rootProject.file('LICENSE')) { + rename { "${it}_${mod_name}" } + } +} + +jar { + from(rootProject.file('LICENSE')) { + rename { "${it}_${mod_name}" } + } + + manifest { + attributes([ + 'Specification-Title' : mod_name, + 'Specification-Vendor' : mod_author, + 'Specification-Version' : project.jar.archiveVersion, + 'Implementation-Title' : project.name, + 'Implementation-Version': project.jar.archiveVersion, + 'Implementation-Vendor' : mod_author, + 'Built-On-Minecraft' : minecraft_version + ]) + } +} + +processResources { + var expandProps = [ + 'version' : version, + 'group' : project.group, + 'minecraft_version' : minecraft_version, + 'minecraft_version_range' : minecraft_version_range, + 'fabric_version' : fabric_version, + 'fabric_loader_version' : fabric_loader_version, + 'mod_name' : mod_name, + 'mod_author' : mod_author, + 'mod_id' : mod_id, + 'license' : license, + 'description' : project.description, + 'neoforge_version' : neoforge_version, + 'neoforge_loader_version_range': neoforge_loader_version_range, + 'credits' : credits, + 'java_version' : java_version + ] + + var jsonExpandProps = expandProps.collectEntries { + key, value -> [(key): value instanceof String ? value.replace("\n", "\\\\n") : value] + } + + filesMatching(['META-INF/mods.toml', 'META-INF/neoforge.mods.toml']) { + expand expandProps + } + + filesMatching(['pack.mcmeta', 'fabric.mod.json', '*.mixins.json']) { + expand jsonExpandProps + } + + inputs.properties(expandProps) +} + +publishing { + publications { + register('mavenJava', MavenPublication) { + artifactId base.archivesName.get() + from components.java + } + } + repositories { + maven { + url System.getenv('local_maven_url') ?: 'file://invalid' + } + } +} diff --git a/buildSrc/src/main/groovy/multiloader-loader.gradle b/buildSrc/src/main/groovy/multiloader-loader.gradle new file mode 100644 index 00000000..5f45bb43 --- /dev/null +++ b/buildSrc/src/main/groovy/multiloader-loader.gradle @@ -0,0 +1,95 @@ +// Loader convention plugin - injects common sources into platform builds. + +plugins { + id 'java' +} + +base { + archivesName = "${mod_id}-${minecraft_version}-${version}-${project.name}" +} + +tasks.withType(AbstractArchiveTask).configureEach { + archiveVersion.set('') +} + +java { + toolchain.languageVersion = JavaLanguageVersion.of(java_version) +} + +configurations { + commonJava { + canBeConsumed = false + canBeResolved = true + } + commonResources { + canBeConsumed = false + canBeResolved = true + } +} + +dependencies { + commonJava project(path: ':common', configuration: 'commonJava') + commonResources project(path: ':common', configuration: 'commonResources') +} + +tasks.named('compileJava').configure { + dependsOn(configurations.commonJava) + source(configurations.commonJava.incoming.artifactView { + attributes { attribute(Usage.USAGE_ATTRIBUTE, objects.named(Usage, Usage.JAVA_RUNTIME)) } + }.files) +} + +tasks.named('processResources').configure { + dependsOn(configurations.commonResources) + from(configurations.commonResources.incoming.artifactView { + attributes { attribute(Usage.USAGE_ATTRIBUTE, objects.named(Usage, Usage.JAVA_RUNTIME)) } + }.files) + + // Property expansion for mod metadata files + var expandProps = [ + 'version' : version, + 'group' : project.group, + 'minecraft_version' : minecraft_version, + 'minecraft_version_range' : minecraft_version_range, + 'fabric_version' : fabric_version, + 'fabric_loader_version' : fabric_loader_version, + 'mod_name' : mod_name, + 'mod_author' : mod_author, + 'mod_id' : mod_id, + 'license' : license, + 'description' : project.description ?: '', + 'neoforge_version' : neoforge_version, + 'neoforge_loader_version_range': neoforge_loader_version_range, + 'credits' : credits, + 'java_version' : java_version + ] + + var jsonExpandProps = expandProps.collectEntries { + key, value -> [(key): value instanceof String ? value.replace("\n", "\\\\n") : value] + } + + filesMatching(['META-INF/mods.toml', 'META-INF/neoforge.mods.toml']) { + expand expandProps + } + + filesMatching(['pack.mcmeta', 'fabric.mod.json', '*.mixins.json']) { + expand jsonExpandProps + } + + inputs.properties(expandProps) +} + +tasks.matching { it.name == 'javadoc' }.configureEach { + source(configurations.commonJava.incoming.artifactView { + attributes { attribute(Usage.USAGE_ATTRIBUTE, objects.named(Usage, Usage.JAVA_RUNTIME)) } + }.files) +} + +tasks.matching { it.name == 'sourcesJar' }.configureEach { + from(configurations.commonJava.incoming.artifactView { + attributes { attribute(Usage.USAGE_ATTRIBUTE, objects.named(Usage, Usage.JAVA_RUNTIME)) } + }.files) + from(configurations.commonResources.incoming.artifactView { + attributes { attribute(Usage.USAGE_ATTRIBUTE, objects.named(Usage, Usage.JAVA_RUNTIME)) } + }.files) +} diff --git a/changes.md b/changes.md index 26a9aac3..0b58da9c 100644 --- a/changes.md +++ b/changes.md @@ -1,41 +1,49 @@ # EyeMine Changelog -## Version 6.0.2 +## Version 7.0.0 - MC 26.1.1 (NeoForge + Fabric) -### Bug Fixes +### Major Changes -#### Gaze-Based Walking Refinements +- **Migrated from Architectury to MultiLoader Template** - the mod now uses Jared's MultiLoader Template with Java ServiceLoader for platform abstraction +- **Upgraded to MC 26.1.1** from MC 1.21.1 +- **Upgraded to Java 25** from Java 21 +- **Dropped Forge support** - Only NeoForge and Fabric are supported -- **Walking now fully stops when gaze is at the on-screen keyboard or outside the window**: In 6.0.1, walking was reduced to 15% speed in these cases. After further testing, full stop is the correct behavior — the original "don't stop completely" feedback from Kirsty was about in-game camera pitch (looking up/down hills), not the on-screen keyboard area. +### Build System -- **Extreme pitch angles no longer fully stop walking**: Looking straight up or down (beyond 80°) now slows movement to 5% instead of stopping entirely. This preserves the ability to navigate hills and look around without losing all momentum. +- Replaced Architectury Loom with buildSrc convention plugins (multiloader-common, multiloader-loader) +- NeoForge uses ModDevGradle, Fabric uses Fabric Loom 1.16.1 +- Gradle upgraded to 9.4.1 -#### Dwell Action Improvements +### Platform Abstraction -- **Dwell actions now suppressed when gaze is at keyboard area or outside window**: Prevents unintended dwell-triggered interactions (e.g., block placement, item use) while the user is interacting with the on-screen keyboard. +- Replaced `@ExpectPlatform` with Java ServiceLoader pattern +- Created service interfaces: `IEyeMineConfigService`, `IInventoryConfigService`, `IPlatformHelper`, `NetworkService` +- Static facade classes delegate to services transparently - no changes needed in calling code ---- +### Event System -## Version 6.0.1 +- Created custom common event bus (`EyeMineEvents`) replacing Architectury events +- Platform entry points forward native events into the common bus +- Fabric: Custom mixins for key input (`FabricKeyboardHandlerMixin`) and screen events (`FabricSetScreenMixin`) -### Bug Fixes +### Rendering -#### Gaze Detection Improvements +- Overlay rendering uses `RenderPipelines.GUI_TEXTURED` with ARGB color int for alpha support +- In-world dwell visualization now uses `RenderTypes.debugQuads()` +- NeoForge block outline is now accomplished via `ExtractBlockOutlineRenderStateEvent` + `CustomBlockOutlineRenderer` +- Fabric block outline is handled via `LevelRenderEvents.BEFORE_BLOCK_OUTLINE` +- Fabric HUD rendering done with `HudElementRegistry` -- **Fixed auto-walking not stopping when looking at keyboard area**: The GLFW cursor reset events at position (0,0) were incorrectly clearing the gaze-below-threshold state. The fix now properly detects and ignores these cursor reset events to preserve the gaze state. +### Mixin Updates -- **Added outside-window gaze detection**: Walking now also pauses/slows when gaze is detected outside the game window, matching the original intended behavior. +- `LivingEntityMixin` rewritten to use `AttributeModifier` on `STEP_HEIGHT` +- `KeyboardInputMixin` rewritten for immutable `Input` record system; fractional walk speed preserved via `moveVector` + - this was an internal change from mojang that just didnt work well for what we needed +- `TitleScreenMixin` updated for `extractRenderState()` and `Matrix3x2fStack` +- Added Fabric-specific mixins for key and screen event forwarding -#### Walking Behavior Changes +### Removed -- **Walking now slows down instead of stopping completely when looking at keyboard**: Per feedback from Kirsty (original developer), stopping completely wasn't intuitive when looking up/down hills. Walking now reduces to 15% speed when gaze is at the keyboard area or outside the window. - -#### Mining and Attacking Fixes - -- **Toggle mining now pauses when looking at keyboard**: Per EyeGazeGirl's feedback ("toggle mining meant to stop too"), continuous mining now pauses when gaze is below the hotbar or outside the window. - -- **Toggle attacking now pauses when looking at keyboard**: Continuous attacking now pauses when gaze is at the keyboard area or outside the window, consistent with mining behavior. - -#### Keybinding Persistence Fix - -- **Fixed keybindings resetting on every game launch**: The AutoJump module was calling `options.save()` and `options.load()` during startup config sync, which could interfere with Minecraft's keybinding loading process. The fix now only persists settings when the user manually toggles them, not during startup. +- Forge subproject +- ModMenu integration (commented out pending 26.1.1-compatible release) diff --git a/common/build.gradle b/common/build.gradle index 5ad2326c..b60b20ac 100644 --- a/common/build.gradle +++ b/common/build.gradle @@ -1,29 +1,32 @@ -architectury { - common(rootProject.enabled_platforms.split(",")) +plugins { + id 'multiloader-common' + id 'net.neoforged.moddev' } -loom { - accessWidenerPath = file("src/main/resources/eyemine.accesswidener") +neoForge { + neoFormVersion = neo_form_version +} + +configurations { + commonJava { + canBeConsumed = true + canBeResolved = false + } + commonResources { + canBeConsumed = true + canBeResolved = false + } } dependencies { - // We depend on fabric loader here to use the fabric @Environment annotations and get the mixin dependencies - // Do NOT use other classes from fabric loader - modImplementation "net.fabricmc:fabric-loader:${rootProject.fabric_loader_version}" - // Remove the next line if you don't want to depend on the API - modApi "dev.architectury:architectury:${rootProject.architectury_version}" + compileOnly "org.spongepowered:mixin:0.8.7" } -publishing { - publications { - mavenCommon(MavenPublication) { - artifactId = rootProject.archives_base_name - from components.java - } +artifacts { + commonJava(sourceSets.main.java.sourceDirectories.singleFile) { + builtBy(tasks.named('classes')) } - - // See https://docs.gradle.org/current/userguide/publishing_maven.html for information on how to set up publishing. - repositories { - // Add repositories to publish to here. + commonResources(sourceSets.main.resources.sourceDirectories.singleFile) { + builtBy(tasks.named('classes')) } } diff --git a/common/src/main/java/com/irtimaled/bbor/client/Camera.java b/common/src/main/java/com/irtimaled/bbor/client/Camera.java index 6591103e..c6b95112 100644 --- a/common/src/main/java/com/irtimaled/bbor/client/Camera.java +++ b/common/src/main/java/com/irtimaled/bbor/client/Camera.java @@ -5,7 +5,7 @@ public class Camera { private static Vec3 getPos() { - return Minecraft.getInstance().gameRenderer.getMainCamera().getPosition(); + return Minecraft.getInstance().gameRenderer.getMainCamera().position(); } public static double getX() { diff --git a/common/src/main/java/com/irtimaled/bbor/client/renderers/AbstractRenderer.java b/common/src/main/java/com/irtimaled/bbor/client/renderers/AbstractRenderer.java index 599815be..82fda918 100644 --- a/common/src/main/java/com/irtimaled/bbor/client/renderers/AbstractRenderer.java +++ b/common/src/main/java/com/irtimaled/bbor/client/renderers/AbstractRenderer.java @@ -187,9 +187,6 @@ public static void renderBlockFaceCentralisedDwell(PoseStack poseStack, VertexCo public static void renderCubeAtPosition(PoseStack poseStack, VertexConsumer vertexConsumer, Vec3 pos, Color color, int opacity, double size) { -// RenderSystem.polygonMode(GL11.GL_FRONT_AND_BACK, GL11.GL_FILL); -// RenderSystem.enableBlend(); -// RenderSystem.blendFuncSeparate(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA, GL11.GL_ONE, GL11.GL_ZERO); // Set up bounding cube corners OffsetPoint min = new OffsetPoint(pos.x() - size, pos.y() - size, pos.z() - size); @@ -236,9 +233,6 @@ public static void renderCubeAtPosition(PoseStack poseStack, VertexConsumer vert vertexConsumer.addVertex(matrix4f, minX, maxY, maxZ).setColor(r, g, b, opacity); vertexConsumer.addVertex(matrix4f, minX, maxY, minZ).setColor(r, g, b, opacity); -// RenderSystem.disableBlend(); -// RenderSystem.enablePolygonOffset(); -// RenderSystem.polygonOffset(-1.f, -1.f); } public static void renderFaces(OffsetPoint min, OffsetPoint max, Color color, int alpha) { @@ -297,7 +291,6 @@ public static void renderFaces(OffsetPoint min, OffsetPoint max, Color color, in } void renderLine(OffsetPoint startPoint, OffsetPoint endPoint, Color color) { - RenderSystem.polygonMode(GL11.GL_FRONT_AND_BACK, GL11.GL_LINE); Renderer.startLines() .setColor(color) @@ -306,29 +299,21 @@ void renderLine(OffsetPoint startPoint, OffsetPoint endPoint, Color color) { } void renderFilledFaces(OffsetPoint min, OffsetPoint max, Color color, int alpha) { - RenderSystem.polygonMode(GL11.GL_FRONT_AND_BACK, GL11.GL_LINE); - RenderSystem.enableBlend(); renderFaces(min, max, color, alpha); - RenderSystem.disableBlend(); - RenderSystem.enablePolygonOffset(); - RenderSystem.polygonOffset(-1.f, -1.f); } void renderText(PoseStack poseStack, OffsetPoint offsetPoint, String... texts) { Font fontRenderer = Minecraft.getInstance().font; // RenderSystem.pushMatrix(); TODO: Redo when renderText() is required -// RenderSystem.polygonMode(GL11.GL_FRONT_AND_BACK, GL11.GL_FILL); // RenderSystem.translated(offsetPoint.getX(), offsetPoint.getY() + 0.002D, offsetPoint.getZ()); // GL11.glNormal3f(0.0F, 1.0F, 0.0F); // RenderSystem.rotatef(0.0F, 0.0F, 1.0F, 0.0F); // RenderSystem.rotatef(90.0F, 1.0F, 0.0F, 0.0F); // RenderSystem.scalef(-0.0175F, -0.0175F, 0.0175F); // -// RenderSystem.enableBlend(); -// RenderSystem.blendFuncSeparate(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA, GL11.GL_ONE, GL11.GL_ZERO); // // RenderSystem.disableDepthTest(); // RenderSystem.enableDepthTest(); @@ -340,7 +325,6 @@ void renderText(PoseStack poseStack, OffsetPoint offsetPoint, String... texts) { // top += fontRenderer.lineHeight; // } // RenderSystem.disableTexture(); -// RenderSystem.disableBlend(); } private static void enablePointSmooth() { diff --git a/common/src/main/java/com/irtimaled/bbor/client/renderers/Renderer.java b/common/src/main/java/com/irtimaled/bbor/client/renderers/Renderer.java index e2669e86..40e9aa45 100644 --- a/common/src/main/java/com/irtimaled/bbor/client/renderers/Renderer.java +++ b/common/src/main/java/com/irtimaled/bbor/client/renderers/Renderer.java @@ -1,8 +1,8 @@ package com.irtimaled.bbor.client.renderers; import com.mojang.blaze3d.vertex.BufferBuilder; -import com.mojang.blaze3d.vertex.BufferUploader; import com.mojang.blaze3d.vertex.DefaultVertexFormat; +import com.mojang.blaze3d.vertex.MeshData; import com.mojang.blaze3d.vertex.Tesselator; import com.mojang.blaze3d.vertex.VertexFormat; import com.mojang.blaze3d.vertex.VertexFormat.Mode; @@ -20,15 +20,10 @@ static Renderer startQuads() { return new Renderer(Mode.QUADS, DefaultVertexFormat.POSITION_COLOR); } -// static Renderer startPoints() { -// return new Renderer(GL11.GL_POINTS, DefaultVertexFormat.POSITION_COLOR); -// } - public static Renderer startTextured() { return new Renderer(Mode.QUADS, DefaultVertexFormat.POSITION_TEX_COLOR); } - private static final Tesselator tessellator = new Tesselator(2097152); private static BufferBuilder bufferBuilder; private int red; @@ -37,7 +32,7 @@ public static Renderer startTextured() { private int alpha; private Renderer(Mode glMode, VertexFormat vertexFormat) { - this.bufferBuilder = tessellator.begin(glMode, vertexFormat); + bufferBuilder = Tesselator.getInstance().begin(glMode, vertexFormat); this.glMode = glMode; } @@ -73,7 +68,6 @@ public Renderer addPoints(OffsetPoint[] points) { Renderer addPoint(double x, double y, double z) { pos((float) x, (float) y, (float) z); color(); - draw(); return this; } @@ -81,11 +75,9 @@ public Renderer addPoint(double x, double y, double z, float u, float v) { pos((float) x, (float) y, (float) z); tex(u, v); color(); - draw(); return this; } - private void pos(float x, float y, float z) { bufferBuilder.addVertex(x, y, z); } @@ -99,6 +91,9 @@ private void color() { } public void draw() { - BufferUploader.drawWithShader(bufferBuilder.buildOrThrow()); + MeshData mesh = bufferBuilder.build(); + if (mesh != null) { + mesh.close(); + } } } diff --git a/common/src/main/java/com/specialeffect/eyemine/EyeMineClient.java b/common/src/main/java/com/specialeffect/eyemine/EyeMineClient.java index f3243fe2..9fdda8ec 100644 --- a/common/src/main/java/com/specialeffect/eyemine/EyeMineClient.java +++ b/common/src/main/java/com/specialeffect/eyemine/EyeMineClient.java @@ -3,6 +3,7 @@ import com.specialeffect.eyemine.client.CreativeClientHelper; import com.specialeffect.eyemine.client.Keybindings; import com.specialeffect.eyemine.client.MainClientHandler; +import com.specialeffect.eyemine.event.EyeMineEvents; import com.specialeffect.eyemine.submod.IConfigListener; import com.specialeffect.eyemine.submod.SubMod; import com.specialeffect.eyemine.submod.mining.ContinuouslyMine; @@ -32,11 +33,6 @@ import com.specialeffect.eyemine.submod.movement.Sneak; import com.specialeffect.eyemine.submod.movement.Swim; import com.specialeffect.eyemine.submod.utils.DebugAverageFps; -import dev.architectury.event.events.client.ClientGuiEvent; -import dev.architectury.event.events.client.ClientLifecycleEvent; -import dev.architectury.event.events.client.ClientRawInputEvent; -import dev.architectury.registry.client.keymappings.KeyMappingRegistry; -import net.minecraft.client.KeyMapping; import java.util.ArrayList; import java.util.List; @@ -54,17 +50,13 @@ public static void init() { // Setup all other sub mods instantiateSubMods(); - ClientGuiEvent.SET_SCREEN.register(MainClientHandler::onGuiOpen); - ClientGuiEvent.RENDER_HUD.register(MainClientHandler::onRenderGameOverlayEvent); - ClientRawInputEvent.KEY_PRESSED.register(CreativeClientHelper::onKeyInput); + EyeMineEvents.SCREEN_SET.register(MainClientHandler::onGuiOpen); + EyeMineEvents.RENDER_HUD.register(MainClientHandler::onRenderGameOverlayEvent); + EyeMineEvents.KEY_PRESSED.register(CreativeClientHelper::onKeyInput); - if (!Keybindings.keybindings.isEmpty()) { - for (KeyMapping keyBinding : Keybindings.keybindings) { - KeyMappingRegistry.register(keyBinding); - } - } + // Key mappings are registered by platform entry points via Keybindings.keybindings list - ClientLifecycleEvent.CLIENT_SETUP.register((client) -> { + EyeMineEvents.CLIENT_SETUP.register((client) -> { if (!setupComplete) { setupComplete = true; refresh(); diff --git a/common/src/main/java/com/specialeffect/eyemine/client/CreativeClientHelper.java b/common/src/main/java/com/specialeffect/eyemine/client/CreativeClientHelper.java index 37d37321..065e034a 100644 --- a/common/src/main/java/com/specialeffect/eyemine/client/CreativeClientHelper.java +++ b/common/src/main/java/com/specialeffect/eyemine/client/CreativeClientHelper.java @@ -17,7 +17,7 @@ import com.specialeffect.inventory.manager.ChestInventoryManager; import com.specialeffect.inventory.manager.CreativeInventoryManager; import com.specialeffect.inventory.manager.SurvivalInventoryManager; -import dev.architectury.event.EventResult; +import com.specialeffect.eyemine.event.EventResult; import net.minecraft.client.Minecraft; import net.minecraft.client.gui.screens.Screen; import net.minecraft.client.gui.screens.inventory.ContainerScreen; @@ -27,7 +27,7 @@ public class CreativeClientHelper { public static EventResult onKeyInput(Minecraft minecraft, int keyCode, int scanCode, int action, int modifiers) { - if (InputConstants.isKeyDown(minecraft.getWindow().getWindow(), 292)) { + if (InputConstants.isKeyDown(minecraft.getWindow(), 292)) { return EventResult.pass(); } diff --git a/common/src/main/java/com/specialeffect/eyemine/client/EyeMineRenderType.java b/common/src/main/java/com/specialeffect/eyemine/client/EyeMineRenderType.java index 289c97a1..6db7ca54 100644 --- a/common/src/main/java/com/specialeffect/eyemine/client/EyeMineRenderType.java +++ b/common/src/main/java/com/specialeffect/eyemine/client/EyeMineRenderType.java @@ -11,46 +11,23 @@ package com.specialeffect.eyemine.client; -import com.mojang.blaze3d.vertex.DefaultVertexFormat; -import com.mojang.blaze3d.vertex.VertexFormat; -import com.mojang.blaze3d.vertex.VertexFormat.Mode; -import net.minecraft.client.renderer.RenderStateShard; -import net.minecraft.client.renderer.RenderType; +import net.minecraft.client.renderer.rendertype.RenderType; +import net.minecraft.client.renderer.rendertype.RenderTypes; -public class EyeMineRenderType extends RenderType { - public EyeMineRenderType(String nameIn, VertexFormat formatIn, Mode drawModeIn, int bufferSizeIn, boolean useDelegateIn, boolean needsSortingIn, Runnable setupTaskIn, Runnable clearTaskIn) { - super(nameIn, formatIn, drawModeIn, bufferSizeIn, useDelegateIn, needsSortingIn, setupTaskIn, clearTaskIn); - } - - public static RenderType dwellRenderType() { - return RenderType.create("eyemine:dwell", DefaultVertexFormat.POSITION_COLOR, Mode.QUADS, 2097152, false, false, getDwellState()); - } - - private static CompositeState getDwellState() { - return CompositeState.builder() - .setShaderState(RenderStateShard.POSITION_COLOR_SHADER) - .setLightmapState(LIGHTMAP) - .setTransparencyState(TRANSLUCENT_TRANSPARENCY) - .setOutputState(TRANSLUCENT_TARGET) - .setLayeringState(VIEW_OFFSET_Z_LAYERING) - .setCullState(NO_CULL) - .setDepthTestState(NO_DEPTH_TEST) - .createCompositeState(true); - } +/** + * Custom RenderTypes for EyeMine's in-world rendering (dwell indicators, block outlines). + * In MC 26.1.1, uses RenderTypes utility for translucent position-color rendering. + */ +public class EyeMineRenderType { - public static RenderType cubeRenderType() { - return RenderType.create("eyemine:cube", DefaultVertexFormat.POSITION_COLOR, Mode.QUADS, 2097152, false, false, getCubeState()); - } + public static RenderType dwellRenderType() { + // Use the debug quads type for translucent position-color quads + // TODO: If this doesn't render correctly, create a proper custom RenderType + // using the new RenderSetup/RenderPipeline API + return RenderTypes.debugQuads(); + } - private static CompositeState getCubeState() { - return CompositeState.builder() - .setShaderState(RenderStateShard.POSITION_COLOR_SHADER) - .setLightmapState(LIGHTMAP) - .setTransparencyState(TRANSLUCENT_TRANSPARENCY) - .setOutputState(TRANSLUCENT_TARGET) - .setLayeringState(VIEW_OFFSET_Z_LAYERING) - .setCullState(NO_CULL) - .setDepthTestState(NO_DEPTH_TEST) - .createCompositeState(true); - } + public static RenderType cubeRenderType() { + return dwellRenderType(); + } } diff --git a/common/src/main/java/com/specialeffect/eyemine/client/Keybindings.java b/common/src/main/java/com/specialeffect/eyemine/client/Keybindings.java index 82e82579..31298c95 100644 --- a/common/src/main/java/com/specialeffect/eyemine/client/Keybindings.java +++ b/common/src/main/java/com/specialeffect/eyemine/client/Keybindings.java @@ -12,10 +12,21 @@ package com.specialeffect.eyemine.client; import net.minecraft.client.KeyMapping; +import net.minecraft.resources.Identifier; import java.util.ArrayList; import java.util.List; public class Keybindings { public static final List keybindings = new ArrayList<>(); + + // Custom key mapping categories for EyeMine + public static final KeyMapping.Category EYEGAZE_SETTINGS = KeyMapping.Category.register( + Identifier.fromNamespaceAndPath("eyemine", "eyegaze_settings")); + public static final KeyMapping.Category EYEGAZE_COMMON = KeyMapping.Category.register( + Identifier.fromNamespaceAndPath("eyemine", "eyegaze_common")); + public static final KeyMapping.Category EYEGAZE_EXTRA = KeyMapping.Category.register( + Identifier.fromNamespaceAndPath("eyemine", "eyegaze_extra")); + public static final KeyMapping.Category EYEGAZE_ADVANCED = KeyMapping.Category.register( + Identifier.fromNamespaceAndPath("eyemine", "eyegaze_advanced")); } diff --git a/common/src/main/java/com/specialeffect/eyemine/client/MainClientHandler.java b/common/src/main/java/com/specialeffect/eyemine/client/MainClientHandler.java index 99e71918..dadf329c 100644 --- a/common/src/main/java/com/specialeffect/eyemine/client/MainClientHandler.java +++ b/common/src/main/java/com/specialeffect/eyemine/client/MainClientHandler.java @@ -17,10 +17,10 @@ import com.specialeffect.eyemine.mixin.AbstractContainerScreenAccessor; import com.specialeffect.eyemine.platform.EyeMineConfig; import com.specialeffect.inventory.manager.CreativeInventoryManager; -import dev.architectury.event.CompoundEventResult; +import com.specialeffect.eyemine.event.ScreenSetResult; import net.minecraft.client.DeltaTracker; import net.minecraft.client.Minecraft; -import net.minecraft.client.gui.GuiGraphics; +import net.minecraft.client.gui.GuiGraphicsExtractor; import net.minecraft.client.gui.screens.Screen; import net.minecraft.client.gui.screens.inventory.CreativeModeInventoryScreen; @@ -31,7 +31,7 @@ public class MainClientHandler { public static final List crosshairOverlayList = new ArrayList<>(); private static StateOverlay mStateOverlay; - public static void onRenderGameOverlayEvent(GuiGraphics guiGraphics, DeltaTracker deltaTracker) { + public static void onRenderGameOverlayEvent(GuiGraphicsExtractor guiGraphics, DeltaTracker deltaTracker) { if (!MainClientHandler.crosshairOverlayList.isEmpty()) { Minecraft minecraft = Minecraft.getInstance(); for (ICrosshairOverlay overlay : MainClientHandler.crosshairOverlayList) { @@ -41,15 +41,7 @@ public static void onRenderGameOverlayEvent(GuiGraphics guiGraphics, DeltaTracke } // Replace / augment some GUIs - public static CompoundEventResult onGuiOpen(Screen screen) { - Screen currentScreen = Minecraft.getInstance().screen; -// if (!EyeMineClient.disableCustomNewWorld && screen instanceof CreateWorldScreen && !(currentScreen instanceof CustomCreateWorldScreen)) { -// if (!EyeMineClient.allowMoreOptions) { -// // override the CreateWorldScreen, unless it's been requested from within our own CustomCreateWorldScreen -// return CompoundEventResult.interruptTrue(CustomCreateWorldScreen.create(Minecraft.getInstance(), screen)); -// } -// EyeMineClient.allowMoreOptions = false; -// } + public static ScreenSetResult onGuiOpen(Screen screen) { if (screen instanceof CreativeModeInventoryScreen gui) { // Make sure mouse starts outside container, so we have a sensible reference point AbstractContainerScreenAccessor accessor = (AbstractContainerScreenAccessor) gui; @@ -60,7 +52,7 @@ public static CompoundEventResult onGuiOpen(Screen screen) { gui.getMenu()); con.resetMouse(); } - return CompoundEventResult.pass(); + return ScreenSetResult.pass(); } public static void initialize() { diff --git a/common/src/main/java/com/specialeffect/eyemine/client/gui/CustomCreateWorldScreen.java b/common/src/main/java/com/specialeffect/eyemine/client/gui/CustomCreateWorldScreen.java index 843ee6c2..2327972c 100644 --- a/common/src/main/java/com/specialeffect/eyemine/client/gui/CustomCreateWorldScreen.java +++ b/common/src/main/java/com/specialeffect/eyemine/client/gui/CustomCreateWorldScreen.java @@ -19,7 +19,7 @@ //import com.specialeffect.eyemine.submod.misc.DefaultConfigForNewWorld; //import it.unimi.dsi.fastutil.booleans.BooleanConsumer; //import net.minecraft.FileUtil; -//import net.minecraft.Util; +// //import net.minecraft.client.Minecraft; //import net.minecraft.client.gui.components.Button; //import net.minecraft.client.gui.components.EditBox; @@ -41,7 +41,7 @@ //import net.minecraft.server.packs.repository.ServerPacksSource; //import net.minecraft.world.Difficulty; //import net.minecraft.world.level.DataPackConfig; -//import net.minecraft.world.level.GameRules; +//import net.minecraft.world.level.gamerules.GameRules; //import net.minecraft.world.level.GameType; //import net.minecraft.world.level.LevelSettings; //import net.minecraft.world.level.levelgen.WorldGenSettings; @@ -264,9 +264,9 @@ // LevelSettings levelSettings = new LevelSettings(this.worldNameField.getValue().trim(), GameType.CREATIVE, hardcoreMode, Difficulty.NORMAL, true, new GameRules(), DataPackConfig.DEFAULT); // // GameRules gameRules = levelSettings.gameRules(); -// gameRules.getRule(GameRules.RULE_DAYLIGHT).set(!btnDaytime.getValue(), (MinecraftServer) null); -// gameRules.getRule(GameRules.RULE_WEATHER_CYCLE).set(!btnSunny.getValue(), (MinecraftServer) null); -// gameRules.getRule(GameRules.RULE_KEEPINVENTORY).set(btnInventory.getValue(), (MinecraftServer) null); +// gameRules.getRule(GameRules.ADVANCE_TIME).set(!btnDaytime.getValue(), (MinecraftServer) null); +// gameRules.getRule(GameRules.ADVANCE_WEATHER).set(!btnSunny.getValue(), (MinecraftServer) null); +// gameRules.getRule(GameRules.KEEP_INVENTORY).set(btnInventory.getValue(), (MinecraftServer) null); // // // TODO: more options here? // levelSettings.allowCommands(); diff --git a/common/src/main/java/com/specialeffect/eyemine/client/gui/crosshair/ICrosshairOverlay.java b/common/src/main/java/com/specialeffect/eyemine/client/gui/crosshair/ICrosshairOverlay.java index a89e68b4..5b479b90 100644 --- a/common/src/main/java/com/specialeffect/eyemine/client/gui/crosshair/ICrosshairOverlay.java +++ b/common/src/main/java/com/specialeffect/eyemine/client/gui/crosshair/ICrosshairOverlay.java @@ -12,8 +12,8 @@ package com.specialeffect.eyemine.client.gui.crosshair; import net.minecraft.client.Minecraft; -import net.minecraft.client.gui.GuiGraphics; +import net.minecraft.client.gui.GuiGraphicsExtractor; public interface ICrosshairOverlay { - void renderOverlay(GuiGraphics guiGraphics, Minecraft minecraft); + void renderOverlay(GuiGraphicsExtractor guiGraphics, Minecraft minecraft); } diff --git a/common/src/main/java/com/specialeffect/eyemine/client/gui/crosshair/IconOverlay.java b/common/src/main/java/com/specialeffect/eyemine/client/gui/crosshair/IconOverlay.java index 8fa97f92..24fbac12 100644 --- a/common/src/main/java/com/specialeffect/eyemine/client/gui/crosshair/IconOverlay.java +++ b/common/src/main/java/com/specialeffect/eyemine/client/gui/crosshair/IconOverlay.java @@ -11,22 +11,15 @@ package com.specialeffect.eyemine.client.gui.crosshair; -import com.mojang.blaze3d.systems.RenderSystem; -import com.specialeffect.utils.ModUtils; import net.minecraft.client.Minecraft; -import net.minecraft.client.gui.GuiGraphics; -import net.minecraft.client.renderer.GameRenderer; -import net.minecraft.resources.ResourceLocation; -import org.lwjgl.opengl.GL11; +import net.minecraft.client.gui.GuiGraphicsExtractor; +import net.minecraft.client.renderer.RenderPipelines; +import net.minecraft.resources.Identifier; public class IconOverlay implements ICrosshairOverlay { - private ResourceLocation mResource; + private Identifier mResource; - // Current state public boolean mVisible = false; - - // Position/appearance (see setters) - // Position/size are relative to screen public float mCentreX = 0.5f; public float mCentreY = 0.5f; public float mHeight = 1.0f; @@ -36,7 +29,7 @@ public class IconOverlay implements ICrosshairOverlay { public int fadeCountdown = 0; public IconOverlay(Minecraft mc, String resourcePath) { - mResource = ResourceLocation.tryParse(resourcePath); + mResource = Identifier.tryParse(resourcePath); } public void setPosition(float centreX, float centreY, float height, float aspectRatio) { @@ -50,42 +43,36 @@ public void setVisible(boolean visible) { if (visible != mVisible) { fadeCountdown = fadeTime; } - mVisible = visible; } public void setAlpha(float alpha) { - // Minecraft clips alpha at 0.1, so we add 0.1 back in to get reasonable user-facing behaviour if (alpha > 0.0f && alpha < 0.9f) { alpha += 0.1f; } mAlpha = alpha; } - // A helper function to draw a texture scaled to fit. - public void drawTexture(Minecraft minecraft, int screenHeight, int screenWidth, float fade) { - // calculate position + private static int colorWithAlpha(float alpha) { + int a = Math.clamp((int) (alpha * 255), 0, 255); + return (a << 24) | 0xFFFFFF; + } + + public void drawTexture(GuiGraphicsExtractor guiGraphics, int screenHeight, int screenWidth, float fade) { int height = (int) (screenWidth * mHeight); int width = (int) (height * mAspectRatio); int centreX = (int) (mCentreX * screenWidth); int centreY = (int) (mCentreY * screenHeight); - // render the texture - // TODO:white? black? drop shadow? - RenderSystem.setShader(GameRenderer::getPositionTexShader); - RenderSystem.setShaderColor(1.0F, 1.0F, 1.0F, 1.0F); - RenderSystem.setShaderTexture(0, mResource); - ModUtils.drawTexQuad(centreX - (double) width / 2, centreY - (double) height / 2, - width, height, mAlpha * fade); + float alpha = mAlpha * fade; + int x = centreX - width / 2; + int y = centreY - height / 2; + guiGraphics.blit(RenderPipelines.GUI_TEXTURED, mResource, x, y, 0, 0, width, height, width, height, colorWithAlpha(alpha)); } @Override - public void renderOverlay(GuiGraphics guiGraphics, Minecraft minecraft) { + public void renderOverlay(GuiGraphicsExtractor guiGraphics, Minecraft minecraft) { if (mAlpha > 0.0 && (mVisible || fadeCountdown > 0)) { - RenderSystem.enableBlend(); - RenderSystem.blendFuncSeparate(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA, GL11.GL_ONE, GL11.GL_ZERO); - - // Update fading ticks float fade = 1.0f; if (fadeCountdown > 0) { fadeCountdown--; @@ -95,16 +82,13 @@ public void renderOverlay(GuiGraphics guiGraphics, Minecraft minecraft) { } } - // Don't show if the debug screen is open if (minecraft.getDebugOverlay().showDebugScreen()) { return; } int w = minecraft.getWindow().getGuiScaledWidth(); int h = minecraft.getWindow().getGuiScaledHeight(); - drawTexture(minecraft, h, w, fade); - - RenderSystem.disableBlend(); + drawTexture(guiGraphics, h, w, fade); } } -} \ No newline at end of file +} diff --git a/common/src/main/java/com/specialeffect/eyemine/client/gui/crosshair/JoystickControlOverlay.java b/common/src/main/java/com/specialeffect/eyemine/client/gui/crosshair/JoystickControlOverlay.java index 8d8aaaa9..36c12b42 100644 --- a/common/src/main/java/com/specialeffect/eyemine/client/gui/crosshair/JoystickControlOverlay.java +++ b/common/src/main/java/com/specialeffect/eyemine/client/gui/crosshair/JoystickControlOverlay.java @@ -11,21 +11,18 @@ package com.specialeffect.eyemine.client.gui.crosshair; -import com.mojang.blaze3d.systems.RenderSystem; -import com.specialeffect.utils.ModUtils; import net.minecraft.client.Minecraft; -import net.minecraft.client.gui.GuiGraphics; -import net.minecraft.client.renderer.GameRenderer; -import net.minecraft.resources.ResourceLocation; -import org.lwjgl.opengl.GL11; +import net.minecraft.client.gui.GuiGraphicsExtractor; +import net.minecraft.client.renderer.RenderPipelines; +import net.minecraft.resources.Identifier; public class JoystickControlOverlay implements ICrosshairOverlay { public JoystickControlOverlay() { - mResource = ResourceLocation.fromNamespaceAndPath("eyemine", "textures/icons/overlay.png"); + mResource = Identifier.fromNamespaceAndPath("eyemine", "textures/icons/overlay.png"); } - ResourceLocation mResource; + Identifier mResource; private boolean mVisible = false; @@ -36,7 +33,6 @@ public void setVisible(boolean bVisible) { } public void setAlpha(float alpha) { - // Minecraft clips alpha at 0.1, so we add 0.1 back in to get reasonable user-facing behaviour if (alpha > 0.0f && alpha < 0.9f) { alpha += 0.1f; } @@ -44,20 +40,16 @@ public void setAlpha(float alpha) { } @Override - public void renderOverlay(GuiGraphics guiGraphics, Minecraft minecraft) { + public void renderOverlay(GuiGraphicsExtractor guiGraphics, Minecraft minecraft) { if (mVisible && mAlpha > 0.0f) { - RenderSystem.enableBlend(); - RenderSystem.blendFuncSeparate(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA, GL11.GL_ONE, GL11.GL_ZERO); int w = minecraft.getWindow().getGuiScaledWidth(); int h = minecraft.getWindow().getGuiScaledHeight(); - RenderSystem.setShader(GameRenderer::getPositionTexShader); - RenderSystem.setShaderColor(1.0F, 1.0F, 1.0F, 1.0F); - RenderSystem.setShaderTexture(0, mResource); - ModUtils.drawTexQuad(0, 0, w, h, mAlpha); + int a = Math.clamp((int) (mAlpha * 255), 0, 255); + int color = (a << 24) | 0xFFFFFF; + guiGraphics.blit(RenderPipelines.GUI_TEXTURED, mResource, 0, 0, 0, 0, w, h, w, h, color); - RenderSystem.disableBlend(); } } -} \ No newline at end of file +} diff --git a/common/src/main/java/com/specialeffect/eyemine/client/gui/crosshair/StateOverlay.java b/common/src/main/java/com/specialeffect/eyemine/client/gui/crosshair/StateOverlay.java index 36a9f606..c9620c93 100644 --- a/common/src/main/java/com/specialeffect/eyemine/client/gui/crosshair/StateOverlay.java +++ b/common/src/main/java/com/specialeffect/eyemine/client/gui/crosshair/StateOverlay.java @@ -11,19 +11,16 @@ package com.specialeffect.eyemine.client.gui.crosshair; -import com.mojang.blaze3d.systems.RenderSystem; -import com.specialeffect.utils.ModUtils; import net.minecraft.client.Minecraft; -import net.minecraft.client.gui.GuiGraphics; -import net.minecraft.client.renderer.GameRenderer; -import net.minecraft.resources.ResourceLocation; -import org.lwjgl.opengl.GL11; +import net.minecraft.client.gui.GuiGraphicsExtractor; +import net.minecraft.client.renderer.RenderPipelines; +import net.minecraft.resources.Identifier; import java.util.ArrayList; import java.util.List; // -// StateOverlay implements a simple status bar at the top of the screen which +// StateOverlay implements a simple status bar at the top of the screen which // shows the current states such as attacking, walking, etc. // public class StateOverlay implements ICrosshairOverlay { @@ -35,12 +32,9 @@ public StateOverlay() { } private void rescale() { - // Scale icon sizes to fit screen - int maxSizeByWidth = mDisplayWidth / (mIconsPerRow + mIconPadding); int maxSizeByHeight = 2 * mDisplayHeight / (mIconsPerRow + mIconPadding); mIconSize = Math.min(maxSizeByWidth, maxSizeByHeight); - } private static int mIconSize = 30; @@ -49,71 +43,48 @@ private void rescale() { private int mDisplayHeight; private static final int mIconsPerRow = 10; - // Lists of icons to draw on each half of screen - private static List mResourcesLeft; - private static List mResourcesRight; + private static List mResourcesLeft; + private static List mResourcesRight; private static List mFlagsLeft; private static List mFlagsRight; - // Add texture to list of icons, return position. - // You need to hang onto the position to later turn the - // icon on/off. public synchronized static int registerTextureLeft(String filepath) { - ResourceLocation res = ResourceLocation.tryParse(filepath); + Identifier res = Identifier.tryParse(filepath); mResourcesLeft.add(res); mFlagsLeft.add(false); return mResourcesLeft.size() - 1; } - // Add texture to list of icons, return position. - // You need to hang onto the position to later turn the - // icon on/off. public synchronized static int registerTextureRight(String filepath) { - ResourceLocation res = ResourceLocation.tryParse(filepath); + Identifier res = Identifier.tryParse(filepath); mResourcesRight.add(res); mFlagsRight.add(false); return mResourcesRight.size() - 1; } - // A helper function to draw a texture scaled to fit. - private void drawScaledTextureWithGlow(Minecraft minecraft, ResourceLocation res, int x, int y, int width, int height) { - RenderSystem.setShader(GameRenderer::getPositionTexShader); - RenderSystem.setShaderColor(1.0F, 1.0F, 1.0F, 1.0F); - RenderSystem.setShaderTexture(0, res); - - // First draw enlarged and blurred, for glow. - RenderSystem.texParameter(GL11.GL_TEXTURE_2D, - GL11.GL_TEXTURE_MIN_FILTER, - GL11.GL_LINEAR); - RenderSystem.texParameter(GL11.GL_TEXTURE_2D, - GL11.GL_TEXTURE_MAG_FILTER, - GL11.GL_LINEAR); - -// GlStateManager._texEnv(GL11.GL_TEXTURE_ENV, -// GL11.GL_TEXTURE_ENV_MODE, //TODO: figure out what this was -// GL11.GL_ADD ); - - // We draw the texture larger, in white, at progressive levels of alpha - // for blur effect (the alpha gets added on each layer) - int blurSteps = 4; // how many levels of progressive blur - double totalBlur = (double) width / 12; // in pixels + /** Pack ARGB color int from alpha (0.0-1.0) and white RGB */ + private static int colorWithAlpha(float alpha) { + int a = Math.clamp((int) (alpha * 255), 0, 255); + return (a << 24) | 0xFFFFFF; + } + + private void drawScaledTextureWithGlow(GuiGraphicsExtractor guiGraphics, Identifier res, int x, int y, int width, int height) { + // Draw blur glow effect - progressive larger blits at low alpha + int blurSteps = 4; + double totalBlur = (double) width / 12; for (int i = 0; i < blurSteps; i++) { double blurAmount = totalBlur / blurSteps * (i + 1); - ModUtils.drawTexQuad(x - blurAmount, - y - blurAmount, - width + 2 * blurAmount, - height + 2 * blurAmount, - 1.0f / blurSteps); + float alpha = 1.0f / blurSteps; + int bx = (int) (x - blurAmount); + int by = (int) (y - blurAmount); + int bw = (int) (width + 2 * blurAmount); + int bh = (int) (height + 2 * blurAmount); + guiGraphics.blit(RenderPipelines.GUI_TEXTURED, res, bx, by, 0, 0, bw, bh, bw, bh, colorWithAlpha(alpha)); } -// GlStateManager._texEnv(GL11.GL_TEXTURE_ENV, GL11.GL_TEXTURE_ENV_MODE, GL11.GL_REPLACE ); - - // TODO: it would be nice if we could modulate the alpha of these overlays, but that doesn't - // work naively with the GL_REPLACE strategy we're using here. Will have to brush up my - // OpenGL knowledge to get alpha-icon with drop-shadow - RenderSystem.setShaderTexture(0, res); - ModUtils.drawTexQuad(x, y, width, height, 1.0f); + // Draw the actual icon at full alpha + guiGraphics.blit(RenderPipelines.GUI_TEXTURED, res, x, y, 0, 0, width, height, width, height, colorWithAlpha(1.0f)); } public static void setStateLeftIcon(int i, boolean b) { @@ -125,17 +96,11 @@ public static void setStateRightIcon(int i, boolean b) { } @Override - public void renderOverlay(GuiGraphics guiGraphics, Minecraft minecraft) { - RenderSystem.enableBlend(); - RenderSystem.blendFuncSeparate(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA, GL11.GL_ONE, GL11.GL_ZERO); - - // Don't show if the debug screen is open + public void renderOverlay(GuiGraphicsExtractor guiGraphics, Minecraft minecraft) { if (minecraft.getDebugOverlay().showDebugScreen()) { return; } -// RenderSystem.disableLighting(); - mDisplayWidth = minecraft.getWindow().getGuiScaledWidth(); mDisplayHeight = minecraft.getWindow().getGuiScaledHeight(); this.rescale(); @@ -145,7 +110,7 @@ public void renderOverlay(GuiGraphics guiGraphics, Minecraft minecraft) { int yPos = mIconPadding; for (int i = 0; i < mResourcesLeft.size(); i++) { if (mFlagsLeft.get(i)) { - drawScaledTextureWithGlow(minecraft, mResourcesLeft.get(i), xPos, yPos, mIconSize, mIconSize); + drawScaledTextureWithGlow(guiGraphics, mResourcesLeft.get(i), xPos, yPos, mIconSize, mIconSize); } xPos += mIconSize + mIconPadding; } @@ -154,11 +119,9 @@ public void renderOverlay(GuiGraphics guiGraphics, Minecraft minecraft) { xPos = mDisplayWidth - mIconSize - mIconPadding; for (int i = 0; i < mResourcesRight.size(); i++) { if (mFlagsRight.get(i)) { - drawScaledTextureWithGlow(minecraft, mResourcesRight.get(i), xPos, yPos, mIconSize, mIconSize); + drawScaledTextureWithGlow(guiGraphics, mResourcesRight.get(i), xPos, yPos, mIconSize, mIconSize); } xPos -= (mIconSize + mIconPadding); } - - RenderSystem.disableBlend(); } -} \ No newline at end of file +} diff --git a/common/src/main/java/com/specialeffect/eyemine/event/BlockOutlineEvent.java b/common/src/main/java/com/specialeffect/eyemine/event/BlockOutlineEvent.java index f01d8ead..0e1f9854 100644 --- a/common/src/main/java/com/specialeffect/eyemine/event/BlockOutlineEvent.java +++ b/common/src/main/java/com/specialeffect/eyemine/event/BlockOutlineEvent.java @@ -1,15 +1,9 @@ package com.specialeffect.eyemine.event; -import com.mojang.blaze3d.vertex.PoseStack; -import dev.architectury.event.Event; -import dev.architectury.event.EventFactory; -import dev.architectury.event.EventResult; -import net.minecraft.client.renderer.MultiBufferSource; - -public interface BlockOutlineEvent { - Event OUTLINE = EventFactory.createLoop(new BlockOutlineEvent.BlockOutline[0]); - - public interface BlockOutline { - EventResult renderOutline(MultiBufferSource bufferSource, PoseStack poseStack); - } +/** + * Block outline event - now delegates to EyeMineEvents.BLOCK_OUTLINE. + * Kept for compatibility with existing code that references OUTLINE. + */ +public class BlockOutlineEvent { + public static final EventHolder OUTLINE = EyeMineEvents.BLOCK_OUTLINE; } diff --git a/common/src/main/java/com/specialeffect/eyemine/event/EventHolder.java b/common/src/main/java/com/specialeffect/eyemine/event/EventHolder.java new file mode 100644 index 00000000..97477241 --- /dev/null +++ b/common/src/main/java/com/specialeffect/eyemine/event/EventHolder.java @@ -0,0 +1,16 @@ +package com.specialeffect.eyemine.event; + +import java.util.List; +import java.util.concurrent.CopyOnWriteArrayList; + +public class EventHolder { + private final List listeners = new CopyOnWriteArrayList<>(); + + public void register(T listener) { + listeners.add(listener); + } + + public List getListeners() { + return listeners; + } +} diff --git a/common/src/main/java/com/specialeffect/eyemine/event/EventResult.java b/common/src/main/java/com/specialeffect/eyemine/event/EventResult.java new file mode 100644 index 00000000..346a2683 --- /dev/null +++ b/common/src/main/java/com/specialeffect/eyemine/event/EventResult.java @@ -0,0 +1,12 @@ +package com.specialeffect.eyemine.event; + +public enum EventResult { + PASS, + INTERRUPT_TRUE, + INTERRUPT_FALSE; + + public static EventResult pass() { return PASS; } + public static EventResult interruptTrue() { return INTERRUPT_TRUE; } + public static EventResult interruptFalse() { return INTERRUPT_FALSE; } + public boolean isPresent() { return this != PASS; } +} diff --git a/common/src/main/java/com/specialeffect/eyemine/event/EyeMineEvents.java b/common/src/main/java/com/specialeffect/eyemine/event/EyeMineEvents.java new file mode 100644 index 00000000..85ab31d9 --- /dev/null +++ b/common/src/main/java/com/specialeffect/eyemine/event/EyeMineEvents.java @@ -0,0 +1,77 @@ +package com.specialeffect.eyemine.event; + +import com.mojang.blaze3d.vertex.PoseStack; +import net.minecraft.client.DeltaTracker; +import net.minecraft.client.Minecraft; +import net.minecraft.client.gui.GuiGraphicsExtractor; +import net.minecraft.client.gui.screens.Screen; +import net.minecraft.client.renderer.MultiBufferSource; +import net.minecraft.server.level.ServerLevel; +import net.minecraft.world.damagesource.DamageSource; +import net.minecraft.world.entity.Entity; +import net.minecraft.world.entity.LivingEntity; +import net.minecraft.world.entity.player.Player; +import net.minecraft.world.level.Level; + +public final class EyeMineEvents { + public static final EventHolder CLIENT_TICK = new EventHolder<>(); + public static final EventHolder KEY_PRESSED = new EventHolder<>(); + public static final EventHolder SCREEN_SET = new EventHolder<>(); + public static final EventHolder RENDER_HUD = new EventHolder<>(); + public static final EventHolder CLIENT_SETUP = new EventHolder<>(); + public static final EventHolder ENTITY_DEATH = new EventHolder<>(); + public static final EventHolder ENTITY_ADD = new EventHolder<>(); + public static final EventHolder WORLD_LOAD = new EventHolder<>(); + public static final EventHolder PLAYER_TICK = new EventHolder<>(); + public static final EventHolder BLOCK_OUTLINE = new EventHolder<>(); + + @FunctionalInterface + public interface ClientTickListener { + void onClientTick(Minecraft minecraft); + } + + @FunctionalInterface + public interface KeyPressedListener { + EventResult onKeyPressed(Minecraft minecraft, int keyCode, int scanCode, int action, int modifiers); + } + + @FunctionalInterface + public interface ScreenSetListener { + ScreenSetResult onScreenSet(Screen screen); + } + + @FunctionalInterface + public interface RenderHudListener { + void onRenderHud(GuiGraphicsExtractor graphics, DeltaTracker deltaTracker); + } + + @FunctionalInterface + public interface ClientSetupListener { + void onClientSetup(Minecraft minecraft); + } + + @FunctionalInterface + public interface EntityDeathListener { + EventResult onDeath(LivingEntity entity, DamageSource source); + } + + @FunctionalInterface + public interface EntityAddListener { + EventResult onAdd(Entity entity, Level level); + } + + @FunctionalInterface + public interface WorldLoadListener { + void onWorldLoad(ServerLevel level); + } + + @FunctionalInterface + public interface PlayerTickListener { + void onPlayerTick(Player player); + } + + @FunctionalInterface + public interface BlockOutlineListener { + EventResult renderOutline(MultiBufferSource bufferSource, PoseStack poseStack); + } +} diff --git a/common/src/main/java/com/specialeffect/eyemine/event/ScreenSetResult.java b/common/src/main/java/com/specialeffect/eyemine/event/ScreenSetResult.java new file mode 100644 index 00000000..3dd042a1 --- /dev/null +++ b/common/src/main/java/com/specialeffect/eyemine/event/ScreenSetResult.java @@ -0,0 +1,8 @@ +package com.specialeffect.eyemine.event; + +import net.minecraft.client.gui.screens.Screen; + +public record ScreenSetResult(boolean handled, Screen screen) { + public static ScreenSetResult pass() { return new ScreenSetResult(false, null); } + public static ScreenSetResult set(Screen screen) { return new ScreenSetResult(true, screen); } +} diff --git a/common/src/main/java/com/specialeffect/eyemine/mixin/KeyboardInputMixin.java b/common/src/main/java/com/specialeffect/eyemine/mixin/KeyboardInputMixin.java index c1ae4630..408d4e9b 100644 --- a/common/src/main/java/com/specialeffect/eyemine/mixin/KeyboardInputMixin.java +++ b/common/src/main/java/com/specialeffect/eyemine/mixin/KeyboardInputMixin.java @@ -12,44 +12,44 @@ package com.specialeffect.eyemine.mixin; import com.specialeffect.eyemine.utils.KeyboardInputHelper; -import net.minecraft.client.Options; -import net.minecraft.client.player.Input; +import net.minecraft.client.player.ClientInput; import net.minecraft.client.player.KeyboardInput; -import org.spongepowered.asm.mixin.Final; +import net.minecraft.world.entity.player.Input; +import net.minecraft.world.phys.Vec2; import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.Shadow; import org.spongepowered.asm.mixin.injection.At; -import org.spongepowered.asm.mixin.injection.At.Shift; import org.spongepowered.asm.mixin.injection.Inject; import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; -import org.spongepowered.asm.mixin.injection.callback.LocalCapture; @Mixin(KeyboardInput.class) -public class KeyboardInputMixin extends Input { - @Shadow - @Final - private Options options; +public class KeyboardInputMixin extends ClientInput { - @Inject(method = "tick(ZF)V", - locals = LocalCapture.CAPTURE_FAILEXCEPTION, at = @At( - value = "FIELD", - target = "Lnet/minecraft/client/player/KeyboardInput;up:Z", - shift = Shift.AFTER, - ordinal = 0)) - public void EyeMineTickSetUp(boolean bl, float f, CallbackInfo ci) { - this.up = this.options.keyUp.isDown() || KeyboardInputHelper.mWalkForwardOverride.get(); - } - - @Inject(method = "tick(ZF)V", - locals = LocalCapture.CAPTURE_FAILEXCEPTION, at = @At( - value = "FIELD", - target = "Lnet/minecraft/client/player/KeyboardInput;forwardImpulse:F", - shift = Shift.AFTER, - ordinal = 0)) - public void EyeMineTick(boolean bl, float f, CallbackInfo ci) { + /** + * After tick() computes key presses and moveVector, override forward movement + * if EyeMine walk override is active. + * + * In 26.1.1, Input is an immutable record (boolean flags only), so we: + * 1. Set the forward flag to true in keyPresses + * 2. Override moveVector.x (forward impulse) with the fractional walk speed + * + * moveVector is a Vec2 where x = forward/backward impulse, y = left/right impulse + */ + @Inject(method = "tick()V", at = @At("TAIL")) + public void eyemine$overrideWalkForward(CallbackInfo ci) { if (KeyboardInputHelper.mWalkForwardOverride.get()) { - this.forwardImpulse = Math.max(-1, Math.min(1, KeyboardInputHelper.mOverrideWalkSpeed)); - // TODO: do we still want as drastic a sneak-slowing-down with eyemine?? + Input current = this.keyPresses; + this.keyPresses = new Input( + true, + current.backward(), + current.left(), + current.right(), + current.jump(), + current.shift(), + current.sprint() + ); + // Override the move vector with fractional walk speed + float speed = Math.max(-1, Math.min(1, KeyboardInputHelper.mOverrideWalkSpeed)); + this.moveVector = new Vec2(speed, this.moveVector.y); } } } diff --git a/common/src/main/java/com/specialeffect/eyemine/mixin/LivingEntityMixin.java b/common/src/main/java/com/specialeffect/eyemine/mixin/LivingEntityMixin.java index 864a48c3..6b59516d 100644 --- a/common/src/main/java/com/specialeffect/eyemine/mixin/LivingEntityMixin.java +++ b/common/src/main/java/com/specialeffect/eyemine/mixin/LivingEntityMixin.java @@ -1,22 +1,20 @@ package com.specialeffect.eyemine.mixin; import com.specialeffect.eyemine.submod.movement.IStepUp; -import net.minecraft.core.Holder; +import net.minecraft.resources.Identifier; import net.minecraft.world.entity.LivingEntity; -import net.minecraft.world.entity.ai.attributes.Attribute; +import net.minecraft.world.entity.ai.attributes.AttributeInstance; +import net.minecraft.world.entity.ai.attributes.AttributeModifier; import net.minecraft.world.entity.ai.attributes.Attributes; import net.minecraft.world.entity.player.Player; import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.Shadow; import org.spongepowered.asm.mixin.Unique; -import org.spongepowered.asm.mixin.injection.At; -import org.spongepowered.asm.mixin.injection.Inject; -import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; @Mixin(LivingEntity.class) public abstract class LivingEntityMixin implements IStepUp { - @Shadow - public abstract double getAttributeValue(Holder holder); + + @Unique + private static final Identifier EYEMINE_STEP_UP_ID = Identifier.fromNamespaceAndPath("eyemine", "extra_step_up"); @Unique public float eyemine$extraStepUp = 0.0F; @@ -29,15 +27,21 @@ public abstract class LivingEntityMixin implements IStepUp { @Override public void eyemine$setExtraStepUp(float stepUp) { this.eyemine$extraStepUp = stepUp; - } - - @Inject(method = "maxUpStep()F", at = @At(value = "RETURN"), cancellable = true) - public void maxUpStep(CallbackInfoReturnable cir) { - LivingEntity livingEntity = (LivingEntity) (Object) this; - if (livingEntity instanceof Player && eyemine$getExtraStepUp() > 0.0F) { - float f = (float) this.getAttributeValue(Attributes.STEP_HEIGHT); - float value = livingEntity.getControllingPassenger() instanceof Player ? Math.max(f, 1.0F) : f; - cir.setReturnValue(value + this.eyemine$getExtraStepUp()); + LivingEntity self = (LivingEntity) (Object) this; + if (self instanceof Player) { + AttributeInstance attr = self.getAttribute(Attributes.STEP_HEIGHT); + if (attr != null) { + // Remove old modifier if present + attr.removeModifier(EYEMINE_STEP_UP_ID); + // Add new modifier if non-zero + if (stepUp > 0.0F) { + attr.addTransientModifier(new AttributeModifier( + EYEMINE_STEP_UP_ID, + stepUp, + AttributeModifier.Operation.ADD_VALUE + )); + } + } } } } diff --git a/common/src/main/java/com/specialeffect/eyemine/mixin/MouseHandlerMixin.java b/common/src/main/java/com/specialeffect/eyemine/mixin/MouseHandlerMixin.java index 506cd704..3a915a61 100644 --- a/common/src/main/java/com/specialeffect/eyemine/mixin/MouseHandlerMixin.java +++ b/common/src/main/java/com/specialeffect/eyemine/mixin/MouseHandlerMixin.java @@ -106,7 +106,7 @@ public abstract class MouseHandlerMixin { target = "Lnet/minecraft/client/MouseHandler;minecraft:Lnet/minecraft/client/Minecraft;", ordinal = 0)) public void eyemine$setInputMode(long handle, double xpos, double ypos, CallbackInfo ci) { - GLFW.glfwSetInputMode(this.minecraft.getWindow().getWindow(), GLFW.GLFW_CURSOR, GLFW.GLFW_CURSOR_NORMAL); + GLFW.glfwSetInputMode(this.minecraft.getWindow().handle(), GLFW.GLFW_CURSOR, GLFW.GLFW_CURSOR_NORMAL); } /** @@ -168,7 +168,7 @@ public abstract class MouseHandlerMixin { // In grabbed mode (eye tracker), reset cursor to origin after each move // This makes each subsequent position effectively a delta if (!MouseHelper.ungrabbedMouseMode) { - GLFW.glfwSetCursorPos(this.minecraft.getWindow().getWindow(), 0, 0); + GLFW.glfwSetCursorPos(this.minecraft.getWindow().handle(), 0, 0); this.xpos = 0; this.ypos = 0; // In grabbed mode, call turnPlayer immediately since position IS the delta @@ -341,7 +341,7 @@ public abstract class MouseHandlerMixin { } this.eyemine$resetVelocity(); - int i = this.minecraft.options.invertYMouse().get() ? -1 : 1; + int i = this.minecraft.options.invertMouseY().get() ? -1 : 1; this.minecraft.getTutorial().onMouse(d2, d3); if (this.minecraft.player != null) { @@ -427,11 +427,11 @@ public abstract class MouseHandlerMixin { } @Inject(method = "grabMouse()V", at = @At(value = "INVOKE", - target = "Lcom/mojang/blaze3d/platform/InputConstants;grabOrReleaseMouse(JIDD)V", + target = "Lcom/mojang/blaze3d/platform/InputConstants;grabOrReleaseMouse(Lcom/mojang/blaze3d/platform/Window;IDD)V", ordinal = 0), cancellable = true) public void eyemine$onlyGrabWhenUngrabbed(CallbackInfo ci) { if (!MouseHelper.ungrabbedMouseMode) { - InputConstants.grabOrReleaseMouse(this.minecraft.getWindow().getWindow(), 212995, this.xpos, this.ypos); + InputConstants.grabOrReleaseMouse(this.minecraft.getWindow(), 212995, this.xpos, this.ypos); } this.minecraft.setScreen((Screen) null); diff --git a/common/src/main/java/com/specialeffect/eyemine/mixin/TitleScreenMixin.java b/common/src/main/java/com/specialeffect/eyemine/mixin/TitleScreenMixin.java index bd54dc6c..274c622f 100644 --- a/common/src/main/java/com/specialeffect/eyemine/mixin/TitleScreenMixin.java +++ b/common/src/main/java/com/specialeffect/eyemine/mixin/TitleScreenMixin.java @@ -11,13 +11,13 @@ package com.specialeffect.eyemine.mixin; -import com.mojang.blaze3d.vertex.PoseStack; -import net.minecraft.Util; -import net.minecraft.client.gui.GuiGraphics; + +import net.minecraft.client.gui.GuiGraphicsExtractor; import net.minecraft.client.gui.screens.Screen; import net.minecraft.client.gui.screens.TitleScreen; import net.minecraft.network.chat.Component; import net.minecraft.util.Mth; +import org.joml.Matrix3x2fStack; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.Unique; import org.spongepowered.asm.mixin.injection.At; @@ -38,29 +38,28 @@ protected TitleScreenMixin(Component component) { super(component); } - @Inject(at = @At("HEAD"), method = "render(Lnet/minecraft/client/gui/GuiGraphics;IIF)V") - public void eyemineTitleHeadRender(GuiGraphics guiGraphics, int p_render_1_, int p_render_2_, float p_render_3_, CallbackInfo ci) { + @Inject(at = @At("HEAD"), method = "extractRenderState(Lnet/minecraft/client/gui/GuiGraphicsExtractor;IIF)V") + public void eyemineTitleHeadRender(GuiGraphicsExtractor guiGraphics, int mouseX, int mouseY, float partialTick, CallbackInfo ci) { if (this.eyemine$firstRenderTime == 0L && this.eyemine$showFadeInAnimation) { - this.eyemine$firstRenderTime = Util.getMillis(); + this.eyemine$firstRenderTime = System.currentTimeMillis(); } - - eyemine$animationTime = this.eyemine$showFadeInAnimation ? (float) (Util.getMillis() - this.eyemine$firstRenderTime) / 1000.0F : 1.0F; + eyemine$animationTime = this.eyemine$showFadeInAnimation ? (float) (System.currentTimeMillis() - this.eyemine$firstRenderTime) / 1000.0F : 1.0F; } - @Inject(at = @At("TAIL"), method = "render(Lnet/minecraft/client/gui/GuiGraphics;IIF)V") - public void eyemineTitleTailRender(GuiGraphics guiGraphics, int p_render_1_, int p_render_2_, float p_render_3_, CallbackInfo ci) { + @Inject(at = @At("TAIL"), method = "extractRenderState(Lnet/minecraft/client/gui/GuiGraphicsExtractor;IIF)V") + public void eyemineTitleTailRender(GuiGraphicsExtractor guiGraphics, int mouseX, int mouseY, float partialTick, CallbackInfo ci) { float f1 = this.eyemine$showFadeInAnimation ? Mth.clamp(eyemine$animationTime - 1.0F, 0.0F, 1.0F) : 1.0F; int l = Mth.ceil(f1 * 255.0F) << 24; String subtitle = "EyeMine Edition"; if ((l & -67108864) != 0) { - PoseStack poseStack = guiGraphics.pose(); - poseStack.pushPose(); - poseStack.translate((float) (this.width / 2), 25.0F, 0.0F); + Matrix3x2fStack pose = guiGraphics.pose(); + pose.pushMatrix(); + pose.translate((float) (this.width / 2), 25.0F); float f2 = 1.5f; - poseStack.scale(f2, f2, f2); - guiGraphics.drawCenteredString(this.font, subtitle, 0, -8, 16776960 | l); - poseStack.popPose(); + pose.scale(f2, f2); + guiGraphics.centeredText(this.font, subtitle, 0, -8, 16776960 | l); + pose.popMatrix(); } } } diff --git a/common/src/main/java/com/specialeffect/eyemine/packets/NetworkService.java b/common/src/main/java/com/specialeffect/eyemine/packets/NetworkService.java new file mode 100644 index 00000000..5f689852 --- /dev/null +++ b/common/src/main/java/com/specialeffect/eyemine/packets/NetworkService.java @@ -0,0 +1,25 @@ +package com.specialeffect.eyemine.packets; + +import net.minecraft.network.RegistryFriendlyByteBuf; +import net.minecraft.network.codec.StreamCodec; +import net.minecraft.network.protocol.common.custom.CustomPacketPayload; +import net.minecraft.world.entity.player.Player; + +public interface NetworkService { + void registerC2S( + CustomPacketPayload.Type type, + StreamCodec codec, + PacketHandler handler); + + void sendToServer(CustomPacketPayload payload); + + @FunctionalInterface + interface PacketHandler { + void handle(T payload, PacketContext context); + } + + interface PacketContext { + void queue(Runnable work); + Player getPlayer(); + } +} diff --git a/common/src/main/java/com/specialeffect/eyemine/packets/PacketHandler.java b/common/src/main/java/com/specialeffect/eyemine/packets/PacketHandler.java index d4dd143d..118f84eb 100644 --- a/common/src/main/java/com/specialeffect/eyemine/packets/PacketHandler.java +++ b/common/src/main/java/com/specialeffect/eyemine/packets/PacketHandler.java @@ -17,43 +17,17 @@ import com.specialeffect.eyemine.packets.messages.GatherBlockMessage; import com.specialeffect.eyemine.packets.messages.SendCommandMessage; import com.specialeffect.eyemine.packets.messages.TeleportPlayerToSpawnPointMessage; -import dev.architectury.networking.NetworkManager; +import com.specialeffect.eyemine.platform.Services; public class PacketHandler { - private static final String PROTOCOL_VERSION = "1"; -// public static final Predicate validator = v -> PROTOCOL_VERSION.equals(v) || NetworkRegistry.ABSENT.equals(v) || NetworkRegistry.ACCEPTVANILLA.equals(v); -// public static final SimpleChannel CHANNEL = NetworkRegistry.ChannelBuilder.named(ResourceLocation.fromNamespaceAndPath("specialeffect", EyeMine.MOD_ID)) -// .clientAcceptedVersions(validator) -// .serverAcceptedVersions(validator) -// .networkProtocolVersion(() -> PROTOCOL_VERSION) -// .simpleChannel(); - - -// public static final NetworkChannel CHANNEL = NetworkChannel.create(ResourceLocation.fromNamespaceAndPath("specialeffect", EyeMine.MOD_ID)); - public static void init() { - NetworkManager.registerReceiver(NetworkManager.c2s(), AddItemToHotbar.ID, AddItemToHotbar.CODEC, AddItemToHotbar.Handler::handle); -// CHANNEL.register(AddItemToHotbar.class, AddItemToHotbar::write, AddItemToHotbar::decode, -// AddItemToHotbar.Handler::handle); - - NetworkManager.registerReceiver(NetworkManager.c2s(), SendCommandMessage.ID, SendCommandMessage.CODEC, SendCommandMessage.Handler::handle); -// CHANNEL.register(SendCommandMessage.class, SendCommandMessage::encode, -// SendCommandMessage::decode, SendCommandMessage.Handler::handle); - - NetworkManager.registerReceiver(NetworkManager.c2s(), TeleportPlayerToSpawnPointMessage.ID, TeleportPlayerToSpawnPointMessage.CODEC, TeleportPlayerToSpawnPointMessage.Handler::handle); -// CHANNEL.register(TeleportPlayerToSpawnPointMessage.class, TeleportPlayerToSpawnPointMessage::encode, -// TeleportPlayerToSpawnPointMessage::decode, TeleportPlayerToSpawnPointMessage.Handler::handle); - - NetworkManager.registerReceiver(NetworkManager.c2s(), GatherBlockMessage.ID, GatherBlockMessage.CODEC, GatherBlockMessage.Handler::handle); -// CHANNEL.register(GatherBlockMessage.class, GatherBlockMessage::encode, -// GatherBlockMessage::decode, GatherBlockMessage.Handler::handle); - - NetworkManager.registerReceiver(NetworkManager.c2s(), ActivateBlockAtPosition.ID, ActivateBlockAtPosition.CODEC, ActivateBlockAtPosition.Handler::handle); -// CHANNEL.register(ActivateBlockAtPosition.class, ActivateBlockAtPosition::encode, -// ActivateBlockAtPosition::decode, ActivateBlockAtPosition.Handler::handle); - - NetworkManager.registerReceiver(NetworkManager.c2s(), ChangeFlyingStateMessage.ID, ChangeFlyingStateMessage.CODEC, ChangeFlyingStateMessage.Handler::handle); -// CHANNEL.register(ChangeFlyingStateMessage.class, ChangeFlyingStateMessage::encode, -// ChangeFlyingStateMessage::decode, ChangeFlyingStateMessage.Handler::handle); + NetworkService net = Services.NETWORK; + + net.registerC2S(AddItemToHotbar.ID, AddItemToHotbar.CODEC, AddItemToHotbar.Handler::handle); + net.registerC2S(SendCommandMessage.ID, SendCommandMessage.CODEC, SendCommandMessage.Handler::handle); + net.registerC2S(TeleportPlayerToSpawnPointMessage.ID, TeleportPlayerToSpawnPointMessage.CODEC, TeleportPlayerToSpawnPointMessage.Handler::handle); + net.registerC2S(GatherBlockMessage.ID, GatherBlockMessage.CODEC, GatherBlockMessage.Handler::handle); + net.registerC2S(ActivateBlockAtPosition.ID, ActivateBlockAtPosition.CODEC, ActivateBlockAtPosition.Handler::handle); + net.registerC2S(ChangeFlyingStateMessage.ID, ChangeFlyingStateMessage.CODEC, ChangeFlyingStateMessage.Handler::handle); } } diff --git a/common/src/main/java/com/specialeffect/eyemine/packets/messages/ActivateBlockAtPosition.java b/common/src/main/java/com/specialeffect/eyemine/packets/messages/ActivateBlockAtPosition.java index 54150bd8..bb6664a3 100644 --- a/common/src/main/java/com/specialeffect/eyemine/packets/messages/ActivateBlockAtPosition.java +++ b/common/src/main/java/com/specialeffect/eyemine/packets/messages/ActivateBlockAtPosition.java @@ -12,16 +12,15 @@ package com.specialeffect.eyemine.packets.messages; import com.specialeffect.eyemine.EyeMine; -import dev.architectury.networking.NetworkManager; +import com.specialeffect.eyemine.packets.NetworkService; import net.minecraft.core.BlockPos; import net.minecraft.network.RegistryFriendlyByteBuf; import net.minecraft.network.codec.StreamCodec; import net.minecraft.network.protocol.common.custom.CustomPacketPayload; -import net.minecraft.resources.ResourceLocation; +import net.minecraft.resources.Identifier; import net.minecraft.world.InteractionHand; import net.minecraft.world.entity.player.Player; import net.minecraft.world.level.Level; -import net.minecraft.world.level.block.Block; import net.minecraft.world.level.block.state.BlockState; import net.minecraft.world.phys.BlockHitResult; @@ -32,7 +31,7 @@ public record ActivateBlockAtPosition(BlockPos pos) implements CustomPacketPaylo ActivateBlockAtPosition::new ); public static final CustomPacketPayload.Type ID = new CustomPacketPayload.Type<>( - ResourceLocation.fromNamespaceAndPath(EyeMine.MOD_ID, "activate_block_at_position")); + Identifier.fromNamespaceAndPath(EyeMine.MOD_ID, "activate_block_at_position")); @Override public Type type() { @@ -41,7 +40,7 @@ public Type type() { public static class Handler { @SuppressWarnings("deprecation") - public static void handle(final ActivateBlockAtPosition pkt, NetworkManager.PacketContext context) { + public static void handle(final ActivateBlockAtPosition pkt, NetworkService.PacketContext context) { context.queue(() -> { Player player = context.getPlayer(); if (player == null) { @@ -50,13 +49,13 @@ public static void handle(final ActivateBlockAtPosition pkt, NetworkManager.Pack Level level = player.level(); BlockState state = level.getBlockState(pkt.pos); - Block block = state.getBlock(); - // NOTE this assumes hit is not used by onBlockActivated: could be a problem with some blocks - BlockHitResult hit = null; + // Create a synthetic hit result pointing at the top of the block + BlockHitResult hit = new BlockHitResult( + pkt.pos.getCenter(), net.minecraft.core.Direction.UP, pkt.pos, false); - // NOTE: should use state.onBlockActivated, but this requires non-null hit, so we suppress warning - block.useItemOn(player.getItemInHand(InteractionHand.MAIN_HAND), state, level, pkt.pos, player, InteractionHand.MAIN_HAND, hit); + // Use the BlockState's useItemOn which is public + state.useItemOn(player.getItemInHand(InteractionHand.MAIN_HAND), level, player, InteractionHand.MAIN_HAND, hit); }); } } diff --git a/common/src/main/java/com/specialeffect/eyemine/packets/messages/AddItemToHotbar.java b/common/src/main/java/com/specialeffect/eyemine/packets/messages/AddItemToHotbar.java index 834193ce..65b3f54a 100644 --- a/common/src/main/java/com/specialeffect/eyemine/packets/messages/AddItemToHotbar.java +++ b/common/src/main/java/com/specialeffect/eyemine/packets/messages/AddItemToHotbar.java @@ -12,12 +12,12 @@ package com.specialeffect.eyemine.packets.messages; import com.specialeffect.eyemine.EyeMine; -import dev.architectury.networking.NetworkManager; +import com.specialeffect.eyemine.packets.NetworkService; import net.minecraft.network.RegistryFriendlyByteBuf; import net.minecraft.network.codec.ByteBufCodecs; import net.minecraft.network.codec.StreamCodec; import net.minecraft.network.protocol.common.custom.CustomPacketPayload; -import net.minecraft.resources.ResourceLocation; +import net.minecraft.resources.Identifier; import net.minecraft.world.entity.player.Inventory; import net.minecraft.world.entity.player.Player; import net.minecraft.world.item.ItemStack; @@ -31,7 +31,7 @@ public record AddItemToHotbar(ItemStack item, int slotId) implements CustomPacke AddItemToHotbar::new ); public static final CustomPacketPayload.Type ID = new CustomPacketPayload.Type<>( - ResourceLocation.fromNamespaceAndPath(EyeMine.MOD_ID, "add_item_to_hotbar")); + Identifier.fromNamespaceAndPath(EyeMine.MOD_ID, "add_item_to_hotbar")); @Override public Type type() { @@ -43,7 +43,7 @@ public AddItemToHotbar(ItemStack item) { } public static class Handler { - public static void handle(final AddItemToHotbar pkt, NetworkManager.PacketContext context) { + public static void handle(final AddItemToHotbar pkt, NetworkService.PacketContext context) { context.queue(() -> { Player player = context.getPlayer(); if (player == null) { @@ -56,7 +56,7 @@ public static void handle(final AddItemToHotbar pkt, NetworkManager.PacketContex slot = inventory.getSuitableHotbarSlot(); } inventory.setItem(slot, pkt.item); - inventory.selected = slot; + inventory.setSelectedSlot(slot); }); } } diff --git a/common/src/main/java/com/specialeffect/eyemine/packets/messages/ChangeFlyingStateMessage.java b/common/src/main/java/com/specialeffect/eyemine/packets/messages/ChangeFlyingStateMessage.java index 1083294e..6a81fd8a 100644 --- a/common/src/main/java/com/specialeffect/eyemine/packets/messages/ChangeFlyingStateMessage.java +++ b/common/src/main/java/com/specialeffect/eyemine/packets/messages/ChangeFlyingStateMessage.java @@ -12,12 +12,12 @@ package com.specialeffect.eyemine.packets.messages; import com.specialeffect.eyemine.EyeMine; -import dev.architectury.networking.NetworkManager; +import com.specialeffect.eyemine.packets.NetworkService; import net.minecraft.network.RegistryFriendlyByteBuf; import net.minecraft.network.codec.ByteBufCodecs; import net.minecraft.network.codec.StreamCodec; import net.minecraft.network.protocol.common.custom.CustomPacketPayload; -import net.minecraft.resources.ResourceLocation; +import net.minecraft.resources.Identifier; import net.minecraft.world.entity.MoverType; import net.minecraft.world.entity.player.Player; import net.minecraft.world.phys.Vec3; @@ -31,7 +31,7 @@ public record ChangeFlyingStateMessage(boolean shouldBeFlying, int flyHeight) im ChangeFlyingStateMessage::new ); public static final CustomPacketPayload.Type ID = new CustomPacketPayload.Type<>( - ResourceLocation.fromNamespaceAndPath(EyeMine.MOD_ID, "change_flying_state")); + Identifier.fromNamespaceAndPath(EyeMine.MOD_ID, "change_flying_state")); @Override public Type type() { @@ -39,7 +39,7 @@ public Type type() { } public static class Handler { - public static void handle(final ChangeFlyingStateMessage pkt, NetworkManager.PacketContext context) { + public static void handle(final ChangeFlyingStateMessage pkt, NetworkService.PacketContext context) { context.queue(() -> { Player player = context.getPlayer(); if (player == null) { diff --git a/common/src/main/java/com/specialeffect/eyemine/packets/messages/GatherBlockMessage.java b/common/src/main/java/com/specialeffect/eyemine/packets/messages/GatherBlockMessage.java index 4d99f00a..5850ec64 100644 --- a/common/src/main/java/com/specialeffect/eyemine/packets/messages/GatherBlockMessage.java +++ b/common/src/main/java/com/specialeffect/eyemine/packets/messages/GatherBlockMessage.java @@ -12,12 +12,12 @@ package com.specialeffect.eyemine.packets.messages; import com.specialeffect.eyemine.EyeMine; -import dev.architectury.networking.NetworkManager; +import com.specialeffect.eyemine.packets.NetworkService; import net.minecraft.network.RegistryFriendlyByteBuf; import net.minecraft.network.codec.ByteBufCodecs; import net.minecraft.network.codec.StreamCodec; import net.minecraft.network.protocol.common.custom.CustomPacketPayload; -import net.minecraft.resources.ResourceLocation; +import net.minecraft.resources.Identifier; import net.minecraft.world.entity.Entity; import net.minecraft.world.entity.item.ItemEntity; import net.minecraft.world.entity.player.Player; @@ -30,7 +30,7 @@ public record GatherBlockMessage(int entityId) implements CustomPacketPayload { GatherBlockMessage::new ); public static final CustomPacketPayload.Type ID = new CustomPacketPayload.Type<>( - ResourceLocation.fromNamespaceAndPath(EyeMine.MOD_ID, "gather_block")); + Identifier.fromNamespaceAndPath(EyeMine.MOD_ID, "gather_block")); @Override public Type type() { @@ -38,14 +38,14 @@ public Type type() { } public static class Handler { - public static void handle(final GatherBlockMessage pkt, NetworkManager.PacketContext context) { + public static void handle(final GatherBlockMessage pkt, NetworkService.PacketContext context) { context.queue(() -> { Player player = context.getPlayer(); if (player == null) { return; } - Level level = player.getCommandSenderWorld(); + Level level = player.level(); Entity target = level.getEntity(pkt.entityId); if (target != null && target instanceof ItemEntity) { // Move item next to player to be picked up automatically diff --git a/common/src/main/java/com/specialeffect/eyemine/packets/messages/SendCommandMessage.java b/common/src/main/java/com/specialeffect/eyemine/packets/messages/SendCommandMessage.java index 190864be..6a495c92 100644 --- a/common/src/main/java/com/specialeffect/eyemine/packets/messages/SendCommandMessage.java +++ b/common/src/main/java/com/specialeffect/eyemine/packets/messages/SendCommandMessage.java @@ -12,13 +12,13 @@ package com.specialeffect.eyemine.packets.messages; import com.specialeffect.eyemine.EyeMine; -import dev.architectury.networking.NetworkManager; +import com.specialeffect.eyemine.packets.NetworkService; import net.minecraft.commands.Commands; import net.minecraft.network.RegistryFriendlyByteBuf; import net.minecraft.network.codec.ByteBufCodecs; import net.minecraft.network.codec.StreamCodec; import net.minecraft.network.protocol.common.custom.CustomPacketPayload; -import net.minecraft.resources.ResourceLocation; +import net.minecraft.resources.Identifier; import net.minecraft.server.MinecraftServer; public record SendCommandMessage(String command) implements CustomPacketPayload { @@ -28,7 +28,7 @@ public record SendCommandMessage(String command) implements CustomPacketPayload SendCommandMessage::new ); public static final CustomPacketPayload.Type ID = new CustomPacketPayload.Type<>( - ResourceLocation.fromNamespaceAndPath(EyeMine.MOD_ID, "send_command")); + Identifier.fromNamespaceAndPath(EyeMine.MOD_ID, "send_command")); @Override public Type type() { @@ -36,9 +36,9 @@ public Type type() { } public static class Handler { - public static void handle(final SendCommandMessage pkt, NetworkManager.PacketContext context) { + public static void handle(final SendCommandMessage pkt, NetworkService.PacketContext context) { context.queue(() -> { - MinecraftServer server = context.getPlayer().getServer(); + MinecraftServer server = context.getPlayer().level().getServer(); if (server == null) { System.out.println("Server is null, cannot send command"); } else { diff --git a/common/src/main/java/com/specialeffect/eyemine/packets/messages/TeleportPlayerToSpawnPointMessage.java b/common/src/main/java/com/specialeffect/eyemine/packets/messages/TeleportPlayerToSpawnPointMessage.java index ffc1f37e..8d50fabc 100644 --- a/common/src/main/java/com/specialeffect/eyemine/packets/messages/TeleportPlayerToSpawnPointMessage.java +++ b/common/src/main/java/com/specialeffect/eyemine/packets/messages/TeleportPlayerToSpawnPointMessage.java @@ -12,13 +12,13 @@ package com.specialeffect.eyemine.packets.messages; import com.specialeffect.eyemine.EyeMine; -import dev.architectury.networking.NetworkManager; +import com.specialeffect.eyemine.packets.NetworkService; import net.minecraft.core.BlockPos; import net.minecraft.network.FriendlyByteBuf; import net.minecraft.network.RegistryFriendlyByteBuf; import net.minecraft.network.codec.StreamCodec; import net.minecraft.network.protocol.common.custom.CustomPacketPayload; -import net.minecraft.resources.ResourceLocation; +import net.minecraft.resources.Identifier; import net.minecraft.server.MinecraftServer; import net.minecraft.server.level.ServerLevel; import net.minecraft.server.level.ServerPlayer; @@ -27,7 +27,8 @@ import net.minecraft.world.entity.player.Player; import net.minecraft.world.level.block.Blocks; import net.minecraft.world.level.block.state.BlockState; -import net.minecraft.world.level.portal.DimensionTransition; +import net.minecraft.world.level.portal.TeleportTransition; +import net.minecraft.world.level.storage.LevelData; import net.minecraft.world.phys.Vec3; public record TeleportPlayerToSpawnPointMessage() implements CustomPacketPayload { @@ -35,7 +36,7 @@ public record TeleportPlayerToSpawnPointMessage() implements CustomPacketPayload TeleportPlayerToSpawnPointMessage::write, TeleportPlayerToSpawnPointMessage::new); public static final CustomPacketPayload.Type ID = new CustomPacketPayload.Type<>( - ResourceLocation.fromNamespaceAndPath(EyeMine.MOD_ID, "teleport_to_spawn_point")); + Identifier.fromNamespaceAndPath(EyeMine.MOD_ID, "teleport_to_spawn_point")); @Override public Type type() { @@ -51,39 +52,43 @@ public void write(FriendlyByteBuf buf) { } public static class Handler { - public static void handle(final TeleportPlayerToSpawnPointMessage pkt, NetworkManager.PacketContext context) { + public static void handle(final TeleportPlayerToSpawnPointMessage pkt, NetworkService.PacketContext context) { context.queue(() -> { Player player = context.getPlayer(); if (player == null) { return; } - if (!player.level().isClientSide) { - MinecraftServer server = player.getServer(); + if (!player.level().isClientSide()) { + MinecraftServer server = player.level().getServer(); ServerPlayer serverPlayer = (ServerPlayer) player; - ServerLevel respawnDimension = server.getLevel(serverPlayer.getRespawnDimension()); - BlockPos respawnPos = serverPlayer.getRespawnPosition(); - float respawnAngle = serverPlayer.getRespawnAngle(); - DimensionTransition transition; - if (serverPlayer != null && respawnPos != null) { - transition = serverPlayer.findRespawnPositionAndUseSpawnBlock(false, DimensionTransition.DO_NOTHING); - } else { - transition = null; - } + ServerPlayer.RespawnConfig respawnConfig = serverPlayer.getRespawnConfig(); + TeleportTransition transition; + if (respawnConfig != null) { + LevelData.RespawnData respawnData = respawnConfig.respawnData(); + BlockPos respawnPos = respawnData.pos(); + float respawnAngle = respawnData.yaw(); + ServerLevel respawnDimension = server.getLevel(respawnData.dimension()); + transition = serverPlayer.findRespawnPositionAndUseSpawnBlock(false, TeleportTransition.DO_NOTHING); - if (transition != null) { - BlockState state = respawnDimension.getBlockState(respawnPos); - boolean blockIsRespawnAnchor = state.is(Blocks.RESPAWN_ANCHOR); - Vec3 vector3d = transition.pos(); - float f1; - if (!state.is(BlockTags.BEDS) && !blockIsRespawnAnchor) { - f1 = respawnAngle; - } else { - Vec3 vector3d1 = Vec3.atBottomCenterOf(respawnPos).subtract(vector3d).normalize(); - f1 = (float) Mth.wrapDegrees(Mth.atan2(vector3d1.z, vector3d1.x) * (double) (180F / (float) Math.PI) - 90.0D); + if (transition != null && respawnDimension != null) { + BlockState state = respawnDimension.getBlockState(respawnPos); + boolean blockIsRespawnAnchor = state.is(Blocks.RESPAWN_ANCHOR); + Vec3 vector3d = transition.position(); + float f1; + if (!state.is(BlockTags.BEDS) && !blockIsRespawnAnchor) { + f1 = respawnAngle; + } else { + Vec3 vector3d1 = Vec3.atBottomCenterOf(respawnPos).subtract(vector3d).normalize(); + f1 = (float) Mth.wrapDegrees(Mth.atan2(vector3d1.z, vector3d1.x) * (double) (180F / (float) Math.PI) - 90.0D); + } + serverPlayer.teleportTo(respawnDimension, vector3d.x, vector3d.y, vector3d.z, java.util.Set.of(), f1, 0.0F, false); + serverPlayer.setRespawnPosition( + new ServerPlayer.RespawnConfig( + LevelData.RespawnData.of(respawnDimension.dimension(), BlockPos.containing(vector3d), respawnAngle, 0.0F), + false + ), false); } - serverPlayer.moveTo(vector3d.x, vector3d.y, vector3d.z, f1, 0.0F); - serverPlayer.setRespawnPosition(respawnDimension.dimension(), BlockPos.containing(vector3d), respawnAngle, false, false); } } }); diff --git a/common/src/main/java/com/specialeffect/eyemine/platform/EyeMineConfig.java b/common/src/main/java/com/specialeffect/eyemine/platform/EyeMineConfig.java index e8d4e627..ffd7dfc6 100644 --- a/common/src/main/java/com/specialeffect/eyemine/platform/EyeMineConfig.java +++ b/common/src/main/java/com/specialeffect/eyemine/platform/EyeMineConfig.java @@ -1,197 +1,36 @@ package com.specialeffect.eyemine.platform; -import dev.architectury.injectables.annotations.ExpectPlatform; - public class EyeMineConfig { - @ExpectPlatform - public static boolean getDisableCustomNewWorld() { - // Just throw an error, the content should get replaced at runtime. - throw new AssertionError(); - } - - @ExpectPlatform - public static void setCustomSpeedFactor(float speed) { - // Just throw an error, the content should get replaced at runtime. - throw new AssertionError(); - } - - @ExpectPlatform - public static boolean getUsingMouseEmulation() { - // Just throw an error, the content should get replaced at runtime. - throw new AssertionError(); - } - - @ExpectPlatform - public static boolean getAutoSelectTool() { - // Just throw an error, the content should get replaced at runtime. - throw new AssertionError(); - } - - @ExpectPlatform - public static boolean getAutoSelectSword() { - // Just throw an error, the content should get replaced at runtime. - throw new AssertionError(); - } - - @ExpectPlatform - public static int getTicksBetweenMining() { - // Just throw an error, the content should get replaced at runtime. - throw new AssertionError(); - } - - @ExpectPlatform - public static int getRadiusChests() { - // Just throw an error, the content should get replaced at runtime. - throw new AssertionError(); - } - - @ExpectPlatform - public static double getBowDrawTime() { - // Just throw an error, the content should get replaced at runtime. - throw new AssertionError(); - } - - @ExpectPlatform - public static float getFullscreenOverlayAlpha() { - // Just throw an error, the content should get replaced at runtime. - throw new AssertionError(); - } - - @ExpectPlatform - public static int getIronsightsFovReduction() { - // Just throw an error, the content should get replaced at runtime. - throw new AssertionError(); - } - - @ExpectPlatform - public static double getIronsightsSensitivityReduction() { - // Just throw an error, the content should get replaced at runtime. - throw new AssertionError(); - } - - @ExpectPlatform - public static boolean getUseDwellForSingleUseItem() { - // Just throw an error, the content should get replaced at runtime. - throw new AssertionError(); - } - - @ExpectPlatform - public static boolean getUseDwellForSingleMine() { - // Just throw an error, the content should get replaced at runtime. - throw new AssertionError(); - } - - @ExpectPlatform - public static boolean getServerCompatibilityMode() { - // Just throw an error, the content should get replaced at runtime. - throw new AssertionError(); - } - - @ExpectPlatform - public static int getRadiusDoors() { - // Just throw an error, the content should get replaced at runtime. - throw new AssertionError(); - } - - @ExpectPlatform - public static int getFlyHeightManual() { - // Just throw an error, the content should get replaced at runtime. - throw new AssertionError(); - } - - @ExpectPlatform - public static int getFlyHeightAuto() { - // Just throw an error, the content should get replaced at runtime. - throw new AssertionError(); - } - - @ExpectPlatform - public static boolean getDefaultDoAutoJump() { - // Just throw an error, the content should get replaced at runtime. - throw new AssertionError(); - } - - @ExpectPlatform - public static boolean getDisableAutoJumpFixes() { - // Just throw an error, the content should get replaced at runtime. - throw new AssertionError(); - } - - @ExpectPlatform - public static boolean getMoveWhenMouseStationary() { - // Just throw an error, the content should get replaced at runtime. - throw new AssertionError(); - } - - @ExpectPlatform - public static boolean getSlowdownOnCorners() { - // Just throw an error, the content should get replaced at runtime. - throw new AssertionError(); - } - - @ExpectPlatform - public static int getWalkingSlowdownFilter() { - // Just throw an error, the content should get replaced at runtime. - throw new AssertionError(); - } - - @ExpectPlatform - public static boolean getAllowLadderDescent() { - // Just throw an error, the content should get replaced at runtime. - throw new AssertionError(); - } - - @ExpectPlatform - public static float getCustomSpeedFactor() { - // Just throw an error, the content should get replaced at runtime. - throw new AssertionError(); - } - - @ExpectPlatform - public static float getBoatMaxTurnAtSpeed() { - // Just throw an error, the content should get replaced at runtime. - throw new AssertionError(); - } - - @ExpectPlatform - public static double getBoatSlowdown() { - // Just throw an error, the content should get replaced at runtime. - throw new AssertionError(); - } - - @ExpectPlatform - public static double getDwellTimeSeconds() { - // Just throw an error, the content should get replaced at runtime. - throw new AssertionError(); - } - - @ExpectPlatform - public static double getDwellLockonTimeSeconds() { - // Just throw an error, the content should get replaced at runtime. - throw new AssertionError(); - } - - @ExpectPlatform - public static boolean getDwellShowWithTransparency() { - // Just throw an error, the content should get replaced at runtime. - throw new AssertionError(); - } - - @ExpectPlatform - public static boolean getDwellShowExpanding() { - // Just throw an error, the content should get replaced at runtime. - throw new AssertionError(); - } - - @ExpectPlatform - public static boolean getSlowdownOnAttack() { - // Just throw an error, the content should get replaced at runtime. - throw new AssertionError(); - } - - @ExpectPlatform - public static int getGazeIdleThreshold() { - // Just throw an error, the content should get replaced at runtime. - throw new AssertionError(); - } + public static boolean getDisableCustomNewWorld() { return Services.CONFIG.getDisableCustomNewWorld(); } + public static void setCustomSpeedFactor(float speed) { Services.CONFIG.setCustomSpeedFactor(speed); } + public static boolean getUsingMouseEmulation() { return Services.CONFIG.getUsingMouseEmulation(); } + public static boolean getAutoSelectTool() { return Services.CONFIG.getAutoSelectTool(); } + public static boolean getAutoSelectSword() { return Services.CONFIG.getAutoSelectSword(); } + public static int getTicksBetweenMining() { return Services.CONFIG.getTicksBetweenMining(); } + public static int getRadiusChests() { return Services.CONFIG.getRadiusChests(); } + public static double getBowDrawTime() { return Services.CONFIG.getBowDrawTime(); } + public static float getFullscreenOverlayAlpha() { return Services.CONFIG.getFullscreenOverlayAlpha(); } + public static int getIronsightsFovReduction() { return Services.CONFIG.getIronsightsFovReduction(); } + public static double getIronsightsSensitivityReduction() { return Services.CONFIG.getIronsightsSensitivityReduction(); } + public static boolean getUseDwellForSingleUseItem() { return Services.CONFIG.getUseDwellForSingleUseItem(); } + public static boolean getUseDwellForSingleMine() { return Services.CONFIG.getUseDwellForSingleMine(); } + public static boolean getServerCompatibilityMode() { return Services.CONFIG.getServerCompatibilityMode(); } + public static int getRadiusDoors() { return Services.CONFIG.getRadiusDoors(); } + public static int getFlyHeightManual() { return Services.CONFIG.getFlyHeightManual(); } + public static int getFlyHeightAuto() { return Services.CONFIG.getFlyHeightAuto(); } + public static boolean getDefaultDoAutoJump() { return Services.CONFIG.getDefaultDoAutoJump(); } + public static boolean getDisableAutoJumpFixes() { return Services.CONFIG.getDisableAutoJumpFixes(); } + public static boolean getMoveWhenMouseStationary() { return Services.CONFIG.getMoveWhenMouseStationary(); } + public static boolean getSlowdownOnCorners() { return Services.CONFIG.getSlowdownOnCorners(); } + public static int getWalkingSlowdownFilter() { return Services.CONFIG.getWalkingSlowdownFilter(); } + public static boolean getAllowLadderDescent() { return Services.CONFIG.getAllowLadderDescent(); } + public static float getCustomSpeedFactor() { return Services.CONFIG.getCustomSpeedFactor(); } + public static float getBoatMaxTurnAtSpeed() { return Services.CONFIG.getBoatMaxTurnAtSpeed(); } + public static double getBoatSlowdown() { return Services.CONFIG.getBoatSlowdown(); } + public static double getDwellTimeSeconds() { return Services.CONFIG.getDwellTimeSeconds(); } + public static double getDwellLockonTimeSeconds() { return Services.CONFIG.getDwellLockonTimeSeconds(); } + public static boolean getDwellShowWithTransparency() { return Services.CONFIG.getDwellShowWithTransparency(); } + public static boolean getDwellShowExpanding() { return Services.CONFIG.getDwellShowExpanding(); } + public static boolean getSlowdownOnAttack() { return Services.CONFIG.getSlowdownOnAttack(); } + public static int getGazeIdleThreshold() { return Services.CONFIG.getGazeIdleThreshold(); } } diff --git a/common/src/main/java/com/specialeffect/eyemine/platform/InventoryConfig.java b/common/src/main/java/com/specialeffect/eyemine/platform/InventoryConfig.java index f17b2348..b44795bc 100644 --- a/common/src/main/java/com/specialeffect/eyemine/platform/InventoryConfig.java +++ b/common/src/main/java/com/specialeffect/eyemine/platform/InventoryConfig.java @@ -1,155 +1,29 @@ package com.specialeffect.eyemine.platform; -import dev.architectury.injectables.annotations.ExpectPlatform; - public class InventoryConfig { - @ExpectPlatform - public static int getKey0() { - // Just throw an error, the content should get replaced at runtime. - throw new AssertionError(); - } - - @ExpectPlatform - public static int getKey1() { - // Just throw an error, the content should get replaced at runtime. - throw new AssertionError(); - } - - @ExpectPlatform - public static int getKey2() { - // Just throw an error, the content should get replaced at runtime. - throw new AssertionError(); - } - - @ExpectPlatform - public static int getKey3() { - // Just throw an error, the content should get replaced at runtime. - throw new AssertionError(); - } - - @ExpectPlatform - public static int getKey4() { - // Just throw an error, the content should get replaced at runtime. - throw new AssertionError(); - } - - @ExpectPlatform - public static int getKey5() { - // Just throw an error, the content should get replaced at runtime. - throw new AssertionError(); - } - - @ExpectPlatform - public static int getKey6() { - // Just throw an error, the content should get replaced at runtime. - throw new AssertionError(); - } - - @ExpectPlatform - public static int getKey7() { - // Just throw an error, the content should get replaced at runtime. - throw new AssertionError(); - } - - @ExpectPlatform - public static int getKey8() { - // Just throw an error, the content should get replaced at runtime. - throw new AssertionError(); - } - - @ExpectPlatform - public static int getKey9() { - // Just throw an error, the content should get replaced at runtime. - throw new AssertionError(); - } - - @ExpectPlatform - public static int getKeySurvPrevTab() { - // Just throw an error, the content should get replaced at runtime. - throw new AssertionError(); - } - - @ExpectPlatform - public static int getKeySurvNextTab() { - // Just throw an error, the content should get replaced at runtime. - throw new AssertionError(); - } - - @ExpectPlatform - public static int getKeySurvRecipes() { - // Just throw an error, the content should get replaced at runtime. - throw new AssertionError(); - } - - @ExpectPlatform - public static int getKeySurvCraftable() { - // Just throw an error, the content should get replaced at runtime. - throw new AssertionError(); - } - - @ExpectPlatform - public static int getkeySurvPrevPage() { - // Just throw an error, the content should get replaced at runtime. - throw new AssertionError(); - } - - @ExpectPlatform - public static int getkeySurvNextPage() { - // Just throw an error, the content should get replaced at runtime. - throw new AssertionError(); - } - - @ExpectPlatform - public static int getKeySurvOutput() { - // Just throw an error, the content should get replaced at runtime. - throw new AssertionError(); - } - - @ExpectPlatform - public static int getKeyPrev() { - // Just throw an error, the content should get replaced at runtime. - throw new AssertionError(); - } - - @ExpectPlatform - public static int getKeyNext() { - // Just throw an error, the content should get replaced at runtime. - throw new AssertionError(); - } - - @ExpectPlatform - public static int getKeyNextItemRow() { - // Just throw an error, the content should get replaced at runtime. - throw new AssertionError(); - } - - @ExpectPlatform - public static int getKeyNextItemCol() { - // Just throw an error, the content should get replaced at runtime. - throw new AssertionError(); - } - - @ExpectPlatform - public static int getKeyScrollUp() { - // Just throw an error, the content should get replaced at runtime. - throw new AssertionError(); - } - - @ExpectPlatform - public static int getKeyScrollDown() { - // Just throw an error, the content should get replaced at runtime. - throw new AssertionError(); - } - - @ExpectPlatform - public static int getKeySearch() { - // Just throw an error, the content should get replaced at runtime. - throw new AssertionError(); - } - - @ExpectPlatform - public static int getKeyDrop() { - // Just throw an error, the content should get replaced at runtime. - throw new AssertionError(); - } + public static int getKey0() { return Services.INVENTORY_CONFIG.getKey0(); } + public static int getKey1() { return Services.INVENTORY_CONFIG.getKey1(); } + public static int getKey2() { return Services.INVENTORY_CONFIG.getKey2(); } + public static int getKey3() { return Services.INVENTORY_CONFIG.getKey3(); } + public static int getKey4() { return Services.INVENTORY_CONFIG.getKey4(); } + public static int getKey5() { return Services.INVENTORY_CONFIG.getKey5(); } + public static int getKey6() { return Services.INVENTORY_CONFIG.getKey6(); } + public static int getKey7() { return Services.INVENTORY_CONFIG.getKey7(); } + public static int getKey8() { return Services.INVENTORY_CONFIG.getKey8(); } + public static int getKey9() { return Services.INVENTORY_CONFIG.getKey9(); } + public static int getKeySurvPrevTab() { return Services.INVENTORY_CONFIG.getKeySurvPrevTab(); } + public static int getKeySurvNextTab() { return Services.INVENTORY_CONFIG.getKeySurvNextTab(); } + public static int getKeySurvRecipes() { return Services.INVENTORY_CONFIG.getKeySurvRecipes(); } + public static int getKeySurvCraftable() { return Services.INVENTORY_CONFIG.getKeySurvCraftable(); } + public static int getkeySurvPrevPage() { return Services.INVENTORY_CONFIG.getkeySurvPrevPage(); } + public static int getkeySurvNextPage() { return Services.INVENTORY_CONFIG.getkeySurvNextPage(); } + public static int getKeySurvOutput() { return Services.INVENTORY_CONFIG.getKeySurvOutput(); } + public static int getKeyPrev() { return Services.INVENTORY_CONFIG.getKeyPrev(); } + public static int getKeyNext() { return Services.INVENTORY_CONFIG.getKeyNext(); } + public static int getKeyNextItemRow() { return Services.INVENTORY_CONFIG.getKeyNextItemRow(); } + public static int getKeyNextItemCol() { return Services.INVENTORY_CONFIG.getKeyNextItemCol(); } + public static int getKeyScrollUp() { return Services.INVENTORY_CONFIG.getKeyScrollUp(); } + public static int getKeyScrollDown() { return Services.INVENTORY_CONFIG.getKeyScrollDown(); } + public static int getKeySearch() { return Services.INVENTORY_CONFIG.getKeySearch(); } + public static int getKeyDrop() { return Services.INVENTORY_CONFIG.getKeyDrop(); } } diff --git a/common/src/main/java/com/specialeffect/eyemine/platform/Services.java b/common/src/main/java/com/specialeffect/eyemine/platform/Services.java new file mode 100644 index 00000000..3a89e2a1 --- /dev/null +++ b/common/src/main/java/com/specialeffect/eyemine/platform/Services.java @@ -0,0 +1,27 @@ +package com.specialeffect.eyemine.platform; + +import com.specialeffect.eyemine.packets.NetworkService; +import com.specialeffect.eyemine.platform.services.IEyeMineConfigService; +import com.specialeffect.eyemine.platform.services.IInventoryConfigService; +import com.specialeffect.eyemine.platform.services.IPlatformHelper; +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; + +import java.util.ServiceLoader; + +public class Services { + private static final Logger LOGGER = LogManager.getLogger(); + + public static final IPlatformHelper PLATFORM = load(IPlatformHelper.class); + public static final IEyeMineConfigService CONFIG = load(IEyeMineConfigService.class); + public static final IInventoryConfigService INVENTORY_CONFIG = load(IInventoryConfigService.class); + public static final NetworkService NETWORK = load(NetworkService.class); + + public static T load(Class clazz) { + final T loadedService = ServiceLoader.load(clazz) + .findFirst() + .orElseThrow(() -> new NullPointerException("Failed to load service for " + clazz.getName())); + LOGGER.debug("Loaded {} for service {}", loadedService, clazz); + return loadedService; + } +} diff --git a/common/src/main/java/com/specialeffect/eyemine/platform/services/IEyeMineConfigService.java b/common/src/main/java/com/specialeffect/eyemine/platform/services/IEyeMineConfigService.java new file mode 100644 index 00000000..d9a3ca4a --- /dev/null +++ b/common/src/main/java/com/specialeffect/eyemine/platform/services/IEyeMineConfigService.java @@ -0,0 +1,36 @@ +package com.specialeffect.eyemine.platform.services; + +public interface IEyeMineConfigService { + boolean getDisableCustomNewWorld(); + void setCustomSpeedFactor(float speed); + boolean getUsingMouseEmulation(); + boolean getAutoSelectTool(); + boolean getAutoSelectSword(); + int getTicksBetweenMining(); + int getRadiusChests(); + double getBowDrawTime(); + float getFullscreenOverlayAlpha(); + int getIronsightsFovReduction(); + double getIronsightsSensitivityReduction(); + boolean getUseDwellForSingleUseItem(); + boolean getUseDwellForSingleMine(); + boolean getServerCompatibilityMode(); + int getRadiusDoors(); + int getFlyHeightManual(); + int getFlyHeightAuto(); + boolean getDefaultDoAutoJump(); + boolean getDisableAutoJumpFixes(); + boolean getMoveWhenMouseStationary(); + boolean getSlowdownOnCorners(); + int getWalkingSlowdownFilter(); + boolean getAllowLadderDescent(); + float getCustomSpeedFactor(); + float getBoatMaxTurnAtSpeed(); + double getBoatSlowdown(); + double getDwellTimeSeconds(); + double getDwellLockonTimeSeconds(); + boolean getDwellShowWithTransparency(); + boolean getDwellShowExpanding(); + boolean getSlowdownOnAttack(); + int getGazeIdleThreshold(); +} diff --git a/common/src/main/java/com/specialeffect/eyemine/platform/services/IInventoryConfigService.java b/common/src/main/java/com/specialeffect/eyemine/platform/services/IInventoryConfigService.java new file mode 100644 index 00000000..40f3b0a3 --- /dev/null +++ b/common/src/main/java/com/specialeffect/eyemine/platform/services/IInventoryConfigService.java @@ -0,0 +1,29 @@ +package com.specialeffect.eyemine.platform.services; + +public interface IInventoryConfigService { + int getKey0(); + int getKey1(); + int getKey2(); + int getKey3(); + int getKey4(); + int getKey5(); + int getKey6(); + int getKey7(); + int getKey8(); + int getKey9(); + int getKeySurvPrevTab(); + int getKeySurvNextTab(); + int getKeySurvRecipes(); + int getKeySurvCraftable(); + int getkeySurvPrevPage(); + int getkeySurvNextPage(); + int getKeySurvOutput(); + int getKeyPrev(); + int getKeyNext(); + int getKeyNextItemRow(); + int getKeyNextItemCol(); + int getKeyScrollUp(); + int getKeyScrollDown(); + int getKeySearch(); + int getKeyDrop(); +} diff --git a/common/src/main/java/com/specialeffect/eyemine/platform/services/IPlatformHelper.java b/common/src/main/java/com/specialeffect/eyemine/platform/services/IPlatformHelper.java new file mode 100644 index 00000000..05129278 --- /dev/null +++ b/common/src/main/java/com/specialeffect/eyemine/platform/services/IPlatformHelper.java @@ -0,0 +1,7 @@ +package com.specialeffect.eyemine.platform.services; + +public interface IPlatformHelper { + String getPlatformName(); + boolean isModLoaded(String modId); + boolean isDevelopmentEnvironment(); +} diff --git a/common/src/main/java/com/specialeffect/eyemine/submod/mining/ContinuouslyMine.java b/common/src/main/java/com/specialeffect/eyemine/submod/mining/ContinuouslyMine.java index 81e6fcb4..f61244a8 100644 --- a/common/src/main/java/com/specialeffect/eyemine/submod/mining/ContinuouslyMine.java +++ b/common/src/main/java/com/specialeffect/eyemine/submod/mining/ContinuouslyMine.java @@ -23,10 +23,10 @@ import com.specialeffect.eyemine.submod.misc.ContinuouslyAttack; import com.specialeffect.eyemine.submod.mouse.MouseHandlerMod; import com.specialeffect.utils.ModUtils; -import dev.architectury.event.EventResult; -import dev.architectury.event.events.client.ClientRawInputEvent; -import dev.architectury.event.events.client.ClientTickEvent; -import dev.architectury.networking.NetworkManager; +import com.specialeffect.eyemine.event.EventResult; +import com.specialeffect.eyemine.event.EyeMineEvents; +import com.specialeffect.eyemine.packets.NetworkService; +import com.specialeffect.eyemine.platform.Services; import net.minecraft.client.KeyMapping; import net.minecraft.client.Minecraft; import net.minecraft.client.player.LocalPlayer; @@ -34,7 +34,7 @@ import net.minecraft.world.entity.player.Inventory; import net.minecraft.world.item.ItemStack; import net.minecraft.world.item.Items; -import net.minecraft.world.item.PickaxeItem; +import net.minecraft.tags.ItemTags; import org.lwjgl.glfw.GLFW; import com.specialeffect.eyemine.utils.MouseHelper; @@ -67,14 +67,14 @@ public void onInitializeClient() { "key.eyemine.continious_destroy", Type.KEYSYM, GLFW.GLFW_KEY_M, - "category.eyemine.category.eyegaze_common" // The translation key of the keybinding's category. + Keybindings.EYEGAZE_COMMON // The translation key of the keybinding's category. )); // Register an icon for the overlay mIconIndex = StateOverlay.registerTextureRight("eyemine:textures/icons/mine.png"); - ClientTickEvent.CLIENT_PRE.register(this::onClientTick); - ClientRawInputEvent.KEY_PRESSED.register(this::onKeyInput); + EyeMineEvents.CLIENT_TICK.register(this::onClientTick); + EyeMineEvents.KEY_PRESSED.register(this::onKeyInput); } @Override @@ -165,11 +165,11 @@ private EventResult onKeyInput(Minecraft minecraft, int keyCode, int scanCode, i return EventResult.pass(); } - if (InputConstants.isKeyDown(minecraft.getWindow().getWindow(), 292)) { + if (InputConstants.isKeyDown(minecraft.getWindow(), 292)) { return EventResult.pass(); } - if (mDestroyKB.matches(keyCode, scanCode) && mDestroyKB.consumeClick()) { + if (mDestroyKB.matches(new net.minecraft.client.input.KeyEvent(keyCode, scanCode, modifiers)) && mDestroyKB.consumeClick()) { mIsAttacking = !mIsAttacking; StateOverlay.setStateRightIcon(mIconIndex, mIsAttacking); @@ -197,12 +197,12 @@ static boolean choosePickaxe(Inventory inventory) { // In creative mode, we can either select a pickaxe from the hotbar // or just rustle up a new one - if (inventory.getSelected().getItem() instanceof PickaxeItem) { + if (inventory.getSelectedItem().is(ItemTags.PICKAXES)) { return true; } else { - int pickaxeId = ModUtils.findItemInHotbar(inventory, (item -> item instanceof PickaxeItem)); + int pickaxeId = ModUtils.findItemInHotbar(inventory, (item -> item.builtInRegistryHolder().is(ItemTags.PICKAXES))); if (pickaxeId > -1) { - inventory.selected = pickaxeId; + inventory.setSelectedSlot(pickaxeId); return true; } else { return false; @@ -212,6 +212,6 @@ static boolean choosePickaxe(Inventory inventory) { static void requestCreatePickaxe() { // Ask server to put new item in hotbar - NetworkManager.sendToServer(new AddItemToHotbar(new ItemStack(Items.DIAMOND_PICKAXE))); + Services.NETWORK.sendToServer(new AddItemToHotbar(new ItemStack(Items.DIAMOND_PICKAXE))); } } diff --git a/common/src/main/java/com/specialeffect/eyemine/submod/mining/DwellMine.java b/common/src/main/java/com/specialeffect/eyemine/submod/mining/DwellMine.java index 98b0b5f7..f12b7af5 100644 --- a/common/src/main/java/com/specialeffect/eyemine/submod/mining/DwellMine.java +++ b/common/src/main/java/com/specialeffect/eyemine/submod/mining/DwellMine.java @@ -18,9 +18,8 @@ import com.specialeffect.eyemine.submod.utils.DwellAction; import com.specialeffect.eyemine.submod.utils.TargetBlock; import com.specialeffect.utils.ModUtils; -import dev.architectury.event.EventResult; -import dev.architectury.event.events.client.ClientRawInputEvent; -import dev.architectury.event.events.client.ClientTickEvent; +import com.specialeffect.eyemine.event.EventResult; +import com.specialeffect.eyemine.event.EyeMineEvents; import net.minecraft.client.KeyMapping; import net.minecraft.client.Minecraft; import org.lwjgl.glfw.GLFW; @@ -41,18 +40,18 @@ public void onInitializeClient() { "key.eyemine.toggle_dwell", Type.KEYSYM, GLFW.GLFW_KEY_KP_6, - "category.eyemine.category.eyegaze_extra" // The translation key of the keybinding's category. + Keybindings.EYEGAZE_EXTRA // The translation key of the keybinding's category. )); Keybindings.keybindings.add(mDwellMineOnceKB = new KeyMapping( "key.eyemine.dwell_once", Type.KEYSYM, GLFW.GLFW_KEY_KP_8, - "category.eyemine.category.eyegaze_extra" // The translation key of the keybinding's category. + Keybindings.EYEGAZE_EXTRA // The translation key of the keybinding's category. )); - ClientTickEvent.CLIENT_PRE.register(this::onClientTick); - ClientRawInputEvent.KEY_PRESSED.register(this::onKeyInput); + EyeMineEvents.CLIENT_TICK.register(this::onClientTick); + EyeMineEvents.KEY_PRESSED.register(this::onKeyInput); //Initialize variables super.onInitializeClient(); @@ -69,11 +68,11 @@ private EventResult onKeyInput(Minecraft minecraft, int keyCode, int scanCode, i return EventResult.pass(); } - if (InputConstants.isKeyDown(minecraft.getWindow().getWindow(), 292)) { + if (InputConstants.isKeyDown(minecraft.getWindow(), 292)) { return EventResult.pass(); } - if (mDwellMineKB.matches(keyCode, scanCode) && mDwellMineKB.consumeClick()) { + if (mDwellMineKB.matches(new net.minecraft.client.input.KeyEvent(keyCode, scanCode, modifiers)) && mDwellMineKB.consumeClick()) { if (mDwelling) { // Turn off dwell mine this.setDwelling(false); @@ -86,7 +85,7 @@ private EventResult onKeyInput(Minecraft minecraft, int keyCode, int scanCode, i return EventResult.pass(); } - if (mDwellMineOnceKB.matches(keyCode, scanCode) && mDwellMineOnceKB.consumeClick()) { + if (mDwellMineOnceKB.matches(new net.minecraft.client.input.KeyEvent(keyCode, scanCode, modifiers)) && mDwellMineOnceKB.consumeClick()) { this.dwellOnce(); return EventResult.pass(); } diff --git a/common/src/main/java/com/specialeffect/eyemine/submod/mining/GatherDrops.java b/common/src/main/java/com/specialeffect/eyemine/submod/mining/GatherDrops.java index 957619c7..c6a11c98 100644 --- a/common/src/main/java/com/specialeffect/eyemine/submod/mining/GatherDrops.java +++ b/common/src/main/java/com/specialeffect/eyemine/submod/mining/GatherDrops.java @@ -17,9 +17,10 @@ import com.specialeffect.eyemine.packets.messages.GatherBlockMessage; import com.specialeffect.eyemine.submod.SubMod; import com.specialeffect.utils.ModUtils; -import dev.architectury.event.EventResult; -import dev.architectury.event.events.client.ClientRawInputEvent; -import dev.architectury.networking.NetworkManager; +import com.specialeffect.eyemine.event.EventResult; +import com.specialeffect.eyemine.event.EyeMineEvents; +import com.specialeffect.eyemine.packets.NetworkService; +import com.specialeffect.eyemine.platform.Services; import net.minecraft.client.KeyMapping; import net.minecraft.client.Minecraft; import net.minecraft.client.multiplayer.ClientLevel; @@ -47,10 +48,10 @@ public void onInitializeClient() { "key.eyemine.gather", Type.KEYSYM, GLFW.GLFW_KEY_KP_MULTIPLY, - "category.eyemine.category.eyegaze_extra" // The translation key of the keybinding's category. + Keybindings.EYEGAZE_EXTRA // The translation key of the keybinding's category. )); - ClientRawInputEvent.KEY_PRESSED.register(this::onKeyInput); + EyeMineEvents.KEY_PRESSED.register(this::onKeyInput); } private EventResult onKeyInput(Minecraft minecraft, int keyCode, int scanCode, int action, int modifiers) { @@ -58,12 +59,12 @@ private EventResult onKeyInput(Minecraft minecraft, int keyCode, int scanCode, i return EventResult.pass(); } - if (InputConstants.isKeyDown(minecraft.getWindow().getWindow(), 292)) { + if (InputConstants.isKeyDown(minecraft.getWindow(), 292)) { return EventResult.pass(); } - if (mGatherKB.matches(keyCode, scanCode) && mGatherKB.consumeClick()) { + if (mGatherKB.matches(new net.minecraft.client.input.KeyEvent(keyCode, scanCode, modifiers)) && mGatherKB.consumeClick()) { LocalPlayer player = minecraft.player; gatherBlocks(player); } @@ -82,7 +83,7 @@ public static void gatherBlocks(LocalPlayer player) { LOGGER.debug("gathering " + items.size() + " nearby items"); // Ask server to move items for (ItemEntity itemEntity : items) { - NetworkManager.sendToServer(new GatherBlockMessage(itemEntity.getId())); + Services.NETWORK.sendToServer(new GatherBlockMessage(itemEntity.getId())); } } } diff --git a/common/src/main/java/com/specialeffect/eyemine/submod/mining/MineOne.java b/common/src/main/java/com/specialeffect/eyemine/submod/mining/MineOne.java index e0bc5b45..d0a14c77 100644 --- a/common/src/main/java/com/specialeffect/eyemine/submod/mining/MineOne.java +++ b/common/src/main/java/com/specialeffect/eyemine/submod/mining/MineOne.java @@ -19,16 +19,15 @@ import com.specialeffect.eyemine.submod.utils.DwellAction; import com.specialeffect.eyemine.submod.utils.TargetBlock; import com.specialeffect.utils.ModUtils; -import dev.architectury.event.EventResult; -import dev.architectury.event.events.client.ClientRawInputEvent; -import dev.architectury.event.events.client.ClientTickEvent; +import com.specialeffect.eyemine.event.EventResult; +import com.specialeffect.eyemine.event.EyeMineEvents; import net.minecraft.client.KeyMapping; import net.minecraft.client.Minecraft; import net.minecraft.client.multiplayer.ClientLevel; import net.minecraft.client.player.LocalPlayer; import net.minecraft.core.BlockPos; import net.minecraft.network.chat.Component; -import net.minecraft.world.item.SwordItem; +import net.minecraft.tags.ItemTags; import net.minecraft.world.phys.BlockHitResult; import net.minecraft.world.phys.HitResult; import org.lwjgl.glfw.GLFW; @@ -49,11 +48,11 @@ public void onInitializeClient() { "key.eyemine.mine_singular", Type.KEYSYM, GLFW.GLFW_KEY_N, - "category.eyemine.category.eyegaze_common" // The translation key of the keybinding's category. + Keybindings.EYEGAZE_COMMON // The translation key of the keybinding's category. )); - ClientTickEvent.CLIENT_PRE.register(this::onClientTick); - ClientRawInputEvent.KEY_PRESSED.register(this::onKeyInput); + EyeMineEvents.CLIENT_TICK.register(this::onClientTick); + EyeMineEvents.KEY_PRESSED.register(this::onKeyInput); //Initialize variables super.onInitializeClient(); @@ -70,7 +69,7 @@ public void onClientTick(Minecraft minecraft) { ClientLevel level = minecraft.level; // Swords can't destroy blocks: warn user - if (player.getMainHandItem().getItem() instanceof SwordItem) { + if (player.getMainHandItem().is(ItemTags.SWORDS)) { String message = "Can't destroy blocks with a sword, please select another item"; player.sendSystemMessage(Component.literal(message)); @@ -125,11 +124,11 @@ private EventResult onKeyInput(Minecraft minecraft, int keyCode, int scanCode, i return EventResult.pass(); } - if (InputConstants.isKeyDown(minecraft.getWindow().getWindow(), 292)) { + if (InputConstants.isKeyDown(minecraft.getWindow(), 292)) { return EventResult.pass(); } - if (mDestroyKB.matches(keyCode, scanCode) && mDestroyKB.consumeClick()) { + if (mDestroyKB.matches(new net.minecraft.client.input.KeyEvent(keyCode, scanCode, modifiers)) && mDestroyKB.consumeClick()) { // turn off continuous mining ContinuouslyMine.stop(); diff --git a/common/src/main/java/com/specialeffect/eyemine/submod/misc/AutoOpenDoors.java b/common/src/main/java/com/specialeffect/eyemine/submod/misc/AutoOpenDoors.java index 022c579d..76eddc27 100644 --- a/common/src/main/java/com/specialeffect/eyemine/submod/misc/AutoOpenDoors.java +++ b/common/src/main/java/com/specialeffect/eyemine/submod/misc/AutoOpenDoors.java @@ -15,7 +15,7 @@ import com.specialeffect.eyemine.platform.EyeMineConfig; import com.specialeffect.eyemine.submod.IConfigListener; import com.specialeffect.eyemine.submod.SubMod; -import dev.architectury.event.events.client.ClientTickEvent; +import com.specialeffect.eyemine.event.EyeMineEvents; import net.minecraft.client.Minecraft; import net.minecraft.client.multiplayer.ClientLevel; import net.minecraft.client.multiplayer.prediction.BlockStatePredictionHandler; @@ -25,7 +25,7 @@ import net.minecraft.core.Vec3i; import net.minecraft.network.protocol.game.ServerboundUseItemOnPacket; import net.minecraft.world.InteractionHand; -import net.minecraft.world.ItemInteractionResult; +import net.minecraft.world.InteractionResult; import net.minecraft.world.level.block.state.BlockState; import net.minecraft.world.level.block.state.properties.BlockStateProperties; import net.minecraft.world.phys.BlockHitResult; @@ -38,7 +38,7 @@ public class AutoOpenDoors extends SubMod implements IConfigListener { public final String MODID = "autoopendoors"; public void onInitializeClient() { - ClientTickEvent.CLIENT_PRE.register(this::onClientTick); + EyeMineEvents.CLIENT_TICK.register(this::onClientTick); } public void syncConfig() { @@ -89,7 +89,7 @@ public void onClientTick(Minecraft event) { } BlockHitResult blockHitResult = new BlockHitResult(hitVec, fakeDirection, blockPos, true); - ItemInteractionResult result = state.useItemOn(player.getItemInHand(InteractionHand.MAIN_HAND), level, player, InteractionHand.MAIN_HAND, blockHitResult); + InteractionResult result = state.useItemOn(player.getItemInHand(InteractionHand.MAIN_HAND), level, player, InteractionHand.MAIN_HAND, blockHitResult); if (result.consumesAction()) { BlockStatePredictionHandler blockstatepredictionhandler = ((ClientLevelAccessor) level).eyemineGetPredictionHandler().startPredicting(); int i = blockstatepredictionhandler.currentSequence(); @@ -124,7 +124,7 @@ public void onClientTick(Minecraft event) { } } BlockHitResult blockHitResult = new BlockHitResult(hitVec, fakeDirection, pos, true); - ItemInteractionResult result = state.useItemOn(player.getItemInHand(InteractionHand.MAIN_HAND), level, player, InteractionHand.MAIN_HAND, blockHitResult); + InteractionResult result = state.useItemOn(player.getItemInHand(InteractionHand.MAIN_HAND), level, player, InteractionHand.MAIN_HAND, blockHitResult); if (result.consumesAction()) { BlockStatePredictionHandler blockstatepredictionhandler = ((ClientLevelAccessor) level).eyemineGetPredictionHandler().startPredicting(); int i = blockstatepredictionhandler.currentSequence(); diff --git a/common/src/main/java/com/specialeffect/eyemine/submod/misc/AutoPillar.java b/common/src/main/java/com/specialeffect/eyemine/submod/misc/AutoPillar.java index 81a0a9db..a259d4ab 100644 --- a/common/src/main/java/com/specialeffect/eyemine/submod/misc/AutoPillar.java +++ b/common/src/main/java/com/specialeffect/eyemine/submod/misc/AutoPillar.java @@ -19,15 +19,16 @@ import com.specialeffect.eyemine.packets.messages.AddItemToHotbar; import com.specialeffect.eyemine.submod.SubMod; import com.specialeffect.utils.ModUtils; -import dev.architectury.event.EventResult; -import dev.architectury.event.events.client.ClientRawInputEvent; -import dev.architectury.event.events.client.ClientTickEvent; -import dev.architectury.networking.NetworkManager; +import com.specialeffect.eyemine.event.EventResult; +import com.specialeffect.eyemine.event.EyeMineEvents; +import com.specialeffect.eyemine.packets.NetworkService; +import com.specialeffect.eyemine.platform.Services; import net.minecraft.client.KeyMapping; import net.minecraft.client.Minecraft; import net.minecraft.client.multiplayer.ClientLevel; import net.minecraft.client.player.LocalPlayer; import net.minecraft.network.protocol.game.ServerboundPlayerInputPacket; +import net.minecraft.world.entity.player.Input; import net.minecraft.world.InteractionHand; import net.minecraft.world.entity.player.Inventory; import net.minecraft.world.item.BlockItem; @@ -58,11 +59,11 @@ public void onInitializeClient() { "key.eyemine.pillar", Type.KEYSYM, GLFW.GLFW_KEY_0, - "category.eyemine.category.eyegaze_extra" // The translation key of the keybinding's category. + Keybindings.EYEGAZE_EXTRA // The translation key of the keybinding's category. )); - ClientTickEvent.CLIENT_PRE.register(this::onClientTick); - ClientRawInputEvent.KEY_PRESSED.register(this::onKeyInput); + EyeMineEvents.CLIENT_TICK.register(this::onClientTick); + EyeMineEvents.KEY_PRESSED.register(this::onKeyInput); } private float lastPlayerPitch; @@ -99,7 +100,7 @@ private EventResult onKeyInput(Minecraft minecraft, int keyCode, int scanCode, i return EventResult.pass(); } - if (InputConstants.isKeyDown(minecraft.getWindow().getWindow(), 292)) { + if (InputConstants.isKeyDown(minecraft.getWindow(), 292)) { return EventResult.pass(); } @@ -109,7 +110,7 @@ private EventResult onKeyInput(Minecraft minecraft, int keyCode, int scanCode, i // - next few ticks, gradually reset view // Technically there is no need to change player's view, but the user experience // is weird if you don't (you don't really know what just happened). - if (autoPlaceKeyBinding.matches(keyCode, scanCode) && autoPlaceKeyBinding.consumeClick()) { + if (autoPlaceKeyBinding.matches(new net.minecraft.client.input.KeyEvent(keyCode, scanCode, modifiers)) && autoPlaceKeyBinding.consumeClick()) { float origPitchTemp; synchronized (mOnLivingQueue) { origPitchTemp = lastPlayerPitch; @@ -124,7 +125,9 @@ private EventResult onKeyInput(Minecraft minecraft, int keyCode, int scanCode, i Minecraft mc = Minecraft.getInstance(); LocalPlayer player = mc.player; - player.connection.send(new ServerboundPlayerInputPacket(player.xxa, player.zza, true, player.input.shiftKeyDown)); + player.connection.send(new ServerboundPlayerInputPacket(new Input( + player.zza > 0, player.zza < 0, player.xxa > 0, player.xxa < 0, + true, player.isShiftKeyDown(), false))); player.jumpFromGround(); player.setXRot(90); @@ -176,10 +179,10 @@ static void chooseBlock(Inventory inventory) { // or just rustle up a new one int blockId = ModUtils.findItemInHotbar(inventory, (item -> item instanceof BlockItem)); if (blockId > -1) { - inventory.selected = blockId; + inventory.setSelectedSlot(blockId); } else { // Ask server to put new item in hotbar - NetworkManager.sendToServer(new AddItemToHotbar(new ItemStack(Blocks.SHORT_GRASS))); + Services.NETWORK.sendToServer(new AddItemToHotbar(new ItemStack(Blocks.SHORT_GRASS))); } } } diff --git a/common/src/main/java/com/specialeffect/eyemine/submod/misc/ContinuouslyAttack.java b/common/src/main/java/com/specialeffect/eyemine/submod/misc/ContinuouslyAttack.java index a37834cd..245df69f 100644 --- a/common/src/main/java/com/specialeffect/eyemine/submod/misc/ContinuouslyAttack.java +++ b/common/src/main/java/com/specialeffect/eyemine/submod/misc/ContinuouslyAttack.java @@ -23,20 +23,20 @@ import com.specialeffect.eyemine.submod.mining.ContinuouslyMine; import com.specialeffect.eyemine.utils.MouseHelper; import com.specialeffect.utils.ModUtils; -import dev.architectury.event.EventResult; -import dev.architectury.event.events.client.ClientRawInputEvent; -import dev.architectury.event.events.client.ClientTickEvent; -import dev.architectury.networking.NetworkManager; +import com.specialeffect.eyemine.event.EventResult; +import com.specialeffect.eyemine.event.EyeMineEvents; +import com.specialeffect.eyemine.packets.NetworkService; +import com.specialeffect.eyemine.platform.Services; import net.minecraft.client.KeyMapping; import net.minecraft.client.Minecraft; import net.minecraft.client.player.LocalPlayer; -import net.minecraft.network.protocol.game.ServerboundInteractPacket; +import net.minecraft.client.multiplayer.MultiPlayerGameMode; import net.minecraft.world.InteractionHand; import net.minecraft.world.entity.Entity; import net.minecraft.world.entity.player.Inventory; import net.minecraft.world.item.ItemStack; import net.minecraft.world.item.Items; -import net.minecraft.world.item.SwordItem; +import net.minecraft.tags.ItemTags; import net.minecraft.world.phys.EntityHitResult; import org.lwjgl.glfw.GLFW; @@ -56,14 +56,14 @@ public void onInitializeClient() { "key.eyemine.continious_attack", Type.KEYSYM, GLFW.GLFW_KEY_R, - "category.eyemine.category.eyegaze_common" // The translation key of the keybinding's category. + Keybindings.EYEGAZE_COMMON // The translation key of the keybinding's category. )); // Register an icon for the overlay mIconIndex = StateOverlay.registerTextureRight("eyemine:textures/icons/attack.png"); - ClientTickEvent.CLIENT_PRE.register(this::onClientTick); - ClientRawInputEvent.KEY_PRESSED.register(this::onKeyInput); + EyeMineEvents.CLIENT_TICK.register(this::onClientTick); + EyeMineEvents.KEY_PRESSED.register(this::onKeyInput); } @Override @@ -114,9 +114,11 @@ public void onClientTick(Minecraft minecraft) { final KeyMapping attackBinding = Minecraft.getInstance().options.keyAttack; KeyMapping.click(((KeyMappingAccessor) attackBinding).getActualKey()); } else { - player.attack(entity); -// channel.sendToServer(new AttackEntityMessage(entity)); - player.connection.send(ServerboundInteractPacket.createAttackPacket(entity, player.isShiftKeyDown())); + // Use gameMode.attack which handles both local and server-side + MultiPlayerGameMode gameMode = Minecraft.getInstance().gameMode; + if (gameMode != null) { + gameMode.attack(player, entity); + } } } else { recharging = true; @@ -137,11 +139,11 @@ private EventResult onKeyInput(Minecraft minecraft, int keyCode, int scanCode, i return EventResult.pass(); } - if (InputConstants.isKeyDown(minecraft.getWindow().getWindow(), 292)) { + if (InputConstants.isKeyDown(minecraft.getWindow(), 292)) { return EventResult.pass(); } - if (mAttackKB.matches(keyCode, scanCode) && mAttackKB.consumeClick()) { + if (mAttackKB.matches(new net.minecraft.client.input.KeyEvent(keyCode, scanCode, modifiers)) && mAttackKB.consumeClick()) { mIsAttacking = !mIsAttacking; StateOverlay.setStateRightIcon(mIconIndex, mIsAttacking); @@ -156,12 +158,12 @@ private boolean chooseWeapon(Inventory inventory) { // In creative mode, we can either select a sword from the hotbar // or just rustle up a new one - if (inventory.getSelected().getItem() instanceof SwordItem) { + if (inventory.getSelectedItem().is(ItemTags.SWORDS)) { return true; } else { - int swordId = ModUtils.findItemInHotbar(inventory, (item) -> item instanceof SwordItem); + int swordId = ModUtils.findItemInHotbar(inventory, (item) -> item.builtInRegistryHolder().is(ItemTags.SWORDS)); if (swordId > -1) { - inventory.selected = swordId; + inventory.setSelectedSlot(swordId); return true; } else { return false; @@ -171,6 +173,6 @@ private boolean chooseWeapon(Inventory inventory) { private void requestCreateSword() { // Ask server to put new item in hotbar - NetworkManager.sendToServer(new AddItemToHotbar(new ItemStack(Items.DIAMOND_SWORD))); + Services.NETWORK.sendToServer(new AddItemToHotbar(new ItemStack(Items.DIAMOND_SWORD))); } } diff --git a/common/src/main/java/com/specialeffect/eyemine/submod/misc/DefaultConfigForNewWorld.java b/common/src/main/java/com/specialeffect/eyemine/submod/misc/DefaultConfigForNewWorld.java index 3f7b8804..1ea2de39 100644 --- a/common/src/main/java/com/specialeffect/eyemine/submod/misc/DefaultConfigForNewWorld.java +++ b/common/src/main/java/com/specialeffect/eyemine/submod/misc/DefaultConfigForNewWorld.java @@ -17,11 +17,10 @@ import com.specialeffect.eyemine.submod.IConfigListener; import com.specialeffect.eyemine.submod.SubMod; import com.specialeffect.utils.ModUtils; -import dev.architectury.event.EventResult; -import dev.architectury.event.events.common.EntityEvent; -import dev.architectury.event.events.common.LifecycleEvent; -import dev.architectury.event.events.common.TickEvent; -import dev.architectury.networking.NetworkManager; +import com.specialeffect.eyemine.event.EventResult; +import com.specialeffect.eyemine.event.EyeMineEvents; +import com.specialeffect.eyemine.packets.NetworkService; +import com.specialeffect.eyemine.platform.Services; import net.minecraft.client.player.LocalPlayer; import net.minecraft.core.NonNullList; import net.minecraft.server.MinecraftServer; @@ -32,11 +31,13 @@ import net.minecraft.world.item.AirItem; import net.minecraft.world.item.ItemStack; import net.minecraft.world.item.Items; -import net.minecraft.world.level.GameRules; +import net.minecraft.world.level.gamerules.GameRule; +import net.minecraft.world.level.gamerules.GameRules; import net.minecraft.world.level.GameType; import net.minecraft.world.level.Level; import net.minecraft.world.level.block.Blocks; import net.minecraft.world.level.storage.LevelData; +import net.minecraft.world.level.storage.ServerLevelData; import java.lang.reflect.Field; @@ -59,9 +60,9 @@ public static void setNewWorldOptions(boolean daytime, boolean sunny, boolean ke } public void onInitializeClient() { - EntityEvent.ADD.register(this::onSpawn); - TickEvent.PLAYER_POST.register(this::onLiving); - LifecycleEvent.SERVER_LEVEL_LOAD.register(this::onWorldLoad); + EyeMineEvents.ENTITY_ADD.register(this::onSpawn); + EyeMineEvents.PLAYER_TICK.register(this::onLiving); + EyeMineEvents.WORLD_LOAD.register(this::onWorldLoad); } @Override @@ -89,7 +90,7 @@ private void onLiving(Player player) { firstOnLivingTick = false; if (player.isCreative()) { - NonNullList inventory = player.getInventory().items; + NonNullList inventory = player.getInventory().getNonEquipmentItems(); boolean hasSomeItems = false; for (ItemStack itemStack : inventory) { if (itemStack != null && !(itemStack.getItem() instanceof AirItem)) { @@ -114,21 +115,23 @@ private void onWorldLoad(ServerLevel serverLevel) { MinecraftServer server = serverLevel.getServer(); LevelData info = serverLevel.getLevelData(); - GameRules rules = info.getGameRules(); + GameRules rules = serverLevel.getGameRules(); if (info.getGameTime() < 60) { // First time loading, set rules according to user preference if (server != null && server.getDefaultGameType() == GameType.CREATIVE) { - rules.getRule(GameRules.RULE_DAYLIGHT).set(!alwaysDayTimeSetting, server); - rules.getRule(GameRules.RULE_WEATHER_CYCLE).set(!alwaysSunnySetting, server); - rules.getRule(GameRules.RULE_KEEPINVENTORY).set(keepInventorySetting, server); + rules.set(GameRules.ADVANCE_TIME, !alwaysDayTimeSetting, server); + rules.set(GameRules.ADVANCE_WEATHER, !alwaysSunnySetting, server); + rules.set(GameRules.KEEP_INVENTORY, keepInventorySetting, server); // Extra settings as a result of the above if (alwaysDayTimeSetting) { // we've just turned off daylightcycle while time = morning... - // we prefer full daylight! + // we prefer full daylight! Advance game time to noon. for (ServerLevel level : server.getAllLevels()) { - level.setDayTime(level.getDayTime() + (long) 2000); + if (level.getLevelData() instanceof ServerLevelData sld) { + sld.setGameTime(sld.getGameTime() + 2000L); + } } } } @@ -146,8 +149,8 @@ private void printGameRules(GameRules rules) { try { Object v = f.get(rules); - if (v instanceof GameRules.Key key) { - LOGGER.debug(key + ": " + rules.getRule(key).toString()); + if (v instanceof GameRule rule) { + LOGGER.debug(f.getName() + ": " + rules.get(rule).toString()); } } catch (Exception e) { e.printStackTrace(); @@ -157,22 +160,22 @@ private void printGameRules(GameRules rules) { private void equipPlayer(Inventory inventory) { // Ask server to put new item in hotbar - NetworkManager.sendToServer(new AddItemToHotbar( + Services.NETWORK.sendToServer(new AddItemToHotbar( new ItemStack(Blocks.BRICKS), 0)); - NetworkManager.sendToServer(new AddItemToHotbar( + Services.NETWORK.sendToServer(new AddItemToHotbar( new ItemStack(Blocks.SANDSTONE), 1)); - NetworkManager.sendToServer(new AddItemToHotbar( + Services.NETWORK.sendToServer(new AddItemToHotbar( new ItemStack(Blocks.GLASS_PANE), 2)); - NetworkManager.sendToServer(new AddItemToHotbar( + Services.NETWORK.sendToServer(new AddItemToHotbar( new ItemStack(Blocks.MOSSY_COBBLESTONE), 3)); - NetworkManager.sendToServer(new AddItemToHotbar( + Services.NETWORK.sendToServer(new AddItemToHotbar( new ItemStack(Blocks.TORCH), 6)); - NetworkManager.sendToServer(new AddItemToHotbar( + Services.NETWORK.sendToServer(new AddItemToHotbar( new ItemStack(Items.DIAMOND_PICKAXE), 7)); - NetworkManager.sendToServer(new AddItemToHotbar( + Services.NETWORK.sendToServer(new AddItemToHotbar( new ItemStack(Items.DIAMOND_SWORD), 8)); - inventory.selected = 1; + inventory.setSelectedSlot(1); } -} \ No newline at end of file +} diff --git a/common/src/main/java/com/specialeffect/eyemine/submod/misc/DwellBuild.java b/common/src/main/java/com/specialeffect/eyemine/submod/misc/DwellBuild.java index 39946e2e..e53e4b9e 100644 --- a/common/src/main/java/com/specialeffect/eyemine/submod/misc/DwellBuild.java +++ b/common/src/main/java/com/specialeffect/eyemine/submod/misc/DwellBuild.java @@ -18,9 +18,8 @@ import com.specialeffect.eyemine.submod.utils.DwellAction; import com.specialeffect.eyemine.submod.utils.TargetBlock; import com.specialeffect.utils.ModUtils; -import dev.architectury.event.EventResult; -import dev.architectury.event.events.client.ClientRawInputEvent; -import dev.architectury.event.events.client.ClientTickEvent; +import com.specialeffect.eyemine.event.EventResult; +import com.specialeffect.eyemine.event.EyeMineEvents; import net.minecraft.client.KeyMapping; import net.minecraft.client.Minecraft; import net.minecraft.network.chat.Component; @@ -45,17 +44,17 @@ public void onInitializeClient() { "key.eyemine.toggle_dwell_build", Type.KEYSYM, GLFW.GLFW_KEY_KP_3, - "category.eyemine.category.eyegaze_extra" // The translation key of the keybinding's category. + Keybindings.EYEGAZE_EXTRA // The translation key of the keybinding's category. )); Keybindings.keybindings.add(mDwellBuildOnceKB = new KeyMapping( "key.eyemine.dwell_build_once", Type.KEYSYM, GLFW.GLFW_KEY_KP_7, - "category.eyemine.category.eyegaze_extra" // The translation key of the keybinding's category. + Keybindings.EYEGAZE_EXTRA // The translation key of the keybinding's category. )); - ClientTickEvent.CLIENT_PRE.register(this::onClientTick); - ClientRawInputEvent.KEY_PRESSED.register(this::onKeyInput); + EyeMineEvents.CLIENT_TICK.register(this::onClientTick); + EyeMineEvents.KEY_PRESSED.register(this::onKeyInput); //Initialize variables super.onInitializeClient(); @@ -72,11 +71,11 @@ private EventResult onKeyInput(Minecraft minecraft, int keyCode, int scanCode, i return EventResult.pass(); } - if (InputConstants.isKeyDown(minecraft.getWindow().getWindow(), 292)) { + if (InputConstants.isKeyDown(minecraft.getWindow(), 292)) { return EventResult.pass(); } - if (mDwellBuildKB.matches(keyCode, scanCode) && mDwellBuildKB.consumeClick()) { + if (mDwellBuildKB.matches(new net.minecraft.client.input.KeyEvent(keyCode, scanCode, modifiers)) && mDwellBuildKB.consumeClick()) { Player player = Minecraft.getInstance().player; if (mDwelling) { // Turn off dwell build @@ -84,7 +83,7 @@ private EventResult onKeyInput(Minecraft minecraft, int keyCode, int scanCode, i ModUtils.sendPlayerMessage("Dwell building: OFF"); } else { // Turn on dwell build - ItemStack itemStack = player.getInventory().getSelected(); + ItemStack itemStack = player.getInventory().getSelectedItem(); if (itemStack.isEmpty()) { player.sendSystemMessage(Component.literal("Nothing in hand to use")); return EventResult.pass(); @@ -94,11 +93,11 @@ private EventResult onKeyInput(Minecraft minecraft, int keyCode, int scanCode, i ModUtils.sendPlayerMessage("Dwell building: ON"); } } - if (mDwellBuildOnceKB.matches(keyCode, scanCode) && mDwellBuildOnceKB.consumeClick()) { + if (mDwellBuildOnceKB.matches(new net.minecraft.client.input.KeyEvent(keyCode, scanCode, modifiers)) && mDwellBuildOnceKB.consumeClick()) { Player player = Minecraft.getInstance().player; // Turn on dwell once - ItemStack itemStack = player.getInventory().getSelected(); + ItemStack itemStack = player.getInventory().getSelectedItem(); if (itemStack.isEmpty()) { player.sendSystemMessage(Component.literal("Nothing in hand to use")); return EventResult.pass(); diff --git a/common/src/main/java/com/specialeffect/eyemine/submod/misc/IronSights.java b/common/src/main/java/com/specialeffect/eyemine/submod/misc/IronSights.java index 3c33c00d..f72b7403 100644 --- a/common/src/main/java/com/specialeffect/eyemine/submod/misc/IronSights.java +++ b/common/src/main/java/com/specialeffect/eyemine/submod/misc/IronSights.java @@ -20,8 +20,8 @@ import com.specialeffect.eyemine.submod.IConfigListener; import com.specialeffect.eyemine.submod.SubMod; import com.specialeffect.utils.ModUtils; -import dev.architectury.event.EventResult; -import dev.architectury.event.events.client.ClientRawInputEvent; +import com.specialeffect.eyemine.event.EventResult; +import com.specialeffect.eyemine.event.EyeMineEvents; import net.minecraft.client.KeyMapping; import net.minecraft.client.Minecraft; import org.lwjgl.glfw.GLFW; @@ -43,7 +43,7 @@ public void onInitializeClient() { "key.eyemine.toggle_ironsights", Type.KEYSYM, GLFW.GLFW_KEY_P, - "category.eyemine.category.eyegaze_extra" // The translation key of the keybinding's category. + Keybindings.EYEGAZE_EXTRA // The translation key of the keybinding's category. )); // Set up icon rendering @@ -54,7 +54,7 @@ public void onInitializeClient() { mIcon.setVisible(false); MainClientHandler.addOverlayToRender(mIcon); - ClientRawInputEvent.KEY_PRESSED.register(this::onKeyInput); + EyeMineEvents.KEY_PRESSED.register(this::onKeyInput); } @Override @@ -68,11 +68,11 @@ private EventResult onKeyInput(Minecraft minecraft, int keyCode, int scanCode, i return EventResult.pass(); } - if (InputConstants.isKeyDown(minecraft.getWindow().getWindow(), 292)) { + if (InputConstants.isKeyDown(minecraft.getWindow(), 292)) { return EventResult.pass(); } - if (mToggleIronsight.matches(keyCode, scanCode) && mToggleIronsight.consumeClick()) { + if (mToggleIronsight.matches(new net.minecraft.client.input.KeyEvent(keyCode, scanCode, modifiers)) && mToggleIronsight.consumeClick()) { ironsightsOn = !ironsightsOn; if (ironsightsOn) { minecraft.options.fov().set(minecraft.options.fov().get() - fovReduction); diff --git a/common/src/main/java/com/specialeffect/eyemine/submod/misc/NightVisionHelper.java b/common/src/main/java/com/specialeffect/eyemine/submod/misc/NightVisionHelper.java index b32ad152..39481c6e 100644 --- a/common/src/main/java/com/specialeffect/eyemine/submod/misc/NightVisionHelper.java +++ b/common/src/main/java/com/specialeffect/eyemine/submod/misc/NightVisionHelper.java @@ -13,16 +13,12 @@ import com.specialeffect.eyemine.submod.SubMod; import com.specialeffect.utils.ModUtils; -import dev.architectury.event.EventResult; -import dev.architectury.event.events.client.ClientGuiEvent; -import dev.architectury.event.events.client.ClientRawInputEvent; -import dev.architectury.event.events.client.ClientTickEvent; -import dev.architectury.event.events.common.EntityEvent; -import dev.architectury.event.events.common.LifecycleEvent; +import com.specialeffect.eyemine.event.EventResult; +import com.specialeffect.eyemine.event.EyeMineEvents; import net.minecraft.client.DeltaTracker; import net.minecraft.client.Minecraft; import net.minecraft.client.gui.Font; -import net.minecraft.client.gui.GuiGraphics; +import net.minecraft.client.gui.GuiGraphicsExtractor; import net.minecraft.client.multiplayer.ClientLevel; import net.minecraft.client.player.LocalPlayer; import net.minecraft.core.BlockPos; @@ -58,12 +54,12 @@ public static void cancelAndHide() { } public void onInitializeClient() { - LifecycleEvent.SERVER_LEVEL_LOAD.register(this::onWorldLoad); - EntityEvent.LIVING_DEATH.register(this::onDeath); - EntityEvent.ADD.register(this::onSpawn); - ClientTickEvent.CLIENT_PRE.register(this::onClientTick); - ClientRawInputEvent.KEY_PRESSED.register(this::onKeyInput); - ClientGuiEvent.RENDER_HUD.register(this::onRenderExperienceBar); + EyeMineEvents.WORLD_LOAD.register(this::onWorldLoad); + EyeMineEvents.ENTITY_DEATH.register(this::onDeath); + EyeMineEvents.ENTITY_ADD.register(this::onSpawn); + EyeMineEvents.CLIENT_TICK.register(this::onClientTick); + EyeMineEvents.KEY_PRESSED.register(this::onKeyInput); + EyeMineEvents.RENDER_HUD.register(this::onRenderExperienceBar); } private void onWorldLoad(ServerLevel serverLevel) { @@ -153,7 +149,7 @@ public void onClientTick(Minecraft event) { } // Get lightness of block(s) we're looking at and where player is - boolean isDark = isDark(level, pos, level.random); + boolean isDark = isDark(level, pos, level.getRandom()); // If it's really dark, put message up to remind of night vision if (isDark) { @@ -184,7 +180,7 @@ public static boolean isDark(Level level, BlockPos blockPos, RandomSource random } } - public void onRenderExperienceBar(GuiGraphics guiGraphics, DeltaTracker deltaTracker) { + public void onRenderExperienceBar(GuiGraphicsExtractor guiGraphics, DeltaTracker deltaTracker) { if (mShowMessage) { Minecraft mc = Minecraft.getInstance(); @@ -204,9 +200,9 @@ public void onRenderExperienceBar(GuiGraphics guiGraphics, DeltaTracker deltaTra } } - private void drawCenteredString(GuiGraphics guiGraphics, Font font, String msg, int x, int y, int c) { //TODO: check if we can just use GuiGraphics#drawCenteredString + private void drawCenteredString(GuiGraphicsExtractor guiGraphics, Font font, String msg, int x, int y, int c) { //TODO: check if we can just use GuiGraphics#drawCenteredString int stringWidth = font.width(msg); - guiGraphics.drawString(font, msg, x - stringWidth / 2, y, c); + guiGraphics.text(font, msg, x - stringWidth / 2, y, c); } private EventResult onKeyInput(Minecraft minecraft, int keyCode, int scanCode, int action, int modifiers) { diff --git a/common/src/main/java/com/specialeffect/eyemine/submod/misc/OpenChat.java b/common/src/main/java/com/specialeffect/eyemine/submod/misc/OpenChat.java index d016b58d..ef0c77ed 100644 --- a/common/src/main/java/com/specialeffect/eyemine/submod/misc/OpenChat.java +++ b/common/src/main/java/com/specialeffect/eyemine/submod/misc/OpenChat.java @@ -17,8 +17,8 @@ import com.specialeffect.eyemine.mixin.KeyMappingAccessor; import com.specialeffect.eyemine.submod.SubMod; import com.specialeffect.utils.ModUtils; -import dev.architectury.event.EventResult; -import dev.architectury.event.events.client.ClientRawInputEvent; +import com.specialeffect.eyemine.event.EventResult; +import com.specialeffect.eyemine.event.EyeMineEvents; import net.minecraft.client.KeyMapping; import net.minecraft.client.Minecraft; import org.lwjgl.glfw.GLFW; @@ -34,10 +34,10 @@ public void onInitializeClient() { "key.eyemine.open_chat", Type.KEYSYM, GLFW.GLFW_KEY_END, - "category.eyemine.category.eyegaze_extra" // The translation key of the keybinding's category. + Keybindings.EYEGAZE_EXTRA // The translation key of the keybinding's category. )); - ClientRawInputEvent.KEY_PRESSED.register(this::onKeyInput); + EyeMineEvents.KEY_PRESSED.register(this::onKeyInput); } private EventResult onKeyInput(Minecraft minecraft, int keyCode, int scanCode, int action, int modifiers) { @@ -45,11 +45,11 @@ private EventResult onKeyInput(Minecraft minecraft, int keyCode, int scanCode, i return EventResult.pass(); } - if (InputConstants.isKeyDown(minecraft.getWindow().getWindow(), 292)) { + if (InputConstants.isKeyDown(minecraft.getWindow(), 292)) { return EventResult.pass(); } - if (mOpenChatKB.matches(keyCode, scanCode) && mOpenChatKB.consumeClick()) { + if (mOpenChatKB.matches(new net.minecraft.client.input.KeyEvent(keyCode, scanCode, modifiers)) && mOpenChatKB.consumeClick()) { KeyMapping.click(((KeyMappingAccessor) minecraft.options.keyChat).getActualKey()); } return EventResult.pass(); diff --git a/common/src/main/java/com/specialeffect/eyemine/submod/misc/OpenTablesChests.java b/common/src/main/java/com/specialeffect/eyemine/submod/misc/OpenTablesChests.java index 9045c9e3..99d063d5 100644 --- a/common/src/main/java/com/specialeffect/eyemine/submod/misc/OpenTablesChests.java +++ b/common/src/main/java/com/specialeffect/eyemine/submod/misc/OpenTablesChests.java @@ -19,8 +19,8 @@ import com.specialeffect.eyemine.submod.IConfigListener; import com.specialeffect.eyemine.submod.SubMod; import com.specialeffect.utils.ModUtils; -import dev.architectury.event.EventResult; -import dev.architectury.event.events.client.ClientRawInputEvent; +import com.specialeffect.eyemine.event.EventResult; +import com.specialeffect.eyemine.event.EyeMineEvents; import net.minecraft.client.KeyMapping; import net.minecraft.client.Minecraft; import net.minecraft.client.multiplayer.ClientLevel; @@ -32,7 +32,7 @@ import net.minecraft.network.chat.Component; import net.minecraft.network.protocol.game.ServerboundUseItemOnPacket; import net.minecraft.world.InteractionHand; -import net.minecraft.world.ItemInteractionResult; +import net.minecraft.world.InteractionResult; import net.minecraft.world.entity.player.Player; import net.minecraft.world.level.block.AbstractChestBlock; import net.minecraft.world.level.block.Block; @@ -58,16 +58,16 @@ public void onInitializeClient() { "key.eyemine.open_chest", Type.KEYSYM, GLFW.GLFW_KEY_LEFT_BRACKET, - "category.eyemine.category.eyegaze_extra" // The translation key of the keybinding's category. + Keybindings.EYEGAZE_EXTRA // The translation key of the keybinding's category. )); Keybindings.keybindings.add(mOpenCraftingTableKB = new KeyMapping( "key.eyemine.open_crafting_table", Type.KEYSYM, GLFW.GLFW_KEY_RIGHT_BRACKET, - "category.eyemine.category.eyegaze_extra" // The translation key of the keybinding's category. + Keybindings.EYEGAZE_EXTRA // The translation key of the keybinding's category. )); - ClientRawInputEvent.KEY_PRESSED.register(this::onKeyInput); + EyeMineEvents.KEY_PRESSED.register(this::onKeyInput); } public void syncConfig() { @@ -120,13 +120,13 @@ private EventResult onKeyInput(Minecraft minecraft, int keyCode, int scanCode, i return EventResult.pass(); } - if (InputConstants.isKeyDown(minecraft.getWindow().getWindow(), 292)) { + if (InputConstants.isKeyDown(minecraft.getWindow(), 292)) { return EventResult.pass(); } final LocalPlayer player = Minecraft.getInstance().player; final ClientLevel level = minecraft.level; - if (mOpenChestKB.matches(keyCode, scanCode) && mOpenChestKB.consumeClick()) { + if (mOpenChestKB.matches(new net.minecraft.client.input.KeyEvent(keyCode, scanCode, modifiers)) && mOpenChestKB.consumeClick()) { BlockPos closestBlockPos = OpenTablesChests.findClosestBlockOfType((block -> block instanceof AbstractChestBlock), player, level, mRadius); // Ask server to open @@ -136,14 +136,14 @@ private EventResult onKeyInput(Minecraft minecraft, int keyCode, int scanCode, i BlockState state = level.getBlockState(closestBlockPos); BlockHitResult simulatedHit = getSimulatedHitResult(level, closestBlockPos); - ItemInteractionResult result = state.useItemOn(player.getItemInHand(InteractionHand.MAIN_HAND), level, player, InteractionHand.MAIN_HAND, simulatedHit); + InteractionResult result = state.useItemOn(player.getItemInHand(InteractionHand.MAIN_HAND), level, player, InteractionHand.MAIN_HAND, simulatedHit); if (result.consumesAction()) { BlockStatePredictionHandler blockstatepredictionhandler = ((ClientLevelAccessor) level).eyemineGetPredictionHandler().startPredicting(); int i = blockstatepredictionhandler.currentSequence(); player.connection.send(new ServerboundUseItemOnPacket(InteractionHand.MAIN_HAND, simulatedHit, i)); } } - } else if (mOpenCraftingTableKB.matches(keyCode, scanCode) && mOpenCraftingTableKB.consumeClick()) { + } else if (mOpenCraftingTableKB.matches(new net.minecraft.client.input.KeyEvent(keyCode, scanCode, modifiers)) && mOpenCraftingTableKB.consumeClick()) { BlockPos closestBlockPos = OpenTablesChests.findClosestBlockOfType((block -> block instanceof CraftingTableBlock), player, level, mRadius); // Ask server to open @@ -154,7 +154,7 @@ private EventResult onKeyInput(Minecraft minecraft, int keyCode, int scanCode, i BlockState state = level.getBlockState(closestBlockPos); BlockHitResult simulatedHit = getSimulatedHitResult(level, closestBlockPos); - ItemInteractionResult result = state.useItemOn(player.getItemInHand(InteractionHand.MAIN_HAND), level, player, InteractionHand.MAIN_HAND, simulatedHit); + InteractionResult result = state.useItemOn(player.getItemInHand(InteractionHand.MAIN_HAND), level, player, InteractionHand.MAIN_HAND, simulatedHit); if (result.consumesAction()) { BlockStatePredictionHandler blockstatepredictionhandler = ((ClientLevelAccessor) level).eyemineGetPredictionHandler().startPredicting(); int i = blockstatepredictionhandler.currentSequence(); diff --git a/common/src/main/java/com/specialeffect/eyemine/submod/misc/PickBlock.java b/common/src/main/java/com/specialeffect/eyemine/submod/misc/PickBlock.java index 7964a5ce..1af51753 100644 --- a/common/src/main/java/com/specialeffect/eyemine/submod/misc/PickBlock.java +++ b/common/src/main/java/com/specialeffect/eyemine/submod/misc/PickBlock.java @@ -17,8 +17,8 @@ import com.specialeffect.eyemine.mixin.KeyMappingAccessor; import com.specialeffect.eyemine.submod.SubMod; import com.specialeffect.utils.ModUtils; -import dev.architectury.event.EventResult; -import dev.architectury.event.events.client.ClientRawInputEvent; +import com.specialeffect.eyemine.event.EventResult; +import com.specialeffect.eyemine.event.EyeMineEvents; import net.minecraft.client.KeyMapping; import net.minecraft.client.Minecraft; import org.lwjgl.glfw.GLFW; @@ -34,10 +34,10 @@ public void onInitializeClient() { "key.eyemine.pick_block", Type.KEYSYM, GLFW.GLFW_KEY_KP_2, - "category.eyemine.category.eyegaze_common" // The translation key of the keybinding's category. + Keybindings.EYEGAZE_COMMON // The translation key of the keybinding's category. )); - ClientRawInputEvent.KEY_PRESSED.register(this::onKeyInput); + EyeMineEvents.KEY_PRESSED.register(this::onKeyInput); } private EventResult onKeyInput(Minecraft minecraft, int keyCode, int scanCode, int action, int modifiers) { @@ -45,11 +45,11 @@ private EventResult onKeyInput(Minecraft minecraft, int keyCode, int scanCode, i return EventResult.pass(); } - if (InputConstants.isKeyDown(minecraft.getWindow().getWindow(), 292)) { + if (InputConstants.isKeyDown(minecraft.getWindow(), 292)) { return EventResult.pass(); } - if (mPickBlockKB.matches(keyCode, scanCode) && mPickBlockKB.consumeClick()) { + if (mPickBlockKB.matches(new net.minecraft.client.input.KeyEvent(keyCode, scanCode, modifiers)) && mPickBlockKB.consumeClick()) { KeyMapping pickBlockKey = minecraft.options.keyPickItem; KeyMapping.click(((KeyMappingAccessor) pickBlockKey).getActualKey()); } diff --git a/common/src/main/java/com/specialeffect/eyemine/submod/misc/QuickCommands.java b/common/src/main/java/com/specialeffect/eyemine/submod/misc/QuickCommands.java index b1fced6d..c36f1a33 100644 --- a/common/src/main/java/com/specialeffect/eyemine/submod/misc/QuickCommands.java +++ b/common/src/main/java/com/specialeffect/eyemine/submod/misc/QuickCommands.java @@ -18,25 +18,27 @@ import com.specialeffect.eyemine.packets.messages.TeleportPlayerToSpawnPointMessage; import com.specialeffect.eyemine.submod.SubMod; import com.specialeffect.utils.ModUtils; -import dev.architectury.event.EventResult; -import dev.architectury.event.events.client.ClientRawInputEvent; -import dev.architectury.networking.NetworkManager; +import com.specialeffect.eyemine.event.EventResult; +import com.specialeffect.eyemine.event.EyeMineEvents; +import com.specialeffect.eyemine.packets.NetworkService; +import com.specialeffect.eyemine.platform.Services; import net.minecraft.client.KeyMapping; import net.minecraft.client.Minecraft; -import net.minecraft.client.multiplayer.ClientLevel; import net.minecraft.client.player.LocalPlayer; import net.minecraft.core.Holder; import net.minecraft.world.effect.MobEffect; import net.minecraft.world.effect.MobEffectInstance; import net.minecraft.world.effect.MobEffects; import net.minecraft.world.item.ItemStack; -import net.minecraft.world.level.GameRules; -import net.minecraft.world.level.GameRules.BooleanValue; +import net.minecraft.world.level.gamerules.GameRules; import org.lwjgl.glfw.GLFW; public class QuickCommands extends SubMod { public final String MODID = "quickcommands"; + // Track day/night cycle toggle state locally since GameRules aren't accessible on client in 26.1.1 + private boolean dayNightCycleEnabled = true; + private static KeyMapping mNightVisionKB; private static KeyMapping mDayNightKB; private static KeyMapping mRespawnKB; @@ -48,31 +50,31 @@ public void onInitializeClient() { "key.eyemine.night_vision", Type.KEYSYM, GLFW.GLFW_KEY_F12, - "category.eyemine.category.eyegaze_extra" // The translation key of the keybinding's category. + Keybindings.EYEGAZE_EXTRA // The translation key of the keybinding's category. )); Keybindings.keybindings.add(mDayNightKB = new KeyMapping( "key.eyemine.day_cycle", Type.KEYSYM, GLFW.GLFW_KEY_F14, - "category.eyemine.category.eyegaze_extra" // The translation key of the keybinding's category. + Keybindings.EYEGAZE_EXTRA // The translation key of the keybinding's category. )); Keybindings.keybindings.add(mRespawnKB = new KeyMapping( "key.eyemine.respawn", Type.KEYSYM, GLFW.GLFW_KEY_HOME, - "category.eyemine.category.eyegaze_extra" // The translation key of the keybinding's category. + Keybindings.EYEGAZE_EXTRA // The translation key of the keybinding's category. )); Keybindings.keybindings.add(mDropItemKB = new KeyMapping( "key.eyemine.drop_item", Type.KEYSYM, GLFW.GLFW_KEY_MINUS, - "category.eyemine.category.eyegaze_extra" // The translation key of the keybinding's category. + Keybindings.EYEGAZE_EXTRA // The translation key of the keybinding's category. )); - ClientRawInputEvent.KEY_PRESSED.register(this::onKeyInput); + EyeMineEvents.KEY_PRESSED.register(this::onKeyInput); } private EventResult onKeyInput(Minecraft minecraft, int keyCode, int scanCode, int action, int modifiers) { @@ -80,13 +82,12 @@ private EventResult onKeyInput(Minecraft minecraft, int keyCode, int scanCode, i return EventResult.pass(); } - if (InputConstants.isKeyDown(minecraft.getWindow().getWindow(), 292)) { + if (InputConstants.isKeyDown(minecraft.getWindow(), 292)) { return EventResult.pass(); } final LocalPlayer player = Minecraft.getInstance().player; - final ClientLevel level = minecraft.level; - if (mNightVisionKB.matches(keyCode, scanCode) && mNightVisionKB.consumeClick()) { + if (mNightVisionKB.matches(new net.minecraft.client.input.KeyEvent(keyCode, scanCode, modifiers)) && mNightVisionKB.consumeClick()) { // Toggle night vision effect Holder nightVision = MobEffects.NIGHT_VISION; @@ -102,27 +103,26 @@ private EventResult onKeyInput(Minecraft minecraft, int keyCode, int scanCode, i return EventResult.pass(); } - if (mDropItemKB.matches(keyCode, scanCode) && mDropItemKB.consumeClick()) { + if (mDropItemKB.matches(new net.minecraft.client.input.KeyEvent(keyCode, scanCode, modifiers)) && mDropItemKB.consumeClick()) { // Drop item // This is a duplicate key binding to the built-in one, so we can use the same for discarding // an item while the inventory is open. The inventory keybinding needs to be a key not used // for typing. - ItemStack stack = player.getInventory().getSelected(); + ItemStack stack = player.getInventory().getSelectedItem(); player.drop(stack, true); //TODO: see if this still drops all? } - if (mDayNightKB.matches(keyCode, scanCode) && mDayNightKB.consumeClick()) { - GameRules rules = level.getGameRules(); - - GameRules.Key gameRule = GameRules.RULE_DAYLIGHT; - boolean newBool = !rules.getBoolean(gameRule); + if (mDayNightKB.matches(new net.minecraft.client.input.KeyEvent(keyCode, scanCode, modifiers)) && mDayNightKB.consumeClick()) { + // Toggle the day/night cycle - track state locally since GameRules + // are not accessible on the client side in 26.1.1 + dayNightCycleEnabled = !dayNightCycleEnabled; - String cmd = "/gamerule " + gameRule + " " + newBool; - NetworkManager.sendToServer(new SendCommandMessage(cmd)); + String cmd = "/gamerule " + GameRules.ADVANCE_TIME.id() + " " + dayNightCycleEnabled; + Services.NETWORK.sendToServer(new SendCommandMessage(cmd)); } - if (mRespawnKB.matches(keyCode, scanCode) && mRespawnKB.consumeClick()) { - NetworkManager.sendToServer(new TeleportPlayerToSpawnPointMessage()); + if (mRespawnKB.matches(new net.minecraft.client.input.KeyEvent(keyCode, scanCode, modifiers)) && mRespawnKB.consumeClick()) { + Services.NETWORK.sendToServer(new TeleportPlayerToSpawnPointMessage()); NightVisionHelper.cancelAndHide(); } return EventResult.pass(); diff --git a/common/src/main/java/com/specialeffect/eyemine/submod/misc/SwapMinePlace.java b/common/src/main/java/com/specialeffect/eyemine/submod/misc/SwapMinePlace.java index ac0bfe25..86f5efa0 100644 --- a/common/src/main/java/com/specialeffect/eyemine/submod/misc/SwapMinePlace.java +++ b/common/src/main/java/com/specialeffect/eyemine/submod/misc/SwapMinePlace.java @@ -18,14 +18,13 @@ import com.specialeffect.eyemine.mixin.KeyMappingAccessor; import com.specialeffect.eyemine.submod.SubMod; import com.specialeffect.utils.ModUtils; -import dev.architectury.event.EventResult; -import dev.architectury.event.events.client.ClientGuiEvent; -import dev.architectury.event.events.client.ClientRawInputEvent; +import com.specialeffect.eyemine.event.EventResult; +import com.specialeffect.eyemine.event.EyeMineEvents; import net.minecraft.client.DeltaTracker; import net.minecraft.client.KeyMapping; import net.minecraft.client.Minecraft; import net.minecraft.client.gui.Font; -import net.minecraft.client.gui.GuiGraphics; +import net.minecraft.client.gui.GuiGraphicsExtractor; import org.lwjgl.glfw.GLFW; public class SwapMinePlace extends SubMod { @@ -35,11 +34,11 @@ public void onInitializeClient() { "key.eyemine.swap_mine_place", Type.KEYSYM, GLFW.GLFW_KEY_F10, - "category.eyemine.category.eyegaze_extra" // The translation key of the keybinding's category. + Keybindings.EYEGAZE_EXTRA // The translation key of the keybinding's category. )); - ClientRawInputEvent.KEY_PRESSED.register(this::onKeyInput); - ClientGuiEvent.RENDER_HUD.register(this::onRenderGameOverlayEvent); + EyeMineEvents.KEY_PRESSED.register(this::onKeyInput); + EyeMineEvents.RENDER_HUD.register(this::onRenderGameOverlayEvent); } private static KeyMapping mSwapKB; @@ -49,17 +48,17 @@ private EventResult onKeyInput(Minecraft minecraft, int keyCode, int scanCode, i return EventResult.pass(); } - if (InputConstants.isKeyDown(minecraft.getWindow().getWindow(), 292)) { + if (InputConstants.isKeyDown(minecraft.getWindow(), 292)) { return EventResult.pass(); } - if (mSwapKB.matches(keyCode, scanCode) && mSwapKB.consumeClick()) { + if (mSwapKB.matches(new net.minecraft.client.input.KeyEvent(keyCode, scanCode, modifiers)) && mSwapKB.consumeClick()) { Key attackInput = ((KeyMappingAccessor) Minecraft.getInstance().options.keyAttack).getActualKey(); Key useInput = ((KeyMappingAccessor) Minecraft.getInstance().options.keyUse).getActualKey(); - Minecraft.getInstance().options.setKey(Minecraft.getInstance().options.keyAttack, useInput); - Minecraft.getInstance().options.setKey(Minecraft.getInstance().options.keyUse, attackInput); + Minecraft.getInstance().options.keyAttack.setKey(useInput); + Minecraft.getInstance().options.keyUse.setKey(attackInput); // It's important to force a reload Minecraft.getInstance().options.save(); @@ -71,7 +70,7 @@ private EventResult onKeyInput(Minecraft minecraft, int keyCode, int scanCode, i return EventResult.pass(); } - public void onRenderGameOverlayEvent(GuiGraphics guiGraphics, DeltaTracker deltaTracker) { + public void onRenderGameOverlayEvent(GuiGraphicsExtractor guiGraphics, DeltaTracker deltaTracker) { // If these are swapped, show a warning message KeyMapping attackBinding = Minecraft.getInstance().options.keyAttack; KeyMapping useBinding = Minecraft.getInstance().options.keyUse; @@ -97,8 +96,8 @@ public void onRenderGameOverlayEvent(GuiGraphics guiGraphics, DeltaTracker delta int delta = (msg1width - msg2width) / 2; final Font font = mc.font; - guiGraphics.drawString(font, msg1, w - msg2width - delta - 10, h - 22, 0xffFFFFFF); - guiGraphics.drawString(font, msg2, w - msg2width - 10, h - 12, 0xffFFFFFF); + guiGraphics.text(font, msg1, w - msg2width - delta - 10, h - 22, 0xffFFFFFF); + guiGraphics.text(font, msg2, w - msg2width - 10, h - 12, 0xffFFFFFF); } } diff --git a/common/src/main/java/com/specialeffect/eyemine/submod/misc/UseItem.java b/common/src/main/java/com/specialeffect/eyemine/submod/misc/UseItem.java index bff3dda0..a3ebf493 100644 --- a/common/src/main/java/com/specialeffect/eyemine/submod/misc/UseItem.java +++ b/common/src/main/java/com/specialeffect/eyemine/submod/misc/UseItem.java @@ -19,14 +19,14 @@ import com.specialeffect.eyemine.submod.utils.DwellAction; import com.specialeffect.eyemine.submod.utils.TargetBlock; import com.specialeffect.utils.ModUtils; -import dev.architectury.event.EventResult; -import dev.architectury.event.events.client.ClientRawInputEvent; -import dev.architectury.event.events.client.ClientTickEvent; +import com.specialeffect.eyemine.event.EventResult; +import com.specialeffect.eyemine.event.EyeMineEvents; import net.minecraft.client.DeltaTracker; import net.minecraft.client.KeyMapping; import net.minecraft.client.Minecraft; -import net.minecraft.client.gui.GuiGraphics; +import net.minecraft.client.gui.GuiGraphicsExtractor; import net.minecraft.network.chat.Component; +import net.minecraft.world.entity.player.Inventory; import net.minecraft.world.entity.player.Player; import net.minecraft.world.item.BowItem; import net.minecraft.world.item.CrossbowItem; @@ -48,32 +48,32 @@ public void onInitializeClient() { "key.eyemine.use_item", Type.KEYSYM, GLFW.GLFW_KEY_KP_0, - "category.eyemine.category.eyegaze_common" // The translation key of the keybinding's category. + Keybindings.EYEGAZE_COMMON // The translation key of the keybinding's category. )); Keybindings.keybindings.add(mUseItemContinuouslyKB = new KeyMapping( "key.eyemine.use_item_continuously", Type.KEYSYM, GLFW.GLFW_KEY_KP_1, - "category.eyemine.category.eyegaze_extra" // The translation key of the keybinding's category. + Keybindings.EYEGAZE_EXTRA // The translation key of the keybinding's category. )); Keybindings.keybindings.add(mPrevItemKB = new KeyMapping( "key.eyemine.select_previous_item", Type.KEYSYM, GLFW.GLFW_KEY_KP_4, - "category.eyemine.category.eyegaze_extra" // The translation key of the keybinding's category. + Keybindings.EYEGAZE_EXTRA // The translation key of the keybinding's category. )); Keybindings.keybindings.add(mNextItemKB = new KeyMapping( "key.eyemine.select_next_item", Type.KEYSYM, GLFW.GLFW_KEY_KP_5, - "category.eyemine.category.eyegaze_extra" // The translation key of the keybinding's category. + Keybindings.EYEGAZE_EXTRA // The translation key of the keybinding's category. )); - ClientTickEvent.CLIENT_PRE.register(this::onClientTick); - ClientRawInputEvent.KEY_PRESSED.register(this::onKeyInput); + EyeMineEvents.CLIENT_TICK.register(this::onClientTick); + EyeMineEvents.KEY_PRESSED.register(this::onKeyInput); //Initialize variables super.onInitializeClient(); @@ -114,7 +114,7 @@ public void onClientTick(Minecraft minecraft) { // If it was a crossbow we'll need to re-click to actually fire it Player player = Minecraft.getInstance().player; - Item item = player.getInventory().getSelected().getItem(); + Item item = player.getInventory().getSelectedItem().getItem(); if (item instanceof CrossbowItem) { // Crossbows don't fire on mouse-release, they need another 'click' on the next tick to be shot needBowFire = true; @@ -134,14 +134,14 @@ private EventResult onKeyInput(Minecraft minecraft, int keyCode, int scanCode, i return EventResult.pass(); } - if (InputConstants.isKeyDown(minecraft.getWindow().getWindow(), 292)) { + if (InputConstants.isKeyDown(minecraft.getWindow(), 292)) { return EventResult.pass(); } final KeyMapping useItemKeyBinding = Minecraft.getInstance().options.keyUse; Player player = Minecraft.getInstance().player; - if (mUseItemContinuouslyKB.matches(keyCode, scanCode) && mUseItemContinuouslyKB.consumeClick()) { + if (mUseItemContinuouslyKB.matches(new net.minecraft.client.input.KeyEvent(keyCode, scanCode, modifiers)) && mUseItemContinuouslyKB.consumeClick()) { if (mUsingItem) { // Turn off mUsingItem = false; @@ -150,7 +150,7 @@ private EventResult onKeyInput(Minecraft minecraft, int keyCode, int scanCode, i } else { // Turn on continuous-building - ItemStack itemStack = player.getInventory().getSelected(); + ItemStack itemStack = player.getInventory().getSelectedItem(); if (itemStack.isEmpty()) { player.sendSystemMessage(Component.literal("Nothing in hand to use")); return EventResult.pass(); @@ -161,9 +161,9 @@ private EventResult onKeyInput(Minecraft minecraft, int keyCode, int scanCode, i ModUtils.sendPlayerMessage("Using item: ON"); } - } else if (mUseItemOnceKB.matches(keyCode, scanCode) && mUseItemOnceKB.consumeClick()) { + } else if (mUseItemOnceKB.matches(new net.minecraft.client.input.KeyEvent(keyCode, scanCode, modifiers)) && mUseItemOnceKB.consumeClick()) { - ItemStack stack = player.getInventory().getSelected(); + ItemStack stack = player.getInventory().getSelectedItem(); Item item = stack.getItem(); // Special case for shootable items @@ -192,15 +192,17 @@ private EventResult onKeyInput(Minecraft minecraft, int keyCode, int scanCode, i this.performAction(null); } - } else if (mPrevItemKB.matches(keyCode, scanCode) && mPrevItemKB.consumeClick()) { - player.getInventory().swapPaint(1); - } else if (mNextItemKB.matches(keyCode, scanCode) && mNextItemKB.consumeClick()) { - player.getInventory().swapPaint(-1); + } else if (mPrevItemKB.matches(new net.minecraft.client.input.KeyEvent(keyCode, scanCode, modifiers)) && mPrevItemKB.consumeClick()) { + int current = player.getInventory().getSelectedSlot(); + player.getInventory().setSelectedSlot((current + Inventory.getSelectionSize() - 1) % Inventory.getSelectionSize()); + } else if (mNextItemKB.matches(new net.minecraft.client.input.KeyEvent(keyCode, scanCode, modifiers)) && mNextItemKB.consumeClick()) { + int current = player.getInventory().getSelectedSlot(); + player.getInventory().setSelectedSlot((current + 1) % Inventory.getSelectionSize()); } return EventResult.pass(); } - public void onRenderGameOverlayEvent(GuiGraphics guiGraphics, DeltaTracker deltaTracker) { + public void onRenderGameOverlayEvent(GuiGraphicsExtractor guiGraphics, DeltaTracker deltaTracker) { super.onRenderGameOverlayEvent(guiGraphics, deltaTracker); // If use-item is on, show a warning message @@ -212,7 +214,7 @@ public void onRenderGameOverlayEvent(GuiGraphics guiGraphics, DeltaTracker delta int msgWidth = mc.font.width(msg); - guiGraphics.drawString(mc.font, msg, (int) (w / 2.0) - (int) (msgWidth / 2.0), (int) (h / 2.0) - 20, 0xffFFFFFF); + guiGraphics.text(mc.font, msg, (int) (w / 2.0) - (int) (msgWidth / 2.0), (int) (h / 2.0) - 20, 0xffFFFFFF); } } diff --git a/common/src/main/java/com/specialeffect/eyemine/submod/mouse/MouseHandlerMod.java b/common/src/main/java/com/specialeffect/eyemine/submod/mouse/MouseHandlerMod.java index 12dc3bee..8da9b266 100644 --- a/common/src/main/java/com/specialeffect/eyemine/submod/mouse/MouseHandlerMod.java +++ b/common/src/main/java/com/specialeffect/eyemine/submod/mouse/MouseHandlerMod.java @@ -24,12 +24,9 @@ import com.specialeffect.eyemine.utils.MouseHelper; import com.specialeffect.eyemine.utils.MouseHelper.PlayerMovement; import com.specialeffect.utils.ModUtils; -import dev.architectury.event.CompoundEventResult; -import dev.architectury.event.EventResult; -import dev.architectury.event.events.client.ClientGuiEvent; -import dev.architectury.event.events.client.ClientLifecycleEvent; -import dev.architectury.event.events.client.ClientRawInputEvent; -import dev.architectury.event.events.client.ClientTickEvent; +import com.specialeffect.eyemine.event.ScreenSetResult; +import com.specialeffect.eyemine.event.EventResult; +import com.specialeffect.eyemine.event.EyeMineEvents; import net.minecraft.client.KeyMapping; import net.minecraft.client.Minecraft; import net.minecraft.client.gui.screens.Screen; @@ -63,11 +60,11 @@ public enum InteractionState { private boolean hasPendingConfigChange = false; public void onInitializeClient() { - ClientTickEvent.CLIENT_PRE.register(this::onClientTick); - ClientRawInputEvent.KEY_PRESSED.register(this::onKeyInput); - ClientGuiEvent.SET_SCREEN.register(MouseHandlerMod::onGuiOpen); + EyeMineEvents.CLIENT_TICK.register(this::onClientTick); + EyeMineEvents.KEY_PRESSED.register(this::onKeyInput); + EyeMineEvents.SCREEN_SET.register(MouseHandlerMod::onGuiOpen); - ClientLifecycleEvent.CLIENT_SETUP.register((state) -> setupInitialState()); + EyeMineEvents.CLIENT_SETUP.register((state) -> setupInitialState()); // Set up icon rendering mIconEye = new IconOverlay(Minecraft.getInstance(), "eyemine:textures/icons/eye.png"); @@ -81,14 +78,14 @@ public void onInitializeClient() { "key.eyemine.sensitivity_up", Type.KEYSYM, GLFW.GLFW_KEY_RIGHT, - "category.eyemine.category.eyegaze_settings" // The translation key of the keybinding's category. + Keybindings.EYEGAZE_SETTINGS // The translation key of the keybinding's category. )); Keybindings.keybindings.add(mSensitivityDownKB = new KeyMapping( "key.eyemine.sensitivity_down", Type.KEYSYM, GLFW.GLFW_KEY_LEFT, - "category.eyemine.category.eyegaze_settings" // The translation key of the keybinding's category. + Keybindings.EYEGAZE_SETTINGS // The translation key of the keybinding's category. )); // Used to turn 'look with gaze' on and off when using mouse emulation @@ -98,7 +95,7 @@ public void onInitializeClient() { "key.eyemine.toggle_mouse_look", Type.KEYSYM, GLFW.GLFW_KEY_Y, - "category.eyemine.category.eyegaze_extra" // The translation key of the keybinding's category. + Keybindings.EYEGAZE_EXTRA // The translation key of the keybinding's category. )); } @@ -207,17 +204,17 @@ private EventResult onKeyInput(Minecraft minecraft, int keyCode, int scanCode, i return EventResult.pass(); } - if (InputConstants.isKeyDown(minecraft.getWindow().getWindow(), 292)) { + if (InputConstants.isKeyDown(minecraft.getWindow(), 292)) { return EventResult.pass(); } - if (mSensitivityUpKB.matches(keyCode, scanCode) && mSensitivityUpKB.consumeClick()) { + if (mSensitivityUpKB.matches(new net.minecraft.client.input.KeyEvent(keyCode, scanCode, modifiers)) && mSensitivityUpKB.consumeClick()) { increaseSens(); ModUtils.sendPlayerMessage("Sensitivity: " + toPercent(2.0d * minecraft.options.sensitivity().get())); - } else if (mSensitivityDownKB.matches(keyCode, scanCode) && mSensitivityDownKB.consumeClick()) { + } else if (mSensitivityDownKB.matches(new net.minecraft.client.input.KeyEvent(keyCode, scanCode, modifiers)) && mSensitivityDownKB.consumeClick()) { decreaseSens(); ModUtils.sendPlayerMessage("Sensitivity: " + toPercent(2.0d * minecraft.options.sensitivity().get())); - } else if (mToggleMouseViewControlKB.matches(keyCode, scanCode) && mToggleMouseViewControlKB.consumeClick()) { + } else if (mToggleMouseViewControlKB.matches(new net.minecraft.client.input.KeyEvent(keyCode, scanCode, modifiers)) && mToggleMouseViewControlKB.consumeClick()) { if (mInputSource == InputSource.EyeTracker) { LOGGER.debug("this key doesn't do anything in eyetracker mode"); ModUtils.sendPlayerMessage("Warning: Minecraft expects eye tracker input, not mouse"); @@ -260,13 +257,13 @@ private void increaseSens() { } private static void setEmptyCursor() { - GLFW.glfwSetInputMode(Minecraft.getInstance().getWindow().getWindow(), + GLFW.glfwSetInputMode(Minecraft.getInstance().getWindow().handle(), GLFW.GLFW_CURSOR, GLFW.GLFW_CURSOR_HIDDEN); } private static void setNativeCursor() { - GLFW.glfwSetInputMode(Minecraft.getInstance().getWindow().getWindow(), + GLFW.glfwSetInputMode(Minecraft.getInstance().getWindow().handle(), GLFW.GLFW_CURSOR, GLFW.GLFW_CURSOR_NORMAL); } @@ -280,7 +277,7 @@ public static boolean hasPendingEvent() { return mTicksSinceMouseEvent < 5; } - public static CompoundEventResult onGuiOpen(Screen screen) { + public static ScreenSetResult onGuiOpen(Screen screen) { // For any open event, make sure cursor not overridden if (screen != null) { setNativeCursor(); @@ -291,7 +288,7 @@ public static CompoundEventResult onGuiOpen(Screen screen) { setEmptyCursor(); } } - return CompoundEventResult.interruptTrue(screen); + return ScreenSetResult.set(screen); } // This is the constant offset applied in MC source, corresponding diff --git a/common/src/main/java/com/specialeffect/eyemine/submod/movement/AutoFly.java b/common/src/main/java/com/specialeffect/eyemine/submod/movement/AutoFly.java index 954b67df..3d7b1907 100644 --- a/common/src/main/java/com/specialeffect/eyemine/submod/movement/AutoFly.java +++ b/common/src/main/java/com/specialeffect/eyemine/submod/movement/AutoFly.java @@ -20,10 +20,10 @@ import com.specialeffect.eyemine.submod.IConfigListener; import com.specialeffect.eyemine.submod.SubMod; import com.specialeffect.utils.ModUtils; -import dev.architectury.event.EventResult; -import dev.architectury.event.events.client.ClientRawInputEvent; -import dev.architectury.event.events.client.ClientTickEvent; -import dev.architectury.networking.NetworkManager; +import com.specialeffect.eyemine.event.EventResult; +import com.specialeffect.eyemine.event.EyeMineEvents; +import com.specialeffect.eyemine.packets.NetworkService; +import com.specialeffect.eyemine.platform.Services; import net.minecraft.client.KeyMapping; import net.minecraft.client.Minecraft; import net.minecraft.core.BlockPos; @@ -52,29 +52,29 @@ public void onInitializeClient() { "key.eyemine.toggle_manual_flying", Type.KEYSYM, GLFW.GLFW_KEY_COMMA, - "category.eyemine.category.eyegaze_extra" // The translation key of the keybinding's category. + Keybindings.EYEGAZE_EXTRA // The translation key of the keybinding's category. )); Keybindings.keybindings.add(mFlyAutoKB = new KeyMapping( "key.eyemine.toggle_auto_flying", Type.KEYSYM, GLFW.GLFW_KEY_G, - "category.eyemine.category.eyegaze_extra" // The translation key of the keybinding's category. + Keybindings.EYEGAZE_EXTRA // The translation key of the keybinding's category. )); Keybindings.keybindings.add(mFlyUpKB = new KeyMapping( "key.eyemine.fly_higher", Type.KEYSYM, GLFW.GLFW_KEY_PERIOD, - "category.eyemine.category.eyegaze_extra" // The translation key of the keybinding's category. + Keybindings.EYEGAZE_EXTRA // The translation key of the keybinding's category. )); Keybindings.keybindings.add(mFlyDownKB = new KeyMapping( "key.eyemine.fly_lower", Type.KEYSYM, GLFW.GLFW_KEY_APOSTROPHE, - "category.eyemine.category.eyegaze_extra" // The translation key of the keybinding's category. + Keybindings.EYEGAZE_EXTRA // The translation key of the keybinding's category. )); - ClientTickEvent.CLIENT_PRE.register(this::onClientTick); - ClientRawInputEvent.KEY_PRESSED.register(this::onKeyInput); + EyeMineEvents.CLIENT_TICK.register(this::onClientTick); + EyeMineEvents.KEY_PRESSED.register(this::onKeyInput); // Register an icon for the overlay mIconIndexAuto = StateOverlay.registerTextureLeft("eyemine:textures/icons/fly-auto.png"); @@ -153,7 +153,7 @@ private void stopFlying() { Player player = Minecraft.getInstance().player; player.getAbilities().flying = false; - NetworkManager.sendToServer(new ChangeFlyingStateMessage(false, 0)); + Services.NETWORK.sendToServer(new ChangeFlyingStateMessage(false, 0)); updateIcons(); } @@ -186,7 +186,7 @@ private void setFlying(final boolean bFlyUp, final boolean isAuto) { player.move(MoverType.SELF, new Vec3(0, flyHeight, 0)); } - NetworkManager.sendToServer(new ChangeFlyingStateMessage(true, flyHeight)); + Services.NETWORK.sendToServer(new ChangeFlyingStateMessage(true, flyHeight)); updateIcons(); @@ -224,11 +224,11 @@ private EventResult onKeyInput(Minecraft minecraft, int keyCode, int scanCode, i return EventResult.pass(); } - if (InputConstants.isKeyDown(minecraft.getWindow().getWindow(), 292)) { + if (InputConstants.isKeyDown(minecraft.getWindow(), 292)) { return EventResult.pass(); } - if (mFlyManualKB.matches(keyCode, scanCode) && mFlyManualKB.consumeClick()) { + if (mFlyManualKB.matches(new net.minecraft.client.input.KeyEvent(keyCode, scanCode, modifiers)) && mFlyManualKB.consumeClick()) { if (mIsFlyingManual) { ModUtils.sendPlayerMessage("Fly manual: OFF"); this.stopFlying(); @@ -237,7 +237,7 @@ private EventResult onKeyInput(Minecraft minecraft, int keyCode, int scanCode, i boolean doFlyUp = !mIsFlyingAuto; this.setFlying(doFlyUp, false); } - } else if (mFlyAutoKB.matches(keyCode, scanCode) && mFlyAutoKB.consumeClick()) { + } else if (mFlyAutoKB.matches(new net.minecraft.client.input.KeyEvent(keyCode, scanCode, modifiers)) && mFlyAutoKB.consumeClick()) { if (mIsFlyingAuto) { ModUtils.sendPlayerMessage("Fly auto: OFF"); this.stopFlying(); @@ -246,9 +246,9 @@ private EventResult onKeyInput(Minecraft minecraft, int keyCode, int scanCode, i boolean doFlyUp = !mIsFlyingManual; this.setFlying(doFlyUp, true); } - } else if (mFlyUpKB.matches(keyCode, scanCode) && mFlyUpKB.consumeClick()) { + } else if (mFlyUpKB.matches(new net.minecraft.client.input.KeyEvent(keyCode, scanCode, modifiers)) && mFlyUpKB.consumeClick()) { this.setFlying(true, mIsFlyingAuto); - } else if (mFlyDownKB.matches(keyCode, scanCode) && mFlyDownKB.consumeClick()) { + } else if (mFlyDownKB.matches(new net.minecraft.client.input.KeyEvent(keyCode, scanCode, modifiers)) && mFlyDownKB.consumeClick()) { flyDown(); } AutoFly.updateIcons(); diff --git a/common/src/main/java/com/specialeffect/eyemine/submod/movement/AutoJump.java b/common/src/main/java/com/specialeffect/eyemine/submod/movement/AutoJump.java index bbe4ea3c..13509af4 100644 --- a/common/src/main/java/com/specialeffect/eyemine/submod/movement/AutoJump.java +++ b/common/src/main/java/com/specialeffect/eyemine/submod/movement/AutoJump.java @@ -19,9 +19,8 @@ import com.specialeffect.eyemine.submod.IConfigListener; import com.specialeffect.eyemine.submod.SubMod; import com.specialeffect.utils.ModUtils; -import dev.architectury.event.EventResult; -import dev.architectury.event.events.client.ClientRawInputEvent; -import dev.architectury.event.events.client.ClientTickEvent; +import com.specialeffect.eyemine.event.EventResult; +import com.specialeffect.eyemine.event.EyeMineEvents; import net.minecraft.client.KeyMapping; import net.minecraft.client.Minecraft; import net.minecraft.client.Options; @@ -43,14 +42,14 @@ public void onInitializeClient() { "key.eyemine.toggle_auto_jump", Type.KEYSYM, GLFW.GLFW_KEY_J, - "category.eyemine.category.eyegaze_common" // The translation key of the keybinding's category. + Keybindings.EYEGAZE_COMMON // The translation key of the keybinding's category. )); // Register an icon for the overlay mIconIndex = StateOverlay.registerTextureLeft("eyemine:textures/icons/jump.png"); - ClientTickEvent.CLIENT_PRE.register(this::onClientTick); - ClientRawInputEvent.KEY_PRESSED.register(this::onKeyInput); + EyeMineEvents.CLIENT_TICK.register(this::onClientTick); + EyeMineEvents.KEY_PRESSED.register(this::onKeyInput); } private void updateSettings(boolean autoJump, boolean persist) { @@ -101,11 +100,11 @@ private EventResult onKeyInput(Minecraft minecraft, int keyCode, int scanCode, i return EventResult.pass(); } - if (InputConstants.isKeyDown(minecraft.getWindow().getWindow(), 292)) { + if (InputConstants.isKeyDown(minecraft.getWindow(), 292)) { return EventResult.pass(); } - if (!mAutoJumpDisabled && autoJumpKeyBinding.matches(keyCode, scanCode) && autoJumpKeyBinding.consumeClick()) { + if (!mAutoJumpDisabled && autoJumpKeyBinding.matches(new net.minecraft.client.input.KeyEvent(keyCode, scanCode, modifiers)) && autoJumpKeyBinding.consumeClick()) { mDoingAutoJump = !mDoingAutoJump; // User toggled the setting, so persist it this.updateSettings(mDoingAutoJump, true); diff --git a/common/src/main/java/com/specialeffect/eyemine/submod/movement/BoatController.java b/common/src/main/java/com/specialeffect/eyemine/submod/movement/BoatController.java index a79017e2..41ba6f0b 100644 --- a/common/src/main/java/com/specialeffect/eyemine/submod/movement/BoatController.java +++ b/common/src/main/java/com/specialeffect/eyemine/submod/movement/BoatController.java @@ -14,7 +14,7 @@ import com.specialeffect.eyemine.mixin.KeyMappingAccessor; import net.minecraft.client.KeyMapping; import net.minecraft.client.Minecraft; -import net.minecraft.world.entity.vehicle.Boat; +import net.minecraft.world.entity.vehicle.boat.AbstractBoat; public class BoatController { // Boats are steered with left, right arrow keys to control the paddles @@ -87,7 +87,7 @@ private void control_model(double control_input) { this.steer(steer_amount); } - public void pid_step(Boat boat, double yaw_error) { + public void pid_step(AbstractBoat boat, double yaw_error) { // Reset if new boat if (boat.getId() != this.boat_id) { this.yaw_error = 0; diff --git a/common/src/main/java/com/specialeffect/eyemine/submod/movement/Dismount.java b/common/src/main/java/com/specialeffect/eyemine/submod/movement/Dismount.java index 85e3417f..945afb6e 100644 --- a/common/src/main/java/com/specialeffect/eyemine/submod/movement/Dismount.java +++ b/common/src/main/java/com/specialeffect/eyemine/submod/movement/Dismount.java @@ -16,20 +16,21 @@ import com.specialeffect.eyemine.client.Keybindings; import com.specialeffect.eyemine.submod.SubMod; import com.specialeffect.utils.ModUtils; -import dev.architectury.event.EventResult; -import dev.architectury.event.events.client.ClientRawInputEvent; +import com.specialeffect.eyemine.event.EventResult; +import com.specialeffect.eyemine.event.EyeMineEvents; import net.minecraft.client.KeyMapping; import net.minecraft.client.Minecraft; import net.minecraft.client.player.LocalPlayer; import net.minecraft.network.protocol.game.ServerboundInteractPacket; import net.minecraft.network.protocol.game.ServerboundPlayerInputPacket; +import net.minecraft.world.entity.player.Input; import net.minecraft.world.InteractionHand; import net.minecraft.world.entity.Entity; import net.minecraft.world.entity.Mob; -import net.minecraft.world.entity.Saddleable; -import net.minecraft.world.entity.animal.horse.Horse; -import net.minecraft.world.entity.vehicle.Boat; -import net.minecraft.world.entity.vehicle.Minecart; +import net.minecraft.world.entity.animal.equine.AbstractHorse; +import net.minecraft.world.entity.animal.equine.Horse; +import net.minecraft.world.entity.vehicle.boat.AbstractBoat; +import net.minecraft.world.entity.vehicle.minecart.Minecart; import net.minecraft.world.level.Level; import net.minecraft.world.phys.AABB; import net.minecraft.world.phys.EntityHitResult; @@ -49,10 +50,10 @@ public void onInitializeClient() { "key.eyemine.ride_or_dismount", Type.KEYSYM, GLFW.GLFW_KEY_F15, - "category.eyemine.category.eyegaze_extra" // The translation key of the keybinding's category. + Keybindings.EYEGAZE_EXTRA // The translation key of the keybinding's category. )); - ClientRawInputEvent.KEY_PRESSED.register(this::onKeyInput); + EyeMineEvents.KEY_PRESSED.register(this::onKeyInput); } private EventResult onKeyInput(Minecraft minecraft, int keyCode, int scanCode, int action, int modifiers) { @@ -60,11 +61,11 @@ private EventResult onKeyInput(Minecraft minecraft, int keyCode, int scanCode, i return EventResult.pass(); } - if (InputConstants.isKeyDown(minecraft.getWindow().getWindow(), 292)) { + if (InputConstants.isKeyDown(minecraft.getWindow(), 292)) { return EventResult.pass(); } - if (mDismountKB.matches(keyCode, scanCode) && mDismountKB.consumeClick()) { + if (mDismountKB.matches(new net.minecraft.client.input.KeyEvent(keyCode, scanCode, modifiers)) && mDismountKB.consumeClick()) { LocalPlayer player = Minecraft.getInstance().player; if (player.isPassenger()) { // Dismount player locally @@ -72,7 +73,7 @@ private EventResult onKeyInput(Minecraft minecraft, int keyCode, int scanCode, i player.jumpFromGround(); // Dismount player on server // channel.sendToServer(new DismountPlayerMessage()); - player.connection.send(new ServerboundPlayerInputPacket(player.xxa, player.zza, false, true)); + player.connection.send(new ServerboundPlayerInputPacket(new Input(false, false, false, false, false, true, false))); } else { EntityHitResult entityResult = ModUtils.getMouseOverEntity(); Entity entity = entityResult == null ? null : entityResult.getEntity(); @@ -86,7 +87,7 @@ private EventResult onKeyInput(Minecraft minecraft, int keyCode, int scanCode, i AABB box = player.getBoundingBox().inflate(2); List mobEntities = level.getEntitiesOfClass(Mob.class, box); - List boatEntities = level.getEntitiesOfClass(Boat.class, box); + List boatEntities = level.getEntitiesOfClass(AbstractBoat.class, box); List minecartEntities = level.getEntitiesOfClass(Minecart.class, box); List entities = new ArrayList<>(); @@ -101,7 +102,7 @@ private EventResult onKeyInput(Minecraft minecraft, int keyCode, int scanCode, i ModUtils.sendPlayerMessage("Nothing found to ride"); } else if (entities.size() == 1) { entity = entities.get(0); - if (entity instanceof Saddleable || entity instanceof Minecart || entity instanceof Boat) { + if (entity instanceof AbstractHorse || entity instanceof Minecart || entity instanceof AbstractBoat) { ModUtils.sendPlayerMessage("Attempting to mount nearby " + entity.getName().getString()); } } else { @@ -126,8 +127,8 @@ else if (entity instanceof Horse && ModUtils.sendPlayerMessage("You need an empty hand to ride a horse"); } - entity.interact(player, hand); - player.connection.send(ServerboundInteractPacket.createInteractionPacket(entity, player.isShiftKeyDown(), hand)); + entity.interact(player, hand, entity.position()); + player.connection.send(new ServerboundInteractPacket(entity.getId(), hand, entity.position(), player.isShiftKeyDown())); } } } diff --git a/common/src/main/java/com/specialeffect/eyemine/submod/movement/EasyLadderClimb.java b/common/src/main/java/com/specialeffect/eyemine/submod/movement/EasyLadderClimb.java index c68c15c5..d0fb6a23 100644 --- a/common/src/main/java/com/specialeffect/eyemine/submod/movement/EasyLadderClimb.java +++ b/common/src/main/java/com/specialeffect/eyemine/submod/movement/EasyLadderClimb.java @@ -18,12 +18,12 @@ import com.specialeffect.eyemine.event.BlockOutlineEvent; import com.specialeffect.eyemine.submod.SubMod; import com.specialeffect.utils.ModUtils; -import dev.architectury.event.EventResult; -import dev.architectury.event.events.client.ClientTickEvent; +import com.specialeffect.eyemine.event.EventResult; +import com.specialeffect.eyemine.event.EyeMineEvents; import net.minecraft.client.Minecraft; import net.minecraft.client.player.LocalPlayer; import net.minecraft.client.renderer.MultiBufferSource; -import net.minecraft.client.renderer.RenderType; +import net.minecraft.client.renderer.rendertype.RenderType; import net.minecraft.core.BlockPos; import net.minecraft.core.Direction; import net.minecraft.world.level.Level; @@ -42,7 +42,7 @@ public class EasyLadderClimb extends SubMod { // You'll get nudged toward the centre of the ladder a little bit. public void onInitializeClient() { - ClientTickEvent.CLIENT_PRE.register(this::onClientTick); + EyeMineEvents.CLIENT_TICK.register(this::onClientTick); BlockOutlineEvent.OUTLINE.register(this::onBlockOutlineRender); } diff --git a/common/src/main/java/com/specialeffect/eyemine/submod/movement/MoveWithGaze.java b/common/src/main/java/com/specialeffect/eyemine/submod/movement/MoveWithGaze.java index 0e2b0c90..758b2b94 100644 --- a/common/src/main/java/com/specialeffect/eyemine/submod/movement/MoveWithGaze.java +++ b/common/src/main/java/com/specialeffect/eyemine/submod/movement/MoveWithGaze.java @@ -25,20 +25,20 @@ import com.specialeffect.eyemine.utils.KeyboardInputHelper; import com.specialeffect.eyemine.utils.MouseHelper; import com.specialeffect.utils.ModUtils; -import dev.architectury.event.EventResult; -import dev.architectury.event.events.client.ClientRawInputEvent; -import dev.architectury.event.events.client.ClientTickEvent; +import com.specialeffect.eyemine.event.EventResult; +import com.specialeffect.eyemine.event.EyeMineEvents; import net.minecraft.client.KeyMapping; import net.minecraft.client.Minecraft; import net.minecraft.client.player.LocalPlayer; import net.minecraft.core.BlockPos; import net.minecraft.network.protocol.game.ServerboundMoveVehiclePacket; import net.minecraft.network.protocol.game.ServerboundPlayerInputPacket; +import net.minecraft.world.entity.player.Input; import net.minecraft.world.entity.Entity; import net.minecraft.world.entity.LivingEntity; import net.minecraft.world.entity.player.Player; -import net.minecraft.world.entity.vehicle.Boat; -import net.minecraft.world.entity.vehicle.Minecart; +import net.minecraft.world.entity.vehicle.boat.AbstractBoat; +import net.minecraft.world.entity.vehicle.minecart.Minecart; import net.minecraft.world.level.Level; import net.minecraft.world.level.block.state.BlockState; import net.minecraft.world.phys.EntityHitResult; @@ -77,20 +77,20 @@ public void onInitializeClient() { "key.eyemine.toggle_walking_forward", Type.KEYSYM, GLFW.GLFW_KEY_H, - "category.eyemine.category.eyegaze_common" // The translation key of the keybinding's category. + Keybindings.EYEGAZE_COMMON // The translation key of the keybinding's category. )); Keybindings.keybindings.add(mIncreaseWalkSpeedKB = new KeyMapping( "key.eyemine.increase_walk_speed", Type.KEYSYM, GLFW.GLFW_KEY_UP, - "category.eyemine.category.eyegaze_settings" // The translation key of the keybinding's category. + Keybindings.EYEGAZE_SETTINGS // The translation key of the keybinding's category. )); Keybindings.keybindings.add(mDecreaseWalkSpeedKB = new KeyMapping( "key.eyemine.decrease_walk_speed", Type.KEYSYM, GLFW.GLFW_KEY_DOWN, - "category.eyemine.category.eyegaze_settings" // The translation key of the keybinding's category. + Keybindings.EYEGAZE_SETTINGS // The translation key of the keybinding's category. )); mPrevLookDirs = new LinkedBlockingQueue<>(); @@ -98,8 +98,8 @@ public void onInitializeClient() { // Register an icon for the overlay mIconIndex = StateOverlay.registerTextureLeft("eyemine:textures/icons/walk.png"); - ClientTickEvent.CLIENT_PRE.register(this::onClientTick); - ClientRawInputEvent.KEY_PRESSED.register(this::onKeyInput); + EyeMineEvents.CLIENT_TICK.register(this::onClientTick); + EyeMineEvents.KEY_PRESSED.register(this::onKeyInput); } @Override @@ -216,7 +216,9 @@ public void onClientTick(Minecraft event) { if ((stateInFront != null && stateInFront.isSolid()) && (stateAboveInFront != null && !stateAboveInFront.isSolid())) { if (jumpTicks == 0) { - player.connection.send(new ServerboundPlayerInputPacket(player.xxa, player.zza, true, player.input.shiftKeyDown)); + player.connection.send(new ServerboundPlayerInputPacket(new Input( + player.zza > 0, player.zza < 0, player.xxa > 0, player.xxa < 0, + true, player.isShiftKeyDown(), false))); player.jumpFromGround(); // only jump every N ticks... @@ -231,12 +233,12 @@ public void onClientTick(Minecraft event) { Entity riddenEntity = player.getVehicle(); if (null != riddenEntity) { - if (riddenEntity instanceof Boat boat) { + if (riddenEntity instanceof AbstractBoat boat) { // very special case: you can't steer a boat without keys, // so we first steer left/right with keys until the boat // and the player's view are aligned, only then move // forward - if (boat.isControlledByLocalInstance()) { + if (boat.isLocalInstanceAuthoritative()) { float yawError = boat.getYRot() - player.getYRot(); yawError %= 360; if (yawError < -180) { @@ -270,7 +272,7 @@ public void onClientTick(Minecraft event) { // It's critical we add motion to player on the server, not just // locally player.setDeltaMovement(motionAligned); - player.connection.send(new ServerboundMoveVehiclePacket(riddenEntity)); //TEST IF WORKS + player.connection.send(ServerboundMoveVehiclePacket.fromEntity(riddenEntity)); //TEST IF WORKS } else { // Any other ridden entities that don't work with the movement override?? @@ -368,11 +370,11 @@ private EventResult onKeyInput(Minecraft minecraft, int keyCode, int scanCode, i return EventResult.pass(); } - if (InputConstants.isKeyDown(minecraft.getWindow().getWindow(), 292)) { + if (InputConstants.isKeyDown(minecraft.getWindow(), 292)) { return EventResult.pass(); } - if (mToggleAutoWalkKB.matches(keyCode, scanCode) && mToggleAutoWalkKB.consumeClick()) { + if (mToggleAutoWalkKB.matches(new net.minecraft.client.input.KeyEvent(keyCode, scanCode, modifiers)) && mToggleAutoWalkKB.consumeClick()) { mDoingAutoWalk = !mDoingAutoWalk; MouseHandlerMod.setWalking(mDoingAutoWalk); StateOverlay.setStateLeftIcon(mIconIndex, mDoingAutoWalk); @@ -381,12 +383,12 @@ private EventResult onKeyInput(Minecraft minecraft, int keyCode, int scanCode, i } ModUtils.sendPlayerMessage("Auto walk: " + (mDoingAutoWalk ? "ON" : "OFF")); } - if (mDecreaseWalkSpeedKB.matches(keyCode, scanCode) && mDecreaseWalkSpeedKB.consumeClick()) { + if (mDecreaseWalkSpeedKB.matches(new net.minecraft.client.input.KeyEvent(keyCode, scanCode, modifiers)) && mDecreaseWalkSpeedKB.consumeClick()) { float newSpeed = (float) Math.max(0.1d, 0.9d * EyeMineConfig.getCustomSpeedFactor()); MainClientHandler.saveWalkingSpeed(newSpeed); displayCurrentSpeed(); } - if (mIncreaseWalkSpeedKB.matches(keyCode, scanCode) && mIncreaseWalkSpeedKB.consumeClick()) { + if (mIncreaseWalkSpeedKB.matches(new net.minecraft.client.input.KeyEvent(keyCode, scanCode, modifiers)) && mIncreaseWalkSpeedKB.consumeClick()) { float newSpeed = (float) Math.min(2.0d, EyeMineConfig.getCustomSpeedFactor() * 1.1d); MainClientHandler.saveWalkingSpeed(newSpeed); displayCurrentSpeed(); diff --git a/common/src/main/java/com/specialeffect/eyemine/submod/movement/MoveWithGaze2.java b/common/src/main/java/com/specialeffect/eyemine/submod/movement/MoveWithGaze2.java index 3950a68d..e33d5a8c 100644 --- a/common/src/main/java/com/specialeffect/eyemine/submod/movement/MoveWithGaze2.java +++ b/common/src/main/java/com/specialeffect/eyemine/submod/movement/MoveWithGaze2.java @@ -24,9 +24,8 @@ import com.specialeffect.eyemine.utils.KeyboardInputHelper; import com.specialeffect.eyemine.utils.MouseHelper; import com.specialeffect.utils.ModUtils; -import dev.architectury.event.EventResult; -import dev.architectury.event.events.client.ClientRawInputEvent; -import dev.architectury.event.events.client.ClientTickEvent; +import com.specialeffect.eyemine.event.EventResult; +import com.specialeffect.eyemine.event.EyeMineEvents; import net.minecraft.client.KeyMapping; import net.minecraft.client.Minecraft; import net.minecraft.client.player.LocalPlayer; @@ -50,14 +49,14 @@ public void onInitializeClient() { "key.eyemine.toggle_walking", //Careful walk Type.KEYSYM, GLFW.GLFW_KEY_B, - "category.eyemine.category.eyegaze_common" // The translation key of the keybinding's category. + Keybindings.EYEGAZE_COMMON // The translation key of the keybinding's category. )); // Register an icon for the overlay mIconIndex = StateOverlay.registerTextureLeft("eyemine:textures/icons/legacy-mode.png"); - ClientTickEvent.CLIENT_PRE.register(this::onClientTick); - ClientRawInputEvent.KEY_PRESSED.register(this::onKeyInput); + EyeMineEvents.CLIENT_TICK.register(this::onClientTick); + EyeMineEvents.KEY_PRESSED.register(this::onKeyInput); } private static int mIconIndex; @@ -150,11 +149,11 @@ private EventResult onKeyInput(Minecraft minecraft, int keyCode, int scanCode, i return EventResult.pass(); } - if (InputConstants.isKeyDown(minecraft.getWindow().getWindow(), 292)) { + if (InputConstants.isKeyDown(minecraft.getWindow(), 292)) { return EventResult.pass(); } - if (mToggleAutoWalkKB.matches(keyCode, scanCode) && mToggleAutoWalkKB.consumeClick()) { + if (mToggleAutoWalkKB.matches(new net.minecraft.client.input.KeyEvent(keyCode, scanCode, modifiers)) && mToggleAutoWalkKB.consumeClick()) { mDoingAutoWalk = !mDoingAutoWalk; MouseHandlerMod.setLegacyWalking(mDoingAutoWalk); @@ -164,4 +163,4 @@ private EventResult onKeyInput(Minecraft minecraft, int keyCode, int scanCode, i } return EventResult.pass(); } -} \ No newline at end of file +} diff --git a/common/src/main/java/com/specialeffect/eyemine/submod/movement/Sneak.java b/common/src/main/java/com/specialeffect/eyemine/submod/movement/Sneak.java index d49f9cd2..47860416 100644 --- a/common/src/main/java/com/specialeffect/eyemine/submod/movement/Sneak.java +++ b/common/src/main/java/com/specialeffect/eyemine/submod/movement/Sneak.java @@ -19,9 +19,8 @@ import com.specialeffect.eyemine.submod.SubMod; import com.specialeffect.eyemine.utils.KeyboardInputHelper; import com.specialeffect.utils.ModUtils; -import dev.architectury.event.EventResult; -import dev.architectury.event.events.client.ClientRawInputEvent; -import dev.architectury.event.events.client.ClientTickEvent; +import com.specialeffect.eyemine.event.EventResult; +import com.specialeffect.eyemine.event.EyeMineEvents; import net.minecraft.client.KeyMapping; import net.minecraft.client.Minecraft; import net.minecraft.client.player.LocalPlayer; @@ -44,14 +43,14 @@ public void onInitializeClient() { "key.eyemine.toggle_sneaking", Type.KEYSYM, GLFW.GLFW_KEY_Z, - "category.eyemine.category.eyegaze_extra" // The translation key of the keybinding's category. + Keybindings.EYEGAZE_EXTRA // The translation key of the keybinding's category. )); // Register an icon for the overlay mIconIndex = StateOverlay.registerTextureLeft("eyemine:textures/icons/sneak.png"); - ClientTickEvent.CLIENT_PRE.register(this::onClientTick); - ClientRawInputEvent.KEY_PRESSED.register(this::onKeyInput); + EyeMineEvents.CLIENT_TICK.register(this::onClientTick); + EyeMineEvents.KEY_PRESSED.register(this::onKeyInput); } public void onClientTick(Minecraft minecraft) { @@ -90,11 +89,11 @@ private EventResult onKeyInput(Minecraft minecraft, int keyCode, int scanCode, i return EventResult.pass(); } - if (InputConstants.isKeyDown(minecraft.getWindow().getWindow(), 292)) { + if (InputConstants.isKeyDown(minecraft.getWindow(), 292)) { return EventResult.pass(); } - if (mSneakKB.matches(keyCode, scanCode) && mSneakKB.consumeClick()) { + if (mSneakKB.matches(new net.minecraft.client.input.KeyEvent(keyCode, scanCode, modifiers)) && mSneakKB.consumeClick()) { updateSneak(!mIsSneaking); } return EventResult.pass(); diff --git a/common/src/main/java/com/specialeffect/eyemine/submod/movement/Swim.java b/common/src/main/java/com/specialeffect/eyemine/submod/movement/Swim.java index 4357639c..5758f564 100644 --- a/common/src/main/java/com/specialeffect/eyemine/submod/movement/Swim.java +++ b/common/src/main/java/com/specialeffect/eyemine/submod/movement/Swim.java @@ -18,9 +18,8 @@ import com.specialeffect.eyemine.mixin.KeyMappingAccessor; import com.specialeffect.eyemine.submod.SubMod; import com.specialeffect.utils.ModUtils; -import dev.architectury.event.EventResult; -import dev.architectury.event.events.client.ClientRawInputEvent; -import dev.architectury.event.events.client.ClientTickEvent; +import com.specialeffect.eyemine.event.EventResult; +import com.specialeffect.eyemine.event.EyeMineEvents; import net.minecraft.client.KeyMapping; import net.minecraft.client.Minecraft; import net.minecraft.client.player.LocalPlayer; @@ -43,7 +42,7 @@ public void onInitializeClient() { "key.eyemine.toggle_swimming", Type.KEYSYM, GLFW.GLFW_KEY_V, - "category.eyemine.category.eyegaze_extra" // The translation key of the keybinding's category. + Keybindings.EYEGAZE_EXTRA // The translation key of the keybinding's category. )); // Register an icon for the overlay @@ -51,8 +50,8 @@ public void onInitializeClient() { StateOverlay.setStateLeftIcon(mIconIndex, mSwimmingTurnedOn); - ClientTickEvent.CLIENT_PRE.register(this::onClientTick); - ClientRawInputEvent.KEY_PRESSED.register(this::onKeyInput); + EyeMineEvents.CLIENT_TICK.register(this::onClientTick); + EyeMineEvents.KEY_PRESSED.register(this::onKeyInput); } public static void stopActivelySwimming() { @@ -117,11 +116,11 @@ private EventResult onKeyInput(Minecraft minecraft, int keyCode, int scanCode, i return EventResult.pass(); } - if (InputConstants.isKeyDown(minecraft.getWindow().getWindow(), 292)) { + if (InputConstants.isKeyDown(minecraft.getWindow(), 292)) { return EventResult.pass(); } - if (mSwimKB.matches(keyCode, scanCode) && mSwimKB.consumeClick()) { + if (mSwimKB.matches(new net.minecraft.client.input.KeyEvent(keyCode, scanCode, modifiers)) && mSwimKB.consumeClick()) { final KeyMapping swimBinding = minecraft.options.keyJump; mSwimmingTurnedOn = !mSwimmingTurnedOn; diff --git a/common/src/main/java/com/specialeffect/eyemine/submod/utils/DebugAverageFps.java b/common/src/main/java/com/specialeffect/eyemine/submod/utils/DebugAverageFps.java index d2eee645..77e8e6c9 100644 --- a/common/src/main/java/com/specialeffect/eyemine/submod/utils/DebugAverageFps.java +++ b/common/src/main/java/com/specialeffect/eyemine/submod/utils/DebugAverageFps.java @@ -13,7 +13,7 @@ import com.specialeffect.eyemine.mixin.MinecraftAccessor; import com.specialeffect.eyemine.submod.SubMod; -import dev.architectury.event.events.client.ClientTickEvent; +import com.specialeffect.eyemine.event.EyeMineEvents; import net.minecraft.client.Minecraft; import net.minecraft.client.player.LocalPlayer; @@ -35,7 +35,7 @@ public DebugAverageFps() { public void onInitializeClient() { mPrevFps = new LinkedBlockingQueue<>(); - ClientTickEvent.CLIENT_PRE.register(this::onClientTick); + EyeMineEvents.CLIENT_TICK.register(this::onClientTick); } public void onClientTick(Minecraft event) { diff --git a/common/src/main/java/com/specialeffect/eyemine/submod/utils/DwellAction.java b/common/src/main/java/com/specialeffect/eyemine/submod/utils/DwellAction.java index b7df8d93..9c50243e 100644 --- a/common/src/main/java/com/specialeffect/eyemine/submod/utils/DwellAction.java +++ b/common/src/main/java/com/specialeffect/eyemine/submod/utils/DwellAction.java @@ -22,15 +22,15 @@ import com.specialeffect.eyemine.submod.mouse.MouseHandlerMod; import com.specialeffect.eyemine.utils.MouseHelper; import com.specialeffect.utils.ModUtils; -import dev.architectury.event.EventResult; -import dev.architectury.event.events.client.ClientGuiEvent; +import com.specialeffect.eyemine.event.EventResult; +import com.specialeffect.eyemine.event.EyeMineEvents; import net.minecraft.client.DeltaTracker; import net.minecraft.client.Minecraft; import net.minecraft.client.gui.Font; -import net.minecraft.client.gui.GuiGraphics; +import net.minecraft.client.gui.GuiGraphicsExtractor; import net.minecraft.client.player.LocalPlayer; import net.minecraft.client.renderer.MultiBufferSource; -import net.minecraft.client.renderer.RenderType; +import net.minecraft.client.renderer.rendertype.RenderType; import net.minecraft.world.phys.BlockHitResult; import net.minecraft.world.phys.HitResult.Type; @@ -70,7 +70,7 @@ public DwellAction(String name, int labelOffset) { } public void onInitializeClient() { - ClientGuiEvent.RENDER_HUD.register(this::onRenderGameOverlayEvent); + EyeMineEvents.RENDER_HUD.register(this::onRenderGameOverlayEvent); BlockOutlineEvent.OUTLINE.register(this::onBlockOutlineRender); } @@ -225,7 +225,7 @@ public EventResult onBlockOutlineRender(MultiBufferSource bufferSource, PoseStac return EventResult.pass(); } - public void onRenderGameOverlayEvent(GuiGraphics guiGraphics, DeltaTracker deltaTracker) { + public void onRenderGameOverlayEvent(GuiGraphicsExtractor guiGraphics, DeltaTracker deltaTracker) { // If dwell is on, show a warning message if (mDwelling && showLabel) { Minecraft minecraft = Minecraft.getInstance(); @@ -237,7 +237,7 @@ public void onRenderGameOverlayEvent(GuiGraphics guiGraphics, DeltaTracker delta final Font font = minecraft.font; float msgWidth = (float) font.width(msg); - guiGraphics.drawString(font, msg, (int) (w / 2.0f - msgWidth / 2.0f), (int)(h / 2.0f - 20 - labelOffset), 0xffFFFFFF); + guiGraphics.text(font, msg, (int) (w / 2.0f - msgWidth / 2.0f), (int)(h / 2.0f - 20 - labelOffset), 0xffFFFFFF); } } } diff --git a/common/src/main/java/com/specialeffect/eyemine/utils/MouseHelper.java b/common/src/main/java/com/specialeffect/eyemine/utils/MouseHelper.java index 992e0f32..e8c9446f 100644 --- a/common/src/main/java/com/specialeffect/eyemine/utils/MouseHelper.java +++ b/common/src/main/java/com/specialeffect/eyemine/utils/MouseHelper.java @@ -86,8 +86,8 @@ public enum PlayerMovement { **/ public void moveCursor(MouseHandler mouseHelper, double xpos, double ypos) { if (mouseHelper != null) { - long handle = Minecraft.getInstance().getWindow().getWindow(); - GLFW.glfwSetCursorPos(Minecraft.getInstance().getWindow().getWindow(), xpos, ypos); + long handle = Minecraft.getInstance().getWindow().handle(); + GLFW.glfwSetCursorPos(Minecraft.getInstance().getWindow().handle(), xpos, ypos); ((MouseHandlerAccessor) mouseHelper).invokeOnMove(handle, xpos, ypos); } } @@ -110,7 +110,7 @@ public void leftShiftMouseClickAtPosition(MouseHandler mouseHelper, double xpos, public void scroll(MouseHandler mouseHandler, double amount) { if (mouseHandler != null) { - long handle = Minecraft.getInstance().getWindow().getWindow(); + long handle = Minecraft.getInstance().getWindow().handle(); ((MouseHandlerAccessor) mouseHandler).invokeOnScroll(handle, 0, amount); } } @@ -125,7 +125,7 @@ public void scroll(MouseHandler mouseHandler, double amount) { * mods: GLFW.GLFW_MOD_[SHIFT/CONTROL/ALT/SUPER] */ public void mouseButton(int button, int action, int mods) { - long handle = Minecraft.getInstance().getWindow().getWindow(); + long handle = Minecraft.getInstance().getWindow().handle(); ((MouseHandlerAccessor) Minecraft.getInstance().mouseHandler).invokeOnPress(handle, button, action, mods); } diff --git a/common/src/main/java/com/specialeffect/inventory/manager/ChestInventoryManager.java b/common/src/main/java/com/specialeffect/inventory/manager/ChestInventoryManager.java index 0205c83c..aa6d75a6 100644 --- a/common/src/main/java/com/specialeffect/inventory/manager/ChestInventoryManager.java +++ b/common/src/main/java/com/specialeffect/inventory/manager/ChestInventoryManager.java @@ -166,6 +166,6 @@ private void hoverItem() { int yPos = containerTop + itemRow * itemWidth; int xPos = containerLeft + itemCol * itemWidth; - GLFW.glfwSetCursorPos(Minecraft.getInstance().getWindow().getWindow(), xPos * this.xScale, yPos * this.yScale); + GLFW.glfwSetCursorPos(Minecraft.getInstance().getWindow().handle(), xPos * this.xScale, yPos * this.yScale); } } \ No newline at end of file diff --git a/common/src/main/java/com/specialeffect/inventory/manager/CreativeInventoryManager.java b/common/src/main/java/com/specialeffect/inventory/manager/CreativeInventoryManager.java index 403e1baf..bd48dbca 100644 --- a/common/src/main/java/com/specialeffect/inventory/manager/CreativeInventoryManager.java +++ b/common/src/main/java/com/specialeffect/inventory/manager/CreativeInventoryManager.java @@ -242,7 +242,7 @@ private void hoverItem() { int yPos = containerTop + itemRow * itemWidth; int xPos = containerLeft + itemCol * itemWidth; - GLFW.glfwSetCursorPos(Minecraft.getInstance().getWindow().getWindow(), xPos * this.xScale, yPos * this.yScale); + GLFW.glfwSetCursorPos(Minecraft.getInstance().getWindow().handle(), xPos * this.xScale, yPos * this.yScale); } private void switchToTab(int iTab) { @@ -318,7 +318,7 @@ private void switchToTab(int iTab) { // the same tab again (otherwise this gets missed) this.onTabChanged(); - GLFW.glfwSetCursorPos(Minecraft.getInstance().getWindow().getWindow(), xPos * this.xScale, yPos * this.yScale); + GLFW.glfwSetCursorPos(Minecraft.getInstance().getWindow().handle(), xPos * this.xScale, yPos * this.yScale); } } diff --git a/common/src/main/java/com/specialeffect/inventory/manager/SurvivalInventoryManager.java b/common/src/main/java/com/specialeffect/inventory/manager/SurvivalInventoryManager.java index 627dc55f..6e804646 100644 --- a/common/src/main/java/com/specialeffect/inventory/manager/SurvivalInventoryManager.java +++ b/common/src/main/java/com/specialeffect/inventory/manager/SurvivalInventoryManager.java @@ -123,7 +123,7 @@ private void updateCoordinates(int left, int top, int width, int height, Invento List slots = playerContainer.slots; - int iSlotOutput = playerContainer.getResultSlotIndex(); + int iSlotOutput = InventoryMenu.RESULT_SLOT; for (Slot slot : slots) { @@ -148,7 +148,7 @@ private void processSlots() { List slots = playerContainer.slots; - this.outputSlot = slots.get(playerContainer.getResultSlotIndex()); + this.outputSlot = slots.get(InventoryMenu.RESULT_SLOT); this.slotFirstX = slots.get(10).x; this.slotFirstY = slots.get(10).y; @@ -166,7 +166,7 @@ private void processSlots() { // Parse the list of slots to work out the location of things List slots = playerContainer.inventorySlots; - int iSlotOutput = playerContainer.getResultSlotIndex(); + int iSlotOutput = InventoryMenu.RESULT_SLOT; for (Slot slot : slots) { // if (slot instanceof ) LOGGER.debug(slot.xPos+ ", "+ slot.yPos); @@ -193,7 +193,7 @@ public void hoverOutput() { MouseHelper.instance().moveCursor(helper, xPos * this.xScale, yPos * this.yScale); - playerContainer.quickMoveStack(Minecraft.getInstance().player, playerContainer.getResultSlotIndex()); + playerContainer.quickMoveStack(Minecraft.getInstance().player, InventoryMenu.RESULT_SLOT); } @@ -273,7 +273,7 @@ private void hoverItem() { int yPos = topItemYPos + itemRow * itemWidth; int xPos = leftItemXPos + itemCol * itemWidth; - GLFW.glfwSetCursorPos(Minecraft.getInstance().getWindow().getWindow(), xPos * this.xScale, yPos * this.yScale); + GLFW.glfwSetCursorPos(Minecraft.getInstance().getWindow().handle(), xPos * this.xScale, yPos * this.yScale); } private void switchToTab(int iTab) { diff --git a/common/src/main/java/com/specialeffect/utils/ModUtils.java b/common/src/main/java/com/specialeffect/utils/ModUtils.java index 9b8ba518..f4997a95 100644 --- a/common/src/main/java/com/specialeffect/utils/ModUtils.java +++ b/common/src/main/java/com/specialeffect/utils/ModUtils.java @@ -11,12 +11,6 @@ package com.specialeffect.utils; -import com.mojang.blaze3d.systems.RenderSystem; -import com.mojang.blaze3d.vertex.BufferBuilder; -import com.mojang.blaze3d.vertex.BufferUploader; -import com.mojang.blaze3d.vertex.DefaultVertexFormat; -import com.mojang.blaze3d.vertex.Tesselator; -import com.mojang.blaze3d.vertex.VertexFormat.Mode; import net.minecraft.client.Minecraft; import net.minecraft.core.BlockPos; import net.minecraft.core.Direction; @@ -37,8 +31,6 @@ import net.minecraft.world.phys.EntityHitResult; import net.minecraft.world.phys.HitResult; import net.minecraft.world.phys.Vec3; -import org.lwjgl.opengl.GL11; - import java.awt.Point; import java.util.ArrayList; import java.util.List; @@ -125,28 +117,12 @@ public static Point getCompassPoint(int i) { // } - public static void drawTexQuad(double x, double y, double width, double height, float alpha) { - RenderSystem.setShaderColor(1.0F, 1.0F, 1.0F, alpha); - RenderSystem.enableBlend(); - RenderSystem.blendFuncSeparate(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA, 1, 0); - - Tesselator tesselator = Tesselator.getInstance(); - - int z = 10; - BufferBuilder bufferbuilder = tesselator.begin(Mode.QUADS, DefaultVertexFormat.POSITION_TEX); - bufferbuilder.addVertex((float) x, (float) (y + height), z).setUv(0.0f, 1.0f); - bufferbuilder.addVertex((float) (x + width), (float) (y + height), z).setUv(1.0f, 1.0f); - bufferbuilder.addVertex((float) (x + width), (float) y, z).setUv(1.0f, 0.0f); - bufferbuilder.addVertex((float) x, (float) y, z).setUv(0.0f, 0.0f); - BufferUploader.drawWithShader(bufferbuilder.buildOrThrow()); - } - // Find an item in the hotbar which matches the given class // (this includes all subclasses) public static int findItemInHotbar(Inventory inventory, Predicate Itempredicate) { int itemId = -1; - int currentItemId = inventory.selected; - NonNullList items = inventory.items; + int currentItemId = inventory.getSelectedSlot(); + NonNullList items = inventory.getNonEquipmentItems(); if (items != null) { for (int i = 0; i < Inventory.getSelectionSize(); i++) { ItemStack stack = items.get(i); @@ -258,7 +234,7 @@ public static BlockPos highestSolidPoint(BlockPos pos) { BlockPos blockpos; BlockPos blockpos1; // Start from max build height and search downward - for (blockpos = new BlockPos(pos.getX(), world.getMaxBuildHeight(), pos.getZ()); blockpos.getY() >= world.getMinBuildHeight(); blockpos = blockpos1) { + for (blockpos = new BlockPos(pos.getX(), world.getMaxY(), pos.getZ()); blockpos.getY() >= world.getMinY(); blockpos = blockpos1) { blockpos1 = blockpos.below(); BlockState state = chunk.getBlockState(blockpos1); diff --git a/common/src/main/resources/META-INF/accesstransformer.cfg b/common/src/main/resources/META-INF/accesstransformer.cfg new file mode 100644 index 00000000..cd38b37b --- /dev/null +++ b/common/src/main/resources/META-INF/accesstransformer.cfg @@ -0,0 +1,3 @@ +# EyeMine Access Transformer for NeoForge +public net.minecraft.client.gui.screens.inventory.CreativeModeInventoryScreen selectedTab # CreativeModeTab +public net.minecraft.client.Minecraft missTime # I diff --git a/common/src/main/resources/eyemine-common.mixins.json b/common/src/main/resources/eyemine-common.mixins.json index 7ce8f54e..a1473297 100644 --- a/common/src/main/resources/eyemine-common.mixins.json +++ b/common/src/main/resources/eyemine-common.mixins.json @@ -1,7 +1,7 @@ { "required": true, "minVersion": "0.8.4", - "compatibilityLevel": "JAVA_21", + "compatibilityLevel": "JAVA_25", "package": "com.specialeffect.eyemine.mixin", "target": "@env(DEFAULT)", "mixins": [ diff --git a/common/src/main/resources/eyemine.accesswidener b/common/src/main/resources/eyemine.accesswidener index 13aa3492..a261abf1 100644 --- a/common/src/main/resources/eyemine.accesswidener +++ b/common/src/main/resources/eyemine.accesswidener @@ -1,5 +1,5 @@ -accessWidener v2 named +accessWidener v2 official accessible field net/minecraft/client/gui/screens/inventory/CreativeModeInventoryScreen selectedTab Lnet/minecraft/world/item/CreativeModeTab; -accessible method net/minecraft/world/level/block/state/BlockBehaviour useItemOn (Lnet/minecraft/world/item/ItemStack;Lnet/minecraft/world/level/block/state/BlockState;Lnet/minecraft/world/level/Level;Lnet/minecraft/core/BlockPos;Lnet/minecraft/world/entity/player/Player;Lnet/minecraft/world/InteractionHand;Lnet/minecraft/world/phys/BlockHitResult;)Lnet/minecraft/world/ItemInteractionResult; -accessible field net/minecraft/client/Minecraft missTime I \ No newline at end of file +accessible method net/minecraft/world/level/block/state/BlockBehaviour useItemOn (Lnet/minecraft/world/item/ItemStack;Lnet/minecraft/world/level/block/state/BlockState;Lnet/minecraft/world/level/Level;Lnet/minecraft/core/BlockPos;Lnet/minecraft/world/entity/player/Player;Lnet/minecraft/world/InteractionHand;Lnet/minecraft/world/phys/BlockHitResult;)Lnet/minecraft/world/InteractionResult; +accessible field net/minecraft/client/Minecraft missTime I diff --git a/common/src/main/resources/eyemine.common.json b/common/src/main/resources/eyemine.common.json deleted file mode 100644 index cd3672f2..00000000 --- a/common/src/main/resources/eyemine.common.json +++ /dev/null @@ -1,3 +0,0 @@ -{ - "accessWidener": "eyemine.accesswidener" -} \ No newline at end of file diff --git a/common/src/main/resources/pack.mcmeta b/common/src/main/resources/pack.mcmeta index a939321a..f41cd148 100644 --- a/common/src/main/resources/pack.mcmeta +++ b/common/src/main/resources/pack.mcmeta @@ -3,6 +3,6 @@ "description": { "text": "EyeMine Mod" }, - "pack_format": 32 + "pack_format": 71 } } diff --git a/fabric/build.gradle b/fabric/build.gradle index fbcc8747..b240301b 100644 --- a/fabric/build.gradle +++ b/fabric/build.gradle @@ -1,88 +1,43 @@ plugins { - id "com.github.johnrengelman.shadow" version "8.1.1" + id 'multiloader-loader' + id 'net.fabricmc.fabric-loom' } -architectury { - platformSetupLoomIde() - fabric() -} - -loom { - accessWidenerPath = project(":common").loom.accessWidenerPath -} - -configurations { - common - shadowCommon // Don't use shadow from the shadow plugin because we don't want IDEA to index this. - compileClasspath.extendsFrom common - runtimeClasspath.extendsFrom common - developmentFabric.extendsFrom common -} - -dependencies { - modImplementation "net.fabricmc:fabric-loader:${rootProject.fabric_loader_version}" - modApi "net.fabricmc.fabric-api:fabric-api:${rootProject.fabric_api_version}" - // Remove the next line if you don't want to depend on the API - modApi "dev.architectury:architectury-fabric:${rootProject.architectury_version}" - - common(project(path: ":common", configuration: "namedElements")) { transitive false } - shadowCommon(project(path: ":common", configuration: "transformProductionFabric")) { transitive false } - - modApi("me.shedaniel.cloth:cloth-config-fabric:${project.cloth_config_version}") { - exclude(group: "net.fabricmc.fabric-api") - } - modImplementation "com.terraformersmc:modmenu:${project.mod_menu_version}" -} - -processResources { - inputs.property "version", project.version - - filesMatching("fabric.mod.json") { - expand "version": project.version +repositories { + maven { + url "https://cursemaven.com" + content { + includeGroup "curse.maven" + } } } -shadowJar { - exclude "eyemine.common.json" - - configurations = [project.configurations.shadowCommon] - archiveClassifier.set("dev-shadow") -} - -remapJar { - injectAccessWidener = true - input.set shadowJar.archiveFile - dependsOn shadowJar - archiveBaseName.set "${rootProject.archives_base_name}-${project.minecraft_version}-${project.name}" - archiveClassifier.set('') -} - -jar { - archiveClassifier.set("dev") -} +dependencies { + minecraft "com.mojang:minecraft:${minecraft_version}" + implementation "net.fabricmc:fabric-loader:${fabric_loader_version}" + implementation "net.fabricmc.fabric-api:fabric-api:${fabric_version}" -sourcesJar { - def commonSources = project(":common").sourcesJar - dependsOn commonSources - from commonSources.archiveFile.map { zipTree(it) } + // Cloth Config for Fabric config GUI + implementation "curse.maven:cloth-config-348521:7817582" } -components.java { - withVariantsFromConfiguration(project.configurations.shadowRuntimeElements) { - skip() +loom { + def aw = project(':common').file("src/main/resources/${mod_id}.accesswidener") + if (aw.exists()) { + accessWidenerPath.set(aw) } -} - -publishing { - publications { - mavenFabric(MavenPublication) { - artifactId = rootProject.archives_base_name + "-" + project.minecraft_version + "-" + project.name - from components.java + runs { + client { + client() + setConfigName('Fabric Client') + ideConfigGenerated(true) + runDir('runs/client') + } + server { + server() + setConfigName('Fabric Server') + ideConfigGenerated(true) + runDir('runs/server') } } - - // See https://docs.gradle.org/current/userguide/publishing_maven.html for information on how to set up publishing. - repositories { - // Add repositories to publish to here. - } -} \ No newline at end of file +} diff --git a/fabric/src/main/java/com/specialeffect/eyemine/EyeMineClientFabric.java b/fabric/src/main/java/com/specialeffect/eyemine/EyeMineClientFabric.java index 37b19177..e90429a4 100644 --- a/fabric/src/main/java/com/specialeffect/eyemine/EyeMineClientFabric.java +++ b/fabric/src/main/java/com/specialeffect/eyemine/EyeMineClientFabric.java @@ -2,28 +2,96 @@ import com.specialeffect.eyemine.config.EyeMineConfig; import com.specialeffect.eyemine.config.InventoryConfig; -import com.specialeffect.eyemine.event.BlockOutlineEvent; +import com.specialeffect.eyemine.event.EyeMineEvents; +import com.specialeffect.eyemine.event.EventResult; import me.shedaniel.autoconfig.AutoConfig; import me.shedaniel.autoconfig.serializer.Toml4jConfigSerializer; import net.fabricmc.api.ClientModInitializer; -import net.fabricmc.fabric.api.client.rendering.v1.WorldRenderEvents; +import net.fabricmc.fabric.api.client.event.lifecycle.v1.ClientTickEvents; +import net.fabricmc.fabric.api.client.keymapping.v1.KeyMappingHelper; +import net.fabricmc.fabric.api.client.rendering.v1.hud.HudElementRegistry; +import net.fabricmc.fabric.api.client.rendering.v1.level.LevelRenderEvents; +import net.fabricmc.fabric.api.entity.event.v1.ServerLivingEntityEvents; +import net.fabricmc.fabric.api.event.lifecycle.v1.ServerLevelEvents; +import net.minecraft.client.KeyMapping; +import net.minecraft.client.Minecraft; +import net.minecraft.resources.Identifier; import net.minecraft.world.InteractionResult; public class EyeMineClientFabric implements ClientModInitializer { - @Override - public void onInitializeClient() { - AutoConfig.register(EyeMineConfig.class, Toml4jConfigSerializer::new); - AutoConfig.register(InventoryConfig.class, Toml4jConfigSerializer::new); - WorldRenderEvents.BLOCK_OUTLINE.register((blockOutline, blockOutlineContext) -> { - BlockOutlineEvent.OUTLINE.invoker().renderOutline(blockOutline.consumers(), blockOutline.matrixStack()); - return true; - }); - - AutoConfig.getConfigHolder(EyeMineConfig.class).registerSaveListener((manager, data) -> { - EyeMineClient.refresh(); - return InteractionResult.PASS; - }); - EyeMineClient.init(); - } -} \ No newline at end of file + @Override + public void onInitializeClient() { + AutoConfig.register(EyeMineConfig.class, Toml4jConfigSerializer::new); + AutoConfig.register(InventoryConfig.class, Toml4jConfigSerializer::new); + + AutoConfig.getConfigHolder(EyeMineConfig.class).registerSaveListener((manager, data) -> { + EyeMineClient.refresh(); + return InteractionResult.PASS; + }); + + EyeMineClient.init(); + + for (KeyMapping keyBinding : com.specialeffect.eyemine.client.Keybindings.keybindings) { + KeyMappingHelper.registerKeyMapping(keyBinding); + } + + registerEventForwarders(); + + EyeMineClient.setupComplete = true; + EyeMineClient.refresh(); + for (var listener : EyeMineEvents.CLIENT_SETUP.getListeners()) { + listener.onClientSetup(Minecraft.getInstance()); + } + } + + private void registerEventForwarders() { + // Client tick + ClientTickEvents.START_CLIENT_TICK.register(client -> { + for (var listener : EyeMineEvents.CLIENT_TICK.getListeners()) { + listener.onClientTick(client); + } + }); + + // HUD rendering + HudElementRegistry.addLast( + Identifier.fromNamespaceAndPath("eyemine", "overlay"), + (graphics, deltaTracker) -> { + for (var listener : EyeMineEvents.RENDER_HUD.getListeners()) { + listener.onRenderHud(graphics, deltaTracker); + } + } + ); + + // Block outline rendering + LevelRenderEvents.BEFORE_BLOCK_OUTLINE.register((context, outlineState) -> { + if (outlineState != null) { + for (var listener : EyeMineEvents.BLOCK_OUTLINE.getListeners()) { + EventResult result = listener.renderOutline(context.bufferSource(), context.poseStack()); + if (result.isPresent()) return false; + } + } + return true; + }); + + // Key input forwarded via FabricKeyboardHandlerMixin + + // Screen set forwarded via FabricSetScreenMixin + + // Server-side: Entity death + ServerLivingEntityEvents.ALLOW_DEATH.register((entity, source, amount) -> { + for (var listener : EyeMineEvents.ENTITY_DEATH.getListeners()) { + EventResult result = listener.onDeath(entity, source); + if (result == EventResult.INTERRUPT_FALSE) return false; + } + return true; + }); + + // Server-side: World load + ServerLevelEvents.LOAD.register((server, level) -> { + for (var listener : EyeMineEvents.WORLD_LOAD.getListeners()) { + listener.onWorldLoad(level); + } + }); + } +} diff --git a/fabric/src/main/java/com/specialeffect/eyemine/config/EyeMineModMenuIntegration.java b/fabric/src/main/java/com/specialeffect/eyemine/config/EyeMineModMenuIntegration.java index 7d8cde66..e446112f 100644 --- a/fabric/src/main/java/com/specialeffect/eyemine/config/EyeMineModMenuIntegration.java +++ b/fabric/src/main/java/com/specialeffect/eyemine/config/EyeMineModMenuIntegration.java @@ -1,12 +1,20 @@ package com.specialeffect.eyemine.config; -import com.terraformersmc.modmenu.api.ConfigScreenFactory; -import com.terraformersmc.modmenu.api.ModMenuApi; -import me.shedaniel.autoconfig.AutoConfig; +// TODO: Uncomment when ModMenu is available for MC 26.1.1 +// Requires: modImplementation "com.terraformersmc:modmenu:" in fabric/build.gradle +// And add "modmenu" entrypoint back to fabric.mod.json -public class EyeMineModMenuIntegration implements ModMenuApi { - @Override - public ConfigScreenFactory getModConfigScreenFactory() { - return parent -> AutoConfig.getConfigScreen(EyeMineConfig.class, parent).get(); - } +//import com.terraformersmc.modmenu.api.ConfigScreenFactory; +//import com.terraformersmc.modmenu.api.ModMenuApi; +//import me.shedaniel.autoconfig.AutoConfig; +// +//public class EyeMineModMenuIntegration implements ModMenuApi { +// @Override +// public ConfigScreenFactory getModConfigScreenFactory() { +// return parent -> AutoConfig.getConfigScreen(EyeMineConfig.class, parent).get(); +// } +//} + +public class EyeMineModMenuIntegration { + // Stub class - ModMenu integration disabled until available for 26.1.1 } diff --git a/fabric/src/main/java/com/specialeffect/eyemine/mixin/FabricKeyboardHandlerMixin.java b/fabric/src/main/java/com/specialeffect/eyemine/mixin/FabricKeyboardHandlerMixin.java new file mode 100644 index 00000000..7ad574bb --- /dev/null +++ b/fabric/src/main/java/com/specialeffect/eyemine/mixin/FabricKeyboardHandlerMixin.java @@ -0,0 +1,33 @@ +package com.specialeffect.eyemine.mixin; + +import com.specialeffect.eyemine.event.EyeMineEvents; +import com.specialeffect.eyemine.event.EventResult; +import net.minecraft.client.KeyboardHandler; +import net.minecraft.client.Minecraft; +import net.minecraft.client.input.KeyEvent; +import org.spongepowered.asm.mixin.Final; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.Shadow; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; + +/** + * Fabric-specific mixin to forward raw key events to EyeMineEvents.KEY_PRESSED. + * NeoForge has InputEvent.Key for this; Fabric needs a mixin. + */ +@Mixin(KeyboardHandler.class) +public class FabricKeyboardHandlerMixin { + @Shadow + @Final + private Minecraft minecraft; + + @Inject(method = "keyPress(JILnet/minecraft/client/input/KeyEvent;)V", at = @At("HEAD")) + private void eyemine$onKeyPress(long windowHandle, int action, KeyEvent keyEvent, CallbackInfo ci) { + for (var listener : EyeMineEvents.KEY_PRESSED.getListeners()) { + EventResult result = listener.onKeyPressed( + minecraft, keyEvent.key(), keyEvent.scancode(), action, keyEvent.modifiers()); + if (result.isPresent()) break; + } + } +} diff --git a/fabric/src/main/java/com/specialeffect/eyemine/mixin/FabricSetScreenMixin.java b/fabric/src/main/java/com/specialeffect/eyemine/mixin/FabricSetScreenMixin.java new file mode 100644 index 00000000..79bdedd6 --- /dev/null +++ b/fabric/src/main/java/com/specialeffect/eyemine/mixin/FabricSetScreenMixin.java @@ -0,0 +1,26 @@ +package com.specialeffect.eyemine.mixin; + +import com.specialeffect.eyemine.event.EyeMineEvents; +import com.specialeffect.eyemine.event.ScreenSetResult; +import net.minecraft.client.Minecraft; +import net.minecraft.client.gui.screens.Screen; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; + +/** + * Fabric-specific mixin to forward screen open events to EyeMineEvents.SCREEN_SET. + * NeoForge has ScreenEvent.Opening for this; Fabric needs a mixin. + */ +@Mixin(Minecraft.class) +public class FabricSetScreenMixin { + + @Inject(method = "setScreen(Lnet/minecraft/client/gui/screens/Screen;)V", at = @At("HEAD")) + private void eyemine$onSetScreen(Screen screen, CallbackInfo ci) { + for (var listener : EyeMineEvents.SCREEN_SET.getListeners()) { + ScreenSetResult result = listener.onScreenSet(screen); + if (result.handled()) break; + } + } +} diff --git a/fabric/src/main/java/com/specialeffect/eyemine/platform/fabric/EyeMineConfigImpl.java b/fabric/src/main/java/com/specialeffect/eyemine/platform/fabric/EyeMineConfigImpl.java index 297b2388..542b7631 100644 --- a/fabric/src/main/java/com/specialeffect/eyemine/platform/fabric/EyeMineConfigImpl.java +++ b/fabric/src/main/java/com/specialeffect/eyemine/platform/fabric/EyeMineConfigImpl.java @@ -1,166 +1,44 @@ package com.specialeffect.eyemine.platform.fabric; import com.specialeffect.eyemine.config.EyeMineConfig; +import com.specialeffect.eyemine.platform.services.IEyeMineConfigService; import me.shedaniel.autoconfig.AutoConfig; -public class EyeMineConfigImpl { - public static boolean getDisableCustomNewWorld() { - EyeMineConfig config = AutoConfig.getConfigHolder(EyeMineConfig.class).getConfig(); - return config.advanced.disableCustomNewWorld; - } - - public static void setCustomSpeedFactor(float speed) { - EyeMineConfig config = AutoConfig.getConfigHolder(EyeMineConfig.class).getConfig(); - config.general.customSpeedFactor = speed; - } - - public static boolean getUsingMouseEmulation() { - EyeMineConfig config = AutoConfig.getConfigHolder(EyeMineConfig.class).getConfig(); - return config.general.usingMouseEmulation; - } - - public static boolean getAutoSelectTool() { - EyeMineConfig config = AutoConfig.getConfigHolder(EyeMineConfig.class).getConfig(); - return config.general.autoSelectTool; - } - - public static boolean getAutoSelectSword() { - EyeMineConfig config = AutoConfig.getConfigHolder(EyeMineConfig.class).getConfig(); - return config.general.autoSelectSword; - } - - public static int getRadiusChests() { - EyeMineConfig config = AutoConfig.getConfigHolder(EyeMineConfig.class).getConfig(); - return config.advanced.radiusChests; - } - - public static int getTicksBetweenMining() { - EyeMineConfig config = AutoConfig.getConfigHolder(EyeMineConfig.class).getConfig(); - return config.advanced.ticksBetweenMining; - } - - public static double getBowDrawTime() { - EyeMineConfig config = AutoConfig.getConfigHolder(EyeMineConfig.class).getConfig(); - return config.advanced.bowDrawTime; - } - - public static float getFullscreenOverlayAlpha() { - EyeMineConfig config = AutoConfig.getConfigHolder(EyeMineConfig.class).getConfig(); - return config.advanced.fullscreenOverlayAlpha; - } - - public static int getIronsightsFovReduction() { - EyeMineConfig config = AutoConfig.getConfigHolder(EyeMineConfig.class).getConfig(); - return config.advanced.ironsightsFovReduction; - } - - public static double getIronsightsSensitivityReduction() { - EyeMineConfig config = AutoConfig.getConfigHolder(EyeMineConfig.class).getConfig(); - return config.advanced.ironsightsSensitivityReduction; - } - - public static boolean getUseDwellForSingleUseItem() { - EyeMineConfig config = AutoConfig.getConfigHolder(EyeMineConfig.class).getConfig(); - return config.dwell.useDwellForSingleUseItem; - } - - public static boolean getUseDwellForSingleMine() { - EyeMineConfig config = AutoConfig.getConfigHolder(EyeMineConfig.class).getConfig(); - return config.dwell.useDwellForSingleMine; - } - - public static int getRadiusDoors() { - EyeMineConfig config = AutoConfig.getConfigHolder(EyeMineConfig.class).getConfig(); - return config.advanced.radiusDoors; - } - - public static boolean getServerCompatibilityMode() { - EyeMineConfig config = AutoConfig.getConfigHolder(EyeMineConfig.class).getConfig(); - return config.advanced.serverCompatibilityMode; - } - - public static int getFlyHeightManual() { - EyeMineConfig config = AutoConfig.getConfigHolder(EyeMineConfig.class).getConfig(); - return config.movement.flyHeightManual; - } - - public static int getFlyHeightAuto() { - EyeMineConfig config = AutoConfig.getConfigHolder(EyeMineConfig.class).getConfig(); - return config.movement.flyHeightAuto; - } - - public static boolean getDefaultDoAutoJump() { - EyeMineConfig config = AutoConfig.getConfigHolder(EyeMineConfig.class).getConfig(); - return config.general.defaultDoAutoJump; - } - - public static boolean getDisableAutoJumpFixes() { - EyeMineConfig config = AutoConfig.getConfigHolder(EyeMineConfig.class).getConfig(); - return config.general.disableAutoJumpFixes; - } - - public static boolean getMoveWhenMouseStationary() { - EyeMineConfig config = AutoConfig.getConfigHolder(EyeMineConfig.class).getConfig(); - return config.movement.moveWhenMouseStationary; - } - - public static boolean getSlowdownOnCorners() { - EyeMineConfig config = AutoConfig.getConfigHolder(EyeMineConfig.class).getConfig(); - return config.movement.slowdownOnCorners; - } - - public static int getWalkingSlowdownFilter() { - EyeMineConfig config = AutoConfig.getConfigHolder(EyeMineConfig.class).getConfig(); - return config.movement.walkingSlowdownFilter; - } - - public static boolean getAllowLadderDescent() { - EyeMineConfig config = AutoConfig.getConfigHolder(EyeMineConfig.class).getConfig(); - return config.movement.allowLadderDescent; - } - - public static float getCustomSpeedFactor() { - EyeMineConfig config = AutoConfig.getConfigHolder(EyeMineConfig.class).getConfig(); - return config.general.customSpeedFactor; - } - - public static float getBoatMaxTurnAtSpeed() { - EyeMineConfig config = AutoConfig.getConfigHolder(EyeMineConfig.class).getConfig(); - return config.movement.boatMaxTurnAtSpeed; - } - - public static double getBoatSlowdown() { - EyeMineConfig config = AutoConfig.getConfigHolder(EyeMineConfig.class).getConfig(); - return config.movement.boatSlowdown; - } - - public static double getDwellTimeSeconds() { - EyeMineConfig config = AutoConfig.getConfigHolder(EyeMineConfig.class).getConfig(); - return config.dwell.dwellTimeSeconds; - } - - public static double getDwellLockonTimeSeconds() { - EyeMineConfig config = AutoConfig.getConfigHolder(EyeMineConfig.class).getConfig(); - return config.dwell.dwellLockonTimeSeconds; - } - - public static boolean getDwellShowWithTransparency() { - EyeMineConfig config = AutoConfig.getConfigHolder(EyeMineConfig.class).getConfig(); - return config.dwell.dwellShowWithTransparency; - } - - public static boolean getDwellShowExpanding() { - EyeMineConfig config = AutoConfig.getConfigHolder(EyeMineConfig.class).getConfig(); - return config.dwell.dwellShowExpanding; - } - - public static boolean getSlowdownOnAttack() { - EyeMineConfig config = AutoConfig.getConfigHolder(EyeMineConfig.class).getConfig(); - return config.movement.slowdownOnAttack; - } - - public static int getGazeIdleThreshold() { - EyeMineConfig config = AutoConfig.getConfigHolder(EyeMineConfig.class).getConfig(); - return config.movement.gazeIdleThreshold; - } +public class EyeMineConfigImpl implements IEyeMineConfigService { + private EyeMineConfig getConfig() { + return AutoConfig.getConfigHolder(EyeMineConfig.class).getConfig(); + } + + @Override public boolean getDisableCustomNewWorld() { return getConfig().advanced.disableCustomNewWorld; } + @Override public void setCustomSpeedFactor(float speed) { getConfig().general.customSpeedFactor = speed; } + @Override public boolean getUsingMouseEmulation() { return getConfig().general.usingMouseEmulation; } + @Override public boolean getAutoSelectTool() { return getConfig().general.autoSelectTool; } + @Override public boolean getAutoSelectSword() { return getConfig().general.autoSelectSword; } + @Override public int getRadiusChests() { return getConfig().advanced.radiusChests; } + @Override public int getTicksBetweenMining() { return getConfig().advanced.ticksBetweenMining; } + @Override public double getBowDrawTime() { return getConfig().advanced.bowDrawTime; } + @Override public float getFullscreenOverlayAlpha() { return getConfig().advanced.fullscreenOverlayAlpha; } + @Override public int getIronsightsFovReduction() { return getConfig().advanced.ironsightsFovReduction; } + @Override public double getIronsightsSensitivityReduction() { return getConfig().advanced.ironsightsSensitivityReduction; } + @Override public boolean getUseDwellForSingleUseItem() { return getConfig().dwell.useDwellForSingleUseItem; } + @Override public boolean getUseDwellForSingleMine() { return getConfig().dwell.useDwellForSingleMine; } + @Override public int getRadiusDoors() { return getConfig().advanced.radiusDoors; } + @Override public boolean getServerCompatibilityMode() { return getConfig().advanced.serverCompatibilityMode; } + @Override public int getFlyHeightManual() { return getConfig().movement.flyHeightManual; } + @Override public int getFlyHeightAuto() { return getConfig().movement.flyHeightAuto; } + @Override public boolean getDefaultDoAutoJump() { return getConfig().general.defaultDoAutoJump; } + @Override public boolean getDisableAutoJumpFixes() { return getConfig().general.disableAutoJumpFixes; } + @Override public boolean getMoveWhenMouseStationary() { return getConfig().movement.moveWhenMouseStationary; } + @Override public boolean getSlowdownOnCorners() { return getConfig().movement.slowdownOnCorners; } + @Override public int getWalkingSlowdownFilter() { return getConfig().movement.walkingSlowdownFilter; } + @Override public boolean getAllowLadderDescent() { return getConfig().movement.allowLadderDescent; } + @Override public float getCustomSpeedFactor() { return getConfig().general.customSpeedFactor; } + @Override public float getBoatMaxTurnAtSpeed() { return getConfig().movement.boatMaxTurnAtSpeed; } + @Override public double getBoatSlowdown() { return getConfig().movement.boatSlowdown; } + @Override public double getDwellTimeSeconds() { return getConfig().dwell.dwellTimeSeconds; } + @Override public double getDwellLockonTimeSeconds() { return getConfig().dwell.dwellLockonTimeSeconds; } + @Override public boolean getDwellShowWithTransparency() { return getConfig().dwell.dwellShowWithTransparency; } + @Override public boolean getDwellShowExpanding() { return getConfig().dwell.dwellShowExpanding; } + @Override public boolean getSlowdownOnAttack() { return getConfig().movement.slowdownOnAttack; } + @Override public int getGazeIdleThreshold() { return getConfig().movement.gazeIdleThreshold; } } diff --git a/fabric/src/main/java/com/specialeffect/eyemine/platform/fabric/FabricNetworkService.java b/fabric/src/main/java/com/specialeffect/eyemine/platform/fabric/FabricNetworkService.java new file mode 100644 index 00000000..89616556 --- /dev/null +++ b/fabric/src/main/java/com/specialeffect/eyemine/platform/fabric/FabricNetworkService.java @@ -0,0 +1,41 @@ +package com.specialeffect.eyemine.platform.fabric; + +import com.specialeffect.eyemine.packets.NetworkService; +import net.fabricmc.fabric.api.client.networking.v1.ClientPlayNetworking; +import net.fabricmc.fabric.api.networking.v1.PayloadTypeRegistry; +import net.fabricmc.fabric.api.networking.v1.ServerPlayNetworking; +import net.minecraft.network.RegistryFriendlyByteBuf; +import net.minecraft.network.codec.StreamCodec; +import net.minecraft.network.protocol.common.custom.CustomPacketPayload; +import net.minecraft.world.entity.player.Player; + +public class FabricNetworkService implements NetworkService { + + @Override + public void registerC2S( + CustomPacketPayload.Type type, + StreamCodec codec, + PacketHandler handler) { + PayloadTypeRegistry.serverboundPlay().register(type, codec); + ServerPlayNetworking.registerGlobalReceiver(type, (payload, context) -> { + handler.handle(payload, new FabricPacketContext(context)); + }); + } + + @Override + public void sendToServer(CustomPacketPayload payload) { + ClientPlayNetworking.send(payload); + } + + private record FabricPacketContext(ServerPlayNetworking.Context fabricContext) implements PacketContext { + @Override + public void queue(Runnable work) { + fabricContext.player().level().getServer().execute(work); + } + + @Override + public Player getPlayer() { + return fabricContext.player(); + } + } +} diff --git a/fabric/src/main/java/com/specialeffect/eyemine/platform/fabric/FabricPlatformHelper.java b/fabric/src/main/java/com/specialeffect/eyemine/platform/fabric/FabricPlatformHelper.java new file mode 100644 index 00000000..e7f50334 --- /dev/null +++ b/fabric/src/main/java/com/specialeffect/eyemine/platform/fabric/FabricPlatformHelper.java @@ -0,0 +1,21 @@ +package com.specialeffect.eyemine.platform.fabric; + +import com.specialeffect.eyemine.platform.services.IPlatformHelper; +import net.fabricmc.loader.api.FabricLoader; + +public class FabricPlatformHelper implements IPlatformHelper { + @Override + public String getPlatformName() { + return "Fabric"; + } + + @Override + public boolean isModLoaded(String modId) { + return FabricLoader.getInstance().isModLoaded(modId); + } + + @Override + public boolean isDevelopmentEnvironment() { + return FabricLoader.getInstance().isDevelopmentEnvironment(); + } +} diff --git a/fabric/src/main/java/com/specialeffect/eyemine/platform/fabric/InventoryConfigImpl.java b/fabric/src/main/java/com/specialeffect/eyemine/platform/fabric/InventoryConfigImpl.java index d787fc16..9882336c 100644 --- a/fabric/src/main/java/com/specialeffect/eyemine/platform/fabric/InventoryConfigImpl.java +++ b/fabric/src/main/java/com/specialeffect/eyemine/platform/fabric/InventoryConfigImpl.java @@ -1,131 +1,37 @@ package com.specialeffect.eyemine.platform.fabric; import com.specialeffect.eyemine.config.InventoryConfig; +import com.specialeffect.eyemine.platform.services.IInventoryConfigService; import me.shedaniel.autoconfig.AutoConfig; -public class InventoryConfigImpl { - public static int getKey0() { - InventoryConfig config = AutoConfig.getConfigHolder(InventoryConfig.class).getConfig(); - return config.configKeys.key0; - } - - public static int getKey1() { - InventoryConfig config = AutoConfig.getConfigHolder(InventoryConfig.class).getConfig(); - return config.configKeys.key1; - } - - public static int getKey2() { - InventoryConfig config = AutoConfig.getConfigHolder(InventoryConfig.class).getConfig(); - return config.configKeys.key2; - } - - public static int getKey3() { - InventoryConfig config = AutoConfig.getConfigHolder(InventoryConfig.class).getConfig(); - return config.configKeys.key3; - } - - public static int getKey4() { - InventoryConfig config = AutoConfig.getConfigHolder(InventoryConfig.class).getConfig(); - return config.configKeys.key4; - } - - public static int getKey5() { - InventoryConfig config = AutoConfig.getConfigHolder(InventoryConfig.class).getConfig(); - return config.configKeys.key5; - } - - public static int getKey6() { - InventoryConfig config = AutoConfig.getConfigHolder(InventoryConfig.class).getConfig(); - return config.configKeys.key6; - } - - public static int getKey7() { - InventoryConfig config = AutoConfig.getConfigHolder(InventoryConfig.class).getConfig(); - return config.configKeys.key7; - } - - public static int getKey8() { - InventoryConfig config = AutoConfig.getConfigHolder(InventoryConfig.class).getConfig(); - return config.configKeys.key8; - } - - public static int getKey9() { - InventoryConfig config = AutoConfig.getConfigHolder(InventoryConfig.class).getConfig(); - return config.configKeys.key9; - } - - public static int getKeySurvPrevTab() { - InventoryConfig config = AutoConfig.getConfigHolder(InventoryConfig.class).getConfig(); - return config.survival.keySurvPrevTab; - } - - public static int getKeySurvNextTab() { - InventoryConfig config = AutoConfig.getConfigHolder(InventoryConfig.class).getConfig(); - return config.survival.keySurvNextTab; - } - - public static int getKeySurvRecipes() { - InventoryConfig config = AutoConfig.getConfigHolder(InventoryConfig.class).getConfig(); - return config.survival.keySurvRecipes; - } - - public static int getKeySurvCraftable() { - InventoryConfig config = AutoConfig.getConfigHolder(InventoryConfig.class).getConfig(); - return config.survival.keySurvCraftable; - } - - public static int getkeySurvPrevPage() { - InventoryConfig config = AutoConfig.getConfigHolder(InventoryConfig.class).getConfig(); - return config.survival.keySurvPrevPage; - } - - public static int getkeySurvNextPage() { - InventoryConfig config = AutoConfig.getConfigHolder(InventoryConfig.class).getConfig(); - return config.survival.keySurvNextPage; - } - - public static int getKeySurvOutput() { - InventoryConfig config = AutoConfig.getConfigHolder(InventoryConfig.class).getConfig(); - return config.survival.keySurvOutput; - } - - public static int getKeyPrev() { - InventoryConfig config = AutoConfig.getConfigHolder(InventoryConfig.class).getConfig(); - return config.navKeys.keyPrev; - } - - public static int getKeyNext() { - InventoryConfig config = AutoConfig.getConfigHolder(InventoryConfig.class).getConfig(); - return config.navKeys.keyNext; - } - - public static int getKeyNextItemRow() { - InventoryConfig config = AutoConfig.getConfigHolder(InventoryConfig.class).getConfig(); - return config.navKeys.keyNextItemRow; - } - - public static int getKeyNextItemCol() { - InventoryConfig config = AutoConfig.getConfigHolder(InventoryConfig.class).getConfig(); - return config.navKeys.keyNextItemCol; - } - - public static int getKeyScrollUp() { - InventoryConfig config = AutoConfig.getConfigHolder(InventoryConfig.class).getConfig(); - return config.navKeys.keyScrollUp; - } - - public static int getKeyScrollDown() { - InventoryConfig config = AutoConfig.getConfigHolder(InventoryConfig.class).getConfig(); - return config.navKeys.keyScrollDown; - } - - public static int getKeySearch() { - InventoryConfig config = AutoConfig.getConfigHolder(InventoryConfig.class).getConfig(); - return config.navKeys.keySearch; - } - - public static int getKeyDrop() { - InventoryConfig config = AutoConfig.getConfigHolder(InventoryConfig.class).getConfig(); - return config.navKeys.keyDrop; - } +public class InventoryConfigImpl implements IInventoryConfigService { + private InventoryConfig getConfig() { + return AutoConfig.getConfigHolder(InventoryConfig.class).getConfig(); + } + + @Override public int getKey0() { return getConfig().configKeys.key0; } + @Override public int getKey1() { return getConfig().configKeys.key1; } + @Override public int getKey2() { return getConfig().configKeys.key2; } + @Override public int getKey3() { return getConfig().configKeys.key3; } + @Override public int getKey4() { return getConfig().configKeys.key4; } + @Override public int getKey5() { return getConfig().configKeys.key5; } + @Override public int getKey6() { return getConfig().configKeys.key6; } + @Override public int getKey7() { return getConfig().configKeys.key7; } + @Override public int getKey8() { return getConfig().configKeys.key8; } + @Override public int getKey9() { return getConfig().configKeys.key9; } + @Override public int getKeySurvPrevTab() { return getConfig().survival.keySurvPrevTab; } + @Override public int getKeySurvNextTab() { return getConfig().survival.keySurvNextTab; } + @Override public int getKeySurvRecipes() { return getConfig().survival.keySurvRecipes; } + @Override public int getKeySurvCraftable() { return getConfig().survival.keySurvCraftable; } + @Override public int getkeySurvPrevPage() { return getConfig().survival.keySurvPrevPage; } + @Override public int getkeySurvNextPage() { return getConfig().survival.keySurvNextPage; } + @Override public int getKeySurvOutput() { return getConfig().survival.keySurvOutput; } + @Override public int getKeyPrev() { return getConfig().navKeys.keyPrev; } + @Override public int getKeyNext() { return getConfig().navKeys.keyNext; } + @Override public int getKeyNextItemRow() { return getConfig().navKeys.keyNextItemRow; } + @Override public int getKeyNextItemCol() { return getConfig().navKeys.keyNextItemCol; } + @Override public int getKeyScrollUp() { return getConfig().navKeys.keyScrollUp; } + @Override public int getKeyScrollDown() { return getConfig().navKeys.keyScrollDown; } + @Override public int getKeySearch() { return getConfig().navKeys.keySearch; } + @Override public int getKeyDrop() { return getConfig().navKeys.keyDrop; } } diff --git a/fabric/src/main/resources/META-INF/services/com.specialeffect.eyemine.packets.NetworkService b/fabric/src/main/resources/META-INF/services/com.specialeffect.eyemine.packets.NetworkService new file mode 100644 index 00000000..aa6877d9 --- /dev/null +++ b/fabric/src/main/resources/META-INF/services/com.specialeffect.eyemine.packets.NetworkService @@ -0,0 +1 @@ +com.specialeffect.eyemine.platform.fabric.FabricNetworkService diff --git a/fabric/src/main/resources/META-INF/services/com.specialeffect.eyemine.platform.services.IEyeMineConfigService b/fabric/src/main/resources/META-INF/services/com.specialeffect.eyemine.platform.services.IEyeMineConfigService new file mode 100644 index 00000000..ad2caad9 --- /dev/null +++ b/fabric/src/main/resources/META-INF/services/com.specialeffect.eyemine.platform.services.IEyeMineConfigService @@ -0,0 +1 @@ +com.specialeffect.eyemine.platform.fabric.EyeMineConfigImpl diff --git a/fabric/src/main/resources/META-INF/services/com.specialeffect.eyemine.platform.services.IInventoryConfigService b/fabric/src/main/resources/META-INF/services/com.specialeffect.eyemine.platform.services.IInventoryConfigService new file mode 100644 index 00000000..53729a40 --- /dev/null +++ b/fabric/src/main/resources/META-INF/services/com.specialeffect.eyemine.platform.services.IInventoryConfigService @@ -0,0 +1 @@ +com.specialeffect.eyemine.platform.fabric.InventoryConfigImpl diff --git a/fabric/src/main/resources/META-INF/services/com.specialeffect.eyemine.platform.services.IPlatformHelper b/fabric/src/main/resources/META-INF/services/com.specialeffect.eyemine.platform.services.IPlatformHelper new file mode 100644 index 00000000..52395038 --- /dev/null +++ b/fabric/src/main/resources/META-INF/services/com.specialeffect.eyemine.platform.services.IPlatformHelper @@ -0,0 +1 @@ +com.specialeffect.eyemine.platform.fabric.FabricPlatformHelper diff --git a/fabric/src/main/resources/eyemine.fabric.mixins.json b/fabric/src/main/resources/eyemine.fabric.mixins.json new file mode 100644 index 00000000..603aed09 --- /dev/null +++ b/fabric/src/main/resources/eyemine.fabric.mixins.json @@ -0,0 +1,13 @@ +{ + "required": true, + "minVersion": "0.8", + "package": "com.specialeffect.eyemine.mixin", + "compatibilityLevel": "JAVA_25", + "client": [ + "FabricKeyboardHandlerMixin", + "FabricSetScreenMixin" + ], + "injectors": { + "defaultRequire": 1 + } +} diff --git a/fabric/src/main/resources/fabric.mod.json b/fabric/src/main/resources/fabric.mod.json index f20e127b..d387356d 100644 --- a/fabric/src/main/resources/fabric.mod.json +++ b/fabric/src/main/resources/fabric.mod.json @@ -1,9 +1,9 @@ { "schemaVersion": 1, - "id": "eyemine", + "id": "${mod_id}", "version": "${version}", - "name": "EyeMine", - "description": "EyeMine by SpecialEffect allows you to play Minecraft using eye gaze.\nIt is designed to work alongside the EyeMine gaze-controlled keyboard. \nFor questions or support, contact eyemine@specialeffect.org.uk", + "name": "${mod_name}", + "description": "${description}", "authors": [ "Kirsty McNaught", "Mrbysco" ], @@ -11,7 +11,7 @@ "homepage": "https://www.specialeffect.org.uk/eyemine", "sources": "https://github.com/SpecialEffect/SpecialEffectMinecraftMods" }, - "license": "GPL-3.0", + "license": "${license}", "icon": "eyemine_logo.png", "environment": "*", "entrypoints": { @@ -20,20 +20,17 @@ ], "client": [ "com.specialeffect.eyemine.EyeMineClientFabric" - ], - "modmenu": [ - "com.specialeffect.eyemine.config.EyeMineModMenuIntegration" ] }, "mixins": [ - "eyemine-common.mixins.json" + "eyemine-common.mixins.json", + "eyemine.fabric.mixins.json" ], "depends": { - "fabricloader": ">=0.15.11", - "minecraft": "~1.21", - "java": ">=21", + "fabricloader": ">=${fabric_loader_version}", + "minecraft": "~${minecraft_version}", + "java": ">=${java_version}", "fabric-api": "*", - "cloth-config": ">=14", - "architectury": ">=13" + "cloth-config": ">=14" } -} \ No newline at end of file +} diff --git a/forge/build.gradle b/forge/build.gradle deleted file mode 100644 index 7c49d846..00000000 --- a/forge/build.gradle +++ /dev/null @@ -1,91 +0,0 @@ -plugins { - id "com.github.johnrengelman.shadow" version "8.1.1" -} - -architectury { - platformSetupLoomIde() - forge() -} - -loom { - accessWidenerPath = project(":common").loom.accessWidenerPath - - forge { - convertAccessWideners = true - extraAccessWideners.add loom.accessWidenerPath.get().asFile.name - - mixinConfig "eyemine-common.mixins.json" - } -} - -configurations { - common - shadowCommon // Don't use shadow from the shadow plugin since it *excludes* files. - compileClasspath.extendsFrom common - runtimeClasspath.extendsFrom common - developmentForge.extendsFrom common -} - -dependencies { - forge "net.minecraftforge:forge:${rootProject.minecraft_version}-${rootProject.forge_version}" - // Remove the next line if you don't want to depend on the API - modApi "dev.architectury:architectury-forge:${rootProject.architectury_version}" - - common(project(path: ":common", configuration: "namedElements")) { transitive false } - shadowCommon(project(path: ":common", configuration: "transformProductionForge")) { transitive = false } - - modCompileOnly("curse.maven:configured-457570:5105022") -} - -processResources { - inputs.property "version", project.version - - filesMatching("META-INF/mods.toml") { - expand "version": project.version - } -} - -shadowJar { - exclude "fabric.mod.json" - exclude "eyemine.common.json" - - configurations = [project.configurations.shadowCommon] - archiveClassifier.set("dev-shadow") -} - -remapJar { - input.set shadowJar.archiveFile - dependsOn shadowJar - archiveBaseName.set "${rootProject.archives_base_name}-${project.minecraft_version}-${project.name}" - archiveClassifier.set('') -} - -jar { - archiveClassifier.set("dev") -} - -sourcesJar { - def commonSources = project(":common").sourcesJar - dependsOn commonSources - from commonSources.archiveFile.map { zipTree(it) } -} - -components.java { - withVariantsFromConfiguration(project.configurations.shadowRuntimeElements) { - skip() - } -} - -publishing { - publications { - mavenForge(MavenPublication) { - artifactId = rootProject.archives_base_name + "-" + project.name - from components.java - } - } - - // See https://docs.gradle.org/current/userguide/publishing_maven.html for information on how to set up publishing. - repositories { - // Add repositories to publish to here. - } -} diff --git a/forge/gradle.properties b/forge/gradle.properties deleted file mode 100644 index 32f842a6..00000000 --- a/forge/gradle.properties +++ /dev/null @@ -1 +0,0 @@ -loom.platform=forge \ No newline at end of file diff --git a/forge/src/main/java/com/inventory/config/InventoryConfig.java b/forge/src/main/java/com/inventory/config/InventoryConfig.java deleted file mode 100644 index b4e7450a..00000000 --- a/forge/src/main/java/com/inventory/config/InventoryConfig.java +++ /dev/null @@ -1,136 +0,0 @@ -/** - * Copyright (C) 2016-2020 Kirsty McNaught - *

- * Developed for SpecialEffect, www.specialeffect.org.uk - *

- * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 3 - * of the License, or (at your option) any later version. - */ - -package com.inventory.config; - -import com.electronwill.nightconfig.core.file.CommentedFileConfig; -import com.electronwill.nightconfig.core.io.WritingMode; -import net.minecraftforge.common.ForgeConfigSpec; -import net.minecraftforge.common.ForgeConfigSpec.ConfigValue; -import net.minecraftforge.eventbus.api.SubscribeEvent; -import net.minecraftforge.fml.event.config.ModConfigEvent; -import org.apache.logging.log4j.LogManager; -import org.apache.logging.log4j.Logger; -import org.lwjgl.glfw.GLFW; - -import java.nio.file.Path; - -public class InventoryConfig { - // Based on McJty/YouTubeModding14 tutorial, MIT license: - // https://github.com/McJty/YouTubeModding14/blob/master/LICENSE - - // Directly reference a log4j logger. - private static final Logger LOGGER = LogManager.getLogger(); - - public static final String CATEGORY_GENERAL = "general"; - - private static final ForgeConfigSpec.Builder CLIENT_BUILDER = new ForgeConfigSpec.Builder(); - - public static ForgeConfigSpec CLIENT_CONFIG; - - public static ConfigValue key0, key1, key2, key3, key4, - key5, key6, key7, key8, key9, - keyNext, keyPrev, keySearch, - keyScrollUp, keyScrollDown, - keyNextItemRow, keyNextItemCol, keyDrop; - - public static ConfigValue keySurvNextTab, keySurvPrevTab, keySurvRecipes, keySurvCraftable, - keySurvPrevPage, keySurvNextPage, keySurvOutput; - - - static { - CLIENT_BUILDER.comment("Inventory shortcut keys").push("Keys"); - setupConfigKeys(); - CLIENT_BUILDER.pop(); - - CLIENT_BUILDER.comment("Navigation keys").push("Keys"); - setupNavKeys(); - CLIENT_BUILDER.pop(); - - CLIENT_BUILDER.comment("Survival inventory keys").push("Keys"); - setupSurvivalKeys(); - CLIENT_BUILDER.pop(); - - CLIENT_CONFIG = CLIENT_BUILDER.build(); - } - - - private static void setupSurvivalKeys() { - - keySurvPrevTab = CLIENT_BUILDER.comment("recipes: prev tab").define("keySurvPrevTab", GLFW.GLFW_KEY_KP_0); - keySurvNextTab = CLIENT_BUILDER.comment("recipes: next tab").define("keySurvNextTab", GLFW.GLFW_KEY_KP_1); - - keySurvRecipes = CLIENT_BUILDER.comment("open/close recipe book").define("keySurvRecipes", GLFW.GLFW_KEY_KP_2); - keySurvCraftable = CLIENT_BUILDER.comment("toggle all/craftable").define("keySurvCraftable", GLFW.GLFW_KEY_KP_3); - - keySurvPrevPage = CLIENT_BUILDER.comment("recipes: prev page").define("keySurvPrevPage", GLFW.GLFW_KEY_KP_4); - keySurvNextPage = CLIENT_BUILDER.comment("recipes: next page").define("keySurvNextPage", GLFW.GLFW_KEY_KP_5); - - keySurvOutput = CLIENT_BUILDER.comment("hover output").define("keySurvOutput", GLFW.GLFW_KEY_KP_6); - - } - - private static void setupConfigKeys() { - - key0 = CLIENT_BUILDER.comment("key0").define("key0", GLFW.GLFW_KEY_KP_0); - key1 = CLIENT_BUILDER.comment("key1").define("key1", GLFW.GLFW_KEY_KP_1); - key2 = CLIENT_BUILDER.comment("key2").define("key2", GLFW.GLFW_KEY_KP_2); - key3 = CLIENT_BUILDER.comment("key3").define("key3", GLFW.GLFW_KEY_KP_3); - key4 = CLIENT_BUILDER.comment("key4").define("key4", GLFW.GLFW_KEY_KP_4); - key5 = CLIENT_BUILDER.comment("key5").define("key5", GLFW.GLFW_KEY_KP_5); - key6 = CLIENT_BUILDER.comment("key6").define("key6", GLFW.GLFW_KEY_KP_6); - key7 = CLIENT_BUILDER.comment("key7").define("key7", GLFW.GLFW_KEY_KP_7); - key8 = CLIENT_BUILDER.comment("key8").define("key8", GLFW.GLFW_KEY_KP_8); - key9 = CLIENT_BUILDER.comment("key9").define("key9", GLFW.GLFW_KEY_KP_9); - - } - - private static void setupNavKeys() { - - keyPrev = CLIENT_BUILDER.comment("keyPrev").define("keyPrev", GLFW.GLFW_KEY_LEFT); - keyNext = CLIENT_BUILDER.comment("keyNext").define("keyNext", GLFW.GLFW_KEY_RIGHT); - keyNextItemRow = CLIENT_BUILDER.comment("keyNextItemRow").define("keyNextItemRow", GLFW.GLFW_KEY_F6); - keyNextItemCol = CLIENT_BUILDER.comment("keyNextItemCol").define("keyNextItemCol", GLFW.GLFW_KEY_F7); - - keyScrollUp = CLIENT_BUILDER.comment("keyScrollUp").define("keyScrollUp", GLFW.GLFW_KEY_F8); - keyScrollDown = CLIENT_BUILDER.comment("keyScrollDown").define("keyScrollDown", GLFW.GLFW_KEY_F9); - - keySearch = CLIENT_BUILDER.comment("keySearch").define("keySearch", GLFW.GLFW_KEY_DOWN); - keyDrop = CLIENT_BUILDER.comment("keyDrop2").define("keyDrop2", GLFW.GLFW_KEY_MINUS); - } - - public static void loadConfig(ForgeConfigSpec spec, Path path) { - - final CommentedFileConfig configData = CommentedFileConfig.builder(path) - .sync() - .autosave() - .writingMode(WritingMode.REPLACE) - .build(); - - configData.load(); - spec.setConfig(configData); - } - - @SubscribeEvent - public static void onLoad(final ModConfigEvent.Loading configEvent) { - LOGGER.info("Inventory config onLoad"); - } - - @SubscribeEvent - public static void onReload(final ModConfigEvent.Reloading configEvent) { - LOGGER.info("Inventory config onReload"); - - if (configEvent.getConfig() != null && configEvent.getConfig().getSpec() == CLIENT_CONFIG) { - // the configspec values are updated for us, but we may want to hook into here too? - } - } - -} \ No newline at end of file diff --git a/forge/src/main/java/com/specialeffect/eyemine/client/forge/ClientHandler.java b/forge/src/main/java/com/specialeffect/eyemine/client/forge/ClientHandler.java deleted file mode 100644 index 13d4c26d..00000000 --- a/forge/src/main/java/com/specialeffect/eyemine/client/forge/ClientHandler.java +++ /dev/null @@ -1,28 +0,0 @@ -/** - * Copyright (C) 2016-2020 Kirsty McNaught - *

- * Developed for SpecialEffect, www.specialeffect.org.uk - *

- * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 3 - * of the License, or (at your option) any later version. - */ - -package com.specialeffect.eyemine.client.forge; - -import com.specialeffect.eyemine.EyeMineClient; -import com.specialeffect.eyemine.event.BlockOutlineEvent; -import net.minecraftforge.client.event.RenderHighlightEvent; -import net.minecraftforge.fml.event.lifecycle.FMLCommonSetupEvent; - -public class ClientHandler { - public static void setup(final FMLCommonSetupEvent event) { - EyeMineClient.setupComplete = true; - EyeMineClient.refresh(); - } - - public static void onOutlineRender(RenderHighlightEvent.Block event) { - BlockOutlineEvent.OUTLINE.invoker().renderOutline(event.getMultiBufferSource(), event.getPoseStack()); - } -} diff --git a/forge/src/main/java/com/specialeffect/eyemine/config/EyeMineConfig.java b/forge/src/main/java/com/specialeffect/eyemine/config/EyeMineConfig.java deleted file mode 100644 index 770a5eea..00000000 --- a/forge/src/main/java/com/specialeffect/eyemine/config/EyeMineConfig.java +++ /dev/null @@ -1,281 +0,0 @@ -/** - * Copyright (C) 2016-2020 Kirsty McNaught - *

- * Developed for SpecialEffect, www.specialeffect.org.uk - *

- * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 3 - * of the License, or (at your option) any later version. - */ - -package com.specialeffect.eyemine.config; - -import com.electronwill.nightconfig.core.file.CommentedFileConfig; -import com.electronwill.nightconfig.core.io.ParsingMode; -import com.electronwill.nightconfig.core.io.WritingMode; -import com.specialeffect.eyemine.EyeMine; -import com.specialeffect.eyemine.EyeMineClient; -import net.minecraftforge.common.ForgeConfigSpec; -import net.minecraftforge.eventbus.api.SubscribeEvent; -import net.minecraftforge.fml.event.config.ModConfigEvent; - -import java.nio.file.Path; - -public class EyeMineConfig { - // Based on McJty/YouTubeModding14 tutorial, MIT license: - // https://github.com/McJty/YouTubeModding14/blob/master/LICENSE - - // Category names for clustering config options in different UIs - public static final String CATEGORY_BASIC = "basic"; - public static final String CATEGORY_ADVANCED = "advanced"; - public static final String CATEGORY_MOVING = "moving"; - public static final String CATEGORY_DWELLING = "dwelling"; - - public static final String CATEGORY_BASIC_USERSTRING = "Basic options"; - public static final String CATEGORY_ADVANCED_USERSTRING = "Advanced options"; - public static final String CATEGORY_MOVING_USERSTRING = "Moving options"; - public static final String CATEGORY_DWELLING_USERSTRING = "Dwelling options"; - - private static final ForgeConfigSpec.Builder CLIENT_BUILDER = new ForgeConfigSpec.Builder(); - public static ForgeConfigSpec CLIENT_CONFIG; - - // Flying options - public static ForgeConfigSpec.IntValue flyHeightManual; - public static ForgeConfigSpec.IntValue flyHeightAuto; - - // Walking options -> walk with gaze - public static ForgeConfigSpec.IntValue walkingSlowdownFilter; - public static ForgeConfigSpec.BooleanValue moveWhenMouseStationary; - public static ForgeConfigSpec.DoubleValue customSpeedFactor; - public static ForgeConfigSpec.IntValue gazeIdleThreshold; - - public static ForgeConfigSpec.BooleanValue slowdownOnCorners; - public static ForgeConfigSpec.BooleanValue slowdownOnAttack; - - public static ForgeConfigSpec.BooleanValue allowLadderDescent; - - // Boats - public static ForgeConfigSpec.DoubleValue boatSlowdown; - public static ForgeConfigSpec.IntValue boatMaxTurnAtSpeed; - - // AutoJump - public static ForgeConfigSpec.BooleanValue defaultDoAutoJump; - public static ForgeConfigSpec.BooleanValue disableAutoJumpFixes; - - // MouseHandler options - public static ForgeConfigSpec.BooleanValue usingMouseEmulation; - - // Mining - public static ForgeConfigSpec.BooleanValue autoSelectTool; - public static ForgeConfigSpec.IntValue ticksBetweenMining; - public static ForgeConfigSpec.BooleanValue serverCompatibilityMode; - - // AutoOpenDoors - public static ForgeConfigSpec.IntValue radiusDoors; - - // OpenTablesChests - public static ForgeConfigSpec.IntValue radiusChests; - - // ContinuouslyAttack - public static ForgeConfigSpec.BooleanValue autoSelectSword; - - // Dwelling options - public static ForgeConfigSpec.DoubleValue dwellTimeSeconds; - public static ForgeConfigSpec.DoubleValue dwellLockonTimeSeconds; - public static ForgeConfigSpec.BooleanValue dwellShowExpanding; - public static ForgeConfigSpec.BooleanValue dwellShowWithTransparency; - public static ForgeConfigSpec.BooleanValue useDwellForSingleMine; - public static ForgeConfigSpec.BooleanValue useDwellForSingleUseItem; - - // Ironsights - public static ForgeConfigSpec.DoubleValue ironsightsSensitivityReduction; - public static ForgeConfigSpec.IntValue ironsightsFovReduction; - - // Bow and arrow - public static ForgeConfigSpec.DoubleValue bowDrawTime; - - // Graphics - public static ForgeConfigSpec.DoubleValue fullscreenOverlayAlpha; - - // Create World - public static ForgeConfigSpec.BooleanValue disableCustomNewWorld; - - static { - CLIENT_BUILDER.comment(CATEGORY_BASIC_USERSTRING).push(CATEGORY_BASIC); - setupBasicConfig(); - CLIENT_BUILDER.pop(); - - CLIENT_BUILDER.comment(CATEGORY_ADVANCED_USERSTRING).push(CATEGORY_ADVANCED); - setupAdvancedConfig(); - CLIENT_BUILDER.pop(); - - CLIENT_BUILDER.comment(CATEGORY_MOVING_USERSTRING).push(CATEGORY_MOVING); - setupMovingConfig(); - CLIENT_BUILDER.pop(); - - CLIENT_BUILDER.comment(CATEGORY_DWELLING_USERSTRING).push(CATEGORY_DWELLING); - setupDwellConfig(); - CLIENT_BUILDER.pop(); - - CLIENT_CONFIG = CLIENT_BUILDER.build(); - } - - private static void setupBasicConfig() { - customSpeedFactor = CLIENT_BUILDER.comment("Walking speed for walk-with-gaze").defineInRange("walkingSpeed", - 0.6, 0.25, 2.0); - - defaultDoAutoJump = CLIENT_BUILDER.comment("Auto-jump switched on by default?") - .define("defaultDoAutoJump", true); - - disableAutoJumpFixes = CLIENT_BUILDER.comment("Disable Auto-Jump Fixes" + - "(EyeMine's extra Auto-Jump fixes can cause problems on servers, " + - "if you notice yourself being teleported back enable this option)") - .define("disableAutoJumpFixes", false); - - usingMouseEmulation = CLIENT_BUILDER.comment( - "Enable mouse-emulation compatibility mode?.\nTurn this on if you're using mouse position as an input to EyeMine") - .define("usingMouseEmulation", false); - - autoSelectSword = CLIENT_BUILDER.comment( - "When attacking, do you want a sword selected automatically?\nThis only applies in Creative Mode.") - .define("autoSelectSword", true); - - autoSelectTool = CLIENT_BUILDER - .comment( - "When mining, do you want pickaxe selected automatically?\nThis only applies in Creative Mode.") - .define("autoSelectTool", true); - - } - - private static void setupAdvancedConfig() { - - disableCustomNewWorld = CLIENT_BUILDER - .comment("Disable the custom new world screen and the defaults it applies to every world") - .define("disableCustomNewWorld", false); - - // This is limited to 6 blocks since the gui doesn't appear if block is too far - // away - radiusChests = CLIENT_BUILDER - .comment("How far away a player needs to be from a chest/table to be able to open it") - .defineInRange("radiusChests", 5, 1, 6); - - radiusDoors = CLIENT_BUILDER.comment( - "How far away a player needs to be from a door to automatically open/close.\nSet to zero to turn off automatic door-opening") - .defineInRange("radiusDoors", 2, 0, 10); - - ticksBetweenMining = CLIENT_BUILDER - .comment("How many ticks to wait before mining again\nOnly affects creative mode") - .defineInRange("ticksBetweenMining", 15, 0, 50); - - // Ironsights - ironsightsFovReduction = CLIENT_BUILDER - .comment("How much to reduce field of view (degrees) when using ironsights") - .defineInRange("ironsightsFovReduction", 20, 0, 40); - - ironsightsSensitivityReduction = CLIENT_BUILDER - .comment("How much to reduce sensitivity (%) when using ironsights") - .defineInRange("ironsightsSensitivityReduction", 13.0, 0.0, 30.0); - - // Bow-firing - bowDrawTime = CLIENT_BUILDER.comment("How long (seconds) to keep bow drawn for when firing with 'Use Item'") - .defineInRange("bowDrawTime", 1.0, 0.5, 5.0); - - fullscreenOverlayAlpha = CLIENT_BUILDER - .comment("Opacity of full-screen overlays (look, careful walk)") - .defineInRange("fullscreenOverlayAlpha", 0.1, 0.0, 0.2); - - serverCompatibilityMode = CLIENT_BUILDER - .comment("Use simpler mining/placing logic to play on servers without EyeMine installed") - .define("serverCompatibilityMode", false); - - } - - private static void setupMovingConfig() { - - slowdownOnCorners = CLIENT_BUILDER - .comment("Slow down auto-walk when going round a corner\nYou may want to turn this off for survival") - .define("slowdownOnCorners", true); - - walkingSlowdownFilter = CLIENT_BUILDER.comment( - "How many ticks to take into account for slowing down while looking around / turning corners.\n(smaller number = faster, 20 = 1 second)") - .defineInRange("walkingSlowdownFilter", 20, 1, 200); - - moveWhenMouseStationary = CLIENT_BUILDER.comment( - "Continue walking forward when the mouse is stationary?\nRecommended to be turned off for eye gaze control, or turned on for joysticks.") - .define("moveWhenMouseStationary", false); - - gazeIdleThreshold = CLIENT_BUILDER.comment( - "Percentage of screen height from bottom where gaze pauses walking\n(for looking at onboard keyboard). 0 = disabled, 10 = bottom 10% of screen") - .defineInRange("gazeIdleThreshold", 10, 0, 50); - - slowdownOnAttack = CLIENT_BUILDER.comment( - "Slow down auto-walk when attacking an entity\nThis only applies when your crosshair is over an entity, and makes\nit easier to chase mobs") - .define("slowdownOnAttack", true); - - flyHeightManual = CLIENT_BUILDER.comment("How high to fly (up/down) in manual mode") - .defineInRange("flyHeightManual", 2, 1, 20); - - flyHeightAuto = CLIENT_BUILDER.comment("How high to fly in auto mode").defineInRange("flyHeightAuto", 6, 1, 10); - - allowLadderDescent = CLIENT_BUILDER.comment( - "Descend ladders by looking down while moving. \n Experimental; may cause problems getting on/off ladders.") - .define("allowLadderDescent", false); - - // Boats - boatSlowdown = CLIENT_BUILDER - .comment("Slowdown applied to forward motion of boats (lower is slower)") - .defineInRange("boatSlowdown", 0.5, 0.01, 1.0); - - boatMaxTurnAtSpeed = CLIENT_BUILDER - .comment("Maximum angle (degrees) at which boat will still travel forwards while turning") - .defineInRange("boatMaxTurnAtSpeed", 30, 1, 90); - } - - private static void setupDwellConfig() { - - dwellTimeSeconds = CLIENT_BUILDER.comment("Time for dwell to complete (seconds)") - .defineInRange("dwellTimeSeconds", 1.2, 0.2, 5.0); - - dwellLockonTimeSeconds = CLIENT_BUILDER - .comment("Time for dwell to lock on (seconds)\n Must be lower than dwellTimeSeconds") - .defineInRange("dwellLockonTimeSeconds", 0.2, 0.0, 1.0); - - dwellShowExpanding = CLIENT_BUILDER.comment("Show dwell expanding instead of shrinking") - .define("dwellShowExpanding", false); - - dwellShowWithTransparency = CLIENT_BUILDER.comment( - "Show dwell by changing transparency instead of growing/shrinking\nThis option overrides dwellShowExpanding") - .define("dwellShowWithTransparency", false); - - useDwellForSingleMine = CLIENT_BUILDER.comment("Use dwell for 'mine once' (creative only)") - .define("useDwellForSingleMine", false); - - useDwellForSingleUseItem = CLIENT_BUILDER.comment("Use dwell for single 'use item'") - .define("useDwellForSingleUseItem", false); - - } - - public static void loadConfig(ForgeConfigSpec spec, Path path) { - final CommentedFileConfig configData = CommentedFileConfig.builder(path).preserveInsertionOrder().sync() - .autosave().writingMode(WritingMode.REPLACE).parsingMode(ParsingMode.ADD).concurrent().build(); - - configData.load(); - spec.setConfig(configData); - } - - @SubscribeEvent - public static void onLoad(final ModConfigEvent.Loading configEvent) { - EyeMine.LOGGER.debug("EyeMine config onLoad"); - } - - @SubscribeEvent - public static void onReload(final ModConfigEvent.Reloading configEvent) { - // the configspec values are updated for us, but we may want to hook into - // here to notify other mods? - EyeMine.LOGGER.info("EyeMine config onReload"); - - EyeMineClient.refresh(); - } - -} \ No newline at end of file diff --git a/forge/src/main/java/com/specialeffect/eyemine/forge/EyeMineForge.java b/forge/src/main/java/com/specialeffect/eyemine/forge/EyeMineForge.java deleted file mode 100644 index 0311d323..00000000 --- a/forge/src/main/java/com/specialeffect/eyemine/forge/EyeMineForge.java +++ /dev/null @@ -1,53 +0,0 @@ -package com.specialeffect.eyemine.forge; - -import com.inventory.config.InventoryConfig; -import com.specialeffect.eyemine.EyeMine; -import com.specialeffect.eyemine.EyeMineClient; -import com.specialeffect.eyemine.client.forge.ClientHandler; -import com.specialeffect.eyemine.config.EyeMineConfig; -import dev.architectury.platform.forge.EventBuses; -import net.minecraftforge.api.distmarker.Dist; -import net.minecraftforge.common.MinecraftForge; -import net.minecraftforge.eventbus.api.IEventBus; -import net.minecraftforge.fml.DistExecutor; -import net.minecraftforge.fml.IExtensionPoint; -import net.minecraftforge.fml.IExtensionPoint.DisplayTest; -import net.minecraftforge.fml.ModLoadingContext; -import net.minecraftforge.fml.common.Mod; -import net.minecraftforge.fml.config.ModConfig; -import net.minecraftforge.fml.javafmlmod.FMLJavaModLoadingContext; - -@Mod(EyeMine.MOD_ID) -public class EyeMineForge { - public EyeMineForge() { - - // Submit our event bus to let architectury register our content on the right time - IEventBus eventBus = FMLJavaModLoadingContext.get().getModEventBus(); - - // Config setup - ModLoadingContext.get().registerConfig(ModConfig.Type.CLIENT, EyeMineConfig.CLIENT_CONFIG, "eyemine-config.toml"); - eventBus.register(EyeMineConfig.class); - ModLoadingContext.get().registerConfig(ModConfig.Type.CLIENT, InventoryConfig.CLIENT_CONFIG, "eyemine-inventory-config.toml"); - eventBus.register(InventoryConfig.class); - - EventBuses.registerModEventBus(EyeMine.MOD_ID, eventBus); - EyeMine.init(); - - //Make sure the mod being absent on the other network side does not cause the client to display the server as incompatible - ModLoadingContext.get().registerExtensionPoint(DisplayTest.class, () -> - new IExtensionPoint.DisplayTest(() -> "Everyone is valid", - (remoteVersionString, networkBool) -> networkBool)); - - DistExecutor.unsafeRunWhenOn(Dist.CLIENT, () -> () -> { - // Hook up config gui -// ModLoadingContext.get().registerExtensionPoint(ExtensionPoint.CONFIGGUIFACTORY, () -> ClientHandler::openSettings); - - // Register this setup method *after* children have registered theirs - // (this way the children will be fully set up before any config gets loaded) - FMLJavaModLoadingContext.get().getModEventBus().addListener(ClientHandler::setup); - - MinecraftForge.EVENT_BUS.addListener(ClientHandler::onOutlineRender); - EyeMineClient.init(); - }); - } -} diff --git a/forge/src/main/java/com/specialeffect/eyemine/platform/forge/EyeMineConfigImpl.java b/forge/src/main/java/com/specialeffect/eyemine/platform/forge/EyeMineConfigImpl.java deleted file mode 100644 index eeb6f1ad..00000000 --- a/forge/src/main/java/com/specialeffect/eyemine/platform/forge/EyeMineConfigImpl.java +++ /dev/null @@ -1,133 +0,0 @@ -package com.specialeffect.eyemine.platform.forge; - -import com.specialeffect.eyemine.config.EyeMineConfig; - -public class EyeMineConfigImpl { - public static boolean getDisableCustomNewWorld() { - return EyeMineConfig.disableCustomNewWorld.get(); - } - - public static void setCustomSpeedFactor(float speed) { - EyeMineConfig.customSpeedFactor.set((double) speed); - } - - public static boolean getUsingMouseEmulation() { - return EyeMineConfig.usingMouseEmulation.get(); - } - - public static boolean getAutoSelectTool() { - return EyeMineConfig.autoSelectTool.get(); - } - - public static boolean getAutoSelectSword() { - return EyeMineConfig.autoSelectSword.get(); - } - - public static int getRadiusChests() { - return EyeMineConfig.radiusChests.get(); - } - - public static int getTicksBetweenMining() { - return EyeMineConfig.ticksBetweenMining.get(); - } - - public static double getBowDrawTime() { - return EyeMineConfig.bowDrawTime.get(); - } - - public static float getFullscreenOverlayAlpha() { - return EyeMineConfig.fullscreenOverlayAlpha.get().floatValue(); - } - - public static int getIronsightsFovReduction() { - return EyeMineConfig.ironsightsFovReduction.get(); - } - - public static double getIronsightsSensitivityReduction() { - return EyeMineConfig.ironsightsSensitivityReduction.get().floatValue(); - } - - public static boolean getUseDwellForSingleUseItem() { - return EyeMineConfig.useDwellForSingleUseItem.get(); - } - - public static boolean getUseDwellForSingleMine() { - return EyeMineConfig.useDwellForSingleMine.get(); - } - - public static int getRadiusDoors() { - return EyeMineConfig.radiusDoors.get(); - } - - public static boolean getServerCompatibilityMode() { - return EyeMineConfig.serverCompatibilityMode.get(); - } - - public static int getFlyHeightManual() { - return EyeMineConfig.flyHeightManual.get(); - } - - public static int getFlyHeightAuto() { - return EyeMineConfig.flyHeightAuto.get(); - } - - public static boolean getDefaultDoAutoJump() { - return EyeMineConfig.defaultDoAutoJump.get(); - } - - public static boolean getDisableAutoJumpFixes() { - return EyeMineConfig.disableAutoJumpFixes.get(); - } - - public static boolean getMoveWhenMouseStationary() { - return EyeMineConfig.moveWhenMouseStationary.get(); - } - - public static boolean getSlowdownOnCorners() { - return EyeMineConfig.slowdownOnCorners.get(); - } - - public static int getWalkingSlowdownFilter() { - return EyeMineConfig.walkingSlowdownFilter.get(); - } - - public static boolean getAllowLadderDescent() { - return EyeMineConfig.allowLadderDescent.get(); - } - - public static float getCustomSpeedFactor() { - return EyeMineConfig.customSpeedFactor.get().floatValue(); - } - - public static float getBoatMaxTurnAtSpeed() { - return EyeMineConfig.boatMaxTurnAtSpeed.get().floatValue(); - } - - public static double getBoatSlowdown() { - return EyeMineConfig.boatSlowdown.get(); - } - - public static double getDwellTimeSeconds() { - return EyeMineConfig.dwellTimeSeconds.get(); - } - - public static double getDwellLockonTimeSeconds() { - return EyeMineConfig.dwellLockonTimeSeconds.get(); - } - - public static boolean getDwellShowWithTransparency() { - return EyeMineConfig.dwellShowWithTransparency.get(); - } - - public static boolean getDwellShowExpanding() { - return EyeMineConfig.dwellShowExpanding.get(); - } - - public static boolean getSlowdownOnAttack() { - return EyeMineConfig.slowdownOnAttack.get(); - } - - public static int getGazeIdleThreshold() { - return EyeMineConfig.gazeIdleThreshold.get(); - } -} diff --git a/forge/src/main/java/com/specialeffect/eyemine/platform/forge/InventoryConfigImpl.java b/forge/src/main/java/com/specialeffect/eyemine/platform/forge/InventoryConfigImpl.java deleted file mode 100644 index e38e55bf..00000000 --- a/forge/src/main/java/com/specialeffect/eyemine/platform/forge/InventoryConfigImpl.java +++ /dev/null @@ -1,105 +0,0 @@ -package com.specialeffect.eyemine.platform.forge; - -import com.inventory.config.InventoryConfig; - -public class InventoryConfigImpl { - public static int getKey0() { - return InventoryConfig.key0.get(); - } - - public static int getKey1() { - return InventoryConfig.key1.get(); - } - - public static int getKey2() { - return InventoryConfig.key2.get(); - } - - public static int getKey3() { - return InventoryConfig.key3.get(); - } - - public static int getKey4() { - return InventoryConfig.key4.get(); - } - - public static int getKey5() { - return InventoryConfig.key5.get(); - } - - public static int getKey6() { - return InventoryConfig.key6.get(); - } - - public static int getKey7() { - return InventoryConfig.key7.get(); - } - - public static int getKey8() { - return InventoryConfig.key8.get(); - } - - public static int getKey9() { - return InventoryConfig.key9.get(); - } - - public static int getKeySurvPrevTab() { - return InventoryConfig.keySurvPrevTab.get(); - } - - public static int getKeySurvNextTab() { - return InventoryConfig.keySurvNextTab.get(); - } - - public static int getKeySurvRecipes() { - return InventoryConfig.keySurvRecipes.get(); - } - - public static int getKeySurvCraftable() { - return InventoryConfig.keySurvCraftable.get(); - } - - public static int getkeySurvPrevPage() { - return InventoryConfig.keySurvPrevPage.get(); - } - - public static int getkeySurvNextPage() { - return InventoryConfig.keySurvNextPage.get(); - } - - public static int getKeySurvOutput() { - return InventoryConfig.keySurvOutput.get(); - } - - public static int getKeyPrev() { - return InventoryConfig.keyPrev.get(); - } - - public static int getKeyNext() { - return InventoryConfig.keyNext.get(); - } - - public static int getKeyNextItemRow() { - return InventoryConfig.keyNextItemRow.get(); - } - - public static int getKeyNextItemCol() { - return InventoryConfig.keyNextItemCol.get(); - } - - public static int getKeyScrollUp() { - return InventoryConfig.keyScrollUp.get(); - } - - public static int getKeyScrollDown() { - return InventoryConfig.keyScrollDown.get(); - } - - public static int getKeySearch() { - return InventoryConfig.keySearch.get(); - } - - public static int getKeyDrop() { - return InventoryConfig.keyDrop.get(); - } -} diff --git a/forge/src/main/resources/META-INF/mods.toml b/forge/src/main/resources/META-INF/mods.toml deleted file mode 100644 index 7cab7bea..00000000 --- a/forge/src/main/resources/META-INF/mods.toml +++ /dev/null @@ -1,42 +0,0 @@ -modLoader="javafml" -loaderVersion="[49,)" -issueTrackerURL="https://github.com/SpecialEffect/SpecialEffectMinecraftMods" -license="GPL-3.0" - -[[mods]] -modId="eyemine" -version="${version}" -displayName="EyeMine" -displayURL="https://www.specialeffect.org.uk/eyemine" -authors="Kirsty McNaught" -logoFile="eyemine_logo.png" -credits = "Written in collaboration with SpecialEffect" -description=''' -EyeMine by SpecialEffect allows you to play Minecraft using eye gaze. - -It is designed to work alongside the EyeMine gaze-controlled keyboard. - -For questions or support, contact eyemine@specialeffect.org.uk -''' - -[[dependencies.eyemine]] - modId="forge" - mandatory=true - versionRange="[49,)" - ordering="NONE" - side="CLIENT" -[[dependencies.eyemine]] - modId="minecraft" - mandatory=true - versionRange="[1.20.4,1.21]" - ordering="NONE" - side="CLIENT" - - - -[[dependencies.eyemine]] -modId = "architectury" -mandatory = true -versionRange = "[11.1.13,)" -ordering = "AFTER" -side = "BOTH" \ No newline at end of file diff --git a/forge/src/main/resources/eyemine_logo.png b/forge/src/main/resources/eyemine_logo.png deleted file mode 100644 index 1cadf8fccc4c3053986fe52f7b616b1b7d9cc91b..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 6320 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 SFHe9+Nb!3B$h)+DKl%@i3a3>7 diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index 94113f20..c61a118f 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,6 +1,6 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-8.11-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-9.4.1-bin.zip networkTimeout=10000 validateDistributionUrl=true zipStoreBase=GRADLE_USER_HOME diff --git a/neoforge/build.gradle b/neoforge/build.gradle index fa83b3fd..4c9e51b2 100644 --- a/neoforge/build.gradle +++ b/neoforge/build.gradle @@ -1,92 +1,40 @@ plugins { - id "com.github.johnrengelman.shadow" version "8.1.1" + id 'multiloader-loader' + id 'net.neoforged.moddev' } -architectury { - platformSetupLoomIde() - neoForge() -} +def accessTransformerFile = project(':common').file("src/main/resources/META-INF/accesstransformer.cfg") -loom { - accessWidenerPath = project(":common").loom.accessWidenerPath +neoForge { + version = neoforge_version - neoForge { - runs { - all {} - } + if (accessTransformerFile.exists()) { + accessTransformers.from(accessTransformerFile) } -} - -configurations { - common - shadowCommon // Don't use shadow from the shadow plugin because we don't want IDEA to index this. - compileClasspath.extendsFrom common - runtimeClasspath.extendsFrom common - developmentNeoForge.extendsFrom common -} - -dependencies { - neoForge "net.neoforged:neoforge:${rootProject.neoforge_version}" - - // Remove the next line if you don't want to depend on the API - modApi "dev.architectury:architectury-neoforge:${rootProject.architectury_version}" - - common(project(path: ":common", configuration: "namedElements")) { transitive false } - shadowCommon(project(path: ":common", configuration: "transformProductionNeoForge")) { transitive = false } - -// modCompileOnly("curse.maven:configured-457570:5105024") -} - -processResources { - inputs.property "version", project.version - - filesMatching("META-INF/neoforge.mods.toml") { - expand "version": project.version - } -} - -shadowJar { - exclude "fabric.mod.json" - exclude "eyemine.common.json" - configurations = [project.configurations.shadowCommon] - archiveClassifier.set("dev-shadow") -} - -remapJar { - input.set shadowJar.archiveFile - dependsOn shadowJar - archiveBaseName.set "${rootProject.archives_base_name}-${project.minecraft_version}-${project.name}" - archiveClassifier.set('') - atAccessWideners.add("${rootProject.archives_base_name}.accesswidener") // this is a path inside the mod jar -} - -jar { - archiveClassifier.set("dev") -} - -sourcesJar { - def commonSources = project(":common").sourcesJar - dependsOn commonSources - from commonSources.archiveFile.map { zipTree(it) } -} + runs { + client { + client() + ideName = 'NeoForge Client' + } -components.java { - withVariantsFromConfiguration(project.configurations.shadowRuntimeElements) { - skip() - } -} + server { + server() + ideName = 'NeoForge Server' + } -publishing { - publications { - mavenNeoForge(MavenPublication) { - artifactId = rootProject.archives_base_name + "-" + project.name - from components.java + clientData { + clientData() + ideName = 'NeoForge Client Data' + programArguments.addAll("--mod=${mod_id}", "--output=${file("src/generated/resources").absolutePath}", "--existing=${file("src/main/resources").absolutePath}") } - } - // See https://docs.gradle.org/current/userguide/publishing_maven.html for information on how to set up publishing. - repositories { - // Add repositories to publish to here. + serverData { + serverData() + ideName = 'NeoForge Server Data' + programArguments.addAll("--mod=${mod_id}", "--output=${file("src/generated/resources").absolutePath}", "--existing=${file("src/main/resources").absolutePath}") + } } } + +sourceSets.main.resources.srcDir 'src/generated/resources' diff --git a/neoforge/src/main/java/com/specialeffect/eyemine/client/neoforge/ClientHandler.java b/neoforge/src/main/java/com/specialeffect/eyemine/client/neoforge/ClientHandler.java index 4cc8b34c..ea31a001 100644 --- a/neoforge/src/main/java/com/specialeffect/eyemine/client/neoforge/ClientHandler.java +++ b/neoforge/src/main/java/com/specialeffect/eyemine/client/neoforge/ClientHandler.java @@ -11,18 +11,110 @@ package com.specialeffect.eyemine.client.neoforge; +import com.specialeffect.eyemine.EyeMine; import com.specialeffect.eyemine.EyeMineClient; -import com.specialeffect.eyemine.event.BlockOutlineEvent; +import com.specialeffect.eyemine.event.EyeMineEvents; +import com.specialeffect.eyemine.event.EventResult; +import com.specialeffect.eyemine.event.ScreenSetResult; +import net.minecraft.client.Minecraft; +import net.minecraft.server.level.ServerLevel; +import net.neoforged.api.distmarker.Dist; +import net.neoforged.bus.api.SubscribeEvent; +import net.neoforged.fml.common.EventBusSubscriber; import net.neoforged.fml.event.lifecycle.FMLCommonSetupEvent; -import net.neoforged.neoforge.client.event.RenderHighlightEvent; +import net.neoforged.neoforge.client.event.ClientTickEvent; +import net.neoforged.neoforge.client.event.InputEvent; +import net.neoforged.neoforge.client.event.RenderGuiLayerEvent; +import net.neoforged.neoforge.client.event.ScreenEvent; +import net.neoforged.neoforge.event.entity.EntityJoinLevelEvent; +import net.neoforged.neoforge.event.entity.living.LivingDeathEvent; +import net.neoforged.neoforge.event.level.LevelEvent; +@EventBusSubscriber(modid = EyeMine.MOD_ID, value = Dist.CLIENT) public class ClientHandler { - public static void setup(final FMLCommonSetupEvent event) { - EyeMineClient.setupComplete = true; - EyeMineClient.refresh(); - } - - public static void onOutlineRender(RenderHighlightEvent.Block event) { - BlockOutlineEvent.OUTLINE.invoker().renderOutline(event.getMultiBufferSource(), event.getPoseStack()); - } + + @SubscribeEvent + public static void onClientTick(ClientTickEvent.Pre event) { + Minecraft mc = Minecraft.getInstance(); + for (var listener : EyeMineEvents.CLIENT_TICK.getListeners()) { + listener.onClientTick(mc); + } + } + + @SubscribeEvent + public static void onKeyInput(InputEvent.Key event) { + Minecraft mc = Minecraft.getInstance(); + for (var listener : EyeMineEvents.KEY_PRESSED.getListeners()) { + EventResult result = listener.onKeyPressed(mc, event.getKey(), event.getScanCode(), event.getAction(), event.getModifiers()); + if (result.isPresent()) break; + } + } + + @SubscribeEvent + public static void onScreenOpen(ScreenEvent.Opening event) { + for (var listener : EyeMineEvents.SCREEN_SET.getListeners()) { + ScreenSetResult result = listener.onScreenSet(event.getNewScreen()); + if (result.handled()) { + if (result.screen() != null) { + event.setNewScreen(result.screen()); + } + break; + } + } + } + + @SubscribeEvent + public static void onRenderHud(RenderGuiLayerEvent.Post event) { + for (var listener : EyeMineEvents.RENDER_HUD.getListeners()) { + listener.onRenderHud(event.getGuiGraphics(), event.getPartialTick()); + } + } + + @SubscribeEvent + public static void onBlockOutline(net.neoforged.neoforge.client.event.ExtractBlockOutlineRenderStateEvent event) { + if (!EyeMineEvents.BLOCK_OUTLINE.getListeners().isEmpty()) { + // Add a custom renderer that delegates to EyeMine's block outline listeners + event.addCustomRenderer((outlineState, bufferSource, poseStack, isTranslucent, levelRenderState) -> { + for (var listener : EyeMineEvents.BLOCK_OUTLINE.getListeners()) { + EventResult result = listener.renderOutline(bufferSource, poseStack); + if (result.isPresent()) return true; + } + return false; + }); + } + } + + @SubscribeEvent + public static void onLivingDeath(LivingDeathEvent event) { + for (var listener : EyeMineEvents.ENTITY_DEATH.getListeners()) { + EventResult result = listener.onDeath(event.getEntity(), event.getSource()); + if (result.isPresent()) break; + } + } + + @SubscribeEvent + public static void onEntityJoin(EntityJoinLevelEvent event) { + for (var listener : EyeMineEvents.ENTITY_ADD.getListeners()) { + EventResult result = listener.onAdd(event.getEntity(), event.getLevel()); + if (result.isPresent()) break; + } + } + + @SubscribeEvent + public static void onWorldLoad(LevelEvent.Load event) { + if (event.getLevel() instanceof ServerLevel serverLevel) { + for (var listener : EyeMineEvents.WORLD_LOAD.getListeners()) { + listener.onWorldLoad(serverLevel); + } + } + } + + public static void onSetup(FMLCommonSetupEvent event) { + EyeMineClient.setupComplete = true; + EyeMineClient.refresh(); + Minecraft mc = Minecraft.getInstance(); + for (var listener : EyeMineEvents.CLIENT_SETUP.getListeners()) { + listener.onClientSetup(mc); + } + } } diff --git a/neoforge/src/main/java/com/specialeffect/eyemine/neoforge/EyeMineNeoForge.java b/neoforge/src/main/java/com/specialeffect/eyemine/neoforge/EyeMineNeoForge.java index 6d9473f1..72f21a3e 100644 --- a/neoforge/src/main/java/com/specialeffect/eyemine/neoforge/EyeMineNeoForge.java +++ b/neoforge/src/main/java/com/specialeffect/eyemine/neoforge/EyeMineNeoForge.java @@ -3,38 +3,54 @@ import com.inventory.config.InventoryConfig; import com.specialeffect.eyemine.EyeMine; import com.specialeffect.eyemine.EyeMineClient; -import com.specialeffect.eyemine.client.neoforge.ClientHandler; +import com.specialeffect.eyemine.client.Keybindings; import com.specialeffect.eyemine.config.EyeMineConfig; +import com.specialeffect.eyemine.platform.neoforge.NeoForgeNetworkService; +import net.minecraft.client.KeyMapping; import net.neoforged.api.distmarker.Dist; import net.neoforged.bus.api.IEventBus; +import net.neoforged.bus.api.SubscribeEvent; import net.neoforged.fml.ModContainer; import net.neoforged.fml.common.Mod; import net.neoforged.fml.config.ModConfig; -import net.neoforged.neoforge.common.NeoForge; +import net.neoforged.neoforge.client.event.RegisterKeyMappingsEvent; +import net.neoforged.neoforge.network.event.RegisterPayloadHandlersEvent; +import net.neoforged.neoforge.network.registration.PayloadRegistrar; @Mod(EyeMine.MOD_ID) public class EyeMineNeoForge { - public EyeMineNeoForge(IEventBus eventBus, ModContainer container, Dist dist) { - // In NeoForge 1.21+, the event bus is passed directly to the constructor - // and Architectury automatically detects it via ModList.getModContainerById() - EyeMine.init(); - - if (dist.isClient()) { - // Config setup - container.registerConfig(ModConfig.Type.CLIENT, EyeMineConfig.CLIENT_CONFIG, "eyemine-config.toml"); - eventBus.register(EyeMineConfig.class); - container.registerConfig(ModConfig.Type.CLIENT, InventoryConfig.CLIENT_CONFIG, "eyemine-inventory-config.toml"); - eventBus.register(InventoryConfig.class); - - // Hook up config gui -// ModLoadingContext.get().registerExtensionPoint(ExtensionPoint.CONFIGGUIFACTORY, () -> ClientHandler::openSettings); - - // Register this setup method *after* children have registered theirs - // (this way the children will be fully set up before any config gets loaded) - eventBus.addListener(ClientHandler::setup); - - NeoForge.EVENT_BUS.addListener(ClientHandler::onOutlineRender); - EyeMineClient.init(); - } - } + public EyeMineNeoForge(IEventBus eventBus, ModContainer container, Dist dist) { + EyeMine.init(); + + eventBus.addListener(this::registerPayloads); + + if (dist.isClient()) { + container.registerConfig(ModConfig.Type.CLIENT, EyeMineConfig.CLIENT_CONFIG, "eyemine-config.toml"); + eventBus.register(EyeMineConfig.class); + container.registerConfig(ModConfig.Type.CLIENT, InventoryConfig.CLIENT_CONFIG, "eyemine-inventory-config.toml"); + eventBus.register(InventoryConfig.class); + + eventBus.addListener(this::registerKeyMappings); + + EyeMineClient.init(); + } + } + + @SuppressWarnings({"unchecked", "rawtypes"}) + private void registerPayloads(RegisterPayloadHandlersEvent event) { + PayloadRegistrar registrar = event.registrar(EyeMine.MOD_ID); + for (var entry : NeoForgeNetworkService.getPendingRegistrations().values()) { + registrar.playToServer( + entry.type(), + (net.minecraft.network.codec.StreamCodec) entry.codec(), + (payload, context) -> entry.handlePayload(payload, context) + ); + } + } + + private void registerKeyMappings(RegisterKeyMappingsEvent event) { + for (KeyMapping keyBinding : Keybindings.keybindings) { + event.register(keyBinding); + } + } } diff --git a/neoforge/src/main/java/com/specialeffect/eyemine/platform/neoforge/EyeMineConfigImpl.java b/neoforge/src/main/java/com/specialeffect/eyemine/platform/neoforge/EyeMineConfigImpl.java index 4bb05215..d72590db 100644 --- a/neoforge/src/main/java/com/specialeffect/eyemine/platform/neoforge/EyeMineConfigImpl.java +++ b/neoforge/src/main/java/com/specialeffect/eyemine/platform/neoforge/EyeMineConfigImpl.java @@ -1,133 +1,39 @@ package com.specialeffect.eyemine.platform.neoforge; import com.specialeffect.eyemine.config.EyeMineConfig; - -public class EyeMineConfigImpl { - public static boolean getDisableCustomNewWorld() { - return EyeMineConfig.disableCustomNewWorld.get(); - } - - public static void setCustomSpeedFactor(float speed) { - EyeMineConfig.customSpeedFactor.set((double) speed); - } - - public static boolean getUsingMouseEmulation() { - return EyeMineConfig.usingMouseEmulation.get(); - } - - public static boolean getAutoSelectTool() { - return EyeMineConfig.autoSelectTool.get(); - } - - public static boolean getAutoSelectSword() { - return EyeMineConfig.autoSelectSword.get(); - } - - public static int getRadiusChests() { - return EyeMineConfig.radiusChests.get(); - } - - public static int getTicksBetweenMining() { - return EyeMineConfig.ticksBetweenMining.get(); - } - - public static double getBowDrawTime() { - return EyeMineConfig.bowDrawTime.get(); - } - - public static float getFullscreenOverlayAlpha() { - return EyeMineConfig.fullscreenOverlayAlpha.get().floatValue(); - } - - public static int getIronsightsFovReduction() { - return EyeMineConfig.ironsightsFovReduction.get(); - } - - public static double getIronsightsSensitivityReduction() { - return EyeMineConfig.ironsightsSensitivityReduction.get().floatValue(); - } - - public static boolean getUseDwellForSingleUseItem() { - return EyeMineConfig.useDwellForSingleUseItem.get(); - } - - public static boolean getUseDwellForSingleMine() { - return EyeMineConfig.useDwellForSingleMine.get(); - } - - public static int getRadiusDoors() { - return EyeMineConfig.radiusDoors.get(); - } - - public static boolean getServerCompatibilityMode() { - return EyeMineConfig.serverCompatibilityMode.get(); - } - - public static int getFlyHeightManual() { - return EyeMineConfig.flyHeightManual.get(); - } - - public static int getFlyHeightAuto() { - return EyeMineConfig.flyHeightAuto.get(); - } - - public static boolean getDefaultDoAutoJump() { - return EyeMineConfig.defaultDoAutoJump.get(); - } - - public static boolean getDisableAutoJumpFixes() { - return EyeMineConfig.disableAutoJumpFixes.get(); - } - - public static boolean getMoveWhenMouseStationary() { - return EyeMineConfig.moveWhenMouseStationary.get(); - } - - public static boolean getSlowdownOnCorners() { - return EyeMineConfig.slowdownOnCorners.get(); - } - - public static int getWalkingSlowdownFilter() { - return EyeMineConfig.walkingSlowdownFilter.get(); - } - - public static boolean getAllowLadderDescent() { - return EyeMineConfig.allowLadderDescent.get(); - } - - public static float getCustomSpeedFactor() { - return EyeMineConfig.customSpeedFactor.get().floatValue(); - } - - public static float getBoatMaxTurnAtSpeed() { - return EyeMineConfig.boatMaxTurnAtSpeed.get().floatValue(); - } - - public static double getBoatSlowdown() { - return EyeMineConfig.boatSlowdown.get(); - } - - public static double getDwellTimeSeconds() { - return EyeMineConfig.dwellTimeSeconds.get(); - } - - public static double getDwellLockonTimeSeconds() { - return EyeMineConfig.dwellLockonTimeSeconds.get(); - } - - public static boolean getDwellShowWithTransparency() { - return EyeMineConfig.dwellShowWithTransparency.get(); - } - - public static boolean getDwellShowExpanding() { - return EyeMineConfig.dwellShowExpanding.get(); - } - - public static boolean getSlowdownOnAttack() { - return EyeMineConfig.slowdownOnAttack.get(); - } - - public static int getGazeIdleThreshold() { - return EyeMineConfig.gazeIdleThreshold.get(); - } +import com.specialeffect.eyemine.platform.services.IEyeMineConfigService; + +public class EyeMineConfigImpl implements IEyeMineConfigService { + @Override public boolean getDisableCustomNewWorld() { return EyeMineConfig.disableCustomNewWorld.get(); } + @Override public void setCustomSpeedFactor(float speed) { EyeMineConfig.customSpeedFactor.set((double) speed); } + @Override public boolean getUsingMouseEmulation() { return EyeMineConfig.usingMouseEmulation.get(); } + @Override public boolean getAutoSelectTool() { return EyeMineConfig.autoSelectTool.get(); } + @Override public boolean getAutoSelectSword() { return EyeMineConfig.autoSelectSword.get(); } + @Override public int getRadiusChests() { return EyeMineConfig.radiusChests.get(); } + @Override public int getTicksBetweenMining() { return EyeMineConfig.ticksBetweenMining.get(); } + @Override public double getBowDrawTime() { return EyeMineConfig.bowDrawTime.get(); } + @Override public float getFullscreenOverlayAlpha() { return EyeMineConfig.fullscreenOverlayAlpha.get().floatValue(); } + @Override public int getIronsightsFovReduction() { return EyeMineConfig.ironsightsFovReduction.get(); } + @Override public double getIronsightsSensitivityReduction() { return EyeMineConfig.ironsightsSensitivityReduction.get().floatValue(); } + @Override public boolean getUseDwellForSingleUseItem() { return EyeMineConfig.useDwellForSingleUseItem.get(); } + @Override public boolean getUseDwellForSingleMine() { return EyeMineConfig.useDwellForSingleMine.get(); } + @Override public int getRadiusDoors() { return EyeMineConfig.radiusDoors.get(); } + @Override public boolean getServerCompatibilityMode() { return EyeMineConfig.serverCompatibilityMode.get(); } + @Override public int getFlyHeightManual() { return EyeMineConfig.flyHeightManual.get(); } + @Override public int getFlyHeightAuto() { return EyeMineConfig.flyHeightAuto.get(); } + @Override public boolean getDefaultDoAutoJump() { return EyeMineConfig.defaultDoAutoJump.get(); } + @Override public boolean getDisableAutoJumpFixes() { return EyeMineConfig.disableAutoJumpFixes.get(); } + @Override public boolean getMoveWhenMouseStationary() { return EyeMineConfig.moveWhenMouseStationary.get(); } + @Override public boolean getSlowdownOnCorners() { return EyeMineConfig.slowdownOnCorners.get(); } + @Override public int getWalkingSlowdownFilter() { return EyeMineConfig.walkingSlowdownFilter.get(); } + @Override public boolean getAllowLadderDescent() { return EyeMineConfig.allowLadderDescent.get(); } + @Override public float getCustomSpeedFactor() { return EyeMineConfig.customSpeedFactor.get().floatValue(); } + @Override public float getBoatMaxTurnAtSpeed() { return EyeMineConfig.boatMaxTurnAtSpeed.get().floatValue(); } + @Override public double getBoatSlowdown() { return EyeMineConfig.boatSlowdown.get(); } + @Override public double getDwellTimeSeconds() { return EyeMineConfig.dwellTimeSeconds.get(); } + @Override public double getDwellLockonTimeSeconds() { return EyeMineConfig.dwellLockonTimeSeconds.get(); } + @Override public boolean getDwellShowWithTransparency() { return EyeMineConfig.dwellShowWithTransparency.get(); } + @Override public boolean getDwellShowExpanding() { return EyeMineConfig.dwellShowExpanding.get(); } + @Override public boolean getSlowdownOnAttack() { return EyeMineConfig.slowdownOnAttack.get(); } + @Override public int getGazeIdleThreshold() { return EyeMineConfig.gazeIdleThreshold.get(); } } diff --git a/neoforge/src/main/java/com/specialeffect/eyemine/platform/neoforge/InventoryConfigImpl.java b/neoforge/src/main/java/com/specialeffect/eyemine/platform/neoforge/InventoryConfigImpl.java index c950cfce..bdaf5938 100644 --- a/neoforge/src/main/java/com/specialeffect/eyemine/platform/neoforge/InventoryConfigImpl.java +++ b/neoforge/src/main/java/com/specialeffect/eyemine/platform/neoforge/InventoryConfigImpl.java @@ -1,105 +1,32 @@ package com.specialeffect.eyemine.platform.neoforge; import com.inventory.config.InventoryConfig; - -public class InventoryConfigImpl { - public static int getKey0() { - return InventoryConfig.key0.get(); - } - - public static int getKey1() { - return InventoryConfig.key1.get(); - } - - public static int getKey2() { - return InventoryConfig.key2.get(); - } - - public static int getKey3() { - return InventoryConfig.key3.get(); - } - - public static int getKey4() { - return InventoryConfig.key4.get(); - } - - public static int getKey5() { - return InventoryConfig.key5.get(); - } - - public static int getKey6() { - return InventoryConfig.key6.get(); - } - - public static int getKey7() { - return InventoryConfig.key7.get(); - } - - public static int getKey8() { - return InventoryConfig.key8.get(); - } - - public static int getKey9() { - return InventoryConfig.key9.get(); - } - - public static int getKeySurvPrevTab() { - return InventoryConfig.keySurvPrevTab.get(); - } - - public static int getKeySurvNextTab() { - return InventoryConfig.keySurvNextTab.get(); - } - - public static int getKeySurvRecipes() { - return InventoryConfig.keySurvRecipes.get(); - } - - public static int getKeySurvCraftable() { - return InventoryConfig.keySurvCraftable.get(); - } - - public static int getkeySurvPrevPage() { - return InventoryConfig.keySurvPrevPage.get(); - } - - public static int getkeySurvNextPage() { - return InventoryConfig.keySurvNextPage.get(); - } - - public static int getKeySurvOutput() { - return InventoryConfig.keySurvOutput.get(); - } - - public static int getKeyPrev() { - return InventoryConfig.keyPrev.get(); - } - - public static int getKeyNext() { - return InventoryConfig.keyNext.get(); - } - - public static int getKeyNextItemRow() { - return InventoryConfig.keyNextItemRow.get(); - } - - public static int getKeyNextItemCol() { - return InventoryConfig.keyNextItemCol.get(); - } - - public static int getKeyScrollUp() { - return InventoryConfig.keyScrollUp.get(); - } - - public static int getKeyScrollDown() { - return InventoryConfig.keyScrollDown.get(); - } - - public static int getKeySearch() { - return InventoryConfig.keySearch.get(); - } - - public static int getKeyDrop() { - return InventoryConfig.keyDrop.get(); - } +import com.specialeffect.eyemine.platform.services.IInventoryConfigService; + +public class InventoryConfigImpl implements IInventoryConfigService { + @Override public int getKey0() { return InventoryConfig.key0.get(); } + @Override public int getKey1() { return InventoryConfig.key1.get(); } + @Override public int getKey2() { return InventoryConfig.key2.get(); } + @Override public int getKey3() { return InventoryConfig.key3.get(); } + @Override public int getKey4() { return InventoryConfig.key4.get(); } + @Override public int getKey5() { return InventoryConfig.key5.get(); } + @Override public int getKey6() { return InventoryConfig.key6.get(); } + @Override public int getKey7() { return InventoryConfig.key7.get(); } + @Override public int getKey8() { return InventoryConfig.key8.get(); } + @Override public int getKey9() { return InventoryConfig.key9.get(); } + @Override public int getKeySurvPrevTab() { return InventoryConfig.keySurvPrevTab.get(); } + @Override public int getKeySurvNextTab() { return InventoryConfig.keySurvNextTab.get(); } + @Override public int getKeySurvRecipes() { return InventoryConfig.keySurvRecipes.get(); } + @Override public int getKeySurvCraftable() { return InventoryConfig.keySurvCraftable.get(); } + @Override public int getkeySurvPrevPage() { return InventoryConfig.keySurvPrevPage.get(); } + @Override public int getkeySurvNextPage() { return InventoryConfig.keySurvNextPage.get(); } + @Override public int getKeySurvOutput() { return InventoryConfig.keySurvOutput.get(); } + @Override public int getKeyPrev() { return InventoryConfig.keyPrev.get(); } + @Override public int getKeyNext() { return InventoryConfig.keyNext.get(); } + @Override public int getKeyNextItemRow() { return InventoryConfig.keyNextItemRow.get(); } + @Override public int getKeyNextItemCol() { return InventoryConfig.keyNextItemCol.get(); } + @Override public int getKeyScrollUp() { return InventoryConfig.keyScrollUp.get(); } + @Override public int getKeyScrollDown() { return InventoryConfig.keyScrollDown.get(); } + @Override public int getKeySearch() { return InventoryConfig.keySearch.get(); } + @Override public int getKeyDrop() { return InventoryConfig.keyDrop.get(); } } diff --git a/neoforge/src/main/java/com/specialeffect/eyemine/platform/neoforge/NeoForgeNetworkService.java b/neoforge/src/main/java/com/specialeffect/eyemine/platform/neoforge/NeoForgeNetworkService.java new file mode 100644 index 00000000..29e980bc --- /dev/null +++ b/neoforge/src/main/java/com/specialeffect/eyemine/platform/neoforge/NeoForgeNetworkService.java @@ -0,0 +1,57 @@ +package com.specialeffect.eyemine.platform.neoforge; + +import com.specialeffect.eyemine.packets.NetworkService; +import net.minecraft.network.RegistryFriendlyByteBuf; +import net.minecraft.network.codec.StreamCodec; +import net.minecraft.network.protocol.common.custom.CustomPacketPayload; +import net.minecraft.world.entity.player.Player; +import net.neoforged.neoforge.client.network.ClientPacketDistributor; +import net.neoforged.neoforge.network.handling.IPayloadContext; + +import java.util.HashMap; +import java.util.Map; + +public class NeoForgeNetworkService implements NetworkService { + private static final Map, RegistrationEntry> pendingRegistrations = new HashMap<>(); + + @SuppressWarnings("unchecked") + public record RegistrationEntry( + CustomPacketPayload.Type type, + StreamCodec codec, + PacketHandler handler) { + + public void handlePayload(CustomPacketPayload payload, IPayloadContext context) { + T typed = (T) payload; + handler.handle(typed, new NeoForgePacketContext(context)); + } + } + + @Override + public void registerC2S( + CustomPacketPayload.Type type, + StreamCodec codec, + PacketHandler handler) { + pendingRegistrations.put(type, new RegistrationEntry<>(type, codec, handler)); + } + + @Override + public void sendToServer(CustomPacketPayload payload) { + ClientPacketDistributor.sendToServer(payload); + } + + public static Map, RegistrationEntry> getPendingRegistrations() { + return pendingRegistrations; + } + + private record NeoForgePacketContext(IPayloadContext neoContext) implements PacketContext { + @Override + public void queue(Runnable work) { + neoContext.enqueueWork(work); + } + + @Override + public Player getPlayer() { + return neoContext.player(); + } + } +} diff --git a/neoforge/src/main/java/com/specialeffect/eyemine/platform/neoforge/NeoForgePlatformHelper.java b/neoforge/src/main/java/com/specialeffect/eyemine/platform/neoforge/NeoForgePlatformHelper.java new file mode 100644 index 00000000..f7107c9e --- /dev/null +++ b/neoforge/src/main/java/com/specialeffect/eyemine/platform/neoforge/NeoForgePlatformHelper.java @@ -0,0 +1,22 @@ +package com.specialeffect.eyemine.platform.neoforge; + +import com.specialeffect.eyemine.platform.services.IPlatformHelper; +import net.neoforged.fml.ModList; +import net.neoforged.fml.loading.FMLLoader; + +public class NeoForgePlatformHelper implements IPlatformHelper { + @Override + public String getPlatformName() { + return "NeoForge"; + } + + @Override + public boolean isModLoaded(String modId) { + return ModList.get().isLoaded(modId); + } + + @Override + public boolean isDevelopmentEnvironment() { + return !FMLLoader.getCurrent().isProduction(); + } +} diff --git a/neoforge/src/main/resources/META-INF/neoforge.mods.toml b/neoforge/src/main/resources/META-INF/neoforge.mods.toml index 3cd4b4da..dc96e01f 100644 --- a/neoforge/src/main/resources/META-INF/neoforge.mods.toml +++ b/neoforge/src/main/resources/META-INF/neoforge.mods.toml @@ -1,44 +1,31 @@ modLoader="javafml" -loaderVersion="[4,)" +loaderVersion="${neoforge_loader_version_range}" issueTrackerURL="https://github.com/SpecialEffect/SpecialEffectMinecraftMods" -license="GPL-3.0" +license="${license}" [[mods]] -modId="eyemine" +modId="${mod_id}" version="${version}" -displayName="EyeMine" +displayName="${mod_name}" displayURL="https://www.specialeffect.org.uk/eyemine" -authors="Kirsty McNaught, Mrbysco" +authors="${mod_author}" logoFile="eyemine_logo.png" -credits = "Written in collaboration with SpecialEffect" -description=''' -EyeMine by SpecialEffect allows you to play Minecraft using eye gaze. +credits="${credits}" +description='''${description}''' -It is designed to work alongside the EyeMine gaze-controlled keyboard. +[[dependencies.${mod_id}]] +modId="neoforge" +type="required" +versionRange="[${neoforge_version},)" +ordering="NONE" +side="CLIENT" -For questions or support, contact eyemine@specialeffect.org.uk -''' +[[dependencies.${mod_id}]] +modId="minecraft" +type="required" +versionRange="${minecraft_version_range}" +ordering="NONE" +side="CLIENT" -[[dependencies.eyemine]] - modId="neoforge" - type="required" - versionRange="[21.0.0-beta,)" - ordering="NONE" - side="CLIENT" -[[dependencies.eyemine]] - modId="minecraft" - type="required" - versionRange="[1.21,1.22]" - ordering="NONE" - side="CLIENT" - - - -[[dependencies.eyemine]] -modId = "architectury" -type = "required" -versionRange = "[13.0.1,)" -ordering = "AFTER" -side = "BOTH" [[mixins]] -config = "eyemine-common.mixins.json" \ No newline at end of file +config="eyemine-common.mixins.json" diff --git a/neoforge/src/main/resources/META-INF/services/com.specialeffect.eyemine.packets.NetworkService b/neoforge/src/main/resources/META-INF/services/com.specialeffect.eyemine.packets.NetworkService new file mode 100644 index 00000000..f38169a2 --- /dev/null +++ b/neoforge/src/main/resources/META-INF/services/com.specialeffect.eyemine.packets.NetworkService @@ -0,0 +1 @@ +com.specialeffect.eyemine.platform.neoforge.NeoForgeNetworkService diff --git a/neoforge/src/main/resources/META-INF/services/com.specialeffect.eyemine.platform.services.IEyeMineConfigService b/neoforge/src/main/resources/META-INF/services/com.specialeffect.eyemine.platform.services.IEyeMineConfigService new file mode 100644 index 00000000..373a3b29 --- /dev/null +++ b/neoforge/src/main/resources/META-INF/services/com.specialeffect.eyemine.platform.services.IEyeMineConfigService @@ -0,0 +1 @@ +com.specialeffect.eyemine.platform.neoforge.EyeMineConfigImpl diff --git a/neoforge/src/main/resources/META-INF/services/com.specialeffect.eyemine.platform.services.IInventoryConfigService b/neoforge/src/main/resources/META-INF/services/com.specialeffect.eyemine.platform.services.IInventoryConfigService new file mode 100644 index 00000000..27e2377e --- /dev/null +++ b/neoforge/src/main/resources/META-INF/services/com.specialeffect.eyemine.platform.services.IInventoryConfigService @@ -0,0 +1 @@ +com.specialeffect.eyemine.platform.neoforge.InventoryConfigImpl diff --git a/neoforge/src/main/resources/META-INF/services/com.specialeffect.eyemine.platform.services.IPlatformHelper b/neoforge/src/main/resources/META-INF/services/com.specialeffect.eyemine.platform.services.IPlatformHelper new file mode 100644 index 00000000..575be5a3 --- /dev/null +++ b/neoforge/src/main/resources/META-INF/services/com.specialeffect.eyemine.platform.services.IPlatformHelper @@ -0,0 +1 @@ +com.specialeffect.eyemine.platform.neoforge.NeoForgePlatformHelper diff --git a/settings.gradle b/settings.gradle index d1f2954b..ba27ebf1 100644 --- a/settings.gradle +++ b/settings.gradle @@ -1,17 +1,26 @@ pluginManagement { repositories { - maven { url "https://maven.fabricmc.net/" } - maven { url "https://maven.architectury.dev/" } - maven { url "https://maven.neoforged.net/releases/" } - maven { url "https://maven.minecraftforge.net/" } - mavenCentral() gradlePluginPortal() + mavenCentral() + exclusiveContent { + forRepository { + maven { + name = 'Fabric' + url = uri('https://maven.fabricmc.net') + } + } + filter { + includeGroupAndSubgroups('net.fabricmc') + } + } } } -include("common") -include("fabric") -include("neoforge") -//include("forge") +plugins { + id 'org.gradle.toolchains.foojay-resolver-convention' version '1.0.0' +} -rootProject.name = "architectury-eyemine" +rootProject.name = 'eyemine' +include('common') +include('fabric') +include('neoforge') From 382c74b7b3dd076e59f6e7857077284d915071f5 Mon Sep 17 00:00:00 2001 From: Saereth Date: Tue, 7 Apr 2026 20:52:40 -0700 Subject: [PATCH 2/4] Fix missing event forwarders, extract key input boilerplate, and clean dead code - Register CLIENT_SETUP listener on NeoForge mod event bus (was never wired up) - Add ENTITY_ADD forwarder on Fabric via ServerEntityEvents.ENTITY_LOAD - Add PLAYER_TICK forwarder on both platforms - Extract KeyInputUtil.shouldIgnoreKeyInput() to DRY 22 submod handlers - Replace System.out.println with EyeMine.LOGGER across 6 files - Remove ~180 lines of dead code from AbstractRenderer and ModUtils --- .../client/renderers/AbstractRenderer.java | 141 ------------------ .../packets/messages/SendCommandMessage.java | 4 +- .../eyemine/submod/KeyInputUtil.java | 29 ++++ .../submod/mining/ContinuouslyMine.java | 15 +- .../eyemine/submod/mining/DwellMine.java | 8 +- .../eyemine/submod/mining/GatherDrops.java | 7 +- .../eyemine/submod/mining/MineOne.java | 8 +- .../eyemine/submod/misc/AutoPillar.java | 7 +- .../submod/misc/ContinuouslyAttack.java | 9 +- .../submod/misc/DefaultConfigForNewWorld.java | 3 +- .../eyemine/submod/misc/DwellBuild.java | 8 +- .../eyemine/submod/misc/IronSights.java | 8 +- .../eyemine/submod/misc/OpenChat.java | 7 +- .../eyemine/submod/misc/OpenTablesChests.java | 8 +- .../eyemine/submod/misc/PickBlock.java | 7 +- .../eyemine/submod/misc/QuickCommands.java | 7 +- .../eyemine/submod/misc/SwapMinePlace.java | 7 +- .../eyemine/submod/misc/UseItem.java | 8 +- .../eyemine/submod/mouse/MouseHandlerMod.java | 10 +- .../eyemine/submod/movement/AutoFly.java | 8 +- .../eyemine/submod/movement/AutoJump.java | 8 +- .../submod/movement/BoatController.java | 3 +- .../eyemine/submod/movement/Dismount.java | 7 +- .../eyemine/submod/movement/MoveWithGaze.java | 10 +- .../submod/movement/MoveWithGaze2.java | 9 +- .../eyemine/submod/movement/Sneak.java | 7 +- .../eyemine/submod/movement/Swim.java | 7 +- .../eyemine/submod/utils/DwellAction.java | 3 +- .../manager/CreativeInventoryManager.java | 3 +- .../com/specialeffect/utils/ModUtils.java | 48 ------ .../eyemine/EyeMineClientFabric.java | 17 +++ .../client/neoforge/ClientHandler.java | 8 + .../eyemine/neoforge/EyeMineNeoForge.java | 3 +- 33 files changed, 134 insertions(+), 308 deletions(-) create mode 100644 common/src/main/java/com/specialeffect/eyemine/submod/KeyInputUtil.java diff --git a/common/src/main/java/com/irtimaled/bbor/client/renderers/AbstractRenderer.java b/common/src/main/java/com/irtimaled/bbor/client/renderers/AbstractRenderer.java index 82fda918..e822ad20 100644 --- a/common/src/main/java/com/irtimaled/bbor/client/renderers/AbstractRenderer.java +++ b/common/src/main/java/com/irtimaled/bbor/client/renderers/AbstractRenderer.java @@ -1,23 +1,15 @@ package com.irtimaled.bbor.client.renderers; -import com.mojang.blaze3d.systems.RenderSystem; import com.mojang.blaze3d.vertex.PoseStack; import com.mojang.blaze3d.vertex.VertexConsumer; -import net.minecraft.client.Minecraft; -import net.minecraft.client.gui.Font; import net.minecraft.core.BlockPos; import net.minecraft.core.Direction; import net.minecraft.world.phys.Vec3; import org.joml.Matrix4f; -import org.lwjgl.opengl.GL11; import java.awt.Color; -import java.util.HashSet; -import java.util.Set; public abstract class AbstractRenderer { - private static double TAU = 6.283185307179586D; - private static double PI = TAU / 2D; public static void renderBlockFace(PoseStack poseStack, VertexConsumer vertexConsumer, BlockPos pos, Direction facing, Color color, int opacity) { OffsetPoint min = new OffsetPoint(pos.getX(), pos.getY(), pos.getZ()); @@ -235,137 +227,4 @@ public static void renderCubeAtPosition(PoseStack poseStack, VertexConsumer vert } - public static void renderFaces(OffsetPoint min, OffsetPoint max, Color color, int alpha) { - double minX = min.getX(); - double minY = min.getY(); - double minZ = min.getZ(); - - double maxX = max.getX(); - double maxY = max.getY(); - double maxZ = max.getZ(); - - Renderer renderer = Renderer.startQuads() - .setColor(color) - .setAlpha(alpha); - - if (minX != maxX && minZ != maxZ) { - renderer.addPoint(minX, minY, minZ) - .addPoint(maxX, minY, minZ) - .addPoint(maxX, minY, maxZ) - .addPoint(minX, minY, maxZ); - - if (minY != maxY) { - renderer.addPoint(minX, maxY, minZ) - .addPoint(maxX, maxY, minZ) - .addPoint(maxX, maxY, maxZ) - .addPoint(minX, maxY, maxZ); - } - } - - if (minX != maxX && minY != maxY) { - renderer.addPoint(minX, minY, maxZ) - .addPoint(minX, maxY, maxZ) - .addPoint(maxX, maxY, maxZ) - .addPoint(maxX, minY, maxZ); - - if (minZ != maxZ) { - renderer.addPoint(minX, minY, minZ) - .addPoint(minX, maxY, minZ) - .addPoint(maxX, maxY, minZ) - .addPoint(maxX, minY, minZ); - } - } - if (minY != maxY && minZ != maxZ) { - renderer.addPoint(minX, minY, minZ) - .addPoint(minX, minY, maxZ) - .addPoint(minX, maxY, maxZ) - .addPoint(minX, maxY, minZ); - - if (minX != maxX) { - renderer.addPoint(maxX, minY, minZ) - .addPoint(maxX, minY, maxZ) - .addPoint(maxX, maxY, maxZ) - .addPoint(maxX, maxY, minZ); - } - } - } - - void renderLine(OffsetPoint startPoint, OffsetPoint endPoint, Color color) { - - Renderer.startLines() - .setColor(color) - .addPoint(startPoint) - .addPoint(endPoint); - } - - void renderFilledFaces(OffsetPoint min, OffsetPoint max, Color color, int alpha) { - - renderFaces(min, max, color, alpha); - - } - - void renderText(PoseStack poseStack, OffsetPoint offsetPoint, String... texts) { - Font fontRenderer = Minecraft.getInstance().font; - -// RenderSystem.pushMatrix(); TODO: Redo when renderText() is required -// RenderSystem.translated(offsetPoint.getX(), offsetPoint.getY() + 0.002D, offsetPoint.getZ()); -// GL11.glNormal3f(0.0F, 1.0F, 0.0F); -// RenderSystem.rotatef(0.0F, 0.0F, 1.0F, 0.0F); -// RenderSystem.rotatef(90.0F, 1.0F, 0.0F, 0.0F); -// RenderSystem.scalef(-0.0175F, -0.0175F, 0.0175F); -// -// -// RenderSystem.disableDepthTest(); -// RenderSystem.enableDepthTest(); -// RenderSystem.depthMask(true); -// float top = -(fontRenderer.lineHeight * texts.length) / 2f; -// for (String text : texts) { -// float left = fontRenderer.width(text) / 2f; -// fontRenderer.draw(poseStack, text, -left, top, -1); -// top += fontRenderer.lineHeight; -// } -// RenderSystem.disableTexture(); - } - - private static void enablePointSmooth() { - RenderSystem.assertOnRenderThread(); - GL11.glEnable(GL11.GL_POINT_SMOOTH); - } - - private static void pointSize(float dotSize) { - RenderSystem.assertOnRenderThread(); - GL11.glPointSize(dotSize); - } - - void renderSphere(OffsetPoint center, double radius, Color color, int density, int dotSize) { - enablePointSmooth(); -// GL11.glEnable(GL11.GL_POINT_SMOOTH); - pointSize(dotSize); -// GL11.glPointSize(dotSize); -// Renderer renderer = Renderer.startPoints() TODO: Redo when renderSphere is required -// .setColor(color); -// buildPoints(center, radius, density) -// .forEach(renderer::addPoint); -// renderer.render(); - } - - private Set buildPoints(OffsetPoint center, double radius, int density) { - int segments = 24 + (density * 8); - - Set points = new HashSet<>(segments * segments); - - double thetaSegment = PI / (double) segments; - double phiSegment = TAU / (double) segments; - - for (double phi = 0.0D; phi < TAU; phi += phiSegment) { - for (double theta = 0.0D; theta < PI; theta += thetaSegment) { - double dx = radius * Math.sin(phi) * Math.cos(theta); - double dz = radius * Math.sin(phi) * Math.sin(theta); - double dy = radius * Math.cos(phi); - - points.add(center.offset(dx, dy, dz)); - } - } - return points; - } } diff --git a/common/src/main/java/com/specialeffect/eyemine/packets/messages/SendCommandMessage.java b/common/src/main/java/com/specialeffect/eyemine/packets/messages/SendCommandMessage.java index 6a495c92..f706fba7 100644 --- a/common/src/main/java/com/specialeffect/eyemine/packets/messages/SendCommandMessage.java +++ b/common/src/main/java/com/specialeffect/eyemine/packets/messages/SendCommandMessage.java @@ -40,11 +40,11 @@ public static void handle(final SendCommandMessage pkt, NetworkService.PacketCon context.queue(() -> { MinecraftServer server = context.getPlayer().level().getServer(); if (server == null) { - System.out.println("Server is null, cannot send command"); + EyeMine.LOGGER.warn("Server is null, cannot send command"); } else { Commands mgr = server.getCommands(); if (null == mgr) { - System.out.println("CommandManager is null, cannot send command"); + EyeMine.LOGGER.warn("CommandManager is null, cannot send command"); } else { mgr.performPrefixedCommand(server.createCommandSourceStack(), pkt.command); } diff --git a/common/src/main/java/com/specialeffect/eyemine/submod/KeyInputUtil.java b/common/src/main/java/com/specialeffect/eyemine/submod/KeyInputUtil.java new file mode 100644 index 00000000..aec372da --- /dev/null +++ b/common/src/main/java/com/specialeffect/eyemine/submod/KeyInputUtil.java @@ -0,0 +1,29 @@ +package com.specialeffect.eyemine.submod; + +import com.mojang.blaze3d.platform.InputConstants; +import com.specialeffect.eyemine.event.EventResult; +import com.specialeffect.utils.ModUtils; +import net.minecraft.client.KeyMapping; +import net.minecraft.client.Minecraft; +import net.minecraft.client.input.KeyEvent; + +/** + * Utility to reduce boilerplate in submod key input handlers. + * Most submods follow the same pattern: check GUI, check F11, check keybinding, run action. + */ +public class KeyInputUtil { + + /** + * Returns true if key events should be ignored (GUI open or F11 debug key held). + */ + public static boolean shouldIgnoreKeyInput(Minecraft minecraft) { + return ModUtils.hasActiveGui() || InputConstants.isKeyDown(minecraft.getWindow(), 292); + } + + /** + * Check if a keybinding was just pressed. Call after shouldIgnoreKeyInput(). + */ + public static boolean wasKeyPressed(KeyMapping binding, int keyCode, int scanCode, int modifiers) { + return binding.matches(new KeyEvent(keyCode, scanCode, modifiers)) && binding.consumeClick(); + } +} diff --git a/common/src/main/java/com/specialeffect/eyemine/submod/mining/ContinuouslyMine.java b/common/src/main/java/com/specialeffect/eyemine/submod/mining/ContinuouslyMine.java index f61244a8..48c3f140 100644 --- a/common/src/main/java/com/specialeffect/eyemine/submod/mining/ContinuouslyMine.java +++ b/common/src/main/java/com/specialeffect/eyemine/submod/mining/ContinuouslyMine.java @@ -11,6 +11,7 @@ package com.specialeffect.eyemine.submod.mining; +import com.specialeffect.eyemine.EyeMine; import com.mojang.blaze3d.platform.InputConstants; import com.mojang.blaze3d.platform.InputConstants.Type; import com.specialeffect.eyemine.client.Keybindings; @@ -19,9 +20,13 @@ import com.specialeffect.eyemine.packets.messages.AddItemToHotbar; import com.specialeffect.eyemine.platform.EyeMineConfig; import com.specialeffect.eyemine.submod.IConfigListener; +import com.specialeffect.eyemine.submod.KeyInputUtil; import com.specialeffect.eyemine.submod.SubMod; +import com.specialeffect.eyemine.submod.KeyInputUtil; import com.specialeffect.eyemine.submod.misc.ContinuouslyAttack; +import com.specialeffect.eyemine.submod.KeyInputUtil; import com.specialeffect.eyemine.submod.mouse.MouseHandlerMod; +import com.specialeffect.eyemine.submod.KeyInputUtil; import com.specialeffect.utils.ModUtils; import com.specialeffect.eyemine.event.EventResult; import com.specialeffect.eyemine.event.EyeMineEvents; @@ -130,14 +135,14 @@ public void onClientTick(Minecraft event) { // accompanying mouse movement. if (MouseHandlerMod.hasPendingEvent() || mMouseEventLastTick) { if (miningTimer == 0) { - System.out.println("attack"); + EyeMine.LOGGER.debug("attack"); KeyMapping.click(((KeyMappingAccessor) attackBinding).getActualKey()); if (player.isCreative()) { miningTimer = miningCooldown.getAsInt(); } } else { if (player.attackAnim == 0) { - System.out.println("swing"); + EyeMine.LOGGER.debug("swing"); player.swing(InteractionHand.MAIN_HAND); } } @@ -161,11 +166,7 @@ public void onClientTick(Minecraft event) { } private EventResult onKeyInput(Minecraft minecraft, int keyCode, int scanCode, int action, int modifiers) { - if (ModUtils.hasActiveGui()) { - return EventResult.pass(); - } - - if (InputConstants.isKeyDown(minecraft.getWindow(), 292)) { + if (KeyInputUtil.shouldIgnoreKeyInput(minecraft)) { return EventResult.pass(); } diff --git a/common/src/main/java/com/specialeffect/eyemine/submod/mining/DwellMine.java b/common/src/main/java/com/specialeffect/eyemine/submod/mining/DwellMine.java index f12b7af5..669ca71e 100644 --- a/common/src/main/java/com/specialeffect/eyemine/submod/mining/DwellMine.java +++ b/common/src/main/java/com/specialeffect/eyemine/submod/mining/DwellMine.java @@ -16,7 +16,9 @@ import com.specialeffect.eyemine.client.Keybindings; import com.specialeffect.eyemine.mixin.KeyMappingAccessor; import com.specialeffect.eyemine.submod.utils.DwellAction; +import com.specialeffect.eyemine.submod.KeyInputUtil; import com.specialeffect.eyemine.submod.utils.TargetBlock; +import com.specialeffect.eyemine.submod.KeyInputUtil; import com.specialeffect.utils.ModUtils; import com.specialeffect.eyemine.event.EventResult; import com.specialeffect.eyemine.event.EyeMineEvents; @@ -64,11 +66,7 @@ public void performAction(TargetBlock block) { } private EventResult onKeyInput(Minecraft minecraft, int keyCode, int scanCode, int action, int modifiers) { - if (ModUtils.hasActiveGui()) { - return EventResult.pass(); - } - - if (InputConstants.isKeyDown(minecraft.getWindow(), 292)) { + if (KeyInputUtil.shouldIgnoreKeyInput(minecraft)) { return EventResult.pass(); } diff --git a/common/src/main/java/com/specialeffect/eyemine/submod/mining/GatherDrops.java b/common/src/main/java/com/specialeffect/eyemine/submod/mining/GatherDrops.java index c6a11c98..30748306 100644 --- a/common/src/main/java/com/specialeffect/eyemine/submod/mining/GatherDrops.java +++ b/common/src/main/java/com/specialeffect/eyemine/submod/mining/GatherDrops.java @@ -16,6 +16,7 @@ import com.specialeffect.eyemine.client.Keybindings; import com.specialeffect.eyemine.packets.messages.GatherBlockMessage; import com.specialeffect.eyemine.submod.SubMod; +import com.specialeffect.eyemine.submod.KeyInputUtil; import com.specialeffect.utils.ModUtils; import com.specialeffect.eyemine.event.EventResult; import com.specialeffect.eyemine.event.EyeMineEvents; @@ -55,11 +56,7 @@ public void onInitializeClient() { } private EventResult onKeyInput(Minecraft minecraft, int keyCode, int scanCode, int action, int modifiers) { - if (ModUtils.hasActiveGui()) { - return EventResult.pass(); - } - - if (InputConstants.isKeyDown(minecraft.getWindow(), 292)) { + if (KeyInputUtil.shouldIgnoreKeyInput(minecraft)) { return EventResult.pass(); } diff --git a/common/src/main/java/com/specialeffect/eyemine/submod/mining/MineOne.java b/common/src/main/java/com/specialeffect/eyemine/submod/mining/MineOne.java index d0a14c77..db780c25 100644 --- a/common/src/main/java/com/specialeffect/eyemine/submod/mining/MineOne.java +++ b/common/src/main/java/com/specialeffect/eyemine/submod/mining/MineOne.java @@ -17,7 +17,9 @@ import com.specialeffect.eyemine.mixin.KeyMappingAccessor; import com.specialeffect.eyemine.platform.EyeMineConfig; import com.specialeffect.eyemine.submod.utils.DwellAction; +import com.specialeffect.eyemine.submod.KeyInputUtil; import com.specialeffect.eyemine.submod.utils.TargetBlock; +import com.specialeffect.eyemine.submod.KeyInputUtil; import com.specialeffect.utils.ModUtils; import com.specialeffect.eyemine.event.EventResult; import com.specialeffect.eyemine.event.EyeMineEvents; @@ -120,11 +122,7 @@ private BlockPos getMouseOverBlockPos() { } private EventResult onKeyInput(Minecraft minecraft, int keyCode, int scanCode, int action, int modifiers) { - if (ModUtils.hasActiveGui()) { - return EventResult.pass(); - } - - if (InputConstants.isKeyDown(minecraft.getWindow(), 292)) { + if (KeyInputUtil.shouldIgnoreKeyInput(minecraft)) { return EventResult.pass(); } diff --git a/common/src/main/java/com/specialeffect/eyemine/submod/misc/AutoPillar.java b/common/src/main/java/com/specialeffect/eyemine/submod/misc/AutoPillar.java index a259d4ab..3ab75d60 100644 --- a/common/src/main/java/com/specialeffect/eyemine/submod/misc/AutoPillar.java +++ b/common/src/main/java/com/specialeffect/eyemine/submod/misc/AutoPillar.java @@ -18,6 +18,7 @@ import com.specialeffect.eyemine.client.Keybindings; import com.specialeffect.eyemine.packets.messages.AddItemToHotbar; import com.specialeffect.eyemine.submod.SubMod; +import com.specialeffect.eyemine.submod.KeyInputUtil; import com.specialeffect.utils.ModUtils; import com.specialeffect.eyemine.event.EventResult; import com.specialeffect.eyemine.event.EyeMineEvents; @@ -96,11 +97,7 @@ protected void queueOnLivingCallback(OnLivingCallback onLivingCallback) { } private EventResult onKeyInput(Minecraft minecraft, int keyCode, int scanCode, int action, int modifiers) { - if (ModUtils.hasActiveGui()) { - return EventResult.pass(); - } - - if (InputConstants.isKeyDown(minecraft.getWindow(), 292)) { + if (KeyInputUtil.shouldIgnoreKeyInput(minecraft)) { return EventResult.pass(); } diff --git a/common/src/main/java/com/specialeffect/eyemine/submod/misc/ContinuouslyAttack.java b/common/src/main/java/com/specialeffect/eyemine/submod/misc/ContinuouslyAttack.java index 245df69f..8f35dbec 100644 --- a/common/src/main/java/com/specialeffect/eyemine/submod/misc/ContinuouslyAttack.java +++ b/common/src/main/java/com/specialeffect/eyemine/submod/misc/ContinuouslyAttack.java @@ -19,8 +19,11 @@ import com.specialeffect.eyemine.packets.messages.AddItemToHotbar; import com.specialeffect.eyemine.platform.EyeMineConfig; import com.specialeffect.eyemine.submod.IConfigListener; +import com.specialeffect.eyemine.submod.KeyInputUtil; import com.specialeffect.eyemine.submod.SubMod; +import com.specialeffect.eyemine.submod.KeyInputUtil; import com.specialeffect.eyemine.submod.mining.ContinuouslyMine; +import com.specialeffect.eyemine.submod.KeyInputUtil; import com.specialeffect.eyemine.utils.MouseHelper; import com.specialeffect.utils.ModUtils; import com.specialeffect.eyemine.event.EventResult; @@ -135,11 +138,7 @@ public void onClientTick(Minecraft minecraft) { } private EventResult onKeyInput(Minecraft minecraft, int keyCode, int scanCode, int action, int modifiers) { - if (ModUtils.hasActiveGui()) { - return EventResult.pass(); - } - - if (InputConstants.isKeyDown(minecraft.getWindow(), 292)) { + if (KeyInputUtil.shouldIgnoreKeyInput(minecraft)) { return EventResult.pass(); } diff --git a/common/src/main/java/com/specialeffect/eyemine/submod/misc/DefaultConfigForNewWorld.java b/common/src/main/java/com/specialeffect/eyemine/submod/misc/DefaultConfigForNewWorld.java index 1ea2de39..f32160bc 100644 --- a/common/src/main/java/com/specialeffect/eyemine/submod/misc/DefaultConfigForNewWorld.java +++ b/common/src/main/java/com/specialeffect/eyemine/submod/misc/DefaultConfigForNewWorld.java @@ -11,6 +11,7 @@ package com.specialeffect.eyemine.submod.misc; +import com.specialeffect.eyemine.EyeMine; import com.specialeffect.eyemine.EyeMineClient; import com.specialeffect.eyemine.packets.messages.AddItemToHotbar; import com.specialeffect.eyemine.platform.EyeMineConfig; @@ -141,7 +142,7 @@ private void onWorldLoad(ServerLevel serverLevel) { @SuppressWarnings("unused") private void printGameRules(GameRules rules) { - System.out.println("Game rules:"); + EyeMine.LOGGER.debug("Game rules:"); // We use reflection to print out any relevant fields Field[] fields = rules.getClass().getFields(); diff --git a/common/src/main/java/com/specialeffect/eyemine/submod/misc/DwellBuild.java b/common/src/main/java/com/specialeffect/eyemine/submod/misc/DwellBuild.java index e53e4b9e..c3e919de 100644 --- a/common/src/main/java/com/specialeffect/eyemine/submod/misc/DwellBuild.java +++ b/common/src/main/java/com/specialeffect/eyemine/submod/misc/DwellBuild.java @@ -16,7 +16,9 @@ import com.specialeffect.eyemine.client.Keybindings; import com.specialeffect.eyemine.mixin.KeyMappingAccessor; import com.specialeffect.eyemine.submod.utils.DwellAction; +import com.specialeffect.eyemine.submod.KeyInputUtil; import com.specialeffect.eyemine.submod.utils.TargetBlock; +import com.specialeffect.eyemine.submod.KeyInputUtil; import com.specialeffect.utils.ModUtils; import com.specialeffect.eyemine.event.EventResult; import com.specialeffect.eyemine.event.EyeMineEvents; @@ -67,11 +69,7 @@ public void performAction(TargetBlock block) { } private EventResult onKeyInput(Minecraft minecraft, int keyCode, int scanCode, int action, int modifiers) { - if (ModUtils.hasActiveGui()) { - return EventResult.pass(); - } - - if (InputConstants.isKeyDown(minecraft.getWindow(), 292)) { + if (KeyInputUtil.shouldIgnoreKeyInput(minecraft)) { return EventResult.pass(); } diff --git a/common/src/main/java/com/specialeffect/eyemine/submod/misc/IronSights.java b/common/src/main/java/com/specialeffect/eyemine/submod/misc/IronSights.java index f72b7403..db072fd7 100644 --- a/common/src/main/java/com/specialeffect/eyemine/submod/misc/IronSights.java +++ b/common/src/main/java/com/specialeffect/eyemine/submod/misc/IronSights.java @@ -18,7 +18,9 @@ import com.specialeffect.eyemine.client.gui.crosshair.IconOverlay; import com.specialeffect.eyemine.platform.EyeMineConfig; import com.specialeffect.eyemine.submod.IConfigListener; +import com.specialeffect.eyemine.submod.KeyInputUtil; import com.specialeffect.eyemine.submod.SubMod; +import com.specialeffect.eyemine.submod.KeyInputUtil; import com.specialeffect.utils.ModUtils; import com.specialeffect.eyemine.event.EventResult; import com.specialeffect.eyemine.event.EyeMineEvents; @@ -64,11 +66,7 @@ public void syncConfig() { } private EventResult onKeyInput(Minecraft minecraft, int keyCode, int scanCode, int action, int modifiers) { - if (ModUtils.hasActiveGui()) { - return EventResult.pass(); - } - - if (InputConstants.isKeyDown(minecraft.getWindow(), 292)) { + if (KeyInputUtil.shouldIgnoreKeyInput(minecraft)) { return EventResult.pass(); } diff --git a/common/src/main/java/com/specialeffect/eyemine/submod/misc/OpenChat.java b/common/src/main/java/com/specialeffect/eyemine/submod/misc/OpenChat.java index ef0c77ed..573710c3 100644 --- a/common/src/main/java/com/specialeffect/eyemine/submod/misc/OpenChat.java +++ b/common/src/main/java/com/specialeffect/eyemine/submod/misc/OpenChat.java @@ -16,6 +16,7 @@ import com.specialeffect.eyemine.client.Keybindings; import com.specialeffect.eyemine.mixin.KeyMappingAccessor; import com.specialeffect.eyemine.submod.SubMod; +import com.specialeffect.eyemine.submod.KeyInputUtil; import com.specialeffect.utils.ModUtils; import com.specialeffect.eyemine.event.EventResult; import com.specialeffect.eyemine.event.EyeMineEvents; @@ -41,11 +42,7 @@ public void onInitializeClient() { } private EventResult onKeyInput(Minecraft minecraft, int keyCode, int scanCode, int action, int modifiers) { - if (ModUtils.hasActiveGui()) { - return EventResult.pass(); - } - - if (InputConstants.isKeyDown(minecraft.getWindow(), 292)) { + if (KeyInputUtil.shouldIgnoreKeyInput(minecraft)) { return EventResult.pass(); } diff --git a/common/src/main/java/com/specialeffect/eyemine/submod/misc/OpenTablesChests.java b/common/src/main/java/com/specialeffect/eyemine/submod/misc/OpenTablesChests.java index 99d063d5..bf0559a4 100644 --- a/common/src/main/java/com/specialeffect/eyemine/submod/misc/OpenTablesChests.java +++ b/common/src/main/java/com/specialeffect/eyemine/submod/misc/OpenTablesChests.java @@ -17,7 +17,9 @@ import com.specialeffect.eyemine.mixin.ClientLevelAccessor; import com.specialeffect.eyemine.platform.EyeMineConfig; import com.specialeffect.eyemine.submod.IConfigListener; +import com.specialeffect.eyemine.submod.KeyInputUtil; import com.specialeffect.eyemine.submod.SubMod; +import com.specialeffect.eyemine.submod.KeyInputUtil; import com.specialeffect.utils.ModUtils; import com.specialeffect.eyemine.event.EventResult; import com.specialeffect.eyemine.event.EyeMineEvents; @@ -116,11 +118,7 @@ public BlockHitResult getSimulatedHitResult(ClientLevel level, BlockPos pos) { } private EventResult onKeyInput(Minecraft minecraft, int keyCode, int scanCode, int action, int modifiers) { - if (ModUtils.hasActiveGui()) { - return EventResult.pass(); - } - - if (InputConstants.isKeyDown(minecraft.getWindow(), 292)) { + if (KeyInputUtil.shouldIgnoreKeyInput(minecraft)) { return EventResult.pass(); } diff --git a/common/src/main/java/com/specialeffect/eyemine/submod/misc/PickBlock.java b/common/src/main/java/com/specialeffect/eyemine/submod/misc/PickBlock.java index 1af51753..d876c455 100644 --- a/common/src/main/java/com/specialeffect/eyemine/submod/misc/PickBlock.java +++ b/common/src/main/java/com/specialeffect/eyemine/submod/misc/PickBlock.java @@ -16,6 +16,7 @@ import com.specialeffect.eyemine.client.Keybindings; import com.specialeffect.eyemine.mixin.KeyMappingAccessor; import com.specialeffect.eyemine.submod.SubMod; +import com.specialeffect.eyemine.submod.KeyInputUtil; import com.specialeffect.utils.ModUtils; import com.specialeffect.eyemine.event.EventResult; import com.specialeffect.eyemine.event.EyeMineEvents; @@ -41,11 +42,7 @@ public void onInitializeClient() { } private EventResult onKeyInput(Minecraft minecraft, int keyCode, int scanCode, int action, int modifiers) { - if (ModUtils.hasActiveGui()) { - return EventResult.pass(); - } - - if (InputConstants.isKeyDown(minecraft.getWindow(), 292)) { + if (KeyInputUtil.shouldIgnoreKeyInput(minecraft)) { return EventResult.pass(); } diff --git a/common/src/main/java/com/specialeffect/eyemine/submod/misc/QuickCommands.java b/common/src/main/java/com/specialeffect/eyemine/submod/misc/QuickCommands.java index c36f1a33..fa7ece0f 100644 --- a/common/src/main/java/com/specialeffect/eyemine/submod/misc/QuickCommands.java +++ b/common/src/main/java/com/specialeffect/eyemine/submod/misc/QuickCommands.java @@ -17,6 +17,7 @@ import com.specialeffect.eyemine.packets.messages.SendCommandMessage; import com.specialeffect.eyemine.packets.messages.TeleportPlayerToSpawnPointMessage; import com.specialeffect.eyemine.submod.SubMod; +import com.specialeffect.eyemine.submod.KeyInputUtil; import com.specialeffect.utils.ModUtils; import com.specialeffect.eyemine.event.EventResult; import com.specialeffect.eyemine.event.EyeMineEvents; @@ -78,11 +79,7 @@ public void onInitializeClient() { } private EventResult onKeyInput(Minecraft minecraft, int keyCode, int scanCode, int action, int modifiers) { - if (ModUtils.hasActiveGui()) { - return EventResult.pass(); - } - - if (InputConstants.isKeyDown(minecraft.getWindow(), 292)) { + if (KeyInputUtil.shouldIgnoreKeyInput(minecraft)) { return EventResult.pass(); } diff --git a/common/src/main/java/com/specialeffect/eyemine/submod/misc/SwapMinePlace.java b/common/src/main/java/com/specialeffect/eyemine/submod/misc/SwapMinePlace.java index 86f5efa0..aa366521 100644 --- a/common/src/main/java/com/specialeffect/eyemine/submod/misc/SwapMinePlace.java +++ b/common/src/main/java/com/specialeffect/eyemine/submod/misc/SwapMinePlace.java @@ -17,6 +17,7 @@ import com.specialeffect.eyemine.client.Keybindings; import com.specialeffect.eyemine.mixin.KeyMappingAccessor; import com.specialeffect.eyemine.submod.SubMod; +import com.specialeffect.eyemine.submod.KeyInputUtil; import com.specialeffect.utils.ModUtils; import com.specialeffect.eyemine.event.EventResult; import com.specialeffect.eyemine.event.EyeMineEvents; @@ -44,11 +45,7 @@ public void onInitializeClient() { private static KeyMapping mSwapKB; private EventResult onKeyInput(Minecraft minecraft, int keyCode, int scanCode, int action, int modifiers) { - if (ModUtils.hasActiveGui()) { - return EventResult.pass(); - } - - if (InputConstants.isKeyDown(minecraft.getWindow(), 292)) { + if (KeyInputUtil.shouldIgnoreKeyInput(minecraft)) { return EventResult.pass(); } diff --git a/common/src/main/java/com/specialeffect/eyemine/submod/misc/UseItem.java b/common/src/main/java/com/specialeffect/eyemine/submod/misc/UseItem.java index a3ebf493..2821096c 100644 --- a/common/src/main/java/com/specialeffect/eyemine/submod/misc/UseItem.java +++ b/common/src/main/java/com/specialeffect/eyemine/submod/misc/UseItem.java @@ -17,7 +17,9 @@ import com.specialeffect.eyemine.mixin.KeyMappingAccessor; import com.specialeffect.eyemine.platform.EyeMineConfig; import com.specialeffect.eyemine.submod.utils.DwellAction; +import com.specialeffect.eyemine.submod.KeyInputUtil; import com.specialeffect.eyemine.submod.utils.TargetBlock; +import com.specialeffect.eyemine.submod.KeyInputUtil; import com.specialeffect.utils.ModUtils; import com.specialeffect.eyemine.event.EventResult; import com.specialeffect.eyemine.event.EyeMineEvents; @@ -130,11 +132,7 @@ public void onClientTick(Minecraft minecraft) { } private EventResult onKeyInput(Minecraft minecraft, int keyCode, int scanCode, int action, int modifiers) { - if (ModUtils.hasActiveGui()) { - return EventResult.pass(); - } - - if (InputConstants.isKeyDown(minecraft.getWindow(), 292)) { + if (KeyInputUtil.shouldIgnoreKeyInput(minecraft)) { return EventResult.pass(); } diff --git a/common/src/main/java/com/specialeffect/eyemine/submod/mouse/MouseHandlerMod.java b/common/src/main/java/com/specialeffect/eyemine/submod/mouse/MouseHandlerMod.java index 8da9b266..f59f5fcc 100644 --- a/common/src/main/java/com/specialeffect/eyemine/submod/mouse/MouseHandlerMod.java +++ b/common/src/main/java/com/specialeffect/eyemine/submod/mouse/MouseHandlerMod.java @@ -18,9 +18,13 @@ import com.specialeffect.eyemine.client.gui.crosshair.IconOverlay; import com.specialeffect.eyemine.platform.EyeMineConfig; import com.specialeffect.eyemine.submod.IConfigListener; +import com.specialeffect.eyemine.submod.KeyInputUtil; import com.specialeffect.eyemine.submod.SubMod; +import com.specialeffect.eyemine.submod.KeyInputUtil; import com.specialeffect.eyemine.submod.movement.MoveWithGaze; +import com.specialeffect.eyemine.submod.KeyInputUtil; import com.specialeffect.eyemine.submod.movement.MoveWithGaze2; +import com.specialeffect.eyemine.submod.KeyInputUtil; import com.specialeffect.eyemine.utils.MouseHelper; import com.specialeffect.eyemine.utils.MouseHelper.PlayerMovement; import com.specialeffect.utils.ModUtils; @@ -200,11 +204,7 @@ public void onClientTick(Minecraft minecraft) { } private EventResult onKeyInput(Minecraft minecraft, int keyCode, int scanCode, int action, int modifiers) { - if (ModUtils.hasActiveGui()) { - return EventResult.pass(); - } - - if (InputConstants.isKeyDown(minecraft.getWindow(), 292)) { + if (KeyInputUtil.shouldIgnoreKeyInput(minecraft)) { return EventResult.pass(); } diff --git a/common/src/main/java/com/specialeffect/eyemine/submod/movement/AutoFly.java b/common/src/main/java/com/specialeffect/eyemine/submod/movement/AutoFly.java index 3d7b1907..3fb6f88c 100644 --- a/common/src/main/java/com/specialeffect/eyemine/submod/movement/AutoFly.java +++ b/common/src/main/java/com/specialeffect/eyemine/submod/movement/AutoFly.java @@ -18,7 +18,9 @@ import com.specialeffect.eyemine.packets.messages.ChangeFlyingStateMessage; import com.specialeffect.eyemine.platform.EyeMineConfig; import com.specialeffect.eyemine.submod.IConfigListener; +import com.specialeffect.eyemine.submod.KeyInputUtil; import com.specialeffect.eyemine.submod.SubMod; +import com.specialeffect.eyemine.submod.KeyInputUtil; import com.specialeffect.utils.ModUtils; import com.specialeffect.eyemine.event.EventResult; import com.specialeffect.eyemine.event.EyeMineEvents; @@ -220,11 +222,7 @@ private void flyDown() { } private EventResult onKeyInput(Minecraft minecraft, int keyCode, int scanCode, int action, int modifiers) { - if (ModUtils.hasActiveGui()) { - return EventResult.pass(); - } - - if (InputConstants.isKeyDown(minecraft.getWindow(), 292)) { + if (KeyInputUtil.shouldIgnoreKeyInput(minecraft)) { return EventResult.pass(); } diff --git a/common/src/main/java/com/specialeffect/eyemine/submod/movement/AutoJump.java b/common/src/main/java/com/specialeffect/eyemine/submod/movement/AutoJump.java index 13509af4..b42e8e2a 100644 --- a/common/src/main/java/com/specialeffect/eyemine/submod/movement/AutoJump.java +++ b/common/src/main/java/com/specialeffect/eyemine/submod/movement/AutoJump.java @@ -17,7 +17,9 @@ import com.specialeffect.eyemine.client.gui.crosshair.StateOverlay; import com.specialeffect.eyemine.platform.EyeMineConfig; import com.specialeffect.eyemine.submod.IConfigListener; +import com.specialeffect.eyemine.submod.KeyInputUtil; import com.specialeffect.eyemine.submod.SubMod; +import com.specialeffect.eyemine.submod.KeyInputUtil; import com.specialeffect.utils.ModUtils; import com.specialeffect.eyemine.event.EventResult; import com.specialeffect.eyemine.event.EyeMineEvents; @@ -96,11 +98,7 @@ public void onClientTick(Minecraft minecraft) { } private EventResult onKeyInput(Minecraft minecraft, int keyCode, int scanCode, int action, int modifiers) { - if (ModUtils.hasActiveGui()) { - return EventResult.pass(); - } - - if (InputConstants.isKeyDown(minecraft.getWindow(), 292)) { + if (KeyInputUtil.shouldIgnoreKeyInput(minecraft)) { return EventResult.pass(); } diff --git a/common/src/main/java/com/specialeffect/eyemine/submod/movement/BoatController.java b/common/src/main/java/com/specialeffect/eyemine/submod/movement/BoatController.java index 41ba6f0b..4f5086e4 100644 --- a/common/src/main/java/com/specialeffect/eyemine/submod/movement/BoatController.java +++ b/common/src/main/java/com/specialeffect/eyemine/submod/movement/BoatController.java @@ -11,6 +11,7 @@ package com.specialeffect.eyemine.submod.movement; +import com.specialeffect.eyemine.EyeMine; import com.specialeffect.eyemine.mixin.KeyMappingAccessor; import net.minecraft.client.KeyMapping; import net.minecraft.client.Minecraft; @@ -57,7 +58,7 @@ public void releaseKeys() { // speed [-1, +1] where +1 is for turning right // if abs(speed) > 1, it will just clip the effect private void steer(double speed) { - System.out.println("steer " + speed); + EyeMine.LOGGER.debug("steer {}", speed); final KeyMapping kbLeft = Minecraft.getInstance().options.keyLeft; final KeyMapping kbRight = Minecraft.getInstance().options.keyRight; diff --git a/common/src/main/java/com/specialeffect/eyemine/submod/movement/Dismount.java b/common/src/main/java/com/specialeffect/eyemine/submod/movement/Dismount.java index 945afb6e..45e6119a 100644 --- a/common/src/main/java/com/specialeffect/eyemine/submod/movement/Dismount.java +++ b/common/src/main/java/com/specialeffect/eyemine/submod/movement/Dismount.java @@ -15,6 +15,7 @@ import com.mojang.blaze3d.platform.InputConstants.Type; import com.specialeffect.eyemine.client.Keybindings; import com.specialeffect.eyemine.submod.SubMod; +import com.specialeffect.eyemine.submod.KeyInputUtil; import com.specialeffect.utils.ModUtils; import com.specialeffect.eyemine.event.EventResult; import com.specialeffect.eyemine.event.EyeMineEvents; @@ -57,11 +58,7 @@ public void onInitializeClient() { } private EventResult onKeyInput(Minecraft minecraft, int keyCode, int scanCode, int action, int modifiers) { - if (ModUtils.hasActiveGui()) { - return EventResult.pass(); - } - - if (InputConstants.isKeyDown(minecraft.getWindow(), 292)) { + if (KeyInputUtil.shouldIgnoreKeyInput(minecraft)) { return EventResult.pass(); } diff --git a/common/src/main/java/com/specialeffect/eyemine/submod/movement/MoveWithGaze.java b/common/src/main/java/com/specialeffect/eyemine/submod/movement/MoveWithGaze.java index 758b2b94..5f108c1c 100644 --- a/common/src/main/java/com/specialeffect/eyemine/submod/movement/MoveWithGaze.java +++ b/common/src/main/java/com/specialeffect/eyemine/submod/movement/MoveWithGaze.java @@ -19,9 +19,13 @@ import com.specialeffect.eyemine.mixin.KeyMappingAccessor; import com.specialeffect.eyemine.platform.EyeMineConfig; import com.specialeffect.eyemine.submod.IConfigListener; +import com.specialeffect.eyemine.submod.KeyInputUtil; import com.specialeffect.eyemine.submod.SubMod; +import com.specialeffect.eyemine.submod.KeyInputUtil; import com.specialeffect.eyemine.submod.misc.ContinuouslyAttack; +import com.specialeffect.eyemine.submod.KeyInputUtil; import com.specialeffect.eyemine.submod.mouse.MouseHandlerMod; +import com.specialeffect.eyemine.submod.KeyInputUtil; import com.specialeffect.eyemine.utils.KeyboardInputHelper; import com.specialeffect.eyemine.utils.MouseHelper; import com.specialeffect.utils.ModUtils; @@ -366,11 +370,7 @@ public static boolean isWalking() { } private EventResult onKeyInput(Minecraft minecraft, int keyCode, int scanCode, int action, int modifiers) { - if (ModUtils.hasActiveGui()) { - return EventResult.pass(); - } - - if (InputConstants.isKeyDown(minecraft.getWindow(), 292)) { + if (KeyInputUtil.shouldIgnoreKeyInput(minecraft)) { return EventResult.pass(); } diff --git a/common/src/main/java/com/specialeffect/eyemine/submod/movement/MoveWithGaze2.java b/common/src/main/java/com/specialeffect/eyemine/submod/movement/MoveWithGaze2.java index e33d5a8c..47b37f61 100644 --- a/common/src/main/java/com/specialeffect/eyemine/submod/movement/MoveWithGaze2.java +++ b/common/src/main/java/com/specialeffect/eyemine/submod/movement/MoveWithGaze2.java @@ -19,8 +19,11 @@ import com.specialeffect.eyemine.client.gui.crosshair.StateOverlay; import com.specialeffect.eyemine.platform.EyeMineConfig; import com.specialeffect.eyemine.submod.IConfigListener; +import com.specialeffect.eyemine.submod.KeyInputUtil; import com.specialeffect.eyemine.submod.SubMod; +import com.specialeffect.eyemine.submod.KeyInputUtil; import com.specialeffect.eyemine.submod.mouse.MouseHandlerMod; +import com.specialeffect.eyemine.submod.KeyInputUtil; import com.specialeffect.eyemine.utils.KeyboardInputHelper; import com.specialeffect.eyemine.utils.MouseHelper; import com.specialeffect.utils.ModUtils; @@ -145,11 +148,7 @@ public void onClientTick(Minecraft minecraft) { private static boolean mDoingAutoWalk = false; private EventResult onKeyInput(Minecraft minecraft, int keyCode, int scanCode, int action, int modifiers) { - if (ModUtils.hasActiveGui()) { - return EventResult.pass(); - } - - if (InputConstants.isKeyDown(minecraft.getWindow(), 292)) { + if (KeyInputUtil.shouldIgnoreKeyInput(minecraft)) { return EventResult.pass(); } diff --git a/common/src/main/java/com/specialeffect/eyemine/submod/movement/Sneak.java b/common/src/main/java/com/specialeffect/eyemine/submod/movement/Sneak.java index 47860416..15a56dad 100644 --- a/common/src/main/java/com/specialeffect/eyemine/submod/movement/Sneak.java +++ b/common/src/main/java/com/specialeffect/eyemine/submod/movement/Sneak.java @@ -17,6 +17,7 @@ import com.specialeffect.eyemine.client.gui.crosshair.StateOverlay; import com.specialeffect.eyemine.mixin.KeyMappingAccessor; import com.specialeffect.eyemine.submod.SubMod; +import com.specialeffect.eyemine.submod.KeyInputUtil; import com.specialeffect.eyemine.utils.KeyboardInputHelper; import com.specialeffect.utils.ModUtils; import com.specialeffect.eyemine.event.EventResult; @@ -85,11 +86,7 @@ private static void updateSneak(boolean bSneak) { } private EventResult onKeyInput(Minecraft minecraft, int keyCode, int scanCode, int action, int modifiers) { - if (ModUtils.hasActiveGui()) { - return EventResult.pass(); - } - - if (InputConstants.isKeyDown(minecraft.getWindow(), 292)) { + if (KeyInputUtil.shouldIgnoreKeyInput(minecraft)) { return EventResult.pass(); } diff --git a/common/src/main/java/com/specialeffect/eyemine/submod/movement/Swim.java b/common/src/main/java/com/specialeffect/eyemine/submod/movement/Swim.java index 5758f564..fcf0388f 100644 --- a/common/src/main/java/com/specialeffect/eyemine/submod/movement/Swim.java +++ b/common/src/main/java/com/specialeffect/eyemine/submod/movement/Swim.java @@ -17,6 +17,7 @@ import com.specialeffect.eyemine.client.gui.crosshair.StateOverlay; import com.specialeffect.eyemine.mixin.KeyMappingAccessor; import com.specialeffect.eyemine.submod.SubMod; +import com.specialeffect.eyemine.submod.KeyInputUtil; import com.specialeffect.utils.ModUtils; import com.specialeffect.eyemine.event.EventResult; import com.specialeffect.eyemine.event.EyeMineEvents; @@ -112,11 +113,7 @@ else if ((player.onGround() || isPlayerInAir(player)) && } private EventResult onKeyInput(Minecraft minecraft, int keyCode, int scanCode, int action, int modifiers) { - if (ModUtils.hasActiveGui()) { - return EventResult.pass(); - } - - if (InputConstants.isKeyDown(minecraft.getWindow(), 292)) { + if (KeyInputUtil.shouldIgnoreKeyInput(minecraft)) { return EventResult.pass(); } diff --git a/common/src/main/java/com/specialeffect/eyemine/submod/utils/DwellAction.java b/common/src/main/java/com/specialeffect/eyemine/submod/utils/DwellAction.java index 9c50243e..f7fa1ad2 100644 --- a/common/src/main/java/com/specialeffect/eyemine/submod/utils/DwellAction.java +++ b/common/src/main/java/com/specialeffect/eyemine/submod/utils/DwellAction.java @@ -11,6 +11,7 @@ package com.specialeffect.eyemine.submod.utils; +import com.specialeffect.eyemine.EyeMine; import com.irtimaled.bbor.client.renderers.AbstractRenderer; import com.mojang.blaze3d.vertex.PoseStack; import com.mojang.blaze3d.vertex.VertexConsumer; @@ -135,7 +136,7 @@ public void onClientTick(Minecraft minecraft) { // Place block if dwell complete if (currentTarget != null && liveTargets.get(currentTarget).hasCompleted()) { - System.out.println("Performing"); + EyeMine.LOGGER.debug("Performing dwell action"); this.performAction(currentTarget); liveTargets.remove(currentTarget); if (oneShot) { diff --git a/common/src/main/java/com/specialeffect/inventory/manager/CreativeInventoryManager.java b/common/src/main/java/com/specialeffect/inventory/manager/CreativeInventoryManager.java index bd48dbca..d96bb2cd 100644 --- a/common/src/main/java/com/specialeffect/inventory/manager/CreativeInventoryManager.java +++ b/common/src/main/java/com/specialeffect/inventory/manager/CreativeInventoryManager.java @@ -11,6 +11,7 @@ package com.specialeffect.inventory.manager; +import com.specialeffect.eyemine.EyeMine; import com.specialeffect.eyemine.platform.InventoryConfig; import com.specialeffect.eyemine.utils.MouseHelper; import com.specialeffect.utils.ModUtils; @@ -139,7 +140,7 @@ private void updateItemPos() { // This allows users to set cursor position manually and then make adjustments // with prev/next MouseHandler helper = Minecraft.getInstance().mouseHandler; - System.out.println(helper.xpos() + ", " + helper.ypos()); + EyeMine.LOGGER.debug("Creative inventory pos: {}, {}", helper.xpos(), helper.ypos()); int x = (int) (helper.xpos() / this.xScale); int y = (int) (helper.ypos() / this.yScale); int i = ModUtils.findSlotInContainer(creativeContainer, guiLeft, guiTop, x, y, itemWidth); diff --git a/common/src/main/java/com/specialeffect/utils/ModUtils.java b/common/src/main/java/com/specialeffect/utils/ModUtils.java index f4997a95..6a39a9f9 100644 --- a/common/src/main/java/com/specialeffect/utils/ModUtils.java +++ b/common/src/main/java/com/specialeffect/utils/ModUtils.java @@ -106,16 +106,6 @@ public static Point getCompassPoint(int i) { } return p; } -// -// public static Point getScaledDisplaySize(Minecraft mc) { -// Point p = new Point(0, 0); -// ScaledResolution res = new ScaledResolution(mc); -// p.setLocation(res.getScaledWidth(), res.getScaledHeight()); -// -// return p; -// -// } - // Find an item in the hotbar which matches the given class // (this includes all subclasses) @@ -187,44 +177,6 @@ public static BlockHitResult getMouseOverBlock() { } } - // Check if there's a block at the given position which - // blocks movement. - @SuppressWarnings("unused") - private boolean doesBlockMovement(BlockPos pos) { - Level world = Minecraft.getInstance().level; - return world.getBlockState(pos).blocksMotion(); - } - - @SuppressWarnings("unused") - private boolean isDirectlyFacingSideHit(Direction sideHit, Vec3 lookVec) { - double thresh = 0.8; - switch (sideHit) { - case NORTH: - if (lookVec.z > thresh) { - return true; - } - break; - case EAST: - if (lookVec.x < -thresh) { - return true; - } - break; - case SOUTH: - if (lookVec.z < -thresh) { - return true; - } - break; - case WEST: - if (lookVec.x > thresh) { - return true; - } - break; - default: - break; - } - return false; - } - public static BlockPos highestSolidPoint(BlockPos pos) { // Gets a spawn-able location above the point // Highest solid block that isn't foliage diff --git a/fabric/src/main/java/com/specialeffect/eyemine/EyeMineClientFabric.java b/fabric/src/main/java/com/specialeffect/eyemine/EyeMineClientFabric.java index e90429a4..2a9bfff0 100644 --- a/fabric/src/main/java/com/specialeffect/eyemine/EyeMineClientFabric.java +++ b/fabric/src/main/java/com/specialeffect/eyemine/EyeMineClientFabric.java @@ -12,6 +12,7 @@ import net.fabricmc.fabric.api.client.rendering.v1.hud.HudElementRegistry; import net.fabricmc.fabric.api.client.rendering.v1.level.LevelRenderEvents; import net.fabricmc.fabric.api.entity.event.v1.ServerLivingEntityEvents; +import net.fabricmc.fabric.api.event.lifecycle.v1.ServerEntityEvents; import net.fabricmc.fabric.api.event.lifecycle.v1.ServerLevelEvents; import net.minecraft.client.KeyMapping; import net.minecraft.client.Minecraft; @@ -87,11 +88,27 @@ private void registerEventForwarders() { return true; }); + // Server-side: Entity added to world + ServerEntityEvents.ENTITY_LOAD.register((entity, level) -> { + for (var listener : EyeMineEvents.ENTITY_ADD.getListeners()) { + listener.onAdd(entity, level); + } + }); + // Server-side: World load ServerLevelEvents.LOAD.register((server, level) -> { for (var listener : EyeMineEvents.WORLD_LOAD.getListeners()) { listener.onWorldLoad(level); } }); + + // Server-side: Player tick - Fabric uses ClientTickEvents for client-side player tick + ClientTickEvents.END_CLIENT_TICK.register(client -> { + if (client.player != null) { + for (var listener : EyeMineEvents.PLAYER_TICK.getListeners()) { + listener.onPlayerTick(client.player); + } + } + }); } } diff --git a/neoforge/src/main/java/com/specialeffect/eyemine/client/neoforge/ClientHandler.java b/neoforge/src/main/java/com/specialeffect/eyemine/client/neoforge/ClientHandler.java index ea31a001..db227184 100644 --- a/neoforge/src/main/java/com/specialeffect/eyemine/client/neoforge/ClientHandler.java +++ b/neoforge/src/main/java/com/specialeffect/eyemine/client/neoforge/ClientHandler.java @@ -29,6 +29,7 @@ import net.neoforged.neoforge.event.entity.EntityJoinLevelEvent; import net.neoforged.neoforge.event.entity.living.LivingDeathEvent; import net.neoforged.neoforge.event.level.LevelEvent; +import net.neoforged.neoforge.event.tick.PlayerTickEvent; @EventBusSubscriber(modid = EyeMine.MOD_ID, value = Dist.CLIENT) public class ClientHandler { @@ -100,6 +101,13 @@ public static void onEntityJoin(EntityJoinLevelEvent event) { } } + @SubscribeEvent + public static void onPlayerTick(PlayerTickEvent.Post event) { + for (var listener : EyeMineEvents.PLAYER_TICK.getListeners()) { + listener.onPlayerTick(event.getEntity()); + } + } + @SubscribeEvent public static void onWorldLoad(LevelEvent.Load event) { if (event.getLevel() instanceof ServerLevel serverLevel) { diff --git a/neoforge/src/main/java/com/specialeffect/eyemine/neoforge/EyeMineNeoForge.java b/neoforge/src/main/java/com/specialeffect/eyemine/neoforge/EyeMineNeoForge.java index 72f21a3e..95f2308c 100644 --- a/neoforge/src/main/java/com/specialeffect/eyemine/neoforge/EyeMineNeoForge.java +++ b/neoforge/src/main/java/com/specialeffect/eyemine/neoforge/EyeMineNeoForge.java @@ -5,11 +5,11 @@ import com.specialeffect.eyemine.EyeMineClient; import com.specialeffect.eyemine.client.Keybindings; import com.specialeffect.eyemine.config.EyeMineConfig; +import com.specialeffect.eyemine.client.neoforge.ClientHandler; import com.specialeffect.eyemine.platform.neoforge.NeoForgeNetworkService; import net.minecraft.client.KeyMapping; import net.neoforged.api.distmarker.Dist; import net.neoforged.bus.api.IEventBus; -import net.neoforged.bus.api.SubscribeEvent; import net.neoforged.fml.ModContainer; import net.neoforged.fml.common.Mod; import net.neoforged.fml.config.ModConfig; @@ -31,6 +31,7 @@ public EyeMineNeoForge(IEventBus eventBus, ModContainer container, Dist dist) { eventBus.register(InventoryConfig.class); eventBus.addListener(this::registerKeyMappings); + eventBus.addListener(ClientHandler::onSetup); EyeMineClient.init(); } From 7abb4518ac7075a9b75a4f9e1c0f9aa83f376621 Mon Sep 17 00:00:00 2001 From: Saereth Date: Wed, 8 Apr 2026 05:19:15 -0700 Subject: [PATCH 3/4] Update mouse handling and metadata for Minecraft 26.1.1 compatibility --- .../specialeffect/eyemine/mixin/MouseHandlerAccessor.java | 5 +++-- .../java/com/specialeffect/eyemine/utils/MouseHelper.java | 3 ++- common/src/main/resources/eyemine-common.mixins.json | 2 +- common/src/main/resources/pack.mcmeta | 6 ++++-- fabric/src/main/resources/eyemine.fabric.mixins.json | 2 +- neoforge/build.gradle | 6 ++++++ 6 files changed, 17 insertions(+), 7 deletions(-) diff --git a/common/src/main/java/com/specialeffect/eyemine/mixin/MouseHandlerAccessor.java b/common/src/main/java/com/specialeffect/eyemine/mixin/MouseHandlerAccessor.java index 0c426c80..175cbb13 100644 --- a/common/src/main/java/com/specialeffect/eyemine/mixin/MouseHandlerAccessor.java +++ b/common/src/main/java/com/specialeffect/eyemine/mixin/MouseHandlerAccessor.java @@ -1,6 +1,7 @@ package com.specialeffect.eyemine.mixin; import net.minecraft.client.MouseHandler; +import net.minecraft.client.input.MouseButtonInfo; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.gen.Invoker; @@ -12,6 +13,6 @@ public interface MouseHandlerAccessor { @Invoker("onScroll") void invokeOnScroll(long l, double d, double e); - @Invoker("onPress") - void invokeOnPress(long l, int i, int j, int k); + @Invoker("onButton") + void invokeOnButton(long l, MouseButtonInfo buttonInfo, int action); } diff --git a/common/src/main/java/com/specialeffect/eyemine/utils/MouseHelper.java b/common/src/main/java/com/specialeffect/eyemine/utils/MouseHelper.java index e8c9446f..21bd905f 100644 --- a/common/src/main/java/com/specialeffect/eyemine/utils/MouseHelper.java +++ b/common/src/main/java/com/specialeffect/eyemine/utils/MouseHelper.java @@ -126,7 +126,8 @@ public void scroll(MouseHandler mouseHandler, double amount) { */ public void mouseButton(int button, int action, int mods) { long handle = Minecraft.getInstance().getWindow().handle(); - ((MouseHandlerAccessor) Minecraft.getInstance().mouseHandler).invokeOnPress(handle, button, action, mods); + ((MouseHandlerAccessor) Minecraft.getInstance().mouseHandler).invokeOnButton( + handle, new net.minecraft.client.input.MouseButtonInfo(button, mods), action); } public static void setMovementState(PlayerMovement state) { diff --git a/common/src/main/resources/eyemine-common.mixins.json b/common/src/main/resources/eyemine-common.mixins.json index a1473297..af30c30e 100644 --- a/common/src/main/resources/eyemine-common.mixins.json +++ b/common/src/main/resources/eyemine-common.mixins.json @@ -1,7 +1,7 @@ { "required": true, "minVersion": "0.8.4", - "compatibilityLevel": "JAVA_25", + "compatibilityLevel": "JAVA_22", "package": "com.specialeffect.eyemine.mixin", "target": "@env(DEFAULT)", "mixins": [ diff --git a/common/src/main/resources/pack.mcmeta b/common/src/main/resources/pack.mcmeta index f41cd148..eb5231a1 100644 --- a/common/src/main/resources/pack.mcmeta +++ b/common/src/main/resources/pack.mcmeta @@ -1,8 +1,10 @@ { "pack": { "description": { - "text": "EyeMine Mod" + "text": "${mod_name}" }, - "pack_format": 71 + "pack_format": 84, + "min_format": 84, + "max_format": 84 } } diff --git a/fabric/src/main/resources/eyemine.fabric.mixins.json b/fabric/src/main/resources/eyemine.fabric.mixins.json index 603aed09..76bfa73c 100644 --- a/fabric/src/main/resources/eyemine.fabric.mixins.json +++ b/fabric/src/main/resources/eyemine.fabric.mixins.json @@ -2,7 +2,7 @@ "required": true, "minVersion": "0.8", "package": "com.specialeffect.eyemine.mixin", - "compatibilityLevel": "JAVA_25", + "compatibilityLevel": "JAVA_22", "client": [ "FabricKeyboardHandlerMixin", "FabricSetScreenMixin" diff --git a/neoforge/build.gradle b/neoforge/build.gradle index 4c9e51b2..bfa4914f 100644 --- a/neoforge/build.gradle +++ b/neoforge/build.gradle @@ -12,6 +12,12 @@ neoForge { accessTransformers.from(accessTransformerFile) } + mods { + "${mod_id}" { + sourceSet sourceSets.main + } + } + runs { client { client() From 1db7b305f963f24f5a89b7e67f7c1895b250fcee Mon Sep 17 00:00:00 2001 From: Saereth Date: Mon, 13 Apr 2026 11:57:26 -0700 Subject: [PATCH 4/4] Fix movement axis mapping and ensure config persistence - Correct KeyboardInput moveVector mapping to use the y-axis for forward movement - Trigger a configuration save when updating the custom speed factor on Fabric and NeoForge - Remove redundant cursor mode override in MouseHandler --- .../eyemine/mixin/KeyboardInputMixin.java | 5 ++--- .../specialeffect/eyemine/mixin/MouseHandlerMixin.java | 10 ---------- .../eyemine/platform/fabric/EyeMineConfigImpl.java | 5 ++++- .../eyemine/platform/neoforge/EyeMineConfigImpl.java | 5 ++++- 4 files changed, 10 insertions(+), 15 deletions(-) diff --git a/common/src/main/java/com/specialeffect/eyemine/mixin/KeyboardInputMixin.java b/common/src/main/java/com/specialeffect/eyemine/mixin/KeyboardInputMixin.java index 408d4e9b..5a7d9ea9 100644 --- a/common/src/main/java/com/specialeffect/eyemine/mixin/KeyboardInputMixin.java +++ b/common/src/main/java/com/specialeffect/eyemine/mixin/KeyboardInputMixin.java @@ -32,7 +32,7 @@ public class KeyboardInputMixin extends ClientInput { * 1. Set the forward flag to true in keyPresses * 2. Override moveVector.x (forward impulse) with the fractional walk speed * - * moveVector is a Vec2 where x = forward/backward impulse, y = left/right impulse + * moveVector is a Vec2 where x = left/right (strafe) impulse, y = forward/backward impulse */ @Inject(method = "tick()V", at = @At("TAIL")) public void eyemine$overrideWalkForward(CallbackInfo ci) { @@ -47,9 +47,8 @@ public class KeyboardInputMixin extends ClientInput { current.shift(), current.sprint() ); - // Override the move vector with fractional walk speed float speed = Math.max(-1, Math.min(1, KeyboardInputHelper.mOverrideWalkSpeed)); - this.moveVector = new Vec2(speed, this.moveVector.y); + this.moveVector = new Vec2(this.moveVector.x, speed); } } } diff --git a/common/src/main/java/com/specialeffect/eyemine/mixin/MouseHandlerMixin.java b/common/src/main/java/com/specialeffect/eyemine/mixin/MouseHandlerMixin.java index 3a915a61..18029ebb 100644 --- a/common/src/main/java/com/specialeffect/eyemine/mixin/MouseHandlerMixin.java +++ b/common/src/main/java/com/specialeffect/eyemine/mixin/MouseHandlerMixin.java @@ -99,16 +99,6 @@ public abstract class MouseHandlerMixin { MouseHelper.addPendingEvent(); } - /** - * Set cursor to normal mode before vanilla processes - this allows us to read position - */ - @Inject(method = "onMove(JDD)V", at = @At(value = "FIELD", - target = "Lnet/minecraft/client/MouseHandler;minecraft:Lnet/minecraft/client/Minecraft;", - ordinal = 0)) - public void eyemine$setInputMode(long handle, double xpos, double ypos, CallbackInfo ci) { - GLFW.glfwSetInputMode(this.minecraft.getWindow().handle(), GLFW.GLFW_CURSOR, GLFW.GLFW_CURSOR_NORMAL); - } - /** * Main injection point - replaces vanilla onMove logic after the window handle check */ diff --git a/fabric/src/main/java/com/specialeffect/eyemine/platform/fabric/EyeMineConfigImpl.java b/fabric/src/main/java/com/specialeffect/eyemine/platform/fabric/EyeMineConfigImpl.java index 542b7631..8026664c 100644 --- a/fabric/src/main/java/com/specialeffect/eyemine/platform/fabric/EyeMineConfigImpl.java +++ b/fabric/src/main/java/com/specialeffect/eyemine/platform/fabric/EyeMineConfigImpl.java @@ -10,7 +10,10 @@ private EyeMineConfig getConfig() { } @Override public boolean getDisableCustomNewWorld() { return getConfig().advanced.disableCustomNewWorld; } - @Override public void setCustomSpeedFactor(float speed) { getConfig().general.customSpeedFactor = speed; } + @Override public void setCustomSpeedFactor(float speed) { + getConfig().general.customSpeedFactor = speed; + AutoConfig.getConfigHolder(EyeMineConfig.class).save(); + } @Override public boolean getUsingMouseEmulation() { return getConfig().general.usingMouseEmulation; } @Override public boolean getAutoSelectTool() { return getConfig().general.autoSelectTool; } @Override public boolean getAutoSelectSword() { return getConfig().general.autoSelectSword; } diff --git a/neoforge/src/main/java/com/specialeffect/eyemine/platform/neoforge/EyeMineConfigImpl.java b/neoforge/src/main/java/com/specialeffect/eyemine/platform/neoforge/EyeMineConfigImpl.java index d72590db..6af7e02f 100644 --- a/neoforge/src/main/java/com/specialeffect/eyemine/platform/neoforge/EyeMineConfigImpl.java +++ b/neoforge/src/main/java/com/specialeffect/eyemine/platform/neoforge/EyeMineConfigImpl.java @@ -5,7 +5,10 @@ public class EyeMineConfigImpl implements IEyeMineConfigService { @Override public boolean getDisableCustomNewWorld() { return EyeMineConfig.disableCustomNewWorld.get(); } - @Override public void setCustomSpeedFactor(float speed) { EyeMineConfig.customSpeedFactor.set((double) speed); } + @Override public void setCustomSpeedFactor(float speed) { + EyeMineConfig.customSpeedFactor.set((double) speed); + EyeMineConfig.customSpeedFactor.save(); + } @Override public boolean getUsingMouseEmulation() { return EyeMineConfig.usingMouseEmulation.get(); } @Override public boolean getAutoSelectTool() { return EyeMineConfig.autoSelectTool.get(); } @Override public boolean getAutoSelectSword() { return EyeMineConfig.autoSelectSword.get(); }