From 45a2b32c97484a44beffef197a855b7f27c24b88 Mon Sep 17 00:00:00 2001 From: Tschipp <11649893+Tschipp@users.noreply.github.com> Date: Tue, 22 Jul 2025 23:48:52 +0200 Subject: [PATCH] Fixed Player Carrying, closes #774 --- .../java/tschipp/carryon/CarryOnCommon.java | 19 ++++++ .../main/java/tschipp/carryon/Constants.java | 1 + .../carryon/common/carry/PickupHandler.java | 5 +- .../common/carry/PlacementHandler.java | 9 ++- .../tschipp/carryon/mixin/EntityMixin.java | 7 +++ ...ientboundStartRidingOtherPlayerPacket.java | 59 +++++++++++++++++++ .../platform/services/IPlatformHelper.java | 7 +++ .../tschipp/carryon/events/CommonEvents.java | 5 ++ .../tschipp/carryon/events/CommonEvents.java | 7 +++ .../tschipp/carryon/events/CommonEvents.java | 6 ++ 10 files changed, 120 insertions(+), 5 deletions(-) create mode 100644 Common/src/main/java/tschipp/carryon/networking/clientbound/ClientboundStartRidingOtherPlayerPacket.java diff --git a/Common/src/main/java/tschipp/carryon/CarryOnCommon.java b/Common/src/main/java/tschipp/carryon/CarryOnCommon.java index d38db0b..0d0e3cf 100644 --- a/Common/src/main/java/tschipp/carryon/CarryOnCommon.java +++ b/Common/src/main/java/tschipp/carryon/CarryOnCommon.java @@ -40,6 +40,7 @@ import tschipp.carryon.common.carry.CarryOnDataManager; import tschipp.carryon.common.carry.PlacementHandler; import tschipp.carryon.common.command.CommandCarryOn; import tschipp.carryon.config.ConfigLoader; +import tschipp.carryon.networking.clientbound.ClientboundStartRidingOtherPlayerPacket; import tschipp.carryon.networking.clientbound.ClientboundStartRidingPacket; import tschipp.carryon.networking.clientbound.ClientboundSyncScriptsPacket; import tschipp.carryon.networking.serverbound.ServerboundCarryKeyPressedPacket; @@ -83,6 +84,14 @@ public class CarryOnCommon ClientboundSyncScriptsPacket::handle, args ); + + Services.PLATFORM.registerClientboundPacket( + ClientboundStartRidingOtherPlayerPacket.TYPE, + ClientboundStartRidingOtherPlayerPacket.class, + ClientboundStartRidingOtherPlayerPacket.CODEC, + ClientboundStartRidingOtherPlayerPacket::handle, + args + ); } public static void registerConfig() @@ -160,6 +169,16 @@ public class CarryOnCommon } } + public static void onRiderDisconnected(Player rider) + { + if(rider.getVehicle() instanceof ServerPlayer vehicle) { + CarryOnData data = CarryOnDataManager.getCarryData(vehicle); + if(data.isCarrying(CarryType.PLAYER)) { + PlacementHandler.placeCarried(vehicle); + } + } + } + private static int potionLevel(CarryOnData carry, Level level) { diff --git a/Common/src/main/java/tschipp/carryon/Constants.java b/Common/src/main/java/tschipp/carryon/Constants.java index a665229..c4f33f3 100644 --- a/Common/src/main/java/tschipp/carryon/Constants.java +++ b/Common/src/main/java/tschipp/carryon/Constants.java @@ -37,5 +37,6 @@ public class Constants { public static final ResourceLocation PACKET_ID_KEY_PRESSED = ResourceLocation.fromNamespaceAndPath(Constants.MOD_ID, "key_pressed"); public static final ResourceLocation PACKET_ID_START_RIDING = ResourceLocation.fromNamespaceAndPath(Constants.MOD_ID, "start_riding"); public static final ResourceLocation PACKET_ID_SYNC_SCRIPTS = ResourceLocation.fromNamespaceAndPath(Constants.MOD_ID, "sync_scripts"); + public static final ResourceLocation PACKET_ID_START_RIDING_OTHER = ResourceLocation.fromNamespaceAndPath(Constants.MOD_ID, "start_riding_other"); } \ No newline at end of file diff --git a/Common/src/main/java/tschipp/carryon/common/carry/PickupHandler.java b/Common/src/main/java/tschipp/carryon/common/carry/PickupHandler.java index fac27ec..fc68f8c 100644 --- a/Common/src/main/java/tschipp/carryon/common/carry/PickupHandler.java +++ b/Common/src/main/java/tschipp/carryon/common/carry/PickupHandler.java @@ -44,6 +44,7 @@ import tschipp.carryon.common.pickupcondition.PickupCondition; import tschipp.carryon.common.pickupcondition.PickupConditionHandler; import tschipp.carryon.common.scripting.CarryOnScript; import tschipp.carryon.common.scripting.ScriptManager; +import tschipp.carryon.networking.clientbound.ClientboundStartRidingOtherPlayerPacket; import tschipp.carryon.networking.clientbound.ClientboundStartRidingPacket; import tschipp.carryon.platform.Services; @@ -224,8 +225,8 @@ public class PickupHandler { player.getServer().getCommands().performPrefixedCommand(player.getServer().createCommandSourceStack(), "/execute as " + player.getGameProfile().getName() + " run " + cmd); } - otherPlayer.startRiding(player); - Services.PLATFORM.sendPacketToPlayer(Constants.PACKET_ID_START_RIDING, new ClientboundStartRidingPacket(otherPlayer.getId(), true), player); + otherPlayer.startRiding(player, true); + Services.PLATFORM.sendPacketToAllPlayers(Constants.PACKET_ID_START_RIDING_OTHER, new ClientboundStartRidingOtherPlayerPacket(player.getId(), otherPlayer.getId(), true), player.serverLevel()); carry.setCarryingPlayer(); player.swing(InteractionHand.MAIN_HAND, true); player.level().playSound(null, player.getOnPos(), SoundEvents.ARMOR_EQUIP_GENERIC.value(), SoundSource.AMBIENT, 1.0f, 0.5f); diff --git a/Common/src/main/java/tschipp/carryon/common/carry/PlacementHandler.java b/Common/src/main/java/tschipp/carryon/common/carry/PlacementHandler.java index a66a6e2..a489e46 100644 --- a/Common/src/main/java/tschipp/carryon/common/carry/PlacementHandler.java +++ b/Common/src/main/java/tschipp/carryon/common/carry/PlacementHandler.java @@ -46,6 +46,8 @@ import tschipp.carryon.Constants; import tschipp.carryon.common.carry.CarryOnData.CarryType; import tschipp.carryon.common.config.ListHandler; import tschipp.carryon.common.scripting.CarryOnScript.ScriptEffects; +import tschipp.carryon.networking.clientbound.ClientboundStartRidingOtherPlayerPacket; +import tschipp.carryon.platform.Services; import javax.annotation.Nullable; import java.util.ArrayList; @@ -173,11 +175,10 @@ public class PlacementHandler if (carry.isCarrying(CarryType.PLAYER)) { Entity otherPlayer = player.getFirstPassenger(); player.ejectPassengers(); + Services.PLATFORM.sendPacketToAllPlayers(Constants.PACKET_ID_START_RIDING_OTHER, new ClientboundStartRidingOtherPlayerPacket(player.getId(), otherPlayer.getId(), false), player.serverLevel()); carry.clear(); CarryOnDataManager.setCarryData(player, carry); - if (otherPlayer == null) - return true; - otherPlayer.teleportTo(placementPos.x, placementPos.y, placementPos.z); + otherPlayer.teleportTo(placementPos.x, placementPos.y, placementPos.z); player.swing(InteractionHand.MAIN_HAND, true); return true; } @@ -222,6 +223,8 @@ public class PlacementHandler else entityHeld = player.getFirstPassenger(); + if(entityHeld == null) + return; double sizeHeldEntity = entityHeld.getBbHeight() * entityHeld.getBbWidth(); double distance = entityClicked.blockPosition().distSqr(player.blockPosition()); diff --git a/Common/src/main/java/tschipp/carryon/mixin/EntityMixin.java b/Common/src/main/java/tschipp/carryon/mixin/EntityMixin.java index c434768..8e4e662 100644 --- a/Common/src/main/java/tschipp/carryon/mixin/EntityMixin.java +++ b/Common/src/main/java/tschipp/carryon/mixin/EntityMixin.java @@ -20,6 +20,7 @@ package tschipp.carryon.mixin; +import com.llamalad7.mixinextras.injector.ModifyExpressionValue; import net.minecraft.server.level.ServerPlayer; import net.minecraft.util.Mth; import net.minecraft.world.entity.Entity; @@ -49,6 +50,12 @@ public abstract class EntityMixin @Shadow public abstract void onPassengerTurned(Entity $$0); + @ModifyExpressionValue(method = "startRiding(Lnet/minecraft/world/entity/Entity;Z)Z", at = @At(value = "INVOKE", target = "Lnet/minecraft/world/entity/EntityType;canSerialize()Z")) + private boolean onStartRidingCheck(boolean original, Entity entity, boolean force) { + if (force && entity instanceof Player) return true; + return original; + } + @Inject(method = "positionRider(Lnet/minecraft/world/entity/Entity;Lnet/minecraft/world/entity/Entity$MoveFunction;)V", at = @At("HEAD"), cancellable = true) private void onPositionPassenger(Entity entity, MoveFunction move, CallbackInfo ci) { diff --git a/Common/src/main/java/tschipp/carryon/networking/clientbound/ClientboundStartRidingOtherPlayerPacket.java b/Common/src/main/java/tschipp/carryon/networking/clientbound/ClientboundStartRidingOtherPlayerPacket.java new file mode 100644 index 0000000..3dfa75f --- /dev/null +++ b/Common/src/main/java/tschipp/carryon/networking/clientbound/ClientboundStartRidingOtherPlayerPacket.java @@ -0,0 +1,59 @@ +/* + * GNU Lesser General Public License v3 + * Copyright (C) 2024 Tschipp + * mrtschipp@gmail.com + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3 of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +package tschipp.carryon.networking.clientbound; + +import net.minecraft.network.RegistryFriendlyByteBuf; +import net.minecraft.network.codec.ByteBufCodecs; +import net.minecraft.network.codec.StreamCodec; +import net.minecraft.world.entity.Entity; +import net.minecraft.world.entity.player.Player; +import tschipp.carryon.Constants; +import tschipp.carryon.networking.PacketBase; + +public record ClientboundStartRidingOtherPlayerPacket(int mount, int rider, boolean ride) implements PacketBase +{ + public static final StreamCodec CODEC = StreamCodec.composite( + ByteBufCodecs.INT, ClientboundStartRidingOtherPlayerPacket::mount, + ByteBufCodecs.INT, ClientboundStartRidingOtherPlayerPacket::rider, + ByteBufCodecs.BOOL, ClientboundStartRidingOtherPlayerPacket::ride, + ClientboundStartRidingOtherPlayerPacket::new + ); + + public static final Type TYPE = new Type<>(Constants.PACKET_ID_START_RIDING_OTHER); + + @Override + public void handle(Player player) + { + Entity mount = player.level().getEntity(this.mount); + Entity rider = player.level().getEntity(this.rider); + + if(mount != null && rider != null) + if(ride) + rider.startRiding(mount, true); + else + rider.stopRiding(); + } + + @Override + public Type type() { + return TYPE; + } +} diff --git a/Common/src/main/java/tschipp/carryon/platform/services/IPlatformHelper.java b/Common/src/main/java/tschipp/carryon/platform/services/IPlatformHelper.java index 71fe051..3082ed4 100644 --- a/Common/src/main/java/tschipp/carryon/platform/services/IPlatformHelper.java +++ b/Common/src/main/java/tschipp/carryon/platform/services/IPlatformHelper.java @@ -26,6 +26,7 @@ import net.minecraft.network.RegistryFriendlyByteBuf; import net.minecraft.network.codec.StreamCodec; import net.minecraft.network.protocol.common.custom.CustomPacketPayload; import net.minecraft.resources.ResourceLocation; +import net.minecraft.server.level.ServerLevel; import net.minecraft.server.level.ServerPlayer; import net.minecraft.world.entity.player.Player; import tschipp.carryon.config.BuiltConfig; @@ -67,4 +68,10 @@ public interface IPlatformHelper { void sendPacketToServer(ResourceLocation id, PacketBase packet); void sendPacketToPlayer(ResourceLocation id, PacketBase packet, ServerPlayer player); + + default void sendPacketToAllPlayers(ResourceLocation id, PacketBase packet, ServerLevel level) { + for(ServerPlayer p : level.players()) + sendPacketToPlayer(id, packet, p); + } + } diff --git a/Fabric/src/main/java/tschipp/carryon/events/CommonEvents.java b/Fabric/src/main/java/tschipp/carryon/events/CommonEvents.java index d1fc739..fc7f9ac 100644 --- a/Fabric/src/main/java/tschipp/carryon/events/CommonEvents.java +++ b/Fabric/src/main/java/tschipp/carryon/events/CommonEvents.java @@ -26,6 +26,7 @@ import net.fabricmc.fabric.api.event.lifecycle.v1.CommonLifecycleEvents; import net.fabricmc.fabric.api.event.lifecycle.v1.ServerLifecycleEvents; import net.fabricmc.fabric.api.event.lifecycle.v1.ServerTickEvents; import net.fabricmc.fabric.api.event.player.*; +import net.fabricmc.fabric.api.networking.v1.ServerPlayConnectionEvents; import net.fabricmc.fabric.api.resource.ResourceManagerHelper; import net.minecraft.core.BlockPos; import net.minecraft.core.Direction; @@ -155,6 +156,10 @@ public class CommonEvents { return InteractionResult.PASS; })); + ServerPlayConnectionEvents.DISCONNECT.register((handler, server) -> { + CarryOnCommon.onRiderDisconnected(handler.getPlayer()); + }); + //TODO: drop carried when attacked } diff --git a/Forge/src/main/java/tschipp/carryon/events/CommonEvents.java b/Forge/src/main/java/tschipp/carryon/events/CommonEvents.java index 106c00e..771cb61 100644 --- a/Forge/src/main/java/tschipp/carryon/events/CommonEvents.java +++ b/Forge/src/main/java/tschipp/carryon/events/CommonEvents.java @@ -40,6 +40,7 @@ import net.minecraftforge.event.TickEvent.ServerTickEvent; import net.minecraftforge.event.entity.living.LivingAttackEvent; import net.minecraftforge.event.entity.living.MobSpawnEvent.FinalizeSpawn; import net.minecraftforge.event.entity.player.AttackEntityEvent; +import net.minecraftforge.event.entity.player.PlayerEvent; import net.minecraftforge.event.entity.player.PlayerEvent.BreakSpeed; import net.minecraftforge.event.entity.player.PlayerEvent.Clone; import net.minecraftforge.event.entity.player.PlayerInteractEvent; @@ -218,4 +219,10 @@ public class CommonEvents CarryOnCommon.onPlayerAttacked(player); } + @SubscribeEvent + public static void onPlayerLoggedOut(PlayerEvent.PlayerLoggedOutEvent event) { + if(event.getEntity() instanceof ServerPlayer player) + CarryOnCommon.onRiderDisconnected(player); + } + } diff --git a/NeoForge/src/main/java/tschipp/carryon/events/CommonEvents.java b/NeoForge/src/main/java/tschipp/carryon/events/CommonEvents.java index 3e59c7e..c5cee43 100644 --- a/NeoForge/src/main/java/tschipp/carryon/events/CommonEvents.java +++ b/NeoForge/src/main/java/tschipp/carryon/events/CommonEvents.java @@ -213,4 +213,10 @@ public class CommonEvents CarryOnCommon.onPlayerAttacked(player); } + @SubscribeEvent + public static void onPlayerLoggedOut(PlayerEvent.PlayerLoggedOutEvent event) { + if(event.getEntity() instanceof ServerPlayer player) + CarryOnCommon.onRiderDisconnected(player); + } + }