isXander / Controlify

Another controller mod - for fabric!
https://www.isxander.dev/mods/controlify
GNU Lesser General Public License v3.0
157 stars 36 forks source link

Controlify recognizes 'Consumer Control' inputs as controllers, then crashes because obviously they aren't controllers #76

Open NyaomiDEV opened 1 year ago

NyaomiDEV commented 1 year ago

Describe the bug On Linux, advanced HID peripherals, such as Logitech mice, keyboards, and macro keyboards and other funny HID stuff expose a virtual device called "Consumer Control" (and other times another one called "System Control") which IDK what that actually does (it should serve macros to the system afaik). However, those virtual devices literally register anything that is a key or an axis, from keyboard events to mouse events to controller events (I guess to make macros work correctly).

Controlify just thinks those devices are worth using, then it crashes.

A log ``` [16:51:12] [Render thread/ERROR]: Reported exception thrown! net.minecraft.class_148: Updating controller state at dev.isxander.controlify.Controlify.wrapControllerError(Controlify.java:309) ~[transformed-mod-controlify.i0:0/:?] at dev.isxander.controlify.Controlify.tick(Controlify.java:235) ~[transformed-mod-controlify.i0:0/:?] at org.quiltmc.qsl.lifecycle.api.client.event.ClientTickEvents.lambda$static$0(ClientTickEvents.java:40) ~[transformed-mod-quilt-lifecycle-events.i0:0/:?] at net.minecraft.class_310.handler$cca002$quilt_lifecycle_events$startTick(class_310.java:14545) ~[transformed-mod-minecraft.i0:0/:?] at net.minecraft.class_310.method_1574(class_310.java) ~[transformed-mod-minecraft.i0:0/:?] at net.minecraft.class_310.method_1523(class_310.java:1180) ~[transformed-mod-minecraft.i0:0/:?] at net.minecraft.class_310.method_1514(class_310.java:801) ~[transformed-mod-minecraft.i0:0/:?] at net.minecraft.client.main.Main.main(Main.java:237) ~[minecraft-1.19.4-client.jar:?] at jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[?:?] at jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77) ~[?:?] at jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[?:?] at java.lang.reflect.Method.invoke(Method.java:568) ~[?:?] at org.quiltmc.loader.impl.game.minecraft.MinecraftGameProvider.launch(MinecraftGameProvider.java:527) ~[quilt-loader-0.18.10.jar:?] at org.quiltmc.loader.impl.launch.knot.Knot.launch(Knot.java:82) ~[quilt-loader-0.18.10.jar:?] at org.quiltmc.loader.impl.launch.knot.KnotClient.main(KnotClient.java:28) ~[quilt-loader-0.18.10.jar:?] at org.prismlauncher.launcher.impl.StandardLauncher.launch(StandardLauncher.java:88) ~[NewLaunch.jar:?] at org.prismlauncher.EntryPoint.listen(EntryPoint.java:126) ~[NewLaunch.jar:?] at org.prismlauncher.EntryPoint.main(EntryPoint.java:71) ~[NewLaunch.jar:?] Caused by: java.lang.NullPointerException: Cannot invoke "java.nio.ByteBuffer.limit()" because "hatBuffer" is null at dev.isxander.controlify.controller.joystick.JoystickState.fromJoystick(JoystickState.java:97) ~[transformed-mod-controlify.i0:0/:?] at dev.isxander.controlify.controller.joystick.SingleJoystickController.updateState(SingleJoystickController.java:56) ~[transformed-mod-controlify.i0:0/:?] at dev.isxander.controlify.Controlify.wrapControllerError(Controlify.java:302) ~[transformed-mod-controlify.i0:0/:?] ... 17 more ---- Minecraft Crash Report ---- // You should try our sister game, Minceraft! Time: 2023-05-21 16:51:12 Description: Updating controller state java.lang.NullPointerException: Cannot invoke "java.nio.ByteBuffer.limit()" because "hatBuffer" is null at dev.isxander.controlify.controller.joystick.JoystickState.fromJoystick(JoystickState.java:97) at dev.isxander.controlify.controller.joystick.SingleJoystickController.updateState(SingleJoystickController.java:56) at dev.isxander.controlify.Controlify.wrapControllerError(Controlify.java:302) at dev.isxander.controlify.Controlify.tick(Controlify.java:235) at org.quiltmc.qsl.lifecycle.api.client.event.ClientTickEvents.lambda$static$0(ClientTickEvents.java:40) at net.minecraft.class_310.handler$cca002$quilt_lifecycle_events$startTick(class_310.java:14545) at net.minecraft.class_310.method_1574(class_310.java) at net.minecraft.class_310.method_1523(class_310.java:1180) at net.minecraft.class_310.method_1514(class_310.java:801) at net.minecraft.client.main.Main.main(Main.java:237) at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77) at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) at java.base/java.lang.reflect.Method.invoke(Method.java:568) at org.quiltmc.loader.impl.game.minecraft.MinecraftGameProvider.launch(MinecraftGameProvider.java:527) at org.quiltmc.loader.impl.launch.knot.Knot.launch(Knot.java:82) at org.quiltmc.loader.impl.launch.knot.KnotClient.main(KnotClient.java:28) at org.prismlauncher.launcher.impl.StandardLauncher.launch(StandardLauncher.java:88) at org.prismlauncher.EntryPoint.listen(EntryPoint.java:126) at org.prismlauncher.EntryPoint.main(EntryPoint.java:71) A detailed walkthrough of the error, its code path and all known details is as follows: --------------------------------------------------------------------------------------- -- Head -- Thread: Render thread Stacktrace: at dev.isxander.controlify.controller.joystick.JoystickState.fromJoystick(JoystickState.java:97) at dev.isxander.controlify.controller.joystick.SingleJoystickController.updateState(SingleJoystickController.java:56) at dev.isxander.controlify.Controlify.wrapControllerError(Controlify.java:302) at dev.isxander.controlify.Controlify.tick(Controlify.java:235) at org.quiltmc.qsl.lifecycle.api.client.event.ClientTickEvents.lambda$static$0(ClientTickEvents.java:40) at net.minecraft.class_310.handler$cca002$quilt_lifecycle_events$startTick(class_310.java:14545) -- Affected controller -- Details: Controller name: Logitech USB Receiver Consumer Control Controller identification: ControllerType[friendlyName=Unknown, mappingId=unknown, themeId=unknown, forceJoystick=false, dontLoad=false] Controller type: dev.isxander.controlify.controller.joystick.SingleJoystickController Stacktrace: at dev.isxander.controlify.Controlify.wrapControllerError(Controlify.java:302) at dev.isxander.controlify.Controlify.tick(Controlify.java:235) at org.quiltmc.qsl.lifecycle.api.client.event.ClientTickEvents.lambda$static$0(ClientTickEvents.java:40) at net.minecraft.class_310.handler$cca002$quilt_lifecycle_events$startTick(class_310.java:14545) at net.minecraft.class_310.method_1574(class_310.java) at net.minecraft.class_310.method_1523(class_310.java:1180) at net.minecraft.class_310.method_1514(class_310.java:801) at net.minecraft.client.main.Main.main(Main.java:237) at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77) at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) at java.base/java.lang.reflect.Method.invoke(Method.java:568) at org.quiltmc.loader.impl.game.minecraft.MinecraftGameProvider.launch(MinecraftGameProvider.java:527) at org.quiltmc.loader.impl.launch.knot.Knot.launch(Knot.java:82) at org.quiltmc.loader.impl.launch.knot.KnotClient.main(KnotClient.java:28) at org.prismlauncher.launcher.impl.StandardLauncher.launch(StandardLauncher.java:88) at org.prismlauncher.EntryPoint.listen(EntryPoint.java:126) at org.prismlauncher.EntryPoint.main(EntryPoint.java:71) -- Last reload -- Details: Reload number: 1 Reload reason: initial Finished: Yes Packs: vanilla, continuity/glass_pane_culling_fix, continuity/default, file/Faithful 32x - 1.19.4.zip, file/Dark UI 32x (1.19.3).zip, file/faithful-ctm-32x-1-19-2.zip, file/Emissive.Faithful.32x.Optifine.zip, file/New+Faithful+Overlays.zip, file/FreshAnimations_v1.8.1.zip, file/Faithful32x-FreshAnimations-v1.8.1.2.zip, controlify/extra_mappings Stacktrace: at net.minecraft.class_6360.method_36565(class_6360.java:49) at net.minecraft.class_310.method_1587(class_310.java:2413) at net.minecraft.class_310.method_1514(class_310.java:820) at net.minecraft.client.main.Main.main(Main.java:237) at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77) at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) at java.base/java.lang.reflect.Method.invoke(Method.java:568) at org.quiltmc.loader.impl.game.minecraft.MinecraftGameProvider.launch(MinecraftGameProvider.java:527) at org.quiltmc.loader.impl.launch.knot.Knot.launch(Knot.java:82) at org.quiltmc.loader.impl.launch.knot.KnotClient.main(KnotClient.java:28) at org.prismlauncher.launcher.impl.StandardLauncher.launch(StandardLauncher.java:88) at org.prismlauncher.EntryPoint.listen(EntryPoint.java:126) at org.prismlauncher.EntryPoint.main(EntryPoint.java:71) ```

