From 8b2dc970cbe62bc8e4212ff897c9b5226468836b Mon Sep 17 00:00:00 2001 From: isXander Date: Sat, 19 Aug 2023 20:01:29 +0100 Subject: [PATCH] =?UTF-8?q?=E2=9E=95=20No=20fly=20drifting,=20improve=20se?= =?UTF-8?q?rver=20policy=20system=20(backwards=20compat=20with=20old=20pac?= =?UTF-8?q?ket)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../dev/isxander/controlify/Controlify.java | 26 +++-------- .../controller/ControllerConfig.java | 1 + .../screen/ControllerConfigScreenFactory.java | 12 ++++++ .../screen/GlobalSettingsScreenFactory.java | 13 +++--- .../controlify/ingame/InGameInputHandler.java | 27 ++++++++++++ .../reacharound/ReachAroundHandler.java | 16 ++++--- .../reacharound/ReachAroundPolicy.java | 23 ---------- .../controlify/server/ControlifyServer.java | 9 +++- .../server/ControlifyServerConfig.java | 1 + ...ava => LegacyReachAroundPolicyPacket.java} | 10 +++-- .../controlify/server/ServerPolicies.java | 43 +++++++++++++++++++ .../controlify/server/ServerPolicy.java | 15 +++++++ .../controlify/server/ServerPolicyPacket.java | 29 +++++++++++++ .../assets/controlify/lang/en_us.json | 4 +- 14 files changed, 169 insertions(+), 60 deletions(-) delete mode 100644 src/main/java/dev/isxander/controlify/reacharound/ReachAroundPolicy.java rename src/main/java/dev/isxander/controlify/server/{ReachAroundPolicyPacket.java => LegacyReachAroundPolicyPacket.java} (54%) create mode 100644 src/main/java/dev/isxander/controlify/server/ServerPolicies.java create mode 100644 src/main/java/dev/isxander/controlify/server/ServerPolicy.java create mode 100644 src/main/java/dev/isxander/controlify/server/ServerPolicyPacket.java diff --git a/src/main/java/dev/isxander/controlify/Controlify.java b/src/main/java/dev/isxander/controlify/Controlify.java index f5f3628..654c540 100644 --- a/src/main/java/dev/isxander/controlify/Controlify.java +++ b/src/main/java/dev/isxander/controlify/Controlify.java @@ -14,9 +14,7 @@ import dev.isxander.controlify.gui.screen.ControllerCalibrationScreen; import dev.isxander.controlify.gui.screen.SDLOnboardingScreen; import dev.isxander.controlify.gui.screen.SubmitUnknownControllerScreen; import dev.isxander.controlify.ingame.ControllerPlayerMovement; -import dev.isxander.controlify.reacharound.ReachAroundHandler; -import dev.isxander.controlify.reacharound.ReachAroundMode; -import dev.isxander.controlify.reacharound.ReachAroundPolicy; +import dev.isxander.controlify.server.*; import dev.isxander.controlify.screenop.ScreenProcessorProvider; import dev.isxander.controlify.config.ControlifyConfig; import dev.isxander.controlify.hid.ControllerHIDService; @@ -24,10 +22,6 @@ import dev.isxander.controlify.api.event.ControlifyEvents; import dev.isxander.controlify.gui.guide.InGameButtonGuide; import dev.isxander.controlify.ingame.InGameInputHandler; import dev.isxander.controlify.mixins.feature.virtualmouse.MouseHandlerAccessor; -import dev.isxander.controlify.server.EntityVibrationPacket; -import dev.isxander.controlify.server.OriginVibrationPacket; -import dev.isxander.controlify.server.ReachAroundPolicyPacket; -import dev.isxander.controlify.server.VibrationPacket; import dev.isxander.controlify.utils.DebugLog; import dev.isxander.controlify.utils.Log; import dev.isxander.controlify.utils.ToastUtils; @@ -250,21 +244,13 @@ public class Controlify implements ControlifyApi { controller.rumbleManager().play(packet.source(), packet.createEffect())); } }); - ClientPlayNetworking.registerGlobalReceiver(ReachAroundPolicyPacket.TYPE, (packet, player, sender) -> { - Log.LOGGER.info("Connected server specified reach around policy is {}.", packet.allowed() ? "ALLOWED" : "DISALLOWED"); - ReachAroundHandler.reachAroundPolicy = ReachAroundPolicy.fromServer(packet.allowed()); - - if (config().globalSettings().reachAround == ReachAroundMode.EVERYWHERE && !packet.allowed()) { - ToastUtils.sendToast( - Component.translatable("controlify.toast.reach_around_disallowed.title"), - Component.translatable("controlify.toast.reach_around_disallowed.description"), - false - ); - } + ClientPlayNetworking.registerGlobalReceiver(ServerPolicyPacket.TYPE, (packet, player, sender) -> { + Log.LOGGER.info("Connected server specified '{}' policy is {}.", packet.id(), packet.allowed() ? "ALLOWED" : "DISALLOWED"); + ServerPolicies.getById(packet.id()).set(ServerPolicy.fromBoolean(packet.allowed())); }); ClientPlayConnectionEvents.DISCONNECT.register((handler, client) -> { - DebugLog.log("Disconnected from server, resetting reach around policy"); - ReachAroundHandler.reachAroundPolicy = ReachAroundPolicy.UNSET; + DebugLog.log("Disconnected from server, resetting server policies"); + ServerPolicies.unsetAll(); }); FabricLoader.getInstance().getEntrypoints("controlify", ControlifyEntrypoint.class).forEach(entrypoint -> { diff --git a/src/main/java/dev/isxander/controlify/controller/ControllerConfig.java b/src/main/java/dev/isxander/controlify/controller/ControllerConfig.java index 1ac312f..a9190d6 100644 --- a/src/main/java/dev/isxander/controlify/controller/ControllerConfig.java +++ b/src/main/java/dev/isxander/controlify/controller/ControllerConfig.java @@ -21,6 +21,7 @@ public abstract class ControllerConfig implements Serializable { public boolean autoJump = false; public boolean toggleSprint = true; public boolean toggleSneak = true; + public boolean disableFlyDrifting = false; public String customName = null; diff --git a/src/main/java/dev/isxander/controlify/gui/screen/ControllerConfigScreenFactory.java b/src/main/java/dev/isxander/controlify/gui/screen/ControllerConfigScreenFactory.java index 610925a..67f67e4 100644 --- a/src/main/java/dev/isxander/controlify/gui/screen/ControllerConfigScreenFactory.java +++ b/src/main/java/dev/isxander/controlify/gui/screen/ControllerConfigScreenFactory.java @@ -16,6 +16,8 @@ import dev.isxander.controlify.gui.guide.InGameButtonGuide; import dev.isxander.controlify.rumble.BasicRumbleEffect; import dev.isxander.controlify.rumble.RumbleSource; import dev.isxander.controlify.rumble.RumbleState; +import dev.isxander.controlify.server.ServerPolicies; +import dev.isxander.controlify.server.ServerPolicy; import dev.isxander.yacl3.api.*; import dev.isxander.yacl3.api.controller.*; import net.minecraft.ChatFormatting; @@ -164,6 +166,16 @@ public class ControllerConfigScreenFactory { .controller(opt -> BooleanControllerBuilder.create(opt) .onOffFormatter()) .build()) + .option(Option.createBuilder() + .name(Component.translatable("controlify.gui.no_fly_drifting")) + .description(OptionDescription.createBuilder() + .text(Component.translatable("controlify.gui.no_fly_drifting.tooltip")) + .text(ServerPolicies.DISABLE_FLY_DRIFTING.get() != ServerPolicy.UNSET ? Component.translatable("controlify.gui.server_controlled").withStyle(ChatFormatting.GOLD) : Component.empty()) + .build()) + .binding(def.disableFlyDrifting, () -> ServerPolicies.DISABLE_FLY_DRIFTING.get().isAllowed() && config.disableFlyDrifting, v -> config.disableFlyDrifting = v) + .controller(TickBoxControllerBuilder::create) + .available(ServerPolicies.DISABLE_FLY_DRIFTING.get().isAllowed()) + .build()) .build(); } diff --git a/src/main/java/dev/isxander/controlify/gui/screen/GlobalSettingsScreenFactory.java b/src/main/java/dev/isxander/controlify/gui/screen/GlobalSettingsScreenFactory.java index 5f65383..a76671c 100644 --- a/src/main/java/dev/isxander/controlify/gui/screen/GlobalSettingsScreenFactory.java +++ b/src/main/java/dev/isxander/controlify/gui/screen/GlobalSettingsScreenFactory.java @@ -3,9 +3,9 @@ package dev.isxander.controlify.gui.screen; import dev.isxander.controlify.Controlify; import dev.isxander.controlify.api.ControlifyApi; import dev.isxander.controlify.config.GlobalSettings; -import dev.isxander.controlify.reacharound.ReachAroundHandler; import dev.isxander.controlify.reacharound.ReachAroundMode; -import dev.isxander.controlify.reacharound.ReachAroundPolicy; +import dev.isxander.controlify.server.ServerPolicies; +import dev.isxander.controlify.server.ServerPolicy; import dev.isxander.yacl3.api.*; import dev.isxander.yacl3.api.controller.BooleanControllerBuilder; import dev.isxander.yacl3.api.controller.EnumControllerBuilder; @@ -42,17 +42,16 @@ public class GlobalSettingsScreenFactory { .text(Component.translatable("controlify.gui.reach_around.tooltip")) .text(Component.translatable("controlify.gui.reach_around.tooltip.parity").withStyle(ChatFormatting.GRAY)) .text(state == ReachAroundMode.EVERYWHERE ? Component.translatable("controlify.gui.reach_around.tooltip.warning").withStyle(ChatFormatting.RED) : Component.empty()) - .text(ReachAroundHandler.reachAroundPolicy != ReachAroundPolicy.UNSET ? Component.translatable("controlify.gui.reach_around.tooltip.server_controlled").withStyle(ChatFormatting.GOLD) : Component.empty()) + .text(ServerPolicies.REACH_AROUND.get() != ServerPolicy.DISALLOWED ? Component.translatable("controlify.gui.server_controlled").withStyle(ChatFormatting.GOLD) : Component.empty()) .build()) .binding(GlobalSettings.DEFAULT.reachAround, () -> globalSettings.reachAround, v -> globalSettings.reachAround = v) .controller(opt -> EnumControllerBuilder.create(opt) .enumClass(ReachAroundMode.class) - .valueFormatter(mode -> switch (ReachAroundHandler.reachAroundPolicy) { - case UNSET -> mode.getDisplayName(); - case ALLOWED -> CommonComponents.OPTION_ON; + .valueFormatter(mode -> switch (ServerPolicies.REACH_AROUND.get()) { + case UNSET, ALLOWED -> mode.getDisplayName(); case DISALLOWED -> CommonComponents.OPTION_OFF; })) - .available(ReachAroundHandler.reachAroundPolicy == ReachAroundPolicy.UNSET) + .available(ServerPolicies.REACH_AROUND.get().isAllowed()) .build()) .option(Option.createBuilder() .name(Component.translatable("controlify.gui.ui_sounds")) diff --git a/src/main/java/dev/isxander/controlify/ingame/InGameInputHandler.java b/src/main/java/dev/isxander/controlify/ingame/InGameInputHandler.java index f1a50af..7e32f8c 100644 --- a/src/main/java/dev/isxander/controlify/ingame/InGameInputHandler.java +++ b/src/main/java/dev/isxander/controlify/ingame/InGameInputHandler.java @@ -50,6 +50,7 @@ public class InGameInputHandler { public void inputTick() { handlePlayerLookInput(); handleKeybinds(); + preventFlyDrifting(); } protected void handleKeybinds() { @@ -233,6 +234,32 @@ public class InGameInputHandler { return this.shouldShowPlayerList; } + public void preventFlyDrifting() { + if (!controller.config().disableFlyDrifting || !ServerPolicies.DISABLE_FLY_DRIFTING.get().isAllowed()) { + return; + } + + LocalPlayer player = minecraft.player; + if (player != null && player.getAbilities().flying && !player.onGround()) { + Vec3 motion = player.getDeltaMovement(); + double x = motion.x; + double y = motion.y; + double z = motion.z; + + if (!player.input.jumping) + y = Math.min(y, 0); + if (!player.input.shiftKeyDown) + y = Math.max(y, 0); + + if (player.input.forwardImpulse == 0 && player.input.leftImpulse == 0) { + x = 0; + z = 0; + } + + player.setDeltaMovement(x, y, z); + } + } + private boolean isAiming(Player player) { return player.isUsingItem() && switch (player.getUseItem().getUseAnimation()) { case BOW, CROSSBOW, SPEAR, SPYGLASS -> true; diff --git a/src/main/java/dev/isxander/controlify/reacharound/ReachAroundHandler.java b/src/main/java/dev/isxander/controlify/reacharound/ReachAroundHandler.java index 7ff5564..7c2c493 100644 --- a/src/main/java/dev/isxander/controlify/reacharound/ReachAroundHandler.java +++ b/src/main/java/dev/isxander/controlify/reacharound/ReachAroundHandler.java @@ -1,15 +1,12 @@ package dev.isxander.controlify.reacharound; import dev.isxander.controlify.Controlify; -import net.minecraft.core.BlockPos; -import net.minecraft.util.Mth; +import dev.isxander.controlify.server.ServerPolicies; import net.minecraft.world.entity.Entity; import net.minecraft.world.phys.BlockHitResult; import net.minecraft.world.phys.HitResult; public class ReachAroundHandler { - public static ReachAroundPolicy reachAroundPolicy = ReachAroundPolicy.UNSET; - public static HitResult getReachAroundHitResult(Entity entity, HitResult hitResult) { // if there is already a valid hit, we don't want to override it if (hitResult.getType() != HitResult.Type.MISS) @@ -34,7 +31,16 @@ public class ReachAroundHandler { } private static boolean canReachAround(Entity cameraEntity) { - return reachAroundPolicy.canReachAround(Controlify.instance().config().globalSettings().reachAround) + boolean allowedToReachAround = switch (ServerPolicies.REACH_AROUND.get()) { + // straight no, not allowed + case DISALLOWED -> false; + // if unset, respect the global setting + case UNSET -> Controlify.instance().config().globalSettings().reachAround.canReachAround(); + // if allowed, global setting is used but even if it singleplayer only it's still enabled. + case ALLOWED -> Controlify.instance().config().globalSettings().reachAround != ReachAroundMode.OFF; + }; + + return allowedToReachAround // don't want to place blocks while riding an entity && cameraEntity.getVehicle() == null // straight ahead = 0deg, up = -90deg, down = 90deg diff --git a/src/main/java/dev/isxander/controlify/reacharound/ReachAroundPolicy.java b/src/main/java/dev/isxander/controlify/reacharound/ReachAroundPolicy.java deleted file mode 100644 index 999ea13..0000000 --- a/src/main/java/dev/isxander/controlify/reacharound/ReachAroundPolicy.java +++ /dev/null @@ -1,23 +0,0 @@ -package dev.isxander.controlify.reacharound; - -import java.util.function.Function; - -public enum ReachAroundPolicy { - ALLOWED(mode -> true), - DISALLOWED(mode -> false), - UNSET(ReachAroundMode::canReachAround); - - private final Function canReachAround; - - ReachAroundPolicy(Function canReachAround) { - this.canReachAround = canReachAround; - } - - public boolean canReachAround(ReachAroundMode mode) { - return canReachAround.apply(mode); - } - - public static ReachAroundPolicy fromServer(boolean allowed) { - return allowed ? ALLOWED : DISALLOWED; - } -} diff --git a/src/main/java/dev/isxander/controlify/server/ControlifyServer.java b/src/main/java/dev/isxander/controlify/server/ControlifyServer.java index 5e39245..cf8480d 100644 --- a/src/main/java/dev/isxander/controlify/server/ControlifyServer.java +++ b/src/main/java/dev/isxander/controlify/server/ControlifyServer.java @@ -21,10 +21,17 @@ public class ControlifyServer implements ModInitializer, DedicatedServerModIniti @Override public void onInitializeServer() { ControlifyServerConfig.INSTANCE.load(); + ControlifyServerConfig.INSTANCE.save(); + Log.LOGGER.info("Reach-around policy: " + ControlifyServerConfig.INSTANCE.getConfig().reachAroundPolicy); + Log.LOGGER.info("No-fly drift policy: " + ControlifyServerConfig.INSTANCE.getConfig().noFlyDriftPolicy); ServerPlayConnectionEvents.INIT.register((handler, server) -> { - ServerPlayNetworking.send(handler.getPlayer(), new ReachAroundPolicyPacket(ControlifyServerConfig.INSTANCE.getConfig().reachAroundPolicy)); + ServerPlayNetworking.send(handler.getPlayer(), new ServerPolicyPacket(ServerPolicies.REACH_AROUND.getId(), ControlifyServerConfig.INSTANCE.getConfig().reachAroundPolicy)); + ServerPlayNetworking.send(handler.getPlayer(), new ServerPolicyPacket(ServerPolicies.DISABLE_FLY_DRIFTING.getId(), ControlifyServerConfig.INSTANCE.getConfig().noFlyDriftPolicy)); + + // backwards compat + ServerPlayNetworking.send(handler.getPlayer(), new LegacyReachAroundPolicyPacket(ControlifyServerConfig.INSTANCE.getConfig().reachAroundPolicy)); }); } } diff --git a/src/main/java/dev/isxander/controlify/server/ControlifyServerConfig.java b/src/main/java/dev/isxander/controlify/server/ControlifyServerConfig.java index 31eb048..348cef6 100644 --- a/src/main/java/dev/isxander/controlify/server/ControlifyServerConfig.java +++ b/src/main/java/dev/isxander/controlify/server/ControlifyServerConfig.java @@ -11,4 +11,5 @@ public class ControlifyServerConfig { .build(); @ConfigEntry public boolean reachAroundPolicy = false; + @ConfigEntry public boolean noFlyDriftPolicy = false; } diff --git a/src/main/java/dev/isxander/controlify/server/ReachAroundPolicyPacket.java b/src/main/java/dev/isxander/controlify/server/LegacyReachAroundPolicyPacket.java similarity index 54% rename from src/main/java/dev/isxander/controlify/server/ReachAroundPolicyPacket.java rename to src/main/java/dev/isxander/controlify/server/LegacyReachAroundPolicyPacket.java index 4b0948d..02e4908 100644 --- a/src/main/java/dev/isxander/controlify/server/ReachAroundPolicyPacket.java +++ b/src/main/java/dev/isxander/controlify/server/LegacyReachAroundPolicyPacket.java @@ -5,10 +5,14 @@ import net.fabricmc.fabric.api.networking.v1.PacketType; import net.minecraft.network.FriendlyByteBuf; import net.minecraft.resources.ResourceLocation; -public record ReachAroundPolicyPacket(boolean allowed) implements FabricPacket { - public static final PacketType TYPE = PacketType.create(new ResourceLocation("controlify", "reach_around_policy"), ReachAroundPolicyPacket::new); +public record LegacyReachAroundPolicyPacket(boolean allowed) implements FabricPacket { + public static final PacketType TYPE = + PacketType.create( + new ResourceLocation("controlify", "reach_around_policy"), + LegacyReachAroundPolicyPacket::new + ); - public ReachAroundPolicyPacket(FriendlyByteBuf buf) { + public LegacyReachAroundPolicyPacket(FriendlyByteBuf buf) { this(buf.readBoolean()); } diff --git a/src/main/java/dev/isxander/controlify/server/ServerPolicies.java b/src/main/java/dev/isxander/controlify/server/ServerPolicies.java new file mode 100644 index 0000000..ad60110 --- /dev/null +++ b/src/main/java/dev/isxander/controlify/server/ServerPolicies.java @@ -0,0 +1,43 @@ +package dev.isxander.controlify.server; + +import java.util.Map; + +public enum ServerPolicies { + REACH_AROUND("reachAround"), + DISABLE_FLY_DRIFTING("disableFlyDrifting"); + + private static final Map BY_ID = Map.of( + REACH_AROUND.getId(), REACH_AROUND, + DISABLE_FLY_DRIFTING.getId(), DISABLE_FLY_DRIFTING + ); + + private final String id; + private ServerPolicy value; + + ServerPolicies(String id) { + this.id = id; + this.value = ServerPolicy.UNSET; + } + + public ServerPolicy get() { + return value; + } + + public void set(ServerPolicy value) { + this.value = value; + } + + public String getId() { + return id; + } + + public static ServerPolicies getById(String id) { + return BY_ID.get(id); + } + + public static void unsetAll() { + for (ServerPolicies policy : values()) { + policy.set(ServerPolicy.UNSET); + } + } +} diff --git a/src/main/java/dev/isxander/controlify/server/ServerPolicy.java b/src/main/java/dev/isxander/controlify/server/ServerPolicy.java new file mode 100644 index 0000000..7e7267d --- /dev/null +++ b/src/main/java/dev/isxander/controlify/server/ServerPolicy.java @@ -0,0 +1,15 @@ +package dev.isxander.controlify.server; + +public enum ServerPolicy { + ALLOWED, + DISALLOWED, + UNSET; + + public boolean isAllowed() { + return this != DISALLOWED; + } + + public static ServerPolicy fromBoolean(boolean value) { + return value ? ALLOWED : DISALLOWED; + } +} diff --git a/src/main/java/dev/isxander/controlify/server/ServerPolicyPacket.java b/src/main/java/dev/isxander/controlify/server/ServerPolicyPacket.java new file mode 100644 index 0000000..c09a378 --- /dev/null +++ b/src/main/java/dev/isxander/controlify/server/ServerPolicyPacket.java @@ -0,0 +1,29 @@ +package dev.isxander.controlify.server; + +import net.fabricmc.fabric.api.networking.v1.FabricPacket; +import net.fabricmc.fabric.api.networking.v1.PacketType; +import net.minecraft.network.FriendlyByteBuf; +import net.minecraft.resources.ResourceLocation; + +public record ServerPolicyPacket(String id, boolean allowed) implements FabricPacket { + public static final PacketType TYPE = + PacketType.create( + new ResourceLocation("controlify", "server_policy"), + ServerPolicyPacket::new + ); + + public ServerPolicyPacket(FriendlyByteBuf buf) { + this(buf.readUtf(), buf.readBoolean()); + } + + @Override + public void write(FriendlyByteBuf buf) { + buf.writeUtf(id); + buf.writeBoolean(allowed); + } + + @Override + public PacketType getType() { + return TYPE; + } +} diff --git a/src/main/resources/assets/controlify/lang/en_us.json b/src/main/resources/assets/controlify/lang/en_us.json index cec22f0..33a74c3 100644 --- a/src/main/resources/assets/controlify/lang/en_us.json +++ b/src/main/resources/assets/controlify/lang/en_us.json @@ -14,7 +14,7 @@ "controlify.gui.reach_around.tooltip": "If enabled, you can interact with the block you are standing on in the direction you are looking.", "controlify.gui.reach_around.tooltip.parity": "This is parity with bedrock edition where you can also do this.", "controlify.gui.reach_around.tooltip.warning": "WARNING: This is an unfair advantage over other players without Controlify, and you will likely be flagged by many anti-cheats. This should only be used in situations where everyone playing recognises that you have this ability and are okay with it.", - "controlify.gui.reach_around.tooltip.server_controlled": "The server you are playing on is controlling this setting.", + "controlify.gui.server_controlled": "The server you are playing on is controlling this setting.", "controlify.reach_around.off": "OFF", "controlify.reach_around.singleplayer_only": "Singleplayer Only", "controlify.reach_around.singleplayer_and_lan": "Singleplayer and LAN", @@ -57,6 +57,8 @@ "controlify.gui.toggle_sprint.tooltip": "How the state of the sprint button behaves.", "controlify.gui.auto_jump": "Auto Jump", "controlify.gui.auto_jump.tooltip": "If the player should automatically jump when you reach a block.", + "controlify.gui.no_fly_drifting": "No Fly Drifting", + "controlify.gui.no_fly_drifting.tooltip": "Disables the slight drifting when you let go of the controls.", "controlify.config.group.accessibility": "Accessibility", "controlify.gui.show_ingame_guide": "Show Ingame Button Guide", "controlify.gui.show_ingame_guide.tooltip": "Show a HUD in-game displaying actions you can do with controller buttons.",