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.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 -> {

View File

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

View File

@ -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.<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();
}

View File

@ -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.<Boolean>createBuilder()
.name(Component.translatable("controlify.gui.ui_sounds"))

View File

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

View File

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

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

View File

@ -11,4 +11,5 @@ public class ControlifyServerConfig {
.build();
@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.resources.ResourceLocation;
public record ReachAroundPolicyPacket(boolean allowed) implements FabricPacket {
public static final PacketType<ReachAroundPolicyPacket> TYPE = PacketType.create(new ResourceLocation("controlify", "reach_around_policy"), ReachAroundPolicyPacket::new);
public record LegacyReachAroundPolicyPacket(boolean allowed) implements FabricPacket {
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());
}

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