To Reproduce Steps to reproduce the behavior:

  1. Have a Linux install
  2. Use a Logitech Bolt receiver with any keyboard / mouse made by Logitech.
  3. Start Minecraft with Controlify.

Expected behavior It works?

Screenshots It just crashes.

Minecraft Info (please complete the following information):

Additional context image

isXander commented 1 year ago

If the device reports itself as a joystick, Controlify will attempt to load it. I think what you are experiencing is just a bug with joystick handling.

NyaomiDEV commented 1 year ago

If the device reports itself as a joystick, Controlify will attempt to load it. I think what you are experiencing is just a bug with joystick handling.

I don't know for sure, but that's all the evidence I could gather. In any case those devices can be safely ignored, possibly by a blacklist by name or some sort.

isXander commented 1 year ago

If you could get the vendor and product ID for these devices, I can add them to a blacklist.

NyaomiDEV commented 1 year ago
ID 046d:c548 Logitech, Inc. Logi Bolt Receiver
ID 3282:0001 Mountain Mountain Everest Keyboard

The problem with this is that Controlify needs to blacklist every customizable mouse/keyboard/trackpad/HID device in existence... which could be a lot of stuff.

I'd say just use a regex on the name... something like /(?:system|consumer) control$/gim. If it matches, discard it.

isXander commented 1 year ago

f373b3fc27f2926df144f1178f0d6a74786c1734 will fix the crashing, which makes this low priority for the moment, as querying the name before loading the controller is close to impossible atm.

isXander commented 1 year ago

This has further been mitigated because you can now press maybe later on the calibration.