forked from Clones/Controlify
✏️ New ControllerManager class to store controllers
This commit is contained in:
@ -7,11 +7,10 @@ import dev.isxander.controlify.api.entrypoint.ControlifyEntrypoint;
|
||||
import dev.isxander.controlify.config.gui.ControllerBindHandler;
|
||||
import dev.isxander.controlify.controller.Controller;
|
||||
import dev.isxander.controlify.controller.ControllerState;
|
||||
import dev.isxander.controlify.controller.joystick.CompoundJoystickController;
|
||||
import dev.isxander.controlify.controller.sdl2.SDL2NativesManager;
|
||||
import dev.isxander.controlify.debug.DebugProperties;
|
||||
import dev.isxander.controlify.gui.screen.ControllerDeadzoneCalibrationScreen;
|
||||
import dev.isxander.controlify.gui.screen.VibrationOnboardingScreen;
|
||||
import dev.isxander.controlify.gui.screen.SDLOnboardingScreen;
|
||||
import dev.isxander.controlify.screenop.ScreenProcessorProvider;
|
||||
import dev.isxander.controlify.config.ControlifyConfig;
|
||||
import dev.isxander.controlify.controller.hid.ControllerHIDService;
|
||||
@ -127,7 +126,7 @@ public class Controlify implements ControlifyApi {
|
||||
// find already connected controllers
|
||||
for (int jid = 0; jid <= GLFW.GLFW_JOYSTICK_LAST; jid++) {
|
||||
if (GLFW.glfwJoystickPresent(jid)) {
|
||||
var controllerOpt = Controller.createOrGet(jid, controllerHIDService.fetchType());
|
||||
var controllerOpt = ControllerManager.createOrGet(jid, controllerHIDService.fetchType(jid));
|
||||
if (controllerOpt.isEmpty()) continue;
|
||||
var controller = controllerOpt.get();
|
||||
|
||||
@ -145,14 +144,12 @@ public class Controlify implements ControlifyApi {
|
||||
}
|
||||
}
|
||||
|
||||
checkCompoundJoysticks();
|
||||
|
||||
if (Controller.CONTROLLERS.isEmpty()) {
|
||||
if (ControllerManager.getConnectedControllers().isEmpty()) {
|
||||
LOGGER.info("No controllers found.");
|
||||
}
|
||||
|
||||
if (getCurrentController().isEmpty() && config().isFirstLaunch()) {
|
||||
this.setCurrentController(Controller.CONTROLLERS.values().stream().findFirst().orElse(null));
|
||||
this.setCurrentController(ControllerManager.getConnectedControllers().stream().findFirst().orElse(null));
|
||||
} else {
|
||||
// setCurrentController saves config
|
||||
config().saveIfDirty();
|
||||
@ -213,7 +210,7 @@ public class Controlify implements ControlifyApi {
|
||||
|
||||
boolean outOfFocus = !config().globalSettings().outOfFocusInput && !client.isWindowActive();
|
||||
|
||||
for (var controller : Controller.CONTROLLERS.values()) {
|
||||
for (var controller : ControllerManager.getConnectedControllers()) {
|
||||
if (!outOfFocus)
|
||||
wrapControllerError(controller::updateState, "Updating controller state", controller);
|
||||
else
|
||||
@ -295,7 +292,7 @@ public class Controlify implements ControlifyApi {
|
||||
}
|
||||
|
||||
private void onControllerHotplugged(int jid) {
|
||||
var controllerOpt = Controller.createOrGet(jid, controllerHIDService.fetchType());
|
||||
var controllerOpt = ControllerManager.createOrGet(jid, controllerHIDService.fetchType(jid));
|
||||
if (controllerOpt.isEmpty()) return;
|
||||
var controller = controllerOpt.get();
|
||||
|
||||
@ -308,9 +305,7 @@ public class Controlify implements ControlifyApi {
|
||||
config().setDirty();
|
||||
}
|
||||
|
||||
checkCompoundJoysticks();
|
||||
|
||||
if (Controller.CONTROLLERS.size() == 1) {
|
||||
if (ControllerManager.getConnectedControllers().size() == 1) {
|
||||
this.setCurrentController(controller);
|
||||
|
||||
ToastUtils.sendToast(
|
||||
@ -325,12 +320,12 @@ public class Controlify implements ControlifyApi {
|
||||
}
|
||||
|
||||
private void onControllerDisconnect(int jid) {
|
||||
Controller.CONTROLLERS.values().stream().filter(controller -> controller.joystickId() == jid).findAny().ifPresent(controller -> {
|
||||
Controller.remove(controller);
|
||||
ControllerManager.getConnectedControllers().stream().filter(controller -> controller.joystickId() == jid).findAny().ifPresent(controller -> {
|
||||
ControllerManager.disconnect(controller);
|
||||
|
||||
controller.hidInfo().ifPresent(controllerHIDService::unconsumeController);
|
||||
|
||||
setCurrentController(Controller.CONTROLLERS.values().stream().findFirst().orElse(null));
|
||||
setCurrentController(ControllerManager.getConnectedControllers().stream().findFirst().orElse(null));
|
||||
LOGGER.info("Controller disconnected: " + controller.name());
|
||||
this.setInputMode(currentController == null ? InputMode.KEYBOARD_MOUSE : InputMode.CONTROLLER);
|
||||
|
||||
@ -340,28 +335,6 @@ public class Controlify implements ControlifyApi {
|
||||
false
|
||||
);
|
||||
});
|
||||
|
||||
checkCompoundJoysticks();
|
||||
}
|
||||
|
||||
private void checkCompoundJoysticks() {
|
||||
config().getCompoundJoysticks().values().forEach(info -> {
|
||||
try {
|
||||
if (info.isLoaded() && !info.canBeUsed()) {
|
||||
LOGGER.warn("Unloading compound joystick " + info.friendlyName() + " due to missing controllers.");
|
||||
Controller.CONTROLLERS.remove(info.type().mappingId());
|
||||
}
|
||||
|
||||
if (!info.isLoaded() && info.canBeUsed()) {
|
||||
LOGGER.info("Loading compound joystick " + info.type().mappingId() + ".");
|
||||
CompoundJoystickController controller = info.attemptCreate().orElseThrow();
|
||||
Controller.CONTROLLERS.put(info.type().mappingId(), controller);
|
||||
config().loadOrCreateControllerData(controller);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private void askToSwitchController(Controller<?, ?> controller) {
|
||||
|
107
src/main/java/dev/isxander/controlify/ControllerManager.java
Normal file
107
src/main/java/dev/isxander/controlify/ControllerManager.java
Normal file
@ -0,0 +1,107 @@
|
||||
package dev.isxander.controlify;
|
||||
|
||||
import com.google.common.collect.ImmutableList;
|
||||
import com.google.common.collect.ImmutableMap;
|
||||
import dev.isxander.controlify.controller.Controller;
|
||||
import dev.isxander.controlify.controller.gamepad.GamepadController;
|
||||
import dev.isxander.controlify.controller.hid.ControllerHIDService;
|
||||
import dev.isxander.controlify.controller.joystick.CompoundJoystickController;
|
||||
import dev.isxander.controlify.controller.joystick.SingleJoystickController;
|
||||
import dev.isxander.controlify.debug.DebugProperties;
|
||||
import dev.isxander.controlify.utils.DebugLog;
|
||||
import net.minecraft.CrashReport;
|
||||
import net.minecraft.CrashReportCategory;
|
||||
import net.minecraft.ReportedException;
|
||||
import org.hid4java.HidDevice;
|
||||
import org.lwjgl.glfw.GLFW;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Optional;
|
||||
|
||||
public final class ControllerManager {
|
||||
private ControllerManager() {
|
||||
}
|
||||
|
||||
private final static Map<String, Controller<?, ?>> CONTROLLERS = new HashMap<>();
|
||||
|
||||
public static Optional<Controller<?, ?>> createOrGet(int joystickId, ControllerHIDService.ControllerHIDInfo hidInfo) {
|
||||
try {
|
||||
Optional<String> uid = hidInfo.createControllerUID();
|
||||
if (uid.isPresent() && CONTROLLERS.containsKey(uid.get())) {
|
||||
return Optional.of(CONTROLLERS.get(uid.get()));
|
||||
}
|
||||
|
||||
if (hidInfo.type().dontLoad()) {
|
||||
DebugLog.log("Preventing load of controller #" + joystickId + " because its type prevents loading.");
|
||||
return Optional.empty();
|
||||
}
|
||||
|
||||
if (GLFW.glfwJoystickIsGamepad(joystickId) && !DebugProperties.FORCE_JOYSTICK && !hidInfo.type().forceJoystick()) {
|
||||
GamepadController controller = new GamepadController(joystickId, hidInfo);
|
||||
CONTROLLERS.put(controller.uid(), controller);
|
||||
checkCompoundJoysticks();
|
||||
return Optional.of(controller);
|
||||
}
|
||||
|
||||
SingleJoystickController controller = new SingleJoystickController(joystickId, hidInfo);
|
||||
CONTROLLERS.put(controller.uid(), controller);
|
||||
checkCompoundJoysticks();
|
||||
return Optional.of(controller);
|
||||
} catch (Throwable e) {
|
||||
CrashReport crashReport = CrashReport.forThrowable(e, "Creating controller #" + joystickId);
|
||||
CrashReportCategory category = crashReport.addCategory("Controller Info");
|
||||
category.setDetail("Joystick ID", joystickId);
|
||||
category.setDetail("Controller identification", hidInfo.type());
|
||||
category.setDetail("HID path", hidInfo.hidDevice().map(HidDevice::getPath).orElse("N/A"));
|
||||
category.setDetail("HID service status", Controlify.instance().controllerHIDService().isDisabled() ? "Disabled" : "Enabled");
|
||||
category.setDetail("GLFW name", Optional.ofNullable(GLFW.glfwGetJoystickName(joystickId)).orElse("N/A"));
|
||||
throw new ReportedException(crashReport);
|
||||
}
|
||||
}
|
||||
|
||||
public static void disconnect(Controller<?, ?> controller) {
|
||||
controller.close();
|
||||
CONTROLLERS.remove(controller.uid(), controller);
|
||||
|
||||
checkCompoundJoysticks();
|
||||
}
|
||||
|
||||
public static void disconnect(String uid) {
|
||||
Controller<?, ?> prev = CONTROLLERS.remove(uid);
|
||||
if (prev != null) {
|
||||
prev.close();
|
||||
}
|
||||
|
||||
checkCompoundJoysticks();
|
||||
}
|
||||
|
||||
public static List<Controller<?, ?>> getConnectedControllers() {
|
||||
return ImmutableList.copyOf(CONTROLLERS.values());
|
||||
}
|
||||
|
||||
public static boolean isControllerConnected(String uid) {
|
||||
return CONTROLLERS.containsKey(uid);
|
||||
}
|
||||
|
||||
private static void checkCompoundJoysticks() {
|
||||
Controlify.instance().config().getCompoundJoysticks().values().forEach(info -> {
|
||||
try {
|
||||
if (info.isLoaded() && !info.canBeUsed()) {
|
||||
Controlify.LOGGER.warn("Unloading compound joystick " + info.friendlyName() + " due to missing controllers.");
|
||||
disconnect(info.type().mappingId());
|
||||
}
|
||||
|
||||
if (!info.isLoaded() && info.canBeUsed()) {
|
||||
Controlify.LOGGER.info("Loading compound joystick " + info.type().mappingId() + ".");
|
||||
CompoundJoystickController controller = info.attemptCreate().orElseThrow();
|
||||
CONTROLLERS.put(info.type().mappingId(), controller);
|
||||
Controlify.instance().config().loadOrCreateControllerData(controller);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
@ -2,6 +2,7 @@ package dev.isxander.controlify.config;
|
||||
|
||||
import com.google.gson.*;
|
||||
import dev.isxander.controlify.Controlify;
|
||||
import dev.isxander.controlify.ControllerManager;
|
||||
import dev.isxander.controlify.controller.Controller;
|
||||
import dev.isxander.controlify.controller.joystick.CompoundJoystickInfo;
|
||||
import dev.isxander.controlify.utils.DebugLog;
|
||||
@ -78,7 +79,7 @@ public class ControlifyConfig {
|
||||
|
||||
JsonObject newControllerData = controllerData.deepCopy(); // we use the old config, so we don't lose disconnected controller data
|
||||
|
||||
for (var controller : Controller.CONTROLLERS.values()) {
|
||||
for (var controller : ControllerManager.getConnectedControllers()) {
|
||||
// `add` replaces if already existing
|
||||
newControllerData.add(controller.uid(), generateControllerConfig(controller));
|
||||
}
|
||||
@ -111,7 +112,7 @@ public class ControlifyConfig {
|
||||
JsonObject controllers = object.getAsJsonObject("controllers");
|
||||
if (controllers != null) {
|
||||
this.controllerData = controllers;
|
||||
for (var controller : Controller.CONTROLLERS.values()) {
|
||||
for (var controller : ControllerManager.getConnectedControllers()) {
|
||||
loadOrCreateControllerData(controller);
|
||||
}
|
||||
} else {
|
||||
|
@ -2,9 +2,11 @@ package dev.isxander.controlify.config.gui;
|
||||
|
||||
import com.google.common.collect.Iterables;
|
||||
import dev.isxander.controlify.Controlify;
|
||||
import dev.isxander.controlify.ControllerManager;
|
||||
import dev.isxander.controlify.api.bind.ControllerBinding;
|
||||
import dev.isxander.controlify.bindings.BindContext;
|
||||
import dev.isxander.controlify.config.GlobalSettings;
|
||||
import dev.isxander.controlify.controller.BatteryLevel;
|
||||
import dev.isxander.controlify.controller.Controller;
|
||||
import dev.isxander.controlify.controller.ControllerConfig;
|
||||
import dev.isxander.controlify.controller.ControllerState;
|
||||
@ -12,7 +14,9 @@ import dev.isxander.controlify.controller.gamepad.GamepadController;
|
||||
import dev.isxander.controlify.controller.gamepad.BuiltinGamepadTheme;
|
||||
import dev.isxander.controlify.controller.joystick.SingleJoystickController;
|
||||
import dev.isxander.controlify.controller.joystick.mapping.JoystickMapping;
|
||||
import dev.isxander.controlify.controller.sdl2.SDL2NativesManager;
|
||||
import dev.isxander.controlify.gui.screen.ControllerDeadzoneCalibrationScreen;
|
||||
import dev.isxander.controlify.gui.screen.SDLOnboardingScreen;
|
||||
import dev.isxander.controlify.reacharound.ReachAroundMode;
|
||||
import dev.isxander.controlify.rumble.BasicRumbleEffect;
|
||||
import dev.isxander.controlify.rumble.RumbleSource;
|
||||
@ -58,7 +62,7 @@ public class YACLHelper {
|
||||
.name(Component.translatable("controlify.gui.current_controller"))
|
||||
.tooltip(Component.translatable("controlify.gui.current_controller.tooltip"))
|
||||
.binding(Controlify.instance().getCurrentController().orElse(Controller.DUMMY), () -> Controlify.instance().getCurrentController().orElse(Controller.DUMMY), v -> Controlify.instance().setCurrentController(v))
|
||||
.controller(opt -> new CyclingListController<>(opt, Iterables.concat(List.of(Controller.DUMMY), Controller.CONTROLLERS.values().stream().filter(Controller::canBeUsed).toList()), c -> Component.literal(c == Controller.DUMMY ? "Disabled" : c.name())))
|
||||
.controller(opt -> new CyclingListController<>(opt, Iterables.concat(List.of(Controller.DUMMY), ControllerManager.getConnectedControllers().stream().filter(Controller::canBeUsed).toList()), c -> Component.literal(c == Controller.DUMMY ? "Disabled" : c.name())))
|
||||
.build())
|
||||
.option(globalVibrationOption = Option.createBuilder(boolean.class)
|
||||
.name(Component.translatable("controlify.gui.load_vibration_natives"))
|
||||
@ -102,7 +106,7 @@ public class YACLHelper {
|
||||
|
||||
yacl.category(globalCategory.build());
|
||||
|
||||
for (var controller : Controller.CONTROLLERS.values()) {
|
||||
for (var controller : ControllerManager.getConnectedControllers()) {
|
||||
yacl.category(createControllerCategory(controller, globalVibrationOption));
|
||||
}
|
||||
|
||||
|
@ -4,15 +4,10 @@ import com.google.common.reflect.TypeToken;
|
||||
import com.google.gson.Gson;
|
||||
import com.google.gson.JsonElement;
|
||||
import dev.isxander.controlify.Controlify;
|
||||
import dev.isxander.controlify.InputMode;
|
||||
import dev.isxander.controlify.api.ControlifyApi;
|
||||
import dev.isxander.controlify.ControllerManager;
|
||||
import dev.isxander.controlify.bindings.ControllerBindings;
|
||||
import dev.isxander.controlify.controller.hid.ControllerHIDService;
|
||||
import dev.isxander.controlify.controller.sdl2.SDL2NativesManager;
|
||||
import dev.isxander.controlify.rumble.RumbleCapable;
|
||||
import dev.isxander.controlify.rumble.RumbleManager;
|
||||
import dev.isxander.controlify.rumble.RumbleSource;
|
||||
import org.libsdl.SDL;
|
||||
import org.lwjgl.glfw.GLFW;
|
||||
|
||||
import java.util.Objects;
|
||||
@ -63,7 +58,7 @@ public abstract class AbstractController<S extends ControllerState, C extends Co
|
||||
protected void setName(String name) {
|
||||
String uniqueName = name;
|
||||
int i = 0;
|
||||
while (CONTROLLERS.values().stream().map(Controller::name).anyMatch(uniqueName::equalsIgnoreCase)) {
|
||||
while (ControllerManager.getConnectedControllers().stream().map(Controller::name).anyMatch(uniqueName::equalsIgnoreCase)) {
|
||||
uniqueName = name + " (" + i++ + ")";
|
||||
if (i > 1000) throw new IllegalStateException("Could not find a unique name for controller " + name + " (" + uid() + ")! (tried " + i + " times)");
|
||||
}
|
||||
|
@ -54,46 +54,6 @@ public interface Controller<S extends ControllerState, C extends ControllerConfi
|
||||
return true;
|
||||
}
|
||||
|
||||
Map<String, Controller<?, ?>> CONTROLLERS = new HashMap<>();
|
||||
|
||||
static Optional<Controller<?, ?>> createOrGet(int joystickId, ControllerHIDService.ControllerHIDInfo hidInfo) {
|
||||
try {
|
||||
Optional<String> uid = hidInfo.createControllerUID();
|
||||
if (uid.isPresent() && CONTROLLERS.containsKey(uid.get())) {
|
||||
return Optional.of(CONTROLLERS.get(uid.get()));
|
||||
}
|
||||
|
||||
if (hidInfo.type().dontLoad()) {
|
||||
DebugLog.log("Preventing load of controller #" + joystickId + " because its type prevents loading.");
|
||||
return Optional.empty();
|
||||
}
|
||||
|
||||
if (GLFW.glfwJoystickIsGamepad(joystickId) && !DebugProperties.FORCE_JOYSTICK && !hidInfo.type().forceJoystick()) {
|
||||
GamepadController controller = new GamepadController(joystickId, hidInfo);
|
||||
CONTROLLERS.put(controller.uid(), controller);
|
||||
return Optional.of(controller);
|
||||
}
|
||||
|
||||
SingleJoystickController controller = new SingleJoystickController(joystickId, hidInfo);
|
||||
CONTROLLERS.put(controller.uid(), controller);
|
||||
return Optional.of(controller);
|
||||
} catch (Throwable e) {
|
||||
CrashReport crashReport = CrashReport.forThrowable(e, "Creating controller #" + joystickId);
|
||||
CrashReportCategory category = crashReport.addCategory("Controller Info");
|
||||
category.setDetail("Joystick ID", joystickId);
|
||||
category.setDetail("Controller identification", hidInfo.type());
|
||||
category.setDetail("HID path", hidInfo.hidDevice().map(HidDevice::getPath).orElse("N/A"));
|
||||
category.setDetail("HID service status", Controlify.instance().controllerHIDService().isDisabled() ? "Disabled" : "Enabled");
|
||||
category.setDetail("GLFW name", Optional.ofNullable(GLFW.glfwGetJoystickName(joystickId)).orElse("N/A"));
|
||||
throw new ReportedException(crashReport);
|
||||
}
|
||||
}
|
||||
|
||||
static void remove(Controller<?, ?> controller) {
|
||||
controller.close();
|
||||
CONTROLLERS.remove(controller.uid(), controller);
|
||||
}
|
||||
|
||||
@Deprecated
|
||||
Controller<?, ?> DUMMY = new Controller<>() {
|
||||
private final ControllerBindings<ControllerState> bindings = new ControllerBindings<>(this);
|
||||
|
@ -1,5 +1,6 @@
|
||||
package dev.isxander.controlify.controller.joystick;
|
||||
|
||||
import dev.isxander.controlify.ControllerManager;
|
||||
import dev.isxander.controlify.controller.Controller;
|
||||
import dev.isxander.controlify.controller.ControllerType;
|
||||
|
||||
@ -13,7 +14,7 @@ public record CompoundJoystickInfo(Collection<String> joystickUids, String frien
|
||||
}
|
||||
|
||||
public boolean canBeUsed() {
|
||||
List<Controller<?, ?>> joysticks = Controller.CONTROLLERS.values().stream().filter(c -> joystickUids.contains(c.uid())).toList();
|
||||
List<Controller<?, ?>> joysticks = ControllerManager.getConnectedControllers().stream().filter(c -> joystickUids.contains(c.uid())).toList();
|
||||
if (joysticks.size() != joystickUids().size()) {
|
||||
return false; // not all controllers are connected
|
||||
}
|
||||
@ -25,13 +26,13 @@ public record CompoundJoystickInfo(Collection<String> joystickUids, String frien
|
||||
}
|
||||
|
||||
public boolean isLoaded() {
|
||||
return Controller.CONTROLLERS.containsKey(createUID(joystickUids));
|
||||
return ControllerManager.isControllerConnected(createUID(joystickUids));
|
||||
}
|
||||
|
||||
public Optional<CompoundJoystickController> attemptCreate() {
|
||||
if (!canBeUsed()) return Optional.empty();
|
||||
|
||||
List<Integer> joystickIDs = Controller.CONTROLLERS.values().stream()
|
||||
List<Integer> joystickIDs = ControllerManager.getConnectedControllers().stream()
|
||||
.filter(c -> joystickUids.contains(c.uid()))
|
||||
.map(Controller::joystickId)
|
||||
.toList();
|
||||
|
@ -2,14 +2,13 @@ package dev.isxander.controlify.mixins.core;
|
||||
|
||||
import com.llamalad7.mixinextras.injector.ModifyExpressionValue;
|
||||
import dev.isxander.controlify.Controlify;
|
||||
import dev.isxander.controlify.ControllerManager;
|
||||
import dev.isxander.controlify.controller.Controller;
|
||||
import dev.isxander.controlify.gui.screen.BetaNoticeScreen;
|
||||
import net.minecraft.client.Minecraft;
|
||||
import net.minecraft.client.gui.components.toasts.SystemToast;
|
||||
import net.minecraft.client.gui.components.toasts.ToastComponent;
|
||||
import net.minecraft.client.gui.screens.Screen;
|
||||
import net.minecraft.client.main.GameConfig;
|
||||
import net.minecraft.network.chat.Component;
|
||||
import net.minecraft.server.packs.resources.ReloadInstance;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
@ -54,18 +53,8 @@ public abstract class MinecraftMixin {
|
||||
setScreen(new BetaNoticeScreen());
|
||||
}
|
||||
|
||||
@ModifyExpressionValue(method = "<init>", at = @At(value = "INVOKE", target = "Lnet/minecraft/server/packs/resources/ReloadableResourceManager;createReload(Ljava/util/concurrent/Executor;Ljava/util/concurrent/Executor;Ljava/util/concurrent/CompletableFuture;Ljava/util/List;)Lnet/minecraft/server/packs/resources/ReloadInstance;"))
|
||||
private ReloadInstance onReloadResources(ReloadInstance resourceReload) {
|
||||
resourceReload.done().thenRun(() -> {
|
||||
if (Controlify.instance().controllerHIDService().isDisabled()) {
|
||||
getToasts().addToast(SystemToast.multiline((Minecraft) (Object) this, SystemToast.SystemToastIds.UNSECURE_SERVER_WARNING, Component.translatable("controlify.error.hid"), Component.translatable("controlify.error.hid.desc")));
|
||||
}
|
||||
});
|
||||
return resourceReload;
|
||||
}
|
||||
|
||||
@Inject(method = "close", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/telemetry/ClientTelemetryManager;close()V"))
|
||||
private void onMinecraftClose(CallbackInfo ci) {
|
||||
Controller.CONTROLLERS.values().forEach(Controller::close);
|
||||
ControllerManager.getConnectedControllers().forEach(Controller::close);
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user