From 1a49605a6a4b9577618caf8d6cb58e4dc19cead2 Mon Sep 17 00:00:00 2001 From: reserveword Date: Wed, 14 Feb 2024 13:31:58 +0800 Subject: [PATCH] =?UTF-8?q?=E5=90=84=E7=A7=8D=E6=9B=B4=E6=96=B0=EF=BC=8C?= =?UTF-8?q?=E5=88=B0=E6=97=B6=E5=80=99=E5=86=8D=E4=B8=80=E7=82=B9=E4=B8=80?= =?UTF-8?q?=E7=82=B9=E5=A1=9E=E5=9B=9E=E6=AD=A3=E5=BC=8F=E7=89=88=E9=87=8C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .gitignore | 4 +- build.gradle | 15 +- .../github/reserveword/imblocker/Common.java | 21 +++ .../reserveword/imblocker/IMCheckState.java | 21 ++- .../reserveword/imblocker/IMManager.java | 72 +++++---- .../assets/imblocker/lang/en_us.json | 4 +- .../assets/imblocker/lang/zh_cn.json | 4 +- .../assets/imblocker/lang/zh_tw.json | 4 +- .../{IMBlocker.png => imblocker.png} | Bin fabric/build.gradle | 27 ++-- .../reserveword/imblocker/FabricCommon.java | 2 + .../reserveword/imblocker/FabricConfig.java | 6 +- .../imblocker/FabricScreenInfo.java | 6 +- .../imblocker/mixin/CottonTextFieldMixin.java | 31 ---- .../imblocker/mixin/FtbTextFieldMixin.java | 21 --- .../imblocker/mixin/FtbWidgetMixin.java | 18 --- .../mixin/MetetorTextFieldMixin.java | 23 --- .../imblocker/mixin/NotebookScreenMixin.java | 20 --- .../imblocker/mixin/ReiTextFieldMixin.java | 35 ----- .../mixin/ReplayModTextFieldMixin.java | 23 --- .../mixin/{ => fabric}/ChatScreenMixin.java | 2 +- .../mixin/fabric/ClickableWidgetMixin.java | 26 ++++ .../{ => fabric}/MinecraftClientMixin.java | 2 +- .../mixin/{ => fabric}/MouseMixin.java | 2 +- .../mixin/fabric/ParentElementMixin.java | 27 ++++ .../imblocker/mixin/fabric/ScreenMixin.java | 17 +++ .../mixin/{ => fabric}/TextFieldMixin.java | 4 +- .../client/resources/imblocker.mixins.json | 12 +- forge/build.gradle | 68 ++------- forge/runs/client/config/fml.toml | 27 ++++ .../reserveword/imblocker/ForgeConfig.java | 124 +++++++--------- .../imblocker/ForgeScreenInfo.java | 27 +--- .../reserveword/imblocker/IMBlocker.java | 39 ++--- .../imblocker/asmdummy/FakeChatScreen.java | 16 -- .../imblocker/asmdummy/FakeFTBLibTextBox.java | 14 -- .../asmdummy/FakeTextFieldWidget.java | 43 ------ .../mixin/forge/ChatScreenMixin.java | 11 ++ .../mixin/forge/ClickableWidgetMixin.java | 26 ++++ .../mixin/forge/MinecraftClientMixin.java | 16 ++ .../imblocker/mixin/forge/MouseMixin.java | 26 ++++ .../mixin/forge/ParentElementMixin.java | 27 ++++ .../imblocker/mixin/forge/ScreenMixin.java | 17 +++ .../imblocker/mixin/forge/TextFieldMixin.java | 31 ++++ .../src/main/resources/META-INF/coremods.json | 5 - .../resources/META-INF/imblocker.mixins.json | 18 +++ forge/src/main/resources/META-INF/mods.toml | 43 ++---- .../main/resources/coremod/chat_screen_asm.js | 37 ----- .../main/resources/coremod/text_field_asm.js | 140 ------------------ .../resources/coremod/window_focus_asm.js | 29 ---- gradle.properties | 64 +++----- gradle/wrapper/gradle-wrapper.properties | 2 +- settings.gradle | 15 +- 52 files changed, 517 insertions(+), 797 deletions(-) rename common/src/main/resources/{IMBlocker.png => imblocker.png} (100%) delete mode 100644 fabric/src/client/java/io/github/reserveword/imblocker/mixin/CottonTextFieldMixin.java delete mode 100644 fabric/src/client/java/io/github/reserveword/imblocker/mixin/FtbTextFieldMixin.java delete mode 100644 fabric/src/client/java/io/github/reserveword/imblocker/mixin/FtbWidgetMixin.java delete mode 100644 fabric/src/client/java/io/github/reserveword/imblocker/mixin/MetetorTextFieldMixin.java delete mode 100644 fabric/src/client/java/io/github/reserveword/imblocker/mixin/NotebookScreenMixin.java delete mode 100644 fabric/src/client/java/io/github/reserveword/imblocker/mixin/ReiTextFieldMixin.java delete mode 100644 fabric/src/client/java/io/github/reserveword/imblocker/mixin/ReplayModTextFieldMixin.java rename fabric/src/client/java/io/github/reserveword/imblocker/mixin/{ => fabric}/ChatScreenMixin.java (83%) create mode 100644 fabric/src/client/java/io/github/reserveword/imblocker/mixin/fabric/ClickableWidgetMixin.java rename fabric/src/client/java/io/github/reserveword/imblocker/mixin/{ => fabric}/MinecraftClientMixin.java (90%) rename fabric/src/client/java/io/github/reserveword/imblocker/mixin/{ => fabric}/MouseMixin.java (94%) create mode 100644 fabric/src/client/java/io/github/reserveword/imblocker/mixin/fabric/ParentElementMixin.java create mode 100644 fabric/src/client/java/io/github/reserveword/imblocker/mixin/fabric/ScreenMixin.java rename fabric/src/client/java/io/github/reserveword/imblocker/mixin/{ => fabric}/TextFieldMixin.java (91%) create mode 100644 forge/runs/client/config/fml.toml delete mode 100644 forge/src/main/java/io/github/reserveword/imblocker/asmdummy/FakeChatScreen.java delete mode 100644 forge/src/main/java/io/github/reserveword/imblocker/asmdummy/FakeFTBLibTextBox.java delete mode 100644 forge/src/main/java/io/github/reserveword/imblocker/asmdummy/FakeTextFieldWidget.java create mode 100644 forge/src/main/java/io/github/reserveword/imblocker/mixin/forge/ChatScreenMixin.java create mode 100644 forge/src/main/java/io/github/reserveword/imblocker/mixin/forge/ClickableWidgetMixin.java create mode 100644 forge/src/main/java/io/github/reserveword/imblocker/mixin/forge/MinecraftClientMixin.java create mode 100644 forge/src/main/java/io/github/reserveword/imblocker/mixin/forge/MouseMixin.java create mode 100644 forge/src/main/java/io/github/reserveword/imblocker/mixin/forge/ParentElementMixin.java create mode 100644 forge/src/main/java/io/github/reserveword/imblocker/mixin/forge/ScreenMixin.java create mode 100644 forge/src/main/java/io/github/reserveword/imblocker/mixin/forge/TextFieldMixin.java delete mode 100644 forge/src/main/resources/META-INF/coremods.json create mode 100644 forge/src/main/resources/META-INF/imblocker.mixins.json delete mode 100644 forge/src/main/resources/coremod/chat_screen_asm.js delete mode 100644 forge/src/main/resources/coremod/text_field_asm.js delete mode 100644 forge/src/main/resources/coremod/window_focus_asm.js diff --git a/.gitignore b/.gitignore index 12f8644..c6db923 100644 --- a/.gitignore +++ b/.gitignore @@ -19,7 +19,7 @@ build # other eclipse -run # Files from Forge MDK -forge*changelog.txt +/forge/runs/ +/fabric/run/ diff --git a/build.gradle b/build.gradle index 2ff0083..8a19baa 100644 --- a/build.gradle +++ b/build.gradle @@ -68,10 +68,7 @@ allprojects { fabric_version : fabric_version, yarn_mappings : yarn_mappings, loader_version : loader_version, - forge_version : forge_version, loader_version_range: loader_version_range, - mapping_channel : mapping_channel, - mapping_version : mapping_version ] tasks.withType(ProcessResources).configureEach { @@ -88,22 +85,20 @@ allprojects { tasks.register('feedbackClass', Copy) { dependsOn "jar" - mustRunAfter ":forge:reobfJar" mustRunAfter ":fabric:remapJar" - from (zipTree(new File(buildDir, "libs/${project.name}.jar"))) { + from (zipTree(layout.buildDirectory.file("libs/${project.name}.jar"))) { include '**/*.class' } - into new File(rootProject.buildDir, 'classes/java/main') + into rootProject.layout.buildDirectory.file('classes/java/main') } tasks.register('feedbackResource', Copy) { dependsOn "jar" - mustRunAfter ":forge:reobfJar" mustRunAfter ":fabric:remapJar" - from (zipTree(new File(buildDir, "libs/${project.name}.jar"))) { + from (zipTree(layout.buildDirectory.file("libs/${project.name}.jar"))) { exclude '**/*.class' } - into new File(rootProject.buildDir, 'resources/main') + into rootProject.layout.buildDirectory.file('resources/main') } tasks.register('feedback') { @@ -112,7 +107,7 @@ allprojects { } } -archivesBaseName "${rootProject.name}_${mod_version}+${minecraft_version}" +base.archivesName = "${rootProject.name}_${mod_version}+${minecraft_version}" project.jar { dependsOn ':common:feedback' diff --git a/common/src/main/java/io/github/reserveword/imblocker/Common.java b/common/src/main/java/io/github/reserveword/imblocker/Common.java index c0e96ae..facb112 100644 --- a/common/src/main/java/io/github/reserveword/imblocker/Common.java +++ b/common/src/main/java/io/github/reserveword/imblocker/Common.java @@ -3,7 +3,28 @@ import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; +import java.util.HashMap; +import java.util.regex.Pattern; + public class Common { public static final String MODID = "imblocker"; public static final Logger LOGGER = LogManager.getLogger(); + private static final Pattern textFieldPattern = Pattern.compile(".*(TextField|EditBox|EditText)[^.]*$", Pattern.CASE_INSENSITIVE); + private static final HashMap, Boolean> textFieldCache = new HashMap<>(); + + public static boolean classIsTextField(Class c) { + if (textFieldCache.containsKey(c)) { + return textFieldCache.get(c); + } + boolean result; + if (c == null) { + result = false; + } else if (textFieldPattern.matcher(c.getName()).matches()) { + result = true; + } else { + result = classIsTextField(c.getSuperclass()); + } + textFieldCache.put(c, result); + return result; + } } diff --git a/common/src/main/java/io/github/reserveword/imblocker/IMCheckState.java b/common/src/main/java/io/github/reserveword/imblocker/IMCheckState.java index faa53ad..16dbd6e 100644 --- a/common/src/main/java/io/github/reserveword/imblocker/IMCheckState.java +++ b/common/src/main/java/io/github/reserveword/imblocker/IMCheckState.java @@ -126,7 +126,7 @@ private static void checkNonPrintable(ScreenInfo screen) { try { screen.charTyped(nonPrintable, 0); // charTyped } catch (Exception e) { - e.printStackTrace(); + Common.LOGGER.error("checkNonPrintable charTyped error:", e); } } state.remove(IMState.NON_PRINTABLE_CHALLENGE_PENDING); @@ -164,20 +164,27 @@ public static void captureClick(BooleanSupplier active) { actives.add(active); } + // connect rules above + private static long nextCheck = System.currentTimeMillis() + Config.INSTANCE.getCheckInterval(); + private static boolean scheduled = false; + public static void clientTick(ScreenInfo screen) { checkScreenList(screen); checkSpecial(); - if (count == 0) checkTick(); + long now = System.currentTimeMillis(); + if (nextCheck < now && (scheduled || screen.get() == null)) { + nextCheck = now + Config.INSTANCE.getCheckInterval(); + scheduled = false; + checkTick(); + } checkNonPrintable(screen); checkClick(); syncState(); - // check interval - if (count > 0) count --; - else count = Config.INSTANCE.getCheckInterval(); } - // connect rules above - private static int count = Config.INSTANCE.getCheckInterval(); + public static void scheduleTickCheck() { + scheduled = true; + } public static void mouseEvent() { state.add(IMState.NON_PRINTABLE_CHALLENGE_PENDING); diff --git a/common/src/main/java/io/github/reserveword/imblocker/IMManager.java b/common/src/main/java/io/github/reserveword/imblocker/IMManager.java index 3b0a62b..e12a9b5 100644 --- a/common/src/main/java/io/github/reserveword/imblocker/IMManager.java +++ b/common/src/main/java/io/github/reserveword/imblocker/IMManager.java @@ -5,6 +5,7 @@ import com.sun.jna.platform.win32.WinDef; import com.sun.jna.platform.win32.WinNT; +@SuppressWarnings("unused") public class IMManager { private static native WinNT.HANDLE ImmGetContext(WinDef.HWND hwnd); @@ -17,8 +18,13 @@ public class IMManager { private static native boolean ImmDestroyContext(WinNT.HANDLE himc); + private static final boolean isWin; + static { - Native.register("imm32"); + isWin = System.getProperty("os.name").toLowerCase().contains("win"); + if (isWin) { + Native.register("imm32"); + } } private static final User32 u = User32.INSTANCE; @@ -26,37 +32,45 @@ public class IMManager { private static boolean state = true; private static void makeOnImp() { - WinDef.HWND hwnd = u.GetForegroundWindow(); - WinNT.HANDLE himc = ImmGetContext(hwnd); - if (himc == null) { - himc = ImmCreateContext(); - ImmAssociateContext(hwnd, himc); + if (isWin) { + WinDef.HWND hwnd = u.GetForegroundWindow(); + WinNT.HANDLE himc = ImmGetContext(hwnd); + if (himc == null) { + himc = ImmCreateContext(); + ImmAssociateContext(hwnd, himc); + } + ImmReleaseContext(hwnd, himc); } - ImmReleaseContext(hwnd, himc); } private static void makeOffImp() { - WinDef.HWND hwnd = u.GetForegroundWindow(); - WinNT.HANDLE himc = ImmAssociateContext(hwnd, null); - if (himc != null) { - ImmDestroyContext(himc); + if (isWin) { + WinDef.HWND hwnd = u.GetForegroundWindow(); + WinNT.HANDLE himc = ImmAssociateContext(hwnd, null); + if (himc != null) { + ImmDestroyContext(himc); + } + ImmReleaseContext(hwnd, himc); } - ImmReleaseContext(hwnd, himc); } private static boolean toggleImp() { - WinDef.HWND hwnd = u.GetForegroundWindow(); - WinNT.HANDLE himc = ImmGetContext(hwnd); - if (himc == null) { - himc = ImmCreateContext(); - ImmAssociateContext(hwnd, himc); - ImmReleaseContext(hwnd, himc); - return true; + if (isWin) { + WinDef.HWND hwnd = u.GetForegroundWindow(); + WinNT.HANDLE himc = ImmGetContext(hwnd); + if (himc == null) { + himc = ImmCreateContext(); + ImmAssociateContext(hwnd, himc); + ImmReleaseContext(hwnd, himc); + return true; + } else { + himc = ImmAssociateContext(hwnd, null); + ImmDestroyContext(himc); + ImmReleaseContext(hwnd, himc); + return false; + } } else { - himc = ImmAssociateContext(hwnd, null); - ImmDestroyContext(himc); - ImmReleaseContext(hwnd, himc); - return false; + return true; // always make im on } } @@ -86,11 +100,13 @@ public static void makeState(boolean on) { } public static void syncState() { - WinDef.HWND hwnd = u.GetForegroundWindow(); - WinNT.HANDLE himc = ImmGetContext(hwnd); - if ((himc == null) == state) { - Common.LOGGER.warn("IM state inconsistent! state={}, im={}", state, himc != null); - toggle(); + if (isWin) { + WinDef.HWND hwnd = u.GetForegroundWindow(); + WinNT.HANDLE himc = ImmGetContext(hwnd); + if ((himc == null) == state) { + Common.LOGGER.warn("IM state inconsistent! state={}, im={}", state, himc != null); + toggle(); + } } } diff --git a/common/src/main/resources/assets/imblocker/lang/en_us.json b/common/src/main/resources/assets/imblocker/lang/en_us.json index 5902f12..301e84e 100644 --- a/common/src/main/resources/assets/imblocker/lang/en_us.json +++ b/common/src/main/resources/assets/imblocker/lang/en_us.json @@ -1,5 +1,5 @@ { - "key.imblocker.checkInterval" : "Per how many ticks do we check text field once? Make sure checkDelay is an exact multiple of this.", + "key.imblocker.checkIntervalMilli" : "Per how many ms do we check text field once?", "key.imblocker.screenBlacklist": "Matched screen would disable your IME", "key.imblocker.screenWhitelist": "Matched screen would enable your IME", "key.imblocker.inputBlacklist": "Matched input box would disable your IME", @@ -8,7 +8,7 @@ "key.imblocker.recoveredScreens": "Here lists all Screens that is not in whitelist nor blacklist, so you may easily add those to whitelist/blacklist.", "key.imblocker.useExperimental": "simulate inputting non-printable characters occasionally to detect active input box. Disable this and let me know if input or control is messed up.", "key.imblocker.checkCommandChat": "Disable IME when typing commands", - "text.autoconfig.imblocker.option.checkInterval" : "Per how many ticks do we check text field once? Make sure checkDelay is an exact multiple of this.", + "text.autoconfig.imblocker.option.checkIntervalMilli" : "Per how many ticks do we check text field once? Make sure checkDelay is an exact multiple of this.", "text.autoconfig.imblocker.option.screenBlacklist": "Matched screen would disable your IME", "text.autoconfig.imblocker.option.screenWhitelist": "Matched screen would enable your IME", "text.autoconfig.imblocker.option.inputBlacklist": "Matched input box would disable your IME", diff --git a/common/src/main/resources/assets/imblocker/lang/zh_cn.json b/common/src/main/resources/assets/imblocker/lang/zh_cn.json index 0f63df3..d9fae28 100644 --- a/common/src/main/resources/assets/imblocker/lang/zh_cn.json +++ b/common/src/main/resources/assets/imblocker/lang/zh_cn.json @@ -1,5 +1,5 @@ { - "key.imblocker.checkInterval": "每多少tick检查一次文本框", + "key.imblocker.checkIntervalMilli": "每多少毫秒检查一次文本框", "key.imblocker.screenBlacklist": "该列表中的GUI屏幕会禁用输入法", "key.imblocker.screenWhitelist": "该列表中的GUI屏幕会激活输入法", "key.imblocker.inputBlacklist": "该列表中的输入框会禁用输入法", @@ -8,7 +8,7 @@ "key.imblocker.recoveredScreens": "列出显示过的GUI屏幕,方便编辑黑白名单", "key.imblocker.useExperimental": "使用不可打印字符判别输入框,如有问题请关闭并咨询作者", "key.imblocker.checkCommandChat": "输入命令时关闭输入法", - "text.autoconfig.imblocker.option.checkInterval": "每多少tick检查一次文本框", + "text.autoconfig.imblocker.option.checkIntervalMilli": "每多少tick检查一次文本框", "text.autoconfig.imblocker.option.screenBlacklist": "该列表中的GUI屏幕会禁用输入法", "text.autoconfig.imblocker.option.screenWhitelist": "该列表中的GUI屏幕会激活输入法", "text.autoconfig.imblocker.option.inputBlacklist": "该列表中的输入框会禁用输入法", diff --git a/common/src/main/resources/assets/imblocker/lang/zh_tw.json b/common/src/main/resources/assets/imblocker/lang/zh_tw.json index 1edb350..ecc91d7 100644 --- a/common/src/main/resources/assets/imblocker/lang/zh_tw.json +++ b/common/src/main/resources/assets/imblocker/lang/zh_tw.json @@ -1,5 +1,5 @@ { - "key.imblocker.checkInterval" : "每隔多少刻檢查一次文字框?請確定 checkDelay 是此數的整數倍。", + "key.imblocker.checkIntervalMilli" : "每隔多少毫秒檢查一次文字框?", "key.imblocker.screenBlacklist": "匹配的螢幕將停用您的輸入法", "key.imblocker.screenWhitelist": "匹配的螢幕將啟用您的輸入法", "key.imblocker.inputBlacklist": "匹配的輸入框將停用您的輸入法", @@ -8,7 +8,7 @@ "key.imblocker.recoveredScreens": "這裡列出了不在白名單或黑名單中的所有螢幕,以便您可以輕鬆將其新增到白名單/黑名單中。", "key.imblocker.useExperimental": "偶爾模擬輸入不可打印字符以檢測活動的輸入框。如果輸入或控件出現問題,請停用此功能並告訴我。", "key.imblocker.checkCommandChat": "在輸入指令時停用輸入法", - "text.autoconfig.imblocker.option.checkInterval" : "每隔多少刻檢查一次文本框?請確定 checkDelay 是此數的整數倍。", + "text.autoconfig.imblocker.option.checkIntervalMilli" : "每隔多少刻檢查一次文本框?請確定 checkDelay 是此數的整數倍。", "text.autoconfig.imblocker.option.screenBlacklist": "匹配的螢幕將停用您的輸入法", "text.autoconfig.imblocker.option.screenWhitelist": "匹配的螢幕將啟用您的輸入法", "text.autoconfig.imblocker.option.inputBlacklist": "匹配的輸入框將停用您的輸入法", diff --git a/common/src/main/resources/IMBlocker.png b/common/src/main/resources/imblocker.png similarity index 100% rename from common/src/main/resources/IMBlocker.png rename to common/src/main/resources/imblocker.png diff --git a/fabric/build.gradle b/fabric/build.gradle index 7b8e59b..a09a8a5 100644 --- a/fabric/build.gradle +++ b/fabric/build.gradle @@ -1,7 +1,7 @@ plugins { id 'eclipse' id 'idea' - id 'fabric-loom' version '1.2-SNAPSHOT' + id 'fabric-loom' version '1.5-SNAPSHOT' } loom { @@ -25,22 +25,18 @@ dependencies { // Fabric API. This is technically optional, but you probably want it anyway. modImplementation "net.fabricmc.fabric-api:fabric-api:${fabric_version}" - modApi "com.terraformersmc:modmenu:${modmenu_version}" - modApi "me.shedaniel.cloth:cloth-config-fabric:${clothconfig_version}" exclude group: "net.fabricmc.fabric-api" + // optional dependencies + modApi "com.terraformersmc:modmenu:$modmenu_version" + modApi "me.shedaniel.cloth:cloth-config-fabric:$clothconfig_version" exclude group: "net.fabricmc.fabric-api" - // REI API for Fabric - modCompileOnlyApi "me.shedaniel:RoughlyEnoughItems-api-fabric:$rei_version" - modCompileOnlyApi "me.shedaniel:RoughlyEnoughItems-default-plugin-fabric:$rei_version" + // compile time reference + // none + + // run time test + modRuntimeOnly "dev.emi:emi-fabric:$emi_version" + modRuntimeOnly "maven.modrinth:replaymod:$replaymod_version" + modRuntimeOnly "maven.modrinth:voxelmap-updated:$voxelmap_version" modRuntimeOnly "me.shedaniel:RoughlyEnoughItems-fabric:$rei_version" - // compat - modCompileOnlyApi "maven.modrinth:replaymod:$replaymod_version" - modCompileOnlyApi "maven.modrinth:notebook:$notebook_version" - modCompileOnly "curse.maven:ftblib-$ftblib_version" - modLocalRuntime "maven.modrinth:voxelmap-updated:$voxelmap_version" - modCompileOnlyApi "dev.emi:emi-fabric:$emi_version:api" - modLocalRuntime "dev.emi:emi-fabric:$emi_version" - // modRuntimeOnly "curse.maven:ftbquest-$ftbquest_version" - modCompileOnly "io.github.cottonmc:LibGui:$cottonlibgui_version" implementation project(':common') } @@ -68,5 +64,4 @@ project.jar { "Implementation-Timestamp": new Date().format("yyyy-MM-dd'T'HH:mm:ssZ") ]) } - exclude 'io/github/reserveword/imblocker/asmdummy' } diff --git a/fabric/src/client/java/io/github/reserveword/imblocker/FabricCommon.java b/fabric/src/client/java/io/github/reserveword/imblocker/FabricCommon.java index 10d8280..e9b1472 100644 --- a/fabric/src/client/java/io/github/reserveword/imblocker/FabricCommon.java +++ b/fabric/src/client/java/io/github/reserveword/imblocker/FabricCommon.java @@ -1,5 +1,6 @@ package io.github.reserveword.imblocker; +import net.minecraft.client.gui.screen.TitleScreen; import net.minecraft.client.gui.screen.ingame.BookEditScreen; import net.minecraft.client.gui.screen.ingame.HangingSignEditScreen; import net.minecraft.client.gui.screen.ingame.SignEditScreen; @@ -11,6 +12,7 @@ public class FabricCommon { BookEditScreen.class.getName(), SignEditScreen.class.getName(), HangingSignEditScreen.class.getName(), + TitleScreen.class.getName(), "journeymap.client.ui.waypoint.WaypointEditor", "com.ldtteam.blockout.BOScreen"); public static final List defaultScreenBlacklist = List.of( diff --git a/fabric/src/client/java/io/github/reserveword/imblocker/FabricConfig.java b/fabric/src/client/java/io/github/reserveword/imblocker/FabricConfig.java index 60b86b8..7ab6dc6 100644 --- a/fabric/src/client/java/io/github/reserveword/imblocker/FabricConfig.java +++ b/fabric/src/client/java/io/github/reserveword/imblocker/FabricConfig.java @@ -17,14 +17,14 @@ @me.shedaniel.autoconfig.annotation.Config(name = Common.MODID) public class FabricConfig extends Config implements ModMenuApi, ConfigData { - int checkInterval = 2; + int checkIntervalMilli = 100; ArrayList screenBlacklist = new ArrayList<>(FabricCommon.defaultScreenBlacklist); ArrayList screenWhitelist = new ArrayList<>(FabricCommon.defaultScreenWhitelist); ArrayList inputBlacklist = new ArrayList<>(); ArrayList inputWhitelist = new ArrayList<>(); boolean enableScreenRecovering = false; ArrayList recoveredScreens = new ArrayList<>(); - boolean useExperimental = true; + boolean useExperimental = false; boolean checkCommandChat = true; @Override @@ -67,7 +67,7 @@ public boolean inInputWhitelist(Class cls) { @Override public Integer getCheckInterval() { - return checkInterval; + return checkIntervalMilli; } @Override diff --git a/fabric/src/client/java/io/github/reserveword/imblocker/FabricScreenInfo.java b/fabric/src/client/java/io/github/reserveword/imblocker/FabricScreenInfo.java index 9e8e362..9101656 100644 --- a/fabric/src/client/java/io/github/reserveword/imblocker/FabricScreenInfo.java +++ b/fabric/src/client/java/io/github/reserveword/imblocker/FabricScreenInfo.java @@ -1,6 +1,6 @@ package io.github.reserveword.imblocker; -import io.github.reserveword.imblocker.mixin.ChatScreenMixin; +import io.github.reserveword.imblocker.mixin.fabric.ChatScreenMixin; import net.minecraft.client.MinecraftClient; import net.minecraft.client.gui.screen.ChatScreen; import net.minecraft.client.gui.screen.Screen; @@ -8,7 +8,7 @@ public class FabricScreenInfo implements IMCheckState.ScreenInfo { private final Screen screen; public FabricScreenInfo() { - screen = MinecraftClient.getInstance().currentScreen;; + screen = MinecraftClient.getInstance().currentScreen; } @Override @@ -27,7 +27,7 @@ public Class type() { } @Override - public String defaultText() throws Throwable { + public String defaultText() { return ((ChatScreenMixin) screen).getOriginalText(); } diff --git a/fabric/src/client/java/io/github/reserveword/imblocker/mixin/CottonTextFieldMixin.java b/fabric/src/client/java/io/github/reserveword/imblocker/mixin/CottonTextFieldMixin.java deleted file mode 100644 index 4575a1b..0000000 --- a/fabric/src/client/java/io/github/reserveword/imblocker/mixin/CottonTextFieldMixin.java +++ /dev/null @@ -1,31 +0,0 @@ -package io.github.reserveword.imblocker.mixin; - -import io.github.cottonmc.cotton.gui.widget.WTextField; -import io.github.cottonmc.cotton.gui.widget.data.InputResult; -import io.github.reserveword.imblocker.IMCheckState; -import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.Pseudo; -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.CallbackInfo; -import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; - -@Pseudo -@Mixin(value = WTextField.class, remap = false) -public abstract class CottonTextFieldMixin { - @Unique - protected boolean editable; - - @Inject(method = "tick", at = @At("HEAD")) - public void tickCallback(CallbackInfo ci) { - IMCheckState.captureTick(this, this.editable); - } - - @Inject(method = "onCharTyped", at = @At("HEAD"), cancellable = true) - public void charTypedCallback(char ch, CallbackInfoReturnable cir) { - if (IMCheckState.captureNonPrintable(this, ch, this.editable)) { - cir.setReturnValue(InputResult.IGNORED); - } - } -} diff --git a/fabric/src/client/java/io/github/reserveword/imblocker/mixin/FtbTextFieldMixin.java b/fabric/src/client/java/io/github/reserveword/imblocker/mixin/FtbTextFieldMixin.java deleted file mode 100644 index 94ab915..0000000 --- a/fabric/src/client/java/io/github/reserveword/imblocker/mixin/FtbTextFieldMixin.java +++ /dev/null @@ -1,21 +0,0 @@ -package io.github.reserveword.imblocker.mixin; - -import dev.ftb.mods.ftblibrary.ui.TextBox; -import dev.ftb.mods.ftblibrary.ui.input.KeyModifiers; -import io.github.reserveword.imblocker.IMCheckState; -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.CallbackInfoReturnable; - -@Mixin(value = TextBox.class, remap = false) -public abstract class FtbTextFieldMixin { - @Shadow - public abstract boolean isFocused(); - - @Inject(method = "charTyped", at = @At("HEAD")) - public void charTypedCallback(char c, KeyModifiers modifiers, CallbackInfoReturnable cir) { - IMCheckState.captureNonPrintable(this, c, this.isFocused()); - } -} diff --git a/fabric/src/client/java/io/github/reserveword/imblocker/mixin/FtbWidgetMixin.java b/fabric/src/client/java/io/github/reserveword/imblocker/mixin/FtbWidgetMixin.java deleted file mode 100644 index 6341902..0000000 --- a/fabric/src/client/java/io/github/reserveword/imblocker/mixin/FtbWidgetMixin.java +++ /dev/null @@ -1,18 +0,0 @@ -package io.github.reserveword.imblocker.mixin; - -import dev.ftb.mods.ftblibrary.ui.TextBox; -import dev.ftb.mods.ftblibrary.ui.Widget; -import io.github.reserveword.imblocker.IMCheckState; -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(value = Widget.class, remap = false) -public abstract class FtbWidgetMixin { - @Inject(method = "tick", at = @At("HEAD")) - public void tickCallback(CallbackInfo ci) { - if ((Object)(this) instanceof TextBox) - IMCheckState.captureTick(this, ((TextBox)(Object)(this)).isFocused()); - } -} diff --git a/fabric/src/client/java/io/github/reserveword/imblocker/mixin/MetetorTextFieldMixin.java b/fabric/src/client/java/io/github/reserveword/imblocker/mixin/MetetorTextFieldMixin.java deleted file mode 100644 index 70c9c21..0000000 --- a/fabric/src/client/java/io/github/reserveword/imblocker/mixin/MetetorTextFieldMixin.java +++ /dev/null @@ -1,23 +0,0 @@ -package io.github.reserveword.imblocker.mixin; - -import io.github.reserveword.imblocker.IMCheckState; -import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.Pseudo; -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.CallbackInfoReturnable; - -@Mixin(targets = "meteordevelopment.meteorclient.gui.widgets.input.WTextBox", remap = false) -@Pseudo -public abstract class MetetorTextFieldMixin { - @Shadow - protected boolean focused; - - @Inject(method = "onCharTyped", at = @At("HEAD"), cancellable = true) - public void charTypedCallback(char c, CallbackInfoReturnable cir) { - if (IMCheckState.captureNonPrintable(this, c, this.focused)) { - cir.setReturnValue(false); - } - } -} diff --git a/fabric/src/client/java/io/github/reserveword/imblocker/mixin/NotebookScreenMixin.java b/fabric/src/client/java/io/github/reserveword/imblocker/mixin/NotebookScreenMixin.java deleted file mode 100644 index fdab832..0000000 --- a/fabric/src/client/java/io/github/reserveword/imblocker/mixin/NotebookScreenMixin.java +++ /dev/null @@ -1,20 +0,0 @@ -package io.github.reserveword.imblocker.mixin; - -import com.june.notebook.NotebookScreen; -import io.github.reserveword.imblocker.IMCheckState; -import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.Pseudo; -import org.spongepowered.asm.mixin.injection.At; -import org.spongepowered.asm.mixin.injection.Inject; -import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; - -@Pseudo -@Mixin(NotebookScreen.class) -public abstract class NotebookScreenMixin { - @Inject(method = "charTyped", at = @At("HEAD"), cancellable = true) - public void charTypedCallback(char codePoint, int modifiers, CallbackInfoReturnable cir) { - if (IMCheckState.captureNonPrintable(this, codePoint, true)) { - cir.setReturnValue(false); - } - } -} diff --git a/fabric/src/client/java/io/github/reserveword/imblocker/mixin/ReiTextFieldMixin.java b/fabric/src/client/java/io/github/reserveword/imblocker/mixin/ReiTextFieldMixin.java deleted file mode 100644 index 209467c..0000000 --- a/fabric/src/client/java/io/github/reserveword/imblocker/mixin/ReiTextFieldMixin.java +++ /dev/null @@ -1,35 +0,0 @@ -package io.github.reserveword.imblocker.mixin; - -import io.github.reserveword.imblocker.IMCheckState; -import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.Pseudo; -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; -import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; - -@Pseudo -@Mixin(targets = { - "me.shedaniel.rei.impl.client.gui.widget.basewidgets.TextFieldWidget", - "me.shedaniel.rei.gui.widget.TextFieldWidget" -}, remap = false) -public abstract class ReiTextFieldMixin { - @Shadow - protected boolean editable; - @Shadow - public abstract boolean isVisible(); - @Shadow - public abstract boolean isFocused(); - - @Inject(method = "tick", at = @At("HEAD")) - public void tickCallback(CallbackInfo ci) { - boolean active = this.isVisible() && this.isFocused() && this.editable; - IMCheckState.captureTick(this, active); - } - - @Inject(method = "charTyped", at = @At("HEAD")) - public void charTypedCallback(char codePoint, int modifiers, CallbackInfoReturnable cir) { - IMCheckState.captureNonPrintable(this, codePoint, this.editable); - } -} diff --git a/fabric/src/client/java/io/github/reserveword/imblocker/mixin/ReplayModTextFieldMixin.java b/fabric/src/client/java/io/github/reserveword/imblocker/mixin/ReplayModTextFieldMixin.java deleted file mode 100644 index 7160c1c..0000000 --- a/fabric/src/client/java/io/github/reserveword/imblocker/mixin/ReplayModTextFieldMixin.java +++ /dev/null @@ -1,23 +0,0 @@ -package io.github.reserveword.imblocker.mixin; - -import io.github.reserveword.imblocker.IMCheckState; -import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.Pseudo; -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.CallbackInfoReturnable; - -@Pseudo -@Mixin(targets = { - "com.replaymod.lib.de.johni0702.minecraft.gui.element.AbstractGuiTextField" -}, remap = false) -public abstract class ReplayModTextFieldMixin { - @Shadow - public abstract boolean isFocused(); - - @Inject(method = "writeChar*", at = @At("HEAD")) - public void charTypedCallback(char c, CallbackInfoReturnable cir) { - IMCheckState.captureNonPrintable(this, c, this.isFocused()); - } -} diff --git a/fabric/src/client/java/io/github/reserveword/imblocker/mixin/ChatScreenMixin.java b/fabric/src/client/java/io/github/reserveword/imblocker/mixin/fabric/ChatScreenMixin.java similarity index 83% rename from fabric/src/client/java/io/github/reserveword/imblocker/mixin/ChatScreenMixin.java rename to fabric/src/client/java/io/github/reserveword/imblocker/mixin/fabric/ChatScreenMixin.java index 6578f4a..d3e9f04 100644 --- a/fabric/src/client/java/io/github/reserveword/imblocker/mixin/ChatScreenMixin.java +++ b/fabric/src/client/java/io/github/reserveword/imblocker/mixin/fabric/ChatScreenMixin.java @@ -1,4 +1,4 @@ -package io.github.reserveword.imblocker.mixin; +package io.github.reserveword.imblocker.mixin.fabric; import net.minecraft.client.gui.screen.ChatScreen; import org.spongepowered.asm.mixin.Mixin; diff --git a/fabric/src/client/java/io/github/reserveword/imblocker/mixin/fabric/ClickableWidgetMixin.java b/fabric/src/client/java/io/github/reserveword/imblocker/mixin/fabric/ClickableWidgetMixin.java new file mode 100644 index 0000000..b5c3e28 --- /dev/null +++ b/fabric/src/client/java/io/github/reserveword/imblocker/mixin/fabric/ClickableWidgetMixin.java @@ -0,0 +1,26 @@ +package io.github.reserveword.imblocker.mixin.fabric; + +import io.github.reserveword.imblocker.Common; +import io.github.reserveword.imblocker.IMCheckState; +import net.minecraft.client.gui.DrawContext; +import net.minecraft.client.gui.widget.ClickableWidget; +import net.minecraft.client.gui.widget.TextFieldWidget; +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; + +@Mixin(ClickableWidget.class) +public abstract class ClickableWidgetMixin { + @Shadow public abstract boolean isFocused(); + @Shadow public abstract boolean isNarratable(); + + @Inject(method = "render", at=@At("HEAD")) + public void captureTick(DrawContext context, int mouseX, int mouseY, float delta, CallbackInfo ci) { + //noinspection ConstantValue + if (!((Object)this instanceof TextFieldWidget) && Common.classIsTextField(this.getClass())) { + IMCheckState.captureTick(this, isFocused() && isNarratable()); + } + } +} diff --git a/fabric/src/client/java/io/github/reserveword/imblocker/mixin/MinecraftClientMixin.java b/fabric/src/client/java/io/github/reserveword/imblocker/mixin/fabric/MinecraftClientMixin.java similarity index 90% rename from fabric/src/client/java/io/github/reserveword/imblocker/mixin/MinecraftClientMixin.java rename to fabric/src/client/java/io/github/reserveword/imblocker/mixin/fabric/MinecraftClientMixin.java index 886973e..33c5033 100644 --- a/fabric/src/client/java/io/github/reserveword/imblocker/mixin/MinecraftClientMixin.java +++ b/fabric/src/client/java/io/github/reserveword/imblocker/mixin/fabric/MinecraftClientMixin.java @@ -1,4 +1,4 @@ -package io.github.reserveword.imblocker.mixin; +package io.github.reserveword.imblocker.mixin.fabric; import io.github.reserveword.imblocker.IMManager; import net.minecraft.client.MinecraftClient; diff --git a/fabric/src/client/java/io/github/reserveword/imblocker/mixin/MouseMixin.java b/fabric/src/client/java/io/github/reserveword/imblocker/mixin/fabric/MouseMixin.java similarity index 94% rename from fabric/src/client/java/io/github/reserveword/imblocker/mixin/MouseMixin.java rename to fabric/src/client/java/io/github/reserveword/imblocker/mixin/fabric/MouseMixin.java index 821f178..24cc9dc 100644 --- a/fabric/src/client/java/io/github/reserveword/imblocker/mixin/MouseMixin.java +++ b/fabric/src/client/java/io/github/reserveword/imblocker/mixin/fabric/MouseMixin.java @@ -1,4 +1,4 @@ -package io.github.reserveword.imblocker.mixin; +package io.github.reserveword.imblocker.mixin.fabric; import io.github.reserveword.imblocker.Config; import io.github.reserveword.imblocker.IMCheckState; diff --git a/fabric/src/client/java/io/github/reserveword/imblocker/mixin/fabric/ParentElementMixin.java b/fabric/src/client/java/io/github/reserveword/imblocker/mixin/fabric/ParentElementMixin.java new file mode 100644 index 0000000..99a9bbf --- /dev/null +++ b/fabric/src/client/java/io/github/reserveword/imblocker/mixin/fabric/ParentElementMixin.java @@ -0,0 +1,27 @@ +package io.github.reserveword.imblocker.mixin.fabric; + +import io.github.reserveword.imblocker.Common; +import io.github.reserveword.imblocker.IMCheckState; +import net.minecraft.client.gui.Element; +import net.minecraft.client.gui.ParentElement; +import org.jetbrains.annotations.Nullable; +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.CallbackInfoReturnable; + +@Mixin(ParentElement.class) +public interface ParentElementMixin { + @Shadow + @Nullable + Element getFocused(); + + @Inject(method = "charTyped", at = @At("HEAD"), cancellable = true) + default void captureChar(char chr, int modifiers, CallbackInfoReturnable cir) { + Element focused = getFocused(); + if (focused != null && Common.classIsTextField(focused.getClass()) && IMCheckState.captureNonPrintable(focused, chr, true)) { + cir.setReturnValue(false); + } + } +} diff --git a/fabric/src/client/java/io/github/reserveword/imblocker/mixin/fabric/ScreenMixin.java b/fabric/src/client/java/io/github/reserveword/imblocker/mixin/fabric/ScreenMixin.java new file mode 100644 index 0000000..44b7437 --- /dev/null +++ b/fabric/src/client/java/io/github/reserveword/imblocker/mixin/fabric/ScreenMixin.java @@ -0,0 +1,17 @@ +package io.github.reserveword.imblocker.mixin.fabric; + +import io.github.reserveword.imblocker.IMCheckState; +import net.minecraft.client.gui.DrawContext; +import net.minecraft.client.gui.screen.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; + +@Mixin(Screen.class) +public class ScreenMixin { + @Inject(method="render", at = @At("HEAD")) + public void checkRender(DrawContext context, int mouseX, int mouseY, float delta, CallbackInfo ci) { + IMCheckState.scheduleTickCheck(); + } +} diff --git a/fabric/src/client/java/io/github/reserveword/imblocker/mixin/TextFieldMixin.java b/fabric/src/client/java/io/github/reserveword/imblocker/mixin/fabric/TextFieldMixin.java similarity index 91% rename from fabric/src/client/java/io/github/reserveword/imblocker/mixin/TextFieldMixin.java rename to fabric/src/client/java/io/github/reserveword/imblocker/mixin/fabric/TextFieldMixin.java index b9892f6..ee2f355 100644 --- a/fabric/src/client/java/io/github/reserveword/imblocker/mixin/TextFieldMixin.java +++ b/fabric/src/client/java/io/github/reserveword/imblocker/mixin/fabric/TextFieldMixin.java @@ -1,4 +1,4 @@ -package io.github.reserveword.imblocker.mixin; +package io.github.reserveword.imblocker.mixin.fabric; import io.github.reserveword.imblocker.IMCheckState; import net.minecraft.client.gui.widget.TextFieldWidget; @@ -14,7 +14,7 @@ public abstract class TextFieldMixin { @Shadow public abstract boolean isActive(); - @Inject(method = "tick", at = @At("HEAD")) + @Inject(method = "renderWidget", at = @At("HEAD")) public void tickCallback(CallbackInfo ci) { IMCheckState.captureTick(this, this.isActive()); } diff --git a/fabric/src/client/resources/imblocker.mixins.json b/fabric/src/client/resources/imblocker.mixins.json index 35075fe..7b2648a 100644 --- a/fabric/src/client/resources/imblocker.mixins.json +++ b/fabric/src/client/resources/imblocker.mixins.json @@ -1,19 +1,15 @@ { "required": false, "minVersion": "0.8", - "package": "io.github.reserveword.imblocker.mixin", + "package": "io.github.reserveword.imblocker.mixin.fabric", "compatibilityLevel": "JAVA_17", "client": [ "ChatScreenMixin", - "CottonTextFieldMixin", - "FtbTextFieldMixin", - "FtbWidgetMixin", - "MetetorTextFieldMixin", + "ClickableWidgetMixin", "MinecraftClientMixin", "MouseMixin", - "NotebookScreenMixin", - "ReiTextFieldMixin", - "ReplayModTextFieldMixin", + "ParentElementMixin", + "ScreenMixin", "TextFieldMixin" ], "injectors": { diff --git a/forge/build.gradle b/forge/build.gradle index c9059bb..c6800ae 100644 --- a/forge/build.gradle +++ b/forge/build.gradle @@ -1,78 +1,28 @@ plugins { id 'eclipse' id 'idea' - id 'net.minecraftforge.gradle' version '[6.0,6.2)' + id 'net.neoforged.gradle.userdev' version "$neogradle_version" } // Mojang ships Java 17 to end users in 1.18+, so your mod should target Java 17. java.toolchain.languageVersion = JavaLanguageVersion.of(17) -minecraft { - mappings channel: mapping_channel, version: mapping_version +runs { + client { + systemProperty 'forge.logging.markers', 'REGISTRIES' - copyIdeResources = true + systemProperty 'forge.logging.console.level', 'debug' - runs { - client { - workingDirectory project.file('run') + systemProperty 'neoforge.enabledGameTestNamespaces', mod_id - property 'forge.logging.markers', 'REGISTRIES' - - property 'forge.logging.console.level', 'debug' - - property 'forge.enabledGameTestNamespaces', mod_id - - mods { - "${mod_id}" { - source sourceSets.main - } - } - } - - server { - workingDirectory project.file('run') - - property 'forge.logging.markers', 'REGISTRIES' - - property 'forge.logging.console.level', 'debug' - - property 'forge.enabledGameTestNamespaces', mod_id - - mods { - "${mod_id}" { - source sourceSets.main - } - } - } + modSource sourceSets.main } } -// Include resources generated by data generators. -sourceSets.main.resources { srcDir 'src/generated/resources' } - dependencies { - minecraft "net.minecraftforge:forge:${minecraft_version}-${forge_version}" + implementation "net.neoforged:neoforge:${neo_version}" - compileOnly fg.deobf("mezz.jei:jei-${minecraft_version}-common-api:${jei_version}") - compileOnly fg.deobf("mezz.jei:jei-${minecraft_version}-forge-api:${jei_version}") - runtimeOnly fg.deobf("mezz.jei:jei-${minecraft_version}-forge:${jei_version}") + runtimeOnly "mezz.jei:jei-${minecraft_version}-neoforge:${jei_version}" implementation project(':common') } - -// Example for how to get properties into the manifest for reading at runtime. -project.jar { - finalizedBy 'reobfJar' - manifest { - attributes([ - "Specification-Title" : mod_id, - "Specification-Vendor" : author, - "Specification-Version" : "1", // We are version 1 of ourselves - "Implementation-Title" : rootProject.name, - "Implementation-Version" : mod_version, - "Implementation-Vendor" : author, - "Implementation-Timestamp": new Date().format("yyyy-MM-dd'T'HH:mm:ssZ") - ]) - } - exclude 'io/github/reserveword/imblocker/asmdummy' -} diff --git a/forge/runs/client/config/fml.toml b/forge/runs/client/config/fml.toml new file mode 100644 index 0000000..d1574bb --- /dev/null +++ b/forge/runs/client/config/fml.toml @@ -0,0 +1,27 @@ +#Early window height +earlyWindowHeight = 480 +#Enable NeoForge global version checking +versionCheck = true +#Should we control the window. Disabling this disables new GL features and can be bad for mods that rely on them. +earlyWindowControl = true +#Early window framebuffer scale +earlyWindowFBScale = 1 +#Disables File Watcher. Used to automatically update config if its file has been modified. +disableConfigWatcher = false +#Early window provider +earlyWindowProvider = "fmlearlywindow" +#Early window width +earlyWindowWidth = 854 +#Early window starts maximized +earlyWindowMaximized = false +#Default config path for servers +defaultConfigPath = "defaultconfigs" +#Disables Optimized DFU client-side - already disabled on servers +disableOptimizedDFU = true +#Skip specific GL versions, may help with buggy graphics card drivers +earlyWindowSkipGLVersions = [] +#Max threads for early initialization parallelism, -1 is based on processor count +maxThreads = -1 +#Squir? +earlyWindowSquir = false + diff --git a/forge/src/main/java/io/github/reserveword/imblocker/ForgeConfig.java b/forge/src/main/java/io/github/reserveword/imblocker/ForgeConfig.java index 647821a..24f20ab 100644 --- a/forge/src/main/java/io/github/reserveword/imblocker/ForgeConfig.java +++ b/forge/src/main/java/io/github/reserveword/imblocker/ForgeConfig.java @@ -3,23 +3,16 @@ import net.minecraft.client.gui.screens.inventory.BookEditScreen; import net.minecraft.client.gui.screens.inventory.HangingSignEditScreen; import net.minecraft.client.gui.screens.inventory.SignEditScreen; -import net.minecraftforge.common.ForgeConfigSpec; -import net.minecraftforge.fml.ModList; -import net.minecraftforge.fml.common.Mod; +import net.neoforged.fml.ModList; +import net.neoforged.neoforge.common.ModConfigSpec; import org.apache.commons.lang3.tuple.Pair; import java.net.URL; import java.security.CodeSource; import java.security.ProtectionDomain; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Collections; -import java.util.HashSet; -import java.util.List; -import java.util.Set; +import java.util.*; import java.util.concurrent.atomic.AtomicReference; -@Mod.EventBusSubscriber public class ForgeConfig extends Config { @Override @@ -42,10 +35,7 @@ public boolean inInputWhitelist(Class cls) { return inputWhitelist.contains(cls); } - @Override - public Integer getCheckInterval() { - return CLIENT.checkInterval.get(); - } + public static final ModConfigSpec clientSpec; @Override public Boolean getUseExperimental() { @@ -76,8 +66,8 @@ public String getClassName(Class cls) { AtomicReference name = new AtomicReference<>("UNKNOWN_SCREEN"); ModList.get().forEachModContainer((modid, mod) -> { try { - if (!"minecraft".equals(modid) && !"imblocker".equals(modid) && loc.equals(mod.getMod().getClass() - .getProtectionDomain().getCodeSource().getLocation())) { + if (!"minecraft".equals(modid) && !"imblocker".equals(modid) && loc == mod.getMod().getClass() + .getProtectionDomain().getCodeSource().getLocation()) { name.set(modid + ":" + cls.getName()); } } catch (NullPointerException npe) { @@ -102,34 +92,65 @@ public static void reload() { inputBlacklist = bakeList(CLIENT.inputBlacklist, "inputBlacklist"); } - /** - * Client specific configuration - only loaded clientside from forge-client.toml - */ - public static class Client { - - private final ForgeConfigSpec.ConfigValue checkInterval; + static { + final Pair specPair = new ModConfigSpec.Builder().configure(ForgeConfig.Client::new); + clientSpec = specPair.getRight(); + CLIENT = specPair.getLeft(); + Config.INSTANCE = new ForgeConfig(); + } - public final ForgeConfigSpec.ConfigValue> screenWhitelist; + private static Set> screenBlacklist; + private static Set> screenWhitelist; + private static Set> inputBlacklist; + private static Set> inputWhitelist; + private final static Set> recoveredScreens = new HashSet<>(); - public final ForgeConfigSpec.ConfigValue> screenBlacklist; + private static Set> bakeList(ModConfigSpec.ConfigValue> cfg, String name) { + Set> clsSet = new HashSet<>(); + for (String s : cfg.get()) { + try { + if (s.contains(":")) { + String[] ss = s.split(":"); + s = ss[ss.length - 1]; + } + clsSet.add(Class.forName(s)); + } catch (ClassNotFoundException e) { + Common.LOGGER.warn("Class {} not found, ignored.", s); + } + } + Common.LOGGER.info("imblocker bakelist {} result {}", name, clsSet); + return clsSet; + } - public final ForgeConfigSpec.ConfigValue> inputWhitelist; + @Override + public Integer getCheckInterval() { + return CLIENT.checkIntervalMilli.get(); + } + public static final ForgeConfig.Client CLIENT; - public final ForgeConfigSpec.ConfigValue> inputBlacklist; + /** + * Client specific configuration - only loaded clientside from forge-client.toml + */ + public static class Client { - private final ForgeConfigSpec.ConfigValue enableScreenRecovering; + public final ModConfigSpec.ConfigValue> screenWhitelist; + public final ModConfigSpec.ConfigValue> screenBlacklist; + public final ModConfigSpec.ConfigValue> inputWhitelist; + public final ModConfigSpec.ConfigValue> inputBlacklist; + private final ModConfigSpec.ConfigValue checkIntervalMilli; + private final ModConfigSpec.ConfigValue enableScreenRecovering; - private final ForgeConfigSpec.ConfigValue> recoveredScreens; + private final ModConfigSpec.ConfigValue> recoveredScreens; - private final ForgeConfigSpec.ConfigValue useExperimental; + private final ModConfigSpec.ConfigValue useExperimental; - private final ForgeConfigSpec.ConfigValue checkCommandChat; + private final ModConfigSpec.ConfigValue checkCommandChat; - Client(ForgeConfigSpec.Builder builder) { - checkInterval = builder - .comment("Checking every tick is not efficient, how about check once every several tick?") - .translation("key.imblocker.checkInterval") - .defineInRange("checkInterval", 2, 1, Integer.MAX_VALUE); + Client(ModConfigSpec.Builder builder) { + checkIntervalMilli = builder + .comment("Check once every several milliseconds") + .translation("key.imblocker.checkIntervalMilli") + .defineInRange("checkIntervalMilli", 100, 1, Integer.MAX_VALUE); screenBlacklist = builder .comment("Matched screens would disable your IME") @@ -171,7 +192,7 @@ public static class Client { useExperimental = builder .comment("Disable this and let me know if input or control is messed up") .translation("key.imblocker.useExperimental") - .define("useExperimental", true); + .define("useExperimental", false); checkCommandChat = builder .comment("Disable IME when typing commands") @@ -180,36 +201,5 @@ public static class Client { } } - private static Set> screenBlacklist; - private static Set> screenWhitelist; - private static Set> inputBlacklist; - private static Set> inputWhitelist; - private final static Set> recoveredScreens = new HashSet<>(); - private static Set> bakeList(ForgeConfigSpec.ConfigValue> cfg, String name) { - Set> clsSet = new HashSet<>(); - for (String s : cfg.get()) { - try { - if (s.contains(":")) { - String[] ss = s.split(":"); - s = ss[ss.length - 1]; - } - clsSet.add(Class.forName(s)); - } catch (ClassNotFoundException e) { - Common.LOGGER.warn("Class {} not found, ignored.", s); - } - } - Common.LOGGER.info("imblocker bakelist {} result {}", name, clsSet); - return clsSet; - } - - public static final ForgeConfigSpec clientSpec; - public static final ForgeConfig.Client CLIENT; - static { - final Pair specPair = new ForgeConfigSpec.Builder().configure(ForgeConfig.Client::new); - clientSpec = specPair.getRight(); - CLIENT = specPair.getLeft(); - Config.INSTANCE = new ForgeConfig(); - } - private ForgeConfig() {} } diff --git a/forge/src/main/java/io/github/reserveword/imblocker/ForgeScreenInfo.java b/forge/src/main/java/io/github/reserveword/imblocker/ForgeScreenInfo.java index fb767bd..4cd8d16 100644 --- a/forge/src/main/java/io/github/reserveword/imblocker/ForgeScreenInfo.java +++ b/forge/src/main/java/io/github/reserveword/imblocker/ForgeScreenInfo.java @@ -1,17 +1,14 @@ package io.github.reserveword.imblocker; +import io.github.reserveword.imblocker.mixin.forge.ChatScreenMixin; import net.minecraft.client.Minecraft; import net.minecraft.client.gui.screens.ChatScreen; import net.minecraft.client.gui.screens.Screen; -import java.lang.invoke.MethodHandle; -import java.lang.invoke.MethodHandles; -import java.lang.invoke.MethodType; - public class ForgeScreenInfo implements IMCheckState.ScreenInfo { private final Screen screen; public ForgeScreenInfo() { - screen = Minecraft.m_91087_().f_91080_; + screen = Minecraft.getInstance().screen; } @Override @@ -30,26 +27,12 @@ public Class type() { } @Override - public String defaultText() throws Throwable { - return (String) getDefaultInputFieldText.invoke(screen); + public String defaultText() { + return ((ChatScreenMixin) screen).getOriginalText(); } @Override public void charTyped(char codePoint, int modifiers) { - screen.m_5534_(codePoint, modifiers); - } - - private static final MethodHandle getDefaultInputFieldText; - static { - MethodHandle getDefaultInputFieldText_tmp; - try { - MethodHandles.Lookup lookup = MethodHandles.lookup(); - //noinspection JavaLangInvokeHandleSignature - getDefaultInputFieldText_tmp = lookup.findVirtual(ChatScreen.class, "getDefaultInputFieldText", MethodType.methodType(String.class)); - } catch (java.lang.NoSuchMethodException | java.lang.IllegalAccessException e) { - getDefaultInputFieldText_tmp = null; - Common.LOGGER.warn("ChatScreen command hook failed:", e); - } - getDefaultInputFieldText = getDefaultInputFieldText_tmp; + screen.charTyped(codePoint, modifiers); } } diff --git a/forge/src/main/java/io/github/reserveword/imblocker/IMBlocker.java b/forge/src/main/java/io/github/reserveword/imblocker/IMBlocker.java index 420976c..674449f 100644 --- a/forge/src/main/java/io/github/reserveword/imblocker/IMBlocker.java +++ b/forge/src/main/java/io/github/reserveword/imblocker/IMBlocker.java @@ -1,44 +1,37 @@ package io.github.reserveword.imblocker; -import net.minecraftforge.client.event.ScreenEvent; -import net.minecraftforge.event.TickEvent; -import net.minecraftforge.eventbus.api.SubscribeEvent; -import net.minecraftforge.fml.ModLoadingContext; -import net.minecraftforge.fml.common.Mod; -import net.minecraftforge.fml.config.ModConfig; -import net.minecraftforge.fml.event.config.ModConfigEvent; -import net.minecraftforge.fml.javafmlmod.FMLJavaModLoadingContext; +import net.neoforged.api.distmarker.Dist; +import net.neoforged.bus.api.SubscribeEvent; +import net.neoforged.fml.ModLoadingContext; +import net.neoforged.fml.common.Mod; +import net.neoforged.fml.config.ModConfig; +import net.neoforged.fml.event.config.ModConfigEvent; +import net.neoforged.neoforge.event.TickEvent; // The value here should match an entry in the META-INF/mods.toml file @Mod(Common.MODID) public class IMBlocker { public IMBlocker() { // Register ourselves for server and other game events we are interested in - FMLJavaModLoadingContext.get().getModEventBus().addListener(this::onConfigLoadReload); ModLoadingContext.get().registerConfig(ModConfig.Type.CLIENT, ForgeConfig.clientSpec); } - @Mod.EventBusSubscriber - public static class RegistryEvents { + @Mod.EventBusSubscriber(Dist.CLIENT) + public static class ForgeEvents { @SubscribeEvent public static void onClientTick(TickEvent.ClientTickEvent cte) { if (cte.phase == TickEvent.Phase.START) { IMCheckState.clientTick(new ForgeScreenInfo()); } } - @SubscribeEvent - public static void onMouseClick(ScreenEvent.MouseButtonPressed mie) { - IMCheckState.mouseEvent(); - } - @SubscribeEvent - public static void onMouseClick(ScreenEvent.MouseButtonReleased mie) { - IMCheckState.mouseEvent(); - } } - @SubscribeEvent - public void onConfigLoadReload(ModConfigEvent e) { - Common.LOGGER.info("imblock {}loading config", (e instanceof ModConfigEvent.Reloading)?"re":""); - ForgeConfig.reload(); + @Mod.EventBusSubscriber(value = Dist.CLIENT, bus = Mod.EventBusSubscriber.Bus.MOD) + public static class ModEvents { + @SubscribeEvent + public static void onConfigLoadReload(ModConfigEvent e) { + Common.LOGGER.info("imblock {}loading config", (e instanceof ModConfigEvent.Reloading)?"re":""); + ForgeConfig.reload(); + } } } diff --git a/forge/src/main/java/io/github/reserveword/imblocker/asmdummy/FakeChatScreen.java b/forge/src/main/java/io/github/reserveword/imblocker/asmdummy/FakeChatScreen.java deleted file mode 100644 index c0f2ebb..0000000 --- a/forge/src/main/java/io/github/reserveword/imblocker/asmdummy/FakeChatScreen.java +++ /dev/null @@ -1,16 +0,0 @@ -package io.github.reserveword.imblocker.asmdummy; - -import net.minecraft.client.gui.screens.Screen; -import net.minecraft.network.chat.Component; - -@SuppressWarnings("ALL") -public class FakeChatScreen extends Screen { - protected FakeChatScreen(Component titleIn) { - super(titleIn); - } - private String defaultInputFieldText = ""; // f_95576_ - - public String getDefaultInputFieldText() { - return defaultInputFieldText; - } -} diff --git a/forge/src/main/java/io/github/reserveword/imblocker/asmdummy/FakeFTBLibTextBox.java b/forge/src/main/java/io/github/reserveword/imblocker/asmdummy/FakeFTBLibTextBox.java deleted file mode 100644 index f3639c5..0000000 --- a/forge/src/main/java/io/github/reserveword/imblocker/asmdummy/FakeFTBLibTextBox.java +++ /dev/null @@ -1,14 +0,0 @@ -package io.github.reserveword.imblocker.asmdummy; - -import io.github.reserveword.imblocker.IMCheckState; - -public class FakeFTBLibTextBox { - public static class FakeSubClass extends FakeFTBLibTextBox { - public boolean submethod() { return false; } - } - - public void tick() { - if (this instanceof FakeSubClass) - IMCheckState.captureTick(this, ((FakeSubClass)this).submethod()); - } -} diff --git a/forge/src/main/java/io/github/reserveword/imblocker/asmdummy/FakeTextFieldWidget.java b/forge/src/main/java/io/github/reserveword/imblocker/asmdummy/FakeTextFieldWidget.java deleted file mode 100644 index 50db00b..0000000 --- a/forge/src/main/java/io/github/reserveword/imblocker/asmdummy/FakeTextFieldWidget.java +++ /dev/null @@ -1,43 +0,0 @@ -package io.github.reserveword.imblocker.asmdummy; - -import io.github.reserveword.imblocker.IMCheckState; -import net.minecraft.SharedConstants; -import net.minecraft.client.gui.Font; -import net.minecraft.client.gui.components.EditBox; -import net.minecraft.network.chat.Component; - -/** - * We use this dummy class to help us decide how we modify EditBox.tick - */ -public class FakeTextFieldWidget extends EditBox { - - private int cursorCounter; - private boolean isEnabled; - - public FakeTextFieldWidget(Font fontRenderer, int x, int y, int width, int height, Component title) { - super(fontRenderer, x, y, width, height, title); - } - - @Override - public void m_94120_() { - IMCheckState.captureTick(this, this.m_94204_()); // canWrite - ++this.cursorCounter; - } - - @Override - public boolean m_5534_(char codePoint, int modifiers) { // charTyped - IMCheckState.captureNonPrintable(this, codePoint, this.m_94204_()); - if (!this.m_94204_()) { - return false; - } else if (SharedConstants.m_136188_(codePoint)) { - if (this.isEnabled) { - this.m_94164_(Character.toString(codePoint)); - } - - return true; - } else { - return false; - } - } - -} diff --git a/forge/src/main/java/io/github/reserveword/imblocker/mixin/forge/ChatScreenMixin.java b/forge/src/main/java/io/github/reserveword/imblocker/mixin/forge/ChatScreenMixin.java new file mode 100644 index 0000000..0bbcf8c --- /dev/null +++ b/forge/src/main/java/io/github/reserveword/imblocker/mixin/forge/ChatScreenMixin.java @@ -0,0 +1,11 @@ +package io.github.reserveword.imblocker.mixin.forge; + +import net.minecraft.client.gui.screens.ChatScreen; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.gen.Accessor; + +@Mixin(ChatScreen.class) +public interface ChatScreenMixin { + @Accessor("initial") + String getOriginalText(); +} diff --git a/forge/src/main/java/io/github/reserveword/imblocker/mixin/forge/ClickableWidgetMixin.java b/forge/src/main/java/io/github/reserveword/imblocker/mixin/forge/ClickableWidgetMixin.java new file mode 100644 index 0000000..7e83b77 --- /dev/null +++ b/forge/src/main/java/io/github/reserveword/imblocker/mixin/forge/ClickableWidgetMixin.java @@ -0,0 +1,26 @@ +package io.github.reserveword.imblocker.mixin.forge; + +import io.github.reserveword.imblocker.Common; +import io.github.reserveword.imblocker.IMCheckState; +import net.minecraft.client.gui.GuiGraphics; +import net.minecraft.client.gui.components.AbstractWidget; +import net.minecraft.client.gui.components.EditBox; +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; + +@Mixin(AbstractWidget.class) +public abstract class ClickableWidgetMixin { + @Shadow public abstract boolean isFocused(); + @Shadow public abstract boolean isActive(); + + @Inject(method = "render", at=@At("HEAD")) + public void captureTick(GuiGraphics p_282421_, int p_93658_, int p_93659_, float p_93660_, CallbackInfo ci) { + //noinspection ConstantValue + if (!((Object)this instanceof EditBox) && Common.classIsTextField(this.getClass())) { + IMCheckState.captureTick(this, isFocused() && isActive()); + } + } +} diff --git a/forge/src/main/java/io/github/reserveword/imblocker/mixin/forge/MinecraftClientMixin.java b/forge/src/main/java/io/github/reserveword/imblocker/mixin/forge/MinecraftClientMixin.java new file mode 100644 index 0000000..0efe7e3 --- /dev/null +++ b/forge/src/main/java/io/github/reserveword/imblocker/mixin/forge/MinecraftClientMixin.java @@ -0,0 +1,16 @@ +package io.github.reserveword.imblocker.mixin.forge; + +import io.github.reserveword.imblocker.IMManager; +import net.minecraft.client.Minecraft; +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(Minecraft.class) +public abstract class MinecraftClientMixin { + @Inject(method = "setWindowActive", at = @At("HEAD")) + public void syncIMState(CallbackInfo ci) { + IMManager.syncState(); + } +} diff --git a/forge/src/main/java/io/github/reserveword/imblocker/mixin/forge/MouseMixin.java b/forge/src/main/java/io/github/reserveword/imblocker/mixin/forge/MouseMixin.java new file mode 100644 index 0000000..29049ea --- /dev/null +++ b/forge/src/main/java/io/github/reserveword/imblocker/mixin/forge/MouseMixin.java @@ -0,0 +1,26 @@ +package io.github.reserveword.imblocker.mixin.forge; + +import io.github.reserveword.imblocker.Config; +import io.github.reserveword.imblocker.IMCheckState; +import net.minecraft.client.Minecraft; +import net.minecraft.client.MouseHandler; +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; + +@Mixin(MouseHandler.class) +public abstract class MouseMixin { + @Final + @Shadow + private Minecraft minecraft; + + @Inject(method = "onPress", at = @At("HEAD")) + private void checkScreenOnMouseButton(long window, int button, int action, int mods, CallbackInfo ci) { + if (minecraft.screen != null && !Config.INSTANCE.inScreenBlacklist(minecraft.screen.getClass())) { + IMCheckState.mouseEvent(); + } + } +} \ No newline at end of file diff --git a/forge/src/main/java/io/github/reserveword/imblocker/mixin/forge/ParentElementMixin.java b/forge/src/main/java/io/github/reserveword/imblocker/mixin/forge/ParentElementMixin.java new file mode 100644 index 0000000..78f7389 --- /dev/null +++ b/forge/src/main/java/io/github/reserveword/imblocker/mixin/forge/ParentElementMixin.java @@ -0,0 +1,27 @@ +package io.github.reserveword.imblocker.mixin.forge; + +import io.github.reserveword.imblocker.Common; +import io.github.reserveword.imblocker.IMCheckState; +import net.minecraft.client.gui.components.events.ContainerEventHandler; +import net.minecraft.client.gui.components.events.GuiEventListener; +import org.jetbrains.annotations.Nullable; +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.CallbackInfoReturnable; + +@Mixin(ContainerEventHandler.class) +public interface ParentElementMixin { + @Shadow + @Nullable + GuiEventListener getFocused(); + + @Inject(method = "charTyped", at = @At("HEAD"), cancellable = true) + default void captureChar(char chr, int modifiers, CallbackInfoReturnable cir) { + GuiEventListener focused = getFocused(); + if (focused != null && Common.classIsTextField(focused.getClass()) && IMCheckState.captureNonPrintable(focused, chr, true)) { + cir.setReturnValue(false); + } + } +} diff --git a/forge/src/main/java/io/github/reserveword/imblocker/mixin/forge/ScreenMixin.java b/forge/src/main/java/io/github/reserveword/imblocker/mixin/forge/ScreenMixin.java new file mode 100644 index 0000000..b1234b7 --- /dev/null +++ b/forge/src/main/java/io/github/reserveword/imblocker/mixin/forge/ScreenMixin.java @@ -0,0 +1,17 @@ +package io.github.reserveword.imblocker.mixin.forge; + +import io.github.reserveword.imblocker.IMCheckState; +import net.minecraft.client.gui.GuiGraphics; +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; + +@Mixin(Screen.class) +public class ScreenMixin { + @Inject(method="render", at = @At("HEAD")) + public void checkRender(GuiGraphics context, int mouseX, int mouseY, float delta, CallbackInfo ci) { + IMCheckState.scheduleTickCheck(); + } +} diff --git a/forge/src/main/java/io/github/reserveword/imblocker/mixin/forge/TextFieldMixin.java b/forge/src/main/java/io/github/reserveword/imblocker/mixin/forge/TextFieldMixin.java new file mode 100644 index 0000000..2d235cc --- /dev/null +++ b/forge/src/main/java/io/github/reserveword/imblocker/mixin/forge/TextFieldMixin.java @@ -0,0 +1,31 @@ +package io.github.reserveword.imblocker.mixin.forge; + +import io.github.reserveword.imblocker.IMCheckState; +import net.minecraft.client.gui.components.EditBox; +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; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; + +@Mixin(EditBox.class) +public abstract class TextFieldMixin { + @Shadow + public abstract boolean canConsumeInput(); + + @Inject(method = "renderWidget", at = @At("HEAD")) + public void tickCallback(CallbackInfo ci) { + IMCheckState.captureTick(this, this.canConsumeInput()); + } + + @Inject(method = "charTyped", at = @At("HEAD")) + public void charTypedCallback(char codePoint, int modifiers, CallbackInfoReturnable cir) { + IMCheckState.captureNonPrintable(this, codePoint, this.canConsumeInput()); + } + + @Inject(method = "onClick", at = @At("HEAD")) + public void onClickCallback(double mouseX, double mouseY, CallbackInfo ci) { + IMCheckState.captureClick(this::canConsumeInput); + } +} diff --git a/forge/src/main/resources/META-INF/coremods.json b/forge/src/main/resources/META-INF/coremods.json deleted file mode 100644 index 0075520..0000000 --- a/forge/src/main/resources/META-INF/coremods.json +++ /dev/null @@ -1,5 +0,0 @@ -{ - "text_field_asm": "coremod/text_field_asm.js", - "window_focus_asm": "coremod/window_focus_asm.js", - "chat_screen_asm": "coremod/chat_screen_asm.js" -} \ No newline at end of file diff --git a/forge/src/main/resources/META-INF/imblocker.mixins.json b/forge/src/main/resources/META-INF/imblocker.mixins.json new file mode 100644 index 0000000..7b89b81 --- /dev/null +++ b/forge/src/main/resources/META-INF/imblocker.mixins.json @@ -0,0 +1,18 @@ +{ + "required": false, + "minVersion": "0.8", + "package": "io.github.reserveword.imblocker.mixin.forge", + "compatibilityLevel": "JAVA_17", + "client": [ + "ChatScreenMixin", + "ClickableWidgetMixin", + "MinecraftClientMixin", + "MouseMixin", + "ParentElementMixin", + "ScreenMixin", + "TextFieldMixin" + ], + "injectors": { + "defaultRequire": 1 + } +} \ No newline at end of file diff --git a/forge/src/main/resources/META-INF/mods.toml b/forge/src/main/resources/META-INF/mods.toml index d595da9..47af683 100644 --- a/forge/src/main/resources/META-INF/mods.toml +++ b/forge/src/main/resources/META-INF/mods.toml @@ -1,33 +1,16 @@ -# This is an example mods.toml file. It contains the data relating to the loading mods. -# There are several mandatory fields (#mandatory), and many more that are optional (#optional). -# The overall format is standard TOML format, v0.5.0. -# Note that there are a couple of TOML lists in this file. -# Find more information on toml format here: https://github.com/toml-lang/toml -# The name of the mod loader type to load - for regular FML @Mod mods it should be javafml -modLoader="javafml" #mandatory -# A version range to match for said mod loader - for regular FML @Mod it will be the forge version -loaderVersion="${loader_version_range}" #mandatory (28 is current forge version) -# A URL to refer people to when problems occur with this mod -issueTrackerURL="${issues_url}" #optional -# A list of mods - how many allowed here is determined by the individual mod loader +modLoader="javafml" +loaderVersion="${loader_version_range}" +issueTrackerURL="${issues_url}" license="${license}" -[[mods]] #mandatory -# The modid of the mod -modId="${mod_id}" #mandatory -# The version number of the mod - there's a few well known ${} variables useable here or just hardcode it -version="${mod_version}" #mandatory - # A display name for the mod -displayName="${mod_name}" #mandatory -# A URL to query for updates for this mod. See the JSON update specification -# updateJSONURL="http://myurl.me/" #optional -# A URL for the "homepage" for this mod, displayed in the mod UI -displayURL="${mod_url}" #optional -# A file name (in the root of the mod JAR) containing a logo for display -logoFile="${mod_logo}" #optional -# A text field displayed in the mod UI -credits="${credits}" #optional -# A text field displayed in the mod UI -authors="${author}" #optional -# The description text for the mod (multi line!) (#mandatory) +[[mods]] +modId="${mod_id}" +version="${mod_version}" +displayName="${mod_name}" +displayURL="${mod_url}" +logoFile="${mod_logo}" +credits="${credits}" +authors="${author}" description='''Blocks Input Methods when you're not using it. 在你不打字的时候自动关闭输入法''' +[[mixins]] +config = "META-INF/imblocker.mixins.json" diff --git a/forge/src/main/resources/coremod/chat_screen_asm.js b/forge/src/main/resources/coremod/chat_screen_asm.js deleted file mode 100644 index 8c9285e..0000000 --- a/forge/src/main/resources/coremod/chat_screen_asm.js +++ /dev/null @@ -1,37 +0,0 @@ -var ASMAPI = Java.type('net.minecraftforge.coremod.api.ASMAPI'); -var MethodNode = Java.type('org.objectweb.asm.tree.MethodNode'); -var InsnNode = Java.type('org.objectweb.asm.tree.InsnNode'); -var VarInsnNode = Java.type('org.objectweb.asm.tree.VarInsnNode'); -var FieldInsnNode = Java.type('org.objectweb.asm.tree.FieldInsnNode'); -var Opcodes = Java.type('org.objectweb.asm.Opcodes'); - -function initializeCoreMod() { - return { - 'chat_screen_asm': { - 'target': { - 'type': 'CLASS', - 'name': 'net.minecraft.client.gui.screens.ChatScreen', - }, - 'transformer': function (node) { - var method = new MethodNode( - /* access = */ Opcodes.ACC_PUBLIC, - /* name = */ 'getDefaultInputFieldText', - /* descriptor = */ '()Ljava/lang/String;', - /* signature = */ null, - /* exceptions = */ null - ) - node.methods.add(method) - il = method.instructions - il.add(new VarInsnNode(Opcodes.ALOAD, 0)) - il.add(new FieldInsnNode( - Opcodes.GETFIELD, - 'net/minecraft/client/gui/screens/ChatScreen', - ASMAPI.mapField('f_95576_'), - 'Ljava/lang/String;' - )) - il.add(new InsnNode(Opcodes.ARETURN)) - return node - } - } - }; -} \ No newline at end of file diff --git a/forge/src/main/resources/coremod/text_field_asm.js b/forge/src/main/resources/coremod/text_field_asm.js deleted file mode 100644 index d35f7d0..0000000 --- a/forge/src/main/resources/coremod/text_field_asm.js +++ /dev/null @@ -1,140 +0,0 @@ -var ASMAPI = Java.type('net.minecraftforge.coremod.api.ASMAPI'); -var InsnList = Java.type('org.objectweb.asm.tree.InsnList'); -var VarInsnNode = Java.type('org.objectweb.asm.tree.VarInsnNode'); -var FieldInsnNode = Java.type('org.objectweb.asm.tree.FieldInsnNode'); -var MethodInsnNode = Java.type('org.objectweb.asm.tree.MethodInsnNode'); -var LabelNode = Java.type('org.objectweb.asm.tree.LabelNode'); -var JumpInsnNode = Java.type('org.objectweb.asm.tree.JumpInsnNode'); -var TypeInsnNode = Java.type('org.objectweb.asm.tree.TypeInsnNode'); -var FrameNode = Java.type('org.objectweb.asm.tree.FrameNode'); -var Opcodes = Java.type('org.objectweb.asm.Opcodes'); - -function initializeCoreMod() { - return { - 'text_field_asm': { - 'target': { - 'type': 'METHOD', - 'class': 'net.minecraft.client.gui.components.EditBox', - 'methodName': 'm_94120_', - 'methodDesc': '()V' - }, - 'transformer': function (method) { - il = new InsnList() - il.add(new VarInsnNode(Opcodes.ALOAD, 0)) - il.add(new VarInsnNode(Opcodes.ALOAD, 0)) - il.add(new MethodInsnNode( - Opcodes.INVOKEVIRTUAL, - 'net/minecraft/client/gui/components/EditBox', - ASMAPI.mapMethod('m_94204_'), - '()Z', - false - )) - il.add(new MethodInsnNode( - Opcodes.INVOKESTATIC, - 'io/github/reserveword/imblocker/IMCheckState', - 'captureTick', - '(Ljava/lang/Object;Z)V', - false - )) - method.instructions.insert(il) - return method - } - }, - 'char_typed_asm': { - 'target': { - 'type': 'METHOD', - 'class': 'net.minecraft.client.gui.components.EditBox', - 'methodName': 'm_5534_', - 'methodDesc': '(CI)Z' - }, - 'transformer': function (method) { - il = new InsnList() - il.add(new VarInsnNode(Opcodes.ALOAD, 0)) - il.add(new VarInsnNode(Opcodes.ILOAD, 1)) - il.add(new VarInsnNode(Opcodes.ALOAD, 0)) - il.add(new MethodInsnNode( - Opcodes.INVOKEVIRTUAL, - 'net/minecraft/client/gui/components/EditBox', - ASMAPI.mapMethod('m_94204_'), - '()Z', - false - )) - il.add(new MethodInsnNode( - Opcodes.INVOKESTATIC, - 'io/github/reserveword/imblocker/IMCheckState', - 'captureNonPrintable', - '(Ljava/lang/Object;CZ)Z', - false - )) - method.instructions.insert(il) - return method - } - }, - 'ftblib_text_field_asm': { - 'target': { - 'type': 'METHOD', - 'class': 'dev.ftb.mods.ftblibrary.ui.Widget', - 'methodName': 'tick', - 'methodDesc': '()V' - }, - 'transformer': function (method) { - label = new LabelNode() - il = new InsnList() - il.add(new VarInsnNode(Opcodes.ALOAD, 0)) - il.add(new TypeInsnNode(Opcodes.INSTANCEOF, 'dev/ftb/mods/ftblibrary/ui/TextBox')) - il.add(new JumpInsnNode(Opcodes.IFEQ, label)) - il.add(new VarInsnNode(Opcodes.ALOAD, 0)) - il.add(new VarInsnNode(Opcodes.ALOAD, 0)) - il.add(new TypeInsnNode(Opcodes.CHECKCAST, 'dev/ftb/mods/ftblibrary/ui/TextBox')) - il.add(new MethodInsnNode( - Opcodes.INVOKEVIRTUAL, - 'dev/ftb/mods/ftblibrary/ui/TextBox', - 'isFocused', - '()Z', - false - )) - il.add(new MethodInsnNode( - Opcodes.INVOKESTATIC, - 'io/github/reserveword/imblocker/IMCheckState', - 'captureTick', - '(Ljava/lang/Object;Z)V', - false - )) - il.add(label) - il.add(new FrameNode(Opcodes.F_SAME, 0, [], 0, [])) - method.instructions.insert(il) - return method - } - }, - 'ftblib_char_typed_asm': { - 'target': { - 'type': 'METHOD', - 'class': 'dev.ftb.mods.ftblibrary.ui.TextBox', - 'methodName': 'charTyped', - 'methodDesc': '(CLdev/ftb/mods/ftblibrary/ui/input/KeyModifiers;)Z' - }, - 'transformer': function (method) { - il = new InsnList() - il.add(new VarInsnNode(Opcodes.ALOAD, 0)) - il.add(new VarInsnNode(Opcodes.ILOAD, 1)) - il.add(new VarInsnNode(Opcodes.ALOAD, 0)) - il.add(new MethodInsnNode( - Opcodes.INVOKEVIRTUAL, - 'dev/ftb/mods/ftblibrary/ui/TextBox', - 'isFocused', - '()Z', - false - )) - il.add(new MethodInsnNode( - Opcodes.INVOKESTATIC, - 'io/github/reserveword/imblocker/IMCheckState', - 'captureNonPrintable', - '(Ljava/lang/Object;CZ)Z', - false - )) - method.instructions.insert(il) - return method - } - } - }; -} \ No newline at end of file diff --git a/forge/src/main/resources/coremod/window_focus_asm.js b/forge/src/main/resources/coremod/window_focus_asm.js deleted file mode 100644 index 09c4cca..0000000 --- a/forge/src/main/resources/coremod/window_focus_asm.js +++ /dev/null @@ -1,29 +0,0 @@ -var ASMAPI = Java.type('net.minecraftforge.coremod.api.ASMAPI'); -var InsnList = Java.type('org.objectweb.asm.tree.InsnList'); -var MethodInsnNode = Java.type('org.objectweb.asm.tree.MethodInsnNode'); -var Opcodes = Java.type('org.objectweb.asm.Opcodes'); - -function initializeCoreMod() { - return { - 'window_focus_asm': { - 'target': { - 'type': 'METHOD', - 'class': 'net.minecraft.client.Minecraft', - 'methodName': 'm_7440_', - 'methodDesc': '(Z)V' - }, - 'transformer': function (method) { - il = new InsnList() - il.add(new MethodInsnNode( - Opcodes.INVOKESTATIC, - 'io/github/reserveword/imblocker/IMManager', - 'syncState', - '()V', - false - )) - method.instructions.insert(il) - return method - } - } - }; -} \ No newline at end of file diff --git a/gradle.properties b/gradle.properties index 2faf138..90f2684 100644 --- a/gradle.properties +++ b/gradle.properties @@ -1,17 +1,14 @@ -# Sets default memory used for gradle commands. Can be overridden by user or command line properties. -# This is required to provide enough memory for the Minecraft decompilation process. -org.gradle.jvmargs=-Xmx3G -Dfile.encoding=UTF-8 -org.gradle.daemon=true -org.gradle.parallel=true +org.gradle.daemon=false +org.gradle.debug=false # mc -minecraft_version=1.20 +minecraft_version=1.20.4 # mod mod_id=imblocker mod_name=IMBlocker -mod_version=4.0.5 -mod_logo=IMBlocker.png +mod_version=4.0.7 +mod_logo=imblocker.png mod_description=Blocks Input Methods when you're not using it.\\n在你不打字的时候自动关闭输入法 mod_url=https://github.com/reserveword/IMBlocker issues_url=https://github.com/reserveword/IMBlocker/issues @@ -20,45 +17,30 @@ license=GPL3 or higher credits=TimmyOVO's InputMethodBlocker for inspiring me to make this mod author=reserveword email=reserveword@outlook.com -flavor=dev # fabric -fabric_version=0.83.0+1.20 -yarn_mappings=1.20+build.1 -loader_version=0.14.21 +fabric_version=0.96.0+1.20.4 +yarn_mappings=1.20.4+build.3 +loader_version=0.15.6 # forge -forge_version=46.0.14 -loader_version_range=[46,) -# The mapping channel to use for mappings. -# The default set of supported mapping channels are ["official", "snapshot", "snapshot_nodoc", "stable", "stable_nodoc"]. -# Additional mapping channels can be registered through the "channelProviders" extension in a Gradle plugin. -# -# | Channel | Version | | -# |-----------|----------------------|--------------------------------------------------------------------------------| -# | official | MCVersion | Official field/method names from Mojang mapping files | -# | parchment | YYYY.MM.DD-MCVersion | Open community-sourced parameter names and javadocs layered on top of official | -# -# You must be aware of the Mojang license when using the 'official' or 'parchment' mappings. -# See more information here: https://github.com/MinecraftForge/MCPConfig/blob/master/Mojang.md -# -# Parchment is an unofficial project maintained by ParchmentMC, separate from Minecraft Forge. -# Additional setup is needed to use their mappings, see https://parchmentmc.org/docs/getting-started -mapping_channel=snapshot -# The mapping version to query from the mapping channel. -# This must match the format required by the mapping channel. -mapping_version=20210309-1.16.5 +loader_version_range=[2.0,) +neo_version=20.4.80-beta +neogradle_version=7.0.80 # dependency versions -jei_version=14.0.0.11 -modmenu_version=7.0.1 -clothconfig_version=11.0.99 +modmenu_version=9.0.0 +clothconfig_version=13.0.121 # compat versions -rei_version=12.0.625 -replaymod_version=1.20.1-2.6.13 -notebook_version=3.0.0 -voxelmap_version=1.20-1.12.8 +jei_version=17.3.0.49 +rei_version=14.0.688 +replaymod_version=1.20.4-2.6.14 +notebook_version=3.1.0 +easyanvils_version=v20.4.2-1.20.4 +puzzleslib_version=v20.4.22-1.20.4 +forgeconfigapiport_version=v20.4.3-1.20.4 +voxelmap_version=1.20.4-1.12.17 ftblib_version=438495:4643333 ftbquest_version=438496:4652999 -cottonlibgui_version=8.0.1+1.20 -emi_version=1.0.3+1.20 +cottonlibgui_version=9.2.2+1.20.2 +emi_version=1.1.1+1.20.4 diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index 37aef8d..c30b486 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.1.1-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-8.3-bin.zip networkTimeout=10000 zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists diff --git a/settings.gradle b/settings.gradle index df4c4f5..d2be0e5 100644 --- a/settings.gradle +++ b/settings.gradle @@ -1,21 +1,14 @@ pluginManagement { repositories { + mavenCentral() + gradlePluginPortal() + maven { url = 'https://maven.neoforged.net/releases' } maven { name = 'Fabric' url = 'https://maven.fabricmc.net/' } - maven { - name = 'MinecraftForge' - url = 'https://maven.minecraftforge.net/' - } - mavenCentral() - gradlePluginPortal() } } -plugins { - id 'org.gradle.toolchains.foojay-resolver-convention' version '0.5.0' -} - include ':fabric', ':forge', ':common' -rootProject.name = 'IMBlocker' \ No newline at end of file +rootProject.name = 'IMBlocker'