diff --git a/build.gradle.kts b/build.gradle.kts index 58762f6..251799c 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -200,6 +200,10 @@ stonecutter { swaps["mod_version_full"] = "\"$version\"" // Replacements + replacements.string(current.parsed >= "26.3") { + replace("InputConstants.Type.KEYSYM", "InputConstants.Type.KEYBOARD") + replace("GLFW.GLFW_KEY_", "InputConstants.KEY_") + } replacements.string(current.parsed >= "26.1") { replace("ClientCommandManager", "ClientCommands") replace("GuiGraphics", "GuiGraphicsExtractor") diff --git a/settings.gradle.kts b/settings.gradle.kts index 81ebce5..9643ab0 100644 --- a/settings.gradle.kts +++ b/settings.gradle.kts @@ -28,6 +28,7 @@ rootProject.name = "EventUtils" stonecutter { create(rootProject) { versions( + "26.3", "26.2", "26.1.2", "1.21.11", diff --git a/src/main/java/cc/aabss/eventutils/EventUtils.java b/src/main/java/cc/aabss/eventutils/EventUtils.java index c4ce5d5..f616a21 100644 --- a/src/main/java/cc/aabss/eventutils/EventUtils.java +++ b/src/main/java/cc/aabss/eventutils/EventUtils.java @@ -18,6 +18,7 @@ import cc.aabss.eventutils.sdk.EnrichedEvent; import cc.aabss.eventutils.sdk.EventWrapper; import cc.aabss.eventutils.stats.Stats; +import cc.aabss.eventutils.versioning.VersionedClient; import cc.aabss.eventutils.versioning.VersionedGameProfile; import cc.aabss.eventutils.websocket.listener.EventCancelledListener; import cc.aabss.eventutils.websocket.listener.EventPostedListener; @@ -38,6 +39,8 @@ import net.fabricmc.loader.api.FabricLoader; import net.minecraft.ChatFormatting; import net.minecraft.client.Minecraft; +import net.minecraft.client.gui.screens.ConfirmScreen; +import net.minecraft.client.gui.screens.Screen; import net.minecraft.client.multiplayer.ClientPacketListener; import net.minecraft.client.multiplayer.ServerData; import net.minecraft.locale.Language; @@ -330,6 +333,32 @@ public static String translate(@NotNull String key) { return Language.getInstance().getOrDefault(key); } + /** + * Shows the exit-confirmation dialog for a window/game close request + * + * @param cancelClose reverts the platform-specific "closing" state; run immediately and again if the user cancels + */ + public static void confirmExit(@NotNull Runnable cancelClose) { + cancelClose.run(); + + final Minecraft client = Minecraft.getInstance(); + client.execute(() -> { + final VersionedClient vClient = new VersionedClient(client); + final Screen current = vClient.screen(); + vClient.setScreen(new ConfirmScreen( + result -> { + if (result) { + client.stop(); + return; + } + cancelClose.run(); + vClient.setScreen(current); + }, + Component.translatable("eventutils.confirm_exit.title"), + Component.translatable("eventutils.confirm_exit.message"))); + }); + } + /** * Simulates an event being posted for testing purposes */ diff --git a/src/main/java/cc/aabss/eventutils/manager/DiscordLinkManager.java b/src/main/java/cc/aabss/eventutils/manager/DiscordLinkManager.java index 6f92f1e..b054531 100644 --- a/src/main/java/cc/aabss/eventutils/manager/DiscordLinkManager.java +++ b/src/main/java/cc/aabss/eventutils/manager/DiscordLinkManager.java @@ -27,6 +27,9 @@ import java.util.Objects; import java.util.concurrent.ScheduledFuture; import java.util.concurrent.TimeUnit; +//? if >=26.3 { +//import java.net.URI; +//?} /** @@ -81,12 +84,21 @@ public synchronized void startLink(@Nullable Screen browserParent, @Nullable Run // Ask Event Alerts to build the OAuth URL, then open the browser mod.http.players.eventUtils.postLinkDiscord(new EUDiscordLinkBody(currentNonce, port)).queue( response -> { - final String url = response != null ? response.url : null; - if (url == null) { + // Get URL + final String urlString = response != null ? response.url : null; + if (urlString == null) { EventUtils.LOGGER.error("[DISCORD_LINK] Link start response missing 'url'"); fail("eventutils.config.discord_link.toast.start"); return; } + + // >=26.3: URI, <26.3: String + //? if >=26.3 { + /*final URI url = URI.create(urlString); + *///?} else { + final String url = urlString; + //?} + // It's okay for browserParent to be null Minecraft.getInstance().execute(() -> ConfirmLinkScreen.confirmLinkNow(browserParent, url)); }, diff --git a/src/main/java/cc/aabss/eventutils/manager/KeybindManager.java b/src/main/java/cc/aabss/eventutils/manager/KeybindManager.java index e06ff56..a07399b 100644 --- a/src/main/java/cc/aabss/eventutils/manager/KeybindManager.java +++ b/src/main/java/cc/aabss/eventutils/manager/KeybindManager.java @@ -14,7 +14,9 @@ import net.minecraft.network.chat.MutableComponent; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; +//? if <26.3 { import org.lwjgl.glfw.GLFW; +//?} //? if >= 26.1 { /*import net.fabricmc.fabric.api.client.keymapping.v1.KeyMappingHelper; *///?} else { @@ -80,7 +82,7 @@ public KeybindManager(@NotNull EventUtils mod) { // Event info key if (!eventInfoKey.isUnbound()) { - if (GLFW.glfwGetKey(windowHandle, ((KeyMappingAccessor) eventInfoKey).getKey().getValue()) == GLFW.GLFW_PRESS) { + if (isKeyDown(eventInfoKey)) { if (canNotPress(eventInfoKey, DEFAULT_COOLDOWN_TIME_MS)) return; EventUtils.LOGGER.debug("Event info key pressed"); @@ -105,7 +107,7 @@ public KeybindManager(@NotNull EventUtils mod) { // Developer Mode: simulate test event if (!testEventKey.isUnbound() && mod.config.developer_mode) { - if (GLFW.glfwGetKey(windowHandle, ((KeyMappingAccessor) testEventKey).getKey().getValue()) == GLFW.GLFW_PRESS) { + if (isKeyDown(testEventKey)) { if (canNotPress(testEventKey, DEFAULT_COOLDOWN_TIME_MS)) return; EventUtils.LOGGER.debug("Test event key pressed"); @@ -161,4 +163,13 @@ private boolean canNotPress(@NotNull KeyMapping keyBinding, long cooldownTimeMs) lastKeyPresses.put(name, now); return false; } + + private boolean isKeyDown(@NotNull KeyMapping key) { + final int keyValue = ((KeyMappingAccessor) key).getKey().getValue(); + //? if >=26.3 { + /*return InputConstants.isKeyDown(keyValue); + *///?} else { + return windowHandle != null && GLFW.glfwGetKey(windowHandle, keyValue) == GLFW.GLFW_PRESS; + //?} + } } diff --git a/src/main/java/cc/aabss/eventutils/mixin/MinecraftMixin.java b/src/main/java/cc/aabss/eventutils/mixin/MinecraftMixin.java index c7e26ca..adb78db 100644 --- a/src/main/java/cc/aabss/eventutils/mixin/MinecraftMixin.java +++ b/src/main/java/cc/aabss/eventutils/mixin/MinecraftMixin.java @@ -1,10 +1,9 @@ +//? if <26.3 { package cc.aabss.eventutils.mixin; import cc.aabss.eventutils.EventUtils; -import cc.aabss.eventutils.versioning.VersionedClient; +import com.mojang.blaze3d.platform.Window; import net.minecraft.client.Minecraft; -import net.minecraft.client.gui.screens.ConfirmScreen; -import net.minecraft.client.gui.screens.Screen; import org.lwjgl.glfw.GLFW; import org.lwjgl.glfw.GLFWWindowCloseCallback; import org.spongepowered.asm.mixin.Mixin; @@ -12,36 +11,26 @@ import org.spongepowered.asm.mixin.injection.Inject; import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; -import static net.minecraft.network.chat.Component.translatable; - @Mixin(Minecraft.class) public class MinecraftMixin { @Inject(method = "run", at = @At("HEAD")) private void onRun(CallbackInfo ci) { if (!EventUtils.MOD.config.confirm_window_close) return; - final Minecraft client = Minecraft.getInstance(); + + // Get handle + final Window window = Minecraft.getInstance().getWindow(); //? if >=1.21.11 { - /*final long handle = client.getWindow().handle(); + /*final long handle = window.handle(); *///?} else { - final long handle = client.getWindow().getWindow(); + final long handle = window.getWindow(); //?} - final GLFWWindowCloseCallback callback = GLFW.glfwSetWindowCloseCallback(handle, win -> client.execute(() -> { - final VersionedClient vClient = new VersionedClient(client); - GLFW.glfwSetWindowShouldClose(handle, false); - final Screen current = vClient.screen(); - vClient.setScreen(new ConfirmScreen( - result -> { - if (result) { - client.stop(); - return; - } - GLFW.glfwSetWindowShouldClose(handle, false); - vClient.setScreen(current); - }, - translatable("eventutils.confirm_exit.title"), - translatable("eventutils.confirm_exit.message"))); - })); + + // Create callback + final GLFWWindowCloseCallback callback = GLFW.glfwSetWindowCloseCallback( + handle, + win -> EventUtils.confirmExit(() -> GLFW.glfwSetWindowShouldClose(handle, false))); if (callback != null) callback.free(); } } +//?} diff --git a/src/main/java/cc/aabss/eventutils/mixin/WindowMixin.java b/src/main/java/cc/aabss/eventutils/mixin/WindowMixin.java new file mode 100644 index 0000000..d2716aa --- /dev/null +++ b/src/main/java/cc/aabss/eventutils/mixin/WindowMixin.java @@ -0,0 +1,21 @@ +//? if >=26.3 { +/*package cc.aabss.eventutils.mixin; + +import cc.aabss.eventutils.EventUtils; +import com.mojang.blaze3d.platform.Window; +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; + + +@Mixin(Window.class) +public class WindowMixin { + @Inject(method = "requestClose", at = @At("HEAD"), cancellable = true) + private void onRequestClose(CallbackInfo ci) { + if (!EventUtils.MOD.config.confirm_window_close) return; + ci.cancel(); + EventUtils.confirmExit(() -> {}); + } +} +*///?} diff --git a/stonecutter.properties.toml b/stonecutter.properties.toml index e797d62..dce9ce9 100644 --- a/stonecutter.properties.toml +++ b/stonecutter.properties.toml @@ -19,58 +19,63 @@ library.okaeri_configs = "df8ae69" library.discord_ipc = "0.11.3" library.faststats = "0.30.1" +["26.3"] +deps.fabric_api = "0.160.5+26.3" +deps.yacl = "3.9.6+26.3-fabric" +deps.owo_lib = "0.13.1+26.2" #TODO: Update to 26.3 when available +deps.modmenu = "21.0.0-beta.1" ["26.2"] -deps.fabric_api="0.152.1+26.2" -deps.yacl="3.9.4+26.2-fabric" +deps.fabric_api = "0.152.1+26.2" +deps.yacl = "3.9.4+26.2-fabric" deps.owo_lib = "0.13.1+26.2" -deps.modmenu="20.0.0" +deps.modmenu = "20.0.0" ["26.1.2"] -deps.fabric_api="0.145.4+26.1.2" -deps.yacl="3.9.2+26.1-fabric" +deps.fabric_api = "0.145.4+26.1.2" +deps.yacl = "3.9.2+26.1-fabric" deps.owo_lib = "0.13.1+26.1" -deps.modmenu="18.0.0" +deps.modmenu = "18.0.0" ["1.21.11"] -deps.fabric_api="0.141.0+1.21.11" -deps.yacl="3.8.1+1.21.11-fabric" +deps.fabric_api = "0.141.0+1.21.11" +deps.yacl = "3.8.1+1.21.11-fabric" deps.owo_lib = "0.13.0+1.21.11" -deps.modmenu="17.0.0" +deps.modmenu = "17.0.0" ["1.21.6"] -deps.fabric_api="0.128.2+1.21.6" -deps.yacl="3.7.1+1.21.6-fabric" +deps.fabric_api = "0.128.2+1.21.6" +deps.yacl = "3.7.1+1.21.6-fabric" deps.owo_lib = "0.12.23+1.21.8" -deps.modmenu="15.0.0" +deps.modmenu = "15.0.0" ["1.21.5"] -deps.fabric_api="0.128.2+1.21.5" -deps.yacl="3.7.1+1.21.5-fabric" +deps.fabric_api = "0.128.2+1.21.5" +deps.yacl = "3.7.1+1.21.5-fabric" deps.owo_lib = "0.12.21+1.21.5" -deps.modmenu="14.0.0" +deps.modmenu = "14.0.0" ["1.21.4"] -deps.fabric_api="0.114.0+1.21.4" -deps.yacl="3.6.2+1.21.4-fabric" -deps.modmenu="13.0.0" +deps.fabric_api = "0.114.0+1.21.4" +deps.yacl = "3.6.2+1.21.4-fabric" +deps.modmenu = "13.0.0" deps.owo_lib = "0.12.20+1.21.4" ["1.21.1"] -deps.fabric_api="0.102.0+1.21.1" -deps.yacl="3.6.0+1.21-fabric" +deps.fabric_api = "0.102.0+1.21.1" +deps.yacl = "3.6.0+1.21-fabric" deps.owo_lib = "0.12.15.4+1.21" -deps.modmenu="11.0.3" +deps.modmenu = "11.0.3" ["1.21"] -deps.fabric_api="0.102.0+1.21" -deps.yacl="3.6.0+1.21-fabric" +deps.fabric_api = "0.102.0+1.21" +deps.yacl = "3.6.0+1.21-fabric" deps.owo_lib = "0.12.15.4+1.21" -deps.modmenu="11.0.3" +deps.modmenu = "11.0.3" ["1.20.4"] -deps.fabric_api="0.97.1+1.20.4" -deps.yacl="3.6.0+1.20.4-fabric" +deps.fabric_api = "0.97.1+1.20.4" +deps.yacl = "3.6.0+1.20.4-fabric" deps.owo_lib = "0.12.6+1.20.3" -deps.modmenu="9.2.0" -deps.placeholder_api="2.4.0-pre.1+1.20.4" +deps.modmenu = "9.2.0" +deps.placeholder_api = "2.4.0-pre.1+1.20.4"