1
0
forked from Clones/Controlify

No fly drifting, improve server policy system (backwards compat with old packet)

This commit is contained in:
isXander
2023-08-19 20:01:29 +01:00
parent fa656304c0
commit 8b2dc970cb
14 changed files with 169 additions and 60 deletions

View File

@ -14,9 +14,7 @@ import dev.isxander.controlify.gui.screen.ControllerCalibrationScreen;
import dev.isxander.controlify.gui.screen.SDLOnboardingScreen; import dev.isxander.controlify.gui.screen.SDLOnboardingScreen;
import dev.isxander.controlify.gui.screen.SubmitUnknownControllerScreen; import dev.isxander.controlify.gui.screen.SubmitUnknownControllerScreen;
import dev.isxander.controlify.ingame.ControllerPlayerMovement; import dev.isxander.controlify.ingame.ControllerPlayerMovement;
import dev.isxander.controlify.reacharound.ReachAroundHandler; import dev.isxander.controlify.server.*;
import dev.isxander.controlify.reacharound.ReachAroundMode;
import dev.isxander.controlify.reacharound.ReachAroundPolicy;
import dev.isxander.controlify.screenop.ScreenProcessorProvider; import dev.isxander.controlify.screenop.ScreenProcessorProvider;
import dev.isxander.controlify.config.ControlifyConfig; import dev.isxander.controlify.config.ControlifyConfig;
import dev.isxander.controlify.hid.ControllerHIDService; 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.gui.guide.InGameButtonGuide;
import dev.isxander.controlify.ingame.InGameInputHandler; import dev.isxander.controlify.ingame.InGameInputHandler;
import dev.isxander.controlify.mixins.feature.virtualmouse.MouseHandlerAccessor; 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.DebugLog;
import dev.isxander.controlify.utils.Log; import dev.isxander.controlify.utils.Log;
import dev.isxander.controlify.utils.ToastUtils; import dev.isxander.controlify.utils.ToastUtils;
@ -250,21 +244,13 @@ public class Controlify implements ControlifyApi {
controller.rumbleManager().play(packet.source(), packet.createEffect())); controller.rumbleManager().play(packet.source(), packet.createEffect()));
} }
}); });
ClientPlayNetworking.registerGlobalReceiver(ReachAroundPolicyPacket.TYPE, (packet, player, sender) -> { ClientPlayNetworking.registerGlobalReceiver(ServerPolicyPacket.TYPE, (packet, player, sender) -> {
Log.LOGGER.info("Connected server specified reach around policy is {}.", packet.allowed() ? "ALLOWED" : "DISALLOWED"); Log.LOGGER.info("Connected server specified '{}' policy is {}.", packet.id(), packet.allowed() ? "ALLOWED" : "DISALLOWED");
ReachAroundHandler.reachAroundPolicy = ReachAroundPolicy.fromServer(packet.allowed()); ServerPolicies.getById(packet.id()).set(ServerPolicy.fromBoolean(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
);
}
}); });
ClientPlayConnectionEvents.DISCONNECT.register((handler, client) -> { ClientPlayConnectionEvents.DISCONNECT.register((handler, client) -> {
DebugLog.log("Disconnected from server, resetting reach around policy"); DebugLog.log("Disconnected from server, resetting server policies");
ReachAroundHandler.reachAroundPolicy = ReachAroundPolicy.UNSET; ServerPolicies.unsetAll();
}); });
FabricLoader.getInstance().getEntrypoints("controlify", ControlifyEntrypoint.class).forEach(entrypoint -> { FabricLoader.getInstance().getEntrypoints("controlify", ControlifyEntrypoint.class).forEach(entrypoint -> {

View File

@ -21,6 +21,7 @@ public abstract class ControllerConfig implements Serializable {
public boolean autoJump = false; public boolean autoJump = false;
public boolean toggleSprint = true; public boolean toggleSprint = true;
public boolean toggleSneak = true; public boolean toggleSneak = true;
public boolean disableFlyDrifting = false;
public String customName = null; public String customName = null;

View File

@ -16,6 +16,8 @@ import dev.isxander.controlify.gui.guide.InGameButtonGuide;
import dev.isxander.controlify.rumble.BasicRumbleEffect; import dev.isxander.controlify.rumble.BasicRumbleEffect;
import dev.isxander.controlify.rumble.RumbleSource; import dev.isxander.controlify.rumble.RumbleSource;
import dev.isxander.controlify.rumble.RumbleState; 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.*;
import dev.isxander.yacl3.api.controller.*; import dev.isxander.yacl3.api.controller.*;
import net.minecraft.ChatFormatting; import net.minecraft.ChatFormatting;
@ -164,6 +166,16 @@ public class ControllerConfigScreenFactory {
.controller(opt -> BooleanControllerBuilder.create(opt) .controller(opt -> BooleanControllerBuilder.create(opt)
.onOffFormatter()) .onOffFormatter())
.build()) .build())
.option(Option.<Boolean>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(); .build();
} }

View File

@ -3,9 +3,9 @@ package dev.isxander.controlify.gui.screen;
import dev.isxander.controlify.Controlify; import dev.isxander.controlify.Controlify;
import dev.isxander.controlify.api.ControlifyApi; import dev.isxander.controlify.api.ControlifyApi;
import dev.isxander.controlify.config.GlobalSettings; import dev.isxander.controlify.config.GlobalSettings;
import dev.isxander.controlify.reacharound.ReachAroundHandler;
import dev.isxander.controlify.reacharound.ReachAroundMode; 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.*;
import dev.isxander.yacl3.api.controller.BooleanControllerBuilder; import dev.isxander.yacl3.api.controller.BooleanControllerBuilder;
import dev.isxander.yacl3.api.controller.EnumControllerBuilder; 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"))
.text(Component.translatable("controlify.gui.reach_around.tooltip.parity").withStyle(ChatFormatting.GRAY)) .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(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()) .build())
.binding(GlobalSettings.DEFAULT.reachAround, () -> globalSettings.reachAround, v -> globalSettings.reachAround = v) .binding(GlobalSettings.DEFAULT.reachAround, () -> globalSettings.reachAround, v -> globalSettings.reachAround = v)
.controller(opt -> EnumControllerBuilder.create(opt) .controller(opt -> EnumControllerBuilder.create(opt)
.enumClass(ReachAroundMode.class) .enumClass(ReachAroundMode.class)
.valueFormatter(mode -> switch (ReachAroundHandler.reachAroundPolicy) { .valueFormatter(mode -> switch (ServerPolicies.REACH_AROUND.get()) {
case UNSET -> mode.getDisplayName(); case UNSET, ALLOWED -> mode.getDisplayName();
case ALLOWED -> CommonComponents.OPTION_ON;
case DISALLOWED -> CommonComponents.OPTION_OFF; case DISALLOWED -> CommonComponents.OPTION_OFF;
})) }))
.available(ReachAroundHandler.reachAroundPolicy == ReachAroundPolicy.UNSET) .available(ServerPolicies.REACH_AROUND.get().isAllowed())
.build()) .build())
.option(Option.<Boolean>createBuilder() .option(Option.<Boolean>createBuilder()
.name(Component.translatable("controlify.gui.ui_sounds")) .name(Component.translatable("controlify.gui.ui_sounds"))

View File

@ -50,6 +50,7 @@ public class InGameInputHandler {
public void inputTick() { public void inputTick() {
handlePlayerLookInput(); handlePlayerLookInput();
handleKeybinds(); handleKeybinds();
preventFlyDrifting();
} }
protected void handleKeybinds() { protected void handleKeybinds() {
@ -233,6 +234,32 @@ public class InGameInputHandler {
return this.shouldShowPlayerList; 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) { private boolean isAiming(Player player) {
return player.isUsingItem() && switch (player.getUseItem().getUseAnimation()) { return player.isUsingItem() && switch (player.getUseItem().getUseAnimation()) {
case BOW, CROSSBOW, SPEAR, SPYGLASS -> true; case BOW, CROSSBOW, SPEAR, SPYGLASS -> true;

View File

@ -1,15 +1,12 @@
package dev.isxander.controlify.reacharound; package dev.isxander.controlify.reacharound;
import dev.isxander.controlify.Controlify; import dev.isxander.controlify.Controlify;
import net.minecraft.core.BlockPos; import dev.isxander.controlify.server.ServerPolicies;
import net.minecraft.util.Mth;
import net.minecraft.world.entity.Entity; import net.minecraft.world.entity.Entity;
import net.minecraft.world.phys.BlockHitResult; import net.minecraft.world.phys.BlockHitResult;
import net.minecraft.world.phys.HitResult; import net.minecraft.world.phys.HitResult;
public class ReachAroundHandler { public class ReachAroundHandler {
public static ReachAroundPolicy reachAroundPolicy = ReachAroundPolicy.UNSET;
public static HitResult getReachAroundHitResult(Entity entity, HitResult hitResult) { public static HitResult getReachAroundHitResult(Entity entity, HitResult hitResult) {
// if there is already a valid hit, we don't want to override it // if there is already a valid hit, we don't want to override it
if (hitResult.getType() != HitResult.Type.MISS) if (hitResult.getType() != HitResult.Type.MISS)
@ -34,7 +31,16 @@ public class ReachAroundHandler {
} }
private static boolean canReachAround(Entity cameraEntity) { 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 // don't want to place blocks while riding an entity
&& cameraEntity.getVehicle() == null && cameraEntity.getVehicle() == null
// straight ahead = 0deg, up = -90deg, down = 90deg // straight ahead = 0deg, up = -90deg, down = 90deg

View File

@ -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<ReachAroundMode, Boolean> canReachAround;
ReachAroundPolicy(Function<ReachAroundMode, Boolean> canReachAround) {
this.canReachAround = canReachAround;
}
public boolean canReachAround(ReachAroundMode mode) {
return canReachAround.apply(mode);
}
public static ReachAroundPolicy fromServer(boolean allowed) {
return allowed ? ALLOWED : DISALLOWED;
}
}

View File

@ -21,10 +21,17 @@ public class ControlifyServer implements ModInitializer, DedicatedServerModIniti
@Override @Override
public void onInitializeServer() { public void onInitializeServer() {
ControlifyServerConfig.INSTANCE.load(); ControlifyServerConfig.INSTANCE.load();
ControlifyServerConfig.INSTANCE.save();
Log.LOGGER.info("Reach-around policy: " + ControlifyServerConfig.INSTANCE.getConfig().reachAroundPolicy); 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) -> { 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));
}); });
} }
} }

View File

@ -11,4 +11,5 @@ public class ControlifyServerConfig {
.build(); .build();
@ConfigEntry public boolean reachAroundPolicy = false; @ConfigEntry public boolean reachAroundPolicy = false;
@ConfigEntry public boolean noFlyDriftPolicy = false;
} }

View File

@ -5,10 +5,14 @@ import net.fabricmc.fabric.api.networking.v1.PacketType;
import net.minecraft.network.FriendlyByteBuf; import net.minecraft.network.FriendlyByteBuf;
import net.minecraft.resources.ResourceLocation; import net.minecraft.resources.ResourceLocation;
public record ReachAroundPolicyPacket(boolean allowed) implements FabricPacket { public record LegacyReachAroundPolicyPacket(boolean allowed) implements FabricPacket {
public static final PacketType<ReachAroundPolicyPacket> TYPE = PacketType.create(new ResourceLocation("controlify", "reach_around_policy"), ReachAroundPolicyPacket::new); public static final PacketType<LegacyReachAroundPolicyPacket> TYPE =
PacketType.create(
new ResourceLocation("controlify", "reach_around_policy"),
LegacyReachAroundPolicyPacket::new
);
public ReachAroundPolicyPacket(FriendlyByteBuf buf) { public LegacyReachAroundPolicyPacket(FriendlyByteBuf buf) {
this(buf.readBoolean()); this(buf.readBoolean());
} }

View File

@ -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<String, ServerPolicies> 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);
}
}
}

View File

@ -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;
}
}

View File

@ -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<ServerPolicyPacket> 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;
}
}

View File

@ -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": "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.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.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.off": "OFF",
"controlify.reach_around.singleplayer_only": "Singleplayer Only", "controlify.reach_around.singleplayer_only": "Singleplayer Only",
"controlify.reach_around.singleplayer_and_lan": "Singleplayer and LAN", "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.toggle_sprint.tooltip": "How the state of the sprint button behaves.",
"controlify.gui.auto_jump": "Auto Jump", "controlify.gui.auto_jump": "Auto Jump",
"controlify.gui.auto_jump.tooltip": "If the player should automatically jump when you reach a block.", "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.config.group.accessibility": "Accessibility",
"controlify.gui.show_ingame_guide": "Show Ingame Button Guide", "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.", "controlify.gui.show_ingame_guide.tooltip": "Show a HUD in-game displaying actions you can do with controller buttons.",