Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
46 changes: 35 additions & 11 deletions build.gradle.kts
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
@file:Suppress("UnstableApiUsage")

plugins {
id("controlify-common")

Expand All @@ -16,12 +18,23 @@ base.archivesName = "controlify"

java.toolchain.languageVersion = JavaLanguageVersion.of(25)

val fabricModDependency = configurations.dependencyScope("fabricModDependency")
configurations.fabricCompileOnly { extendsFrom(fabricModDependency) }
configurations.fabricLocalRuntime { extendsFrom(fabricModDependency) }

val neoforgeModDependency = configurations.dependencyScope("neoforgeModDependency")
configurations.neoforgeCompileOnly { extendsFrom(neoforgeModDependency) }
configurations.neoforgeLocalRuntime { extendsFrom(neoforgeModDependency) }

val fabricApiBom = dependencies.platform("net.fabricmc.fabric-api:fabric-api-bom:${property("dep.fapi")}")

dependencies {
minecraft("com.mojang:minecraft:$minecraftVersion")
fabricLoader(libs.fabric.loader)
neoforgeImplementation("net.neoforged:neoforge:${property("dep.neoforge")}")

ifPresent("dep.neoforge") {
neoforgeImplementation("net.neoforged:neoforge:${property("dep.neoforge")}")
}

implementation(fabricApiBom)
fabricImplementation(fabricApiBom)
Expand All @@ -37,7 +50,7 @@ dependencies {
fabricImplementation("net.fabricmc.fabric-api:fabric-convention-tags-v2")
// this needs to be on main because fabric is shared with main jar
implementation("net.fabricmc.fabric-api:fabric-transitive-access-wideners-v1")
fabricRuntimeOnly("net.fabricmc.fabric-api:fabric-api")
fabricLocalRuntime("net.fabricmc.fabric-api:fabric-api")

commonApi(libs.sdl.java.api)
commonInclude(libs.sdl.java.api)
Expand All @@ -63,25 +76,25 @@ dependencies {
compileOnly("net.caffeinemc:sodium-fabric:$it") {
exclude(group = "net.fabricmc.fabric-api")
}
fabricCompileOnly("net.caffeinemc:sodium-fabric:$it")
neoforgeCompileOnly("net.caffeinemc:sodium-neoforge:$it")
neoforgeCompileOnly("net.caffeinemc:sodium-neoforge-mod:$it")
fabricModDependency("net.caffeinemc:sodium-fabric:$it")
neoforgeModDependency("net.caffeinemc:sodium-neoforge:$it")
neoforgeModDependency("net.caffeinemc:sodium-neoforge-mod:$it")
}

ifPresent("dep.iris") {
compileOnly("maven.modrinth:iris:$it")
fabricCompileOnly("maven.modrinth:iris:$it")
fabricCompileOnly("maven.modrinth:iris:$it")
}
ifPresent("dep.iris-neoforge") {
neoforgeCompileOnly("maven.modrinth:iris:$it")
}

ifPresent("dep.rso") {
compileOnly("maven.modrinth:reeses-sodium-options:$it")
fabricCompileOnly("maven.modrinth:reeses-sodium-options:$it")
fabricModDependency("maven.modrinth:reeses-sodium-options:$it")
}
ifPresent("dep.rso-neoforge") {
neoforgeCompileOnly("maven.modrinth:reeses-sodium-options:$it")
neoforgeModDependency("maven.modrinth:reeses-sodium-options:$it")
}

ifPresent("dep.svc") {
Expand Down Expand Up @@ -116,8 +129,10 @@ stonecutter {

/// Run configurations

runs.register("neoforgeClient") {
runType("client")
ifPresent("dep.neoforge") {
runs.register("neoforgeClient") {
runType("client")
}
}

/// Metadata file generation
Expand Down Expand Up @@ -193,10 +208,19 @@ tasks.withType<Jar>().configureEach {
tasks.withType<JavaCompile>().configureEach {
options.compilerArgs.add("-parameters")
}
// Mixin 0.17.4 changed ModifyArg/ModifyVariable.at from At to At[]. Align the
// compile APIs so common annotation encoding matches in the NeoForge check.
// Existing Mixin runtimes accept both encodings; leave runtime dependencies unchanged.
if (minecraftVersion == "26.3") {
configurations.named("neoforgeCompileClasspath") {
resolutionStrategy.force("net.fabricmc:sponge-mixin:0.17.4+mixin.0.8.7")
}
}

/// Natives in the jar

val includeNatives = sc.current.parsed < "26.3"
//val includeNatives = sc.current.parsed < "26.3"
val includeNatives = true

stonecutter.constants.put("natives_in_jar", includeNatives)

Expand Down
2 changes: 1 addition & 1 deletion gradle/libs.versions.toml
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ modstitch_manifests = "0.1.5"
modstitch_multiloader = "0.1.8"
modstitch_modrepos = "0.1.2"
fabric_loom = "1.17.16"
neoforged_gradle = "7.1.38"
neoforged_gradle = "7.1.39"
spotless = "8.6.0"
undercouch_download = "5.6.0"
wiki_toolkit = "0.4.1"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,11 @@ public class TestUnitWorldContext implements ReversibleCallback {
public TestUnitWorldContext(ClientGameTestContext context) {
this.context = context;
this.world = context.worldBuilder().setUseConsistentSettings(true).create();
this.world.getClientLevel().waitForChunksDownload();
//? if >=26.2 {
this.world.getConnection().waitForChunksDownload();
//?} else {
/*this.world.getClientLevel().waitForChunksDownload();
*///?}
this.level = this.world.getServer().computeOnServer(server -> CTestUtil.getPrincipalPlayer(server).level());
this.floorY = this.world.getServer().computeOnServer(server -> {
var player = CTestUtil.getPrincipalPlayer(server);
Expand All @@ -67,7 +71,11 @@ public TestRegionContext allocateRegion(Vec3i size) {
context.waitTick();
region.teleportPlayer(new BlockPos(1, 1, 1));
context.waitTick();
getWorld().getClientLevel().waitForChunksRender();
//? if >=26.2 {
getWorld().getConnection().waitForChunksRender();
//?} else {
/*getWorld().getClientLevel().waitForChunksRender();
*///?}
return region;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,11 @@ public void runTest(ClientGameTestContext context) {
.withDualsense()
.attachWithDriver(new DualsenseEffectDriver())) {
try (var world = context.worldBuilder().create()) {
world.getClientLevel().waitForChunksRender();
//? if >=26.2 {
world.getConnection().waitForChunksRender();
//?} else {
/*world.getClientLevel().waitForChunksRender();
*///?}

setServerHands(world, new ItemStack(Items.DIAMOND_SWORD), new ItemStack(Items.SHIELD));
context.waitTick();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@

import dev.isxander.controlify.gametest.framework.CTestUtil;
import dev.isxander.controlify.gametest.framework.controller.ControlifyGameTestContext;
import dev.isxander.controlify.screenop.keyboard.KeyboardWidget;
import dev.isxander.controlify.utils.MinecraftUtil;
import dev.isxander.sdl.SdlGamepad;
import net.fabricmc.api.ClientModInitializer;
import net.fabricmc.fabric.api.client.gametest.v1.FabricClientGameTest;
Expand All @@ -17,6 +19,9 @@
import net.minecraft.client.gui.screens.ChatScreen;
import net.minecraft.resources.Identifier;

import java.util.Optional;
import java.util.stream.Stream;

@SuppressWarnings("UnstableApiUsage")
public class KeyboardLayoutTests implements FabricClientGameTest, ClientModInitializer {
private static final Identifier RESOURCE_PACK_ID = CTestUtil.id("keyboard_layout_test");
Expand All @@ -32,7 +37,11 @@ public void runTest(ClientGameTestContext context) {

try (var world = context.worldBuilder()
.create()) {
world.getClientLevel().waitForChunksRender();
//? if >=26.2 {
world.getConnection().waitForChunksRender();
//?} else {
/*world.getClientLevel().waitForChunksRender();
*///?}

runLocaleTest(context, controlify);
}
Expand All @@ -55,10 +64,7 @@ private void runLocaleTest(ClientGameTestContext context, ControlifyGameTestCont
context.waitForScreen(ChatScreen.class);

// check american keyboard layout
context.assertScreenshotContains(TestScreenshotComparisonOptions
.of("keyboard_layout_en_us")
.save()
.withAlgorithm(TestScreenshotComparisonAlgorithm.meanSquaredDifference(0.001f)));
assertKeyboard(context, "en_us");

// press back button to close on-screen keyboard
controller.tapButton(SdlGamepad.SDL_GAMEPAD_BUTTON_EAST);
Expand All @@ -71,16 +77,10 @@ private void runLocaleTest(ClientGameTestContext context, ControlifyGameTestCont
context.waitForScreen(ChatScreen.class);

// check british keyboard layout
context.assertScreenshotContains(TestScreenshotComparisonOptions
.of("keyboard_layout_en_gb")
.save()
.withAlgorithm(TestScreenshotComparisonAlgorithm.meanSquaredDifference(0.001f)));
assertKeyboard(context, "en_gb");
}
// change language without closing chat screen and check en_us loaded
context.assertScreenshotContains(TestScreenshotComparisonOptions
.of("keyboard_layout_en_us")
.save()
.withAlgorithm(TestScreenshotComparisonAlgorithm.meanSquaredDifference(0.001f)));
assertKeyboard(context, "en_us");

// press back button to close on-screen keyboard
controller.tapButton(SdlGamepad.SDL_GAMEPAD_BUTTON_EAST);
Expand All @@ -89,4 +89,20 @@ private void runLocaleTest(ClientGameTestContext context, ControlifyGameTestCont
}

}

private static void assertKeyboard(ClientGameTestContext context, String keyString) {
context.computeOnClient(_ -> {
var chatScreen = (ChatScreen) MinecraftUtil.getScreen();
KeyboardWidget keyboard = chatScreen.children().stream()
.flatMap(child -> child instanceof KeyboardWidget k ? Stream.of(k) : Stream.empty())
.findAny()
.orElse(null);
if (keyboard == null) {
return false;
}

return keyboard.children().stream()
.anyMatch(key -> key.getKeyFunction().displayName().getString().equals(keyString));
});
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
import net.fabricmc.fabric.api.client.gametest.v1.FabricClientGameTest;
import net.fabricmc.fabric.api.client.gametest.v1.context.ClientGameTestContext;

/// Ensures that {@link CTestUtil#resetControlifySettings(ClientGameTestContext)}
/// Ensures that {@link ControlifyGameTestContext#resetSettings()}
/// works appropriately, not leaving behind any stale references.
@SuppressWarnings("UnstableApiUsage")
public class ResetControlifySettingsTests implements FabricClientGameTest {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,11 @@ public void runTest(ClientGameTestContext context) {
.withXbox()
.attach()) {
try (var world = new TestUnitWorldContext(context)) {
world.getWorld().getClientLevel().waitForChunksRender();
//? if >=26.2 {
world.getWorld().getConnection().waitForChunksRender();
//?} else {
/*world.getWorld().getClientLevel().waitForChunksRender();
*///?}

runTest(context, controlify, controller, world, "Lightning bolt", this::testLightningBoltRumble);
runTest(context, controlify, controller, world, "Explosion", this::testExplosionRumble);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,11 @@ public void runTest(ClientGameTestContext context) {
try (var connection = world.connect()) {
context.waitFor(minecraft -> CTestUtil.isToastPresent(minecraft, "controlify.toast.new_server.title"));

connection.getClientLevel().waitForChunksDownload();
//? if >=26.2 {
connection.waitForChunksDownload();
//?} else {
/*connection.getClientLevel().waitForChunksDownload();
*///?}

assertKeyboardMovement(context, true);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,8 @@ public void runTest(ClientGameTestContext context) {
var controllerEntity = controller.getControllerEntity();
var input = controllerEntity.input().orElseThrow();

context.waitTick();

for (var expected : XINPUT_BUTTONS.entrySet()) {
controller.holdButton(expected.getKey());
context.waitFor(_ -> input.rawStateNow().isButtonDown(expected.getValue()), 10);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"width": 7,
"width": 1,
"keys": [
["b", "r", "i", "t", "i", "s", "h"]
["en_gb"]
]
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"width": 7,
"width": 1,
"keys": [
["a", "m", "e", "r", "i", "c", "a"]
["en_us"]
]
}
Binary file not shown.
Binary file not shown.
15 changes: 4 additions & 11 deletions src/main/java/dev/isxander/controlify/Controlify.java
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,6 @@
import net.minecraft.network.chat.Component;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.lwjgl.glfw.GLFW;
import org.spongepowered.asm.mixin.MixinEnvironment;

import java.io.IOException;
Expand Down Expand Up @@ -706,21 +705,15 @@ public VirtualMouseHandler virtualMouseHandler() {
}

public void hideMouse(boolean hide, boolean moveMouse) {
long handle = minecraft.getWindow().handle();

GLFW.glfwSetInputMode(
handle,
GLFW.GLFW_CURSOR,
hide
? GLFW.GLFW_CURSOR_HIDDEN
: GLFW.GLFW_CURSOR_NORMAL
);
CursorUtils.setVisibility(minecraft.getWindow(), !hide);

if (MinecraftUtil.getScreen() != null) {
var mouseHandlerAccessor = (MouseHandlerAccessor) minecraft.mouseHandler;
if (hide && !virtualMouseHandler().isVirtualMouseEnabled() && moveMouse) {
long handle = minecraft.getWindow().handle();
// stop mouse hovering over last element before hiding cursor but don't actually move it
// so when the user switches back to mouse it will be in the same place
mouseHandlerAccessor.controlify$invokeOnMove(handle, -50, -50);
mouseHandlerAccessor.controlify$invokeOnMove(handle, -50, -50 /*? if >=26.3 {*/, 0, 0/*?}*/);
}
}
}
Expand Down
Loading
Loading