diff --git a/Common/src/main/java/tschipp/carryon/CarryOnCommon.java b/Common/src/main/java/tschipp/carryon/CarryOnCommon.java index 5ae81f7..37fa933 100644 --- a/Common/src/main/java/tschipp/carryon/CarryOnCommon.java +++ b/Common/src/main/java/tschipp/carryon/CarryOnCommon.java @@ -161,7 +161,7 @@ public class CarryOnCommon } - private static int potionLevel(CarryOnData carry, Level level) + public static int potionLevel(CarryOnData carry, Level level) { if(carry.isCarrying(CarryType.PLAYER)) return 1; diff --git a/Common/src/main/java/tschipp/carryon/Constants.java b/Common/src/main/java/tschipp/carryon/Constants.java index a665229..47290e5 100644 --- a/Common/src/main/java/tschipp/carryon/Constants.java +++ b/Common/src/main/java/tschipp/carryon/Constants.java @@ -37,5 +37,7 @@ 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"); + public static final ResourceLocation PACKET_ID_SYNC_CARRY_ON_DATA = ResourceLocation.fromNamespaceAndPath(Constants.MOD_ID, "sync_carry_data"); } \ No newline at end of file diff --git a/Common/src/main/java/tschipp/carryon/common/carry/CarryOnData.java b/Common/src/main/java/tschipp/carryon/common/carry/CarryOnData.java index c6e3d00..2977be3 100644 --- a/Common/src/main/java/tschipp/carryon/common/carry/CarryOnData.java +++ b/Common/src/main/java/tschipp/carryon/common/carry/CarryOnData.java @@ -20,7 +20,9 @@ package tschipp.carryon.common.carry; +import com.mojang.serialization.Codec; import com.mojang.serialization.DataResult; +import com.mojang.serialization.MapCodec; import net.minecraft.core.BlockPos; import net.minecraft.core.HolderLookup; import net.minecraft.core.registries.BuiltInRegistries; @@ -28,17 +30,27 @@ import net.minecraft.nbt.CompoundTag; import net.minecraft.nbt.NbtOps; import net.minecraft.nbt.NbtUtils; import net.minecraft.nbt.Tag; +import net.minecraft.network.RegistryFriendlyByteBuf; +import net.minecraft.network.codec.ByteBufCodecs; +import net.minecraft.network.codec.StreamCodec; +import net.minecraft.server.level.ServerPlayer; +import net.minecraft.util.ProblemReporter; import net.minecraft.world.entity.AreaEffectCloud; import net.minecraft.world.entity.Entity; +import net.minecraft.world.entity.EntitySpawnReason; import net.minecraft.world.entity.EntityType; import net.minecraft.world.level.Level; import net.minecraft.world.level.block.entity.BlockEntity; import net.minecraft.world.level.block.state.BlockState; import net.minecraft.world.level.block.state.properties.BlockStateProperties; +import net.minecraft.world.level.storage.TagValueInput; +import net.minecraft.world.level.storage.TagValueOutput; +import net.minecraft.world.level.storage.ValueInput; import tschipp.carryon.Constants; import tschipp.carryon.common.scripting.CarryOnScript; import javax.annotation.Nullable; +import java.util.Objects; import java.util.Optional; public class CarryOnData { @@ -48,6 +60,29 @@ public class CarryOnData { private boolean keyPressed = false; private CarryOnScript activeScript; private int selectedSlot = 0; + private static final ProblemReporter problemReporter = new ProblemReporter.ScopedCollector(Constants.LOG); + + + public static final Codec CODEC = CompoundTag.CODEC.flatXmap( + tag -> { + try { + return DataResult.success(new CarryOnData(tag)); + } catch (Exception e) { + return DataResult.error(e::getMessage); + } + }, + carry -> { + try { + return DataResult.success(carry.getNbt()); + } catch (Exception e) { + return DataResult.error(e::getMessage); + } + } + ); + + public static final StreamCodec STREAM_CODEC = ByteBufCodecs.fromCodecWithRegistries(CODEC); + + public static final String SERIALIZATION_KEY = "CarryOnData"; public CarryOnData(CompoundTag data) { @@ -213,6 +248,11 @@ public class CarryOnData { return this.nbt.getInt("tick"); } + public void setTick(int tick) { + this.nbt.putInt("tick", tick); + } + + public enum CarryType { BLOCK, ENTITY, diff --git a/Common/src/main/java/tschipp/carryon/common/carry/CarryOnDataManager.java b/Common/src/main/java/tschipp/carryon/common/carry/CarryOnDataManager.java index 10d7fa2..f1271da 100644 --- a/Common/src/main/java/tschipp/carryon/common/carry/CarryOnDataManager.java +++ b/Common/src/main/java/tschipp/carryon/common/carry/CarryOnDataManager.java @@ -24,25 +24,22 @@ import net.minecraft.nbt.CompoundTag; import net.minecraft.network.syncher.EntityDataAccessor; import net.minecraft.network.syncher.EntityDataSerializers; import net.minecraft.network.syncher.SynchedEntityData; +import net.minecraft.server.level.ServerPlayer; import net.minecraft.world.entity.player.Player; +import tschipp.carryon.platform.Services; public class CarryOnDataManager { public static CarryOnData getCarryData(Player player) { - return ((ICarrying)player).getCarryOnData(); + return Services.PLATFORM.getCarryData(player); } public static void setCarryData(Player player, CarryOnData data) { - ((ICarrying)player).setCarryOnData(data); - } - - public interface ICarrying { - - void setCarryOnData(CarryOnData data); - - CarryOnData getCarryOnData(); + data.setSelected(player.getInventory().selected); + data.setTick(player.tickCount); + Services.PLATFORM.setCarryData(player, data); } } 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 1cc78fa..2fb734e 100644 --- a/Common/src/main/java/tschipp/carryon/common/carry/PickupHandler.java +++ b/Common/src/main/java/tschipp/carryon/common/carry/PickupHandler.java @@ -26,6 +26,8 @@ import net.minecraft.server.level.ServerPlayer; import net.minecraft.sounds.SoundEvents; import net.minecraft.sounds.SoundSource; import net.minecraft.world.InteractionHand; +import net.minecraft.world.effect.MobEffectInstance; +import net.minecraft.world.effect.MobEffects; import net.minecraft.world.entity.AgeableMob; import net.minecraft.world.entity.Entity; import net.minecraft.world.entity.Entity.RemovalReason; @@ -38,6 +40,7 @@ import net.minecraft.world.level.Level; import net.minecraft.world.level.block.entity.BlockEntity; import net.minecraft.world.level.block.state.BlockState; import net.minecraft.world.phys.Vec3; +import tschipp.carryon.CarryOnCommon; import tschipp.carryon.Constants; import tschipp.carryon.common.config.ListHandler; import tschipp.carryon.common.pickupcondition.PickupCondition; @@ -144,6 +147,8 @@ public class PickupHandler { CarryOnDataManager.setCarryData(player, carry); level.playSound(null, pos, state.getSoundType().getHitSound(), SoundSource.BLOCKS, 1.0f, 0.5f); player.swing(InteractionHand.MAIN_HAND, true); + if (!player.isCreative() || Constants.COMMON_CONFIG.settings.slownessInCreative) + player.addEffect(new MobEffectInstance(MobEffects.MOVEMENT_SLOWDOWN, 100000000, CarryOnCommon.potionLevel(carry, player.level()), false, false)); return true; } @@ -224,12 +229,14 @@ 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.level()); 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); CarryOnDataManager.setCarryData(player, carry); + if (!player.isCreative() || Constants.COMMON_CONFIG.settings.slownessInCreative) + player.addEffect(new MobEffectInstance(MobEffects.MOVEMENT_SLOWDOWN, 100000000, CarryOnCommon.potionLevel(carry, player.level()), false, false)); return true; } @@ -253,6 +260,8 @@ public class PickupHandler { player.level().playSound(null, player.getOnPos(), SoundEvents.ARMOR_EQUIP_GENERIC.value(), SoundSource.AMBIENT, 1.0f, 0.5f); CarryOnDataManager.setCarryData(player, carry); player.swing(InteractionHand.MAIN_HAND, true); + if (!player.isCreative() || Constants.COMMON_CONFIG.settings.slownessInCreative) + player.addEffect(new MobEffectInstance(MobEffects.MOVEMENT_SLOWDOWN, 100000000, CarryOnCommon.potionLevel(carry, player.level()), false, false)); return true; } diff --git a/Common/src/main/java/tschipp/carryon/mixin/InventoryMixin.java b/Common/src/main/java/tschipp/carryon/mixin/InventoryMixin.java index ef70295..11ba33c 100644 --- a/Common/src/main/java/tschipp/carryon/mixin/InventoryMixin.java +++ b/Common/src/main/java/tschipp/carryon/mixin/InventoryMixin.java @@ -23,6 +23,7 @@ package tschipp.carryon.mixin; import com.llamalad7.mixinextras.injector.wrapoperation.Operation; import com.llamalad7.mixinextras.injector.wrapoperation.WrapOperation; import net.minecraft.core.NonNullList; +import net.minecraft.server.level.ServerPlayer; import net.minecraft.world.entity.player.Inventory; import net.minecraft.world.entity.player.Player; import net.minecraft.world.item.ItemStack; @@ -34,6 +35,7 @@ import org.spongepowered.asm.mixin.injection.At; import org.spongepowered.asm.mixin.injection.Inject; import org.spongepowered.asm.mixin.injection.Redirect; import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; +import tschipp.carryon.common.carry.CarryOnData; import tschipp.carryon.common.carry.CarryOnDataManager; @Mixin(Inventory.class) diff --git a/Common/src/main/java/tschipp/carryon/mixin/PlayerMixin.java b/Common/src/main/java/tschipp/carryon/mixin/PlayerMixin.java index 4a7458a..f423e67 100644 --- a/Common/src/main/java/tschipp/carryon/mixin/PlayerMixin.java +++ b/Common/src/main/java/tschipp/carryon/mixin/PlayerMixin.java @@ -22,6 +22,7 @@ package tschipp.carryon.mixin; import net.minecraft.nbt.CompoundTag; +import net.minecraft.nbt.NbtOps; import net.minecraft.network.syncher.EntityDataAccessor; import net.minecraft.network.syncher.EntityDataSerializers; import net.minecraft.network.syncher.SynchedEntityData; @@ -39,57 +40,20 @@ import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; import tschipp.carryon.common.carry.CarryOnData; import tschipp.carryon.common.carry.CarryOnDataManager; +import java.util.Optional; + @Mixin(Player.class) -public abstract class PlayerMixin extends LivingEntity implements CarryOnDataManager.ICarrying { - - @Unique - private static final EntityDataAccessor CARRY_DATA_KEY = SynchedEntityData.defineId(Player.class, EntityDataSerializers.COMPOUND_TAG); - - @Override - public void setCarryOnData(CarryOnData data) - { - data.setSelected(this.getInventory().selected); - CompoundTag nbt = data.getNbt(); - nbt.putInt("tick", tickCount); - this.getEntityData().set(CARRY_DATA_KEY, nbt); - } - - @Override - public CarryOnData getCarryOnData() - { - CompoundTag data = this.getEntityData().get(CARRY_DATA_KEY); - return new CarryOnData(data.copy()); - } - - @Shadow - public abstract Inventory getInventory(); - +public abstract class PlayerMixin extends LivingEntity { private PlayerMixin(EntityType type, Level level) { super(type, level); } - - @Inject(method = "defineSynchedData(Lnet/minecraft/network/syncher/SynchedEntityData$Builder;)V", at = @At("RETURN")) - private void onDefineSynchedData(SynchedEntityData.Builder builder, CallbackInfo ci) { - builder.define(CARRY_DATA_KEY, new CompoundTag()); - } - - - @Inject(method = "addAdditionalSaveData(Lnet/minecraft/nbt/CompoundTag;)V", at = @At("RETURN")) - private void onAddAdditionalSaveData(CompoundTag tag, CallbackInfo info) - { - CarryOnData carry = CarryOnDataManager.getCarryData((Player)(Object)this); - tag.put("CarryOnData", carry.getNbt()); - } - @Inject(method = "readAdditionalSaveData(Lnet/minecraft/nbt/CompoundTag;)V", at = @At("RETURN")) private void onReadAdditionalSaveData(CompoundTag tag, CallbackInfo info) { - if (tag.contains("CarryOnData")) { - CarryOnData data = new CarryOnData(tag.getCompound("CarryOnData")); - setCarryOnData(data); - } + Optional res = CarryOnData.CODEC.parse(NbtOps.INSTANCE, tag).result(); + res.ifPresent(data -> CarryOnDataManager.setCarryData((Player)((Object)this), data)); } } diff --git a/Common/src/main/java/tschipp/carryon/networking/clientbound/ClientboundSyncCarryDataPacket.java b/Common/src/main/java/tschipp/carryon/networking/clientbound/ClientboundSyncCarryDataPacket.java deleted file mode 100644 index ba3cec7..0000000 --- a/Common/src/main/java/tschipp/carryon/networking/clientbound/ClientboundSyncCarryDataPacket.java +++ /dev/null @@ -1,6 +0,0 @@ -package tschipp.carryon.networking.clientbound; - -import tschipp.carryon.common.carry.CarryOnData; - -public record ClientboundSyncCarryDataPacket(CarryOnData data) { -} 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..07c1d68 100644 --- a/Common/src/main/java/tschipp/carryon/platform/services/IPlatformHelper.java +++ b/Common/src/main/java/tschipp/carryon/platform/services/IPlatformHelper.java @@ -26,8 +26,11 @@ 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.common.carry.CarryOnData; +import tschipp.carryon.common.carry.CarryOnDataManager; import tschipp.carryon.config.BuiltConfig; import tschipp.carryon.networking.PacketBase; @@ -67,4 +70,14 @@ 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); + } + + CarryOnData getCarryData(Player player); + + void setCarryData(Player player, CarryOnData data); + } diff --git a/Fabric/src/main/java/tschipp/carryon/CarryOnFabricMod.java b/Fabric/src/main/java/tschipp/carryon/CarryOnFabricMod.java index 9cbb4cc..e5c7c43 100644 --- a/Fabric/src/main/java/tschipp/carryon/CarryOnFabricMod.java +++ b/Fabric/src/main/java/tschipp/carryon/CarryOnFabricMod.java @@ -21,13 +21,29 @@ package tschipp.carryon; import net.fabricmc.api.ModInitializer; +import net.fabricmc.fabric.api.attachment.v1.AttachmentRegistry; +import net.fabricmc.fabric.api.attachment.v1.AttachmentSyncPredicate; +import net.fabricmc.fabric.api.attachment.v1.AttachmentType; +import net.minecraft.nbt.CompoundTag; +import net.minecraft.resources.ResourceLocation; +import tschipp.carryon.common.carry.CarryOnData; import tschipp.carryon.config.fabric.ConfigLoaderImpl; import tschipp.carryon.events.CommonEvents; import java.io.IOException; public class CarryOnFabricMod implements ModInitializer { - + + public static final AttachmentType CARRY_ON_DATA_ATTACHMENT_TYPE = AttachmentRegistry.create( + ResourceLocation.fromNamespaceAndPath(Constants.MOD_ID, "carry_on_data"), + builder -> builder + .initializer(() -> new CarryOnData(new CompoundTag())) + .persistent(CarryOnData.CODEC) + .syncWith(CarryOnData.STREAM_CODEC, (t, p) -> p.connection != null) + .copyOnDeath() + + ); + @Override public void onInitialize() { diff --git a/Fabric/src/main/java/tschipp/carryon/platform/FabricPlatformHelper.java b/Fabric/src/main/java/tschipp/carryon/platform/FabricPlatformHelper.java index 020ac7d..64d4bdf 100644 --- a/Fabric/src/main/java/tschipp/carryon/platform/FabricPlatformHelper.java +++ b/Fabric/src/main/java/tschipp/carryon/platform/FabricPlatformHelper.java @@ -25,6 +25,7 @@ import net.fabricmc.fabric.api.networking.v1.PayloadTypeRegistry; import net.fabricmc.fabric.api.networking.v1.ServerPlayNetworking; import net.fabricmc.fabric.api.networking.v1.ServerPlayNetworking.PlayPayloadHandler; import net.fabricmc.loader.api.FabricLoader; +import net.minecraft.nbt.CompoundTag; import net.minecraft.network.FriendlyByteBuf; import net.minecraft.network.RegistryFriendlyByteBuf; import net.minecraft.network.codec.StreamCodec; @@ -35,6 +36,8 @@ import net.minecraft.resources.ResourceLocation; import net.minecraft.server.level.ServerPlayer; import net.minecraft.world.entity.player.Player; import tschipp.carryon.CarryOnFabricClientMod; +import tschipp.carryon.CarryOnFabricMod; +import tschipp.carryon.common.carry.CarryOnData; import tschipp.carryon.config.BuiltConfig; import tschipp.carryon.config.fabric.ConfigLoaderImpl; import tschipp.carryon.networking.PacketBase; @@ -101,4 +104,15 @@ public class FabricPlatformHelper implements IPlatformHelper { { ServerPlayNetworking.send(player, packet); } + + @Override + public CarryOnData getCarryData(Player player) { + CarryOnData data = player.getAttachedOrCreate(CarryOnFabricMod.CARRY_ON_DATA_ATTACHMENT_TYPE); + return data.clone(); + } + + @Override + public void setCarryData(Player player, CarryOnData data) { + player.setAttached(CarryOnFabricMod.CARRY_ON_DATA_ATTACHMENT_TYPE, data); + } } diff --git a/Forge/src/main/java/tschipp/carryon/CarryOnForge.java b/Forge/src/main/java/tschipp/carryon/CarryOnForge.java index 3298026..8ac0df0 100644 --- a/Forge/src/main/java/tschipp/carryon/CarryOnForge.java +++ b/Forge/src/main/java/tschipp/carryon/CarryOnForge.java @@ -28,6 +28,9 @@ import net.minecraftforge.fml.javafmlmod.FMLJavaModLoadingContext; import net.minecraftforge.network.ChannelBuilder; import net.minecraftforge.network.SimpleChannel; import tschipp.carryon.config.forge.ConfigLoaderImpl; +import tschipp.carryon.networking.ClientboundSyncCarryDataPacket; +import tschipp.carryon.networking.clientbound.ClientboundStartRidingPacket; +import tschipp.carryon.platform.Services; @Mod(Constants.MOD_ID) @EventBusSubscriber(bus = Mod.EventBusSubscriber.Bus.MOD) @@ -54,6 +57,13 @@ public class CarryOnForge { CarryOnCommon.registerServerPackets(); CarryOnCommon.registerClientPackets(); + + Services.PLATFORM.registerClientboundPacket( + ClientboundSyncCarryDataPacket.TYPE, + ClientboundSyncCarryDataPacket.class, + ClientboundSyncCarryDataPacket.CODEC, + ClientboundSyncCarryDataPacket::handle + ); } } \ No newline at end of file diff --git a/Forge/src/main/java/tschipp/carryon/carry/CarryOnDataCapability.java b/Forge/src/main/java/tschipp/carryon/carry/CarryOnDataCapability.java new file mode 100644 index 0000000..a4f4f14 --- /dev/null +++ b/Forge/src/main/java/tschipp/carryon/carry/CarryOnDataCapability.java @@ -0,0 +1,23 @@ +package tschipp.carryon.carry; + +import net.minecraft.nbt.CompoundTag; +import tschipp.carryon.common.carry.CarryOnData; + +public class CarryOnDataCapability implements ICarryOnDataCapability { + + private CarryOnData data; + + public CarryOnDataCapability() { + this.data = new CarryOnData(new CompoundTag()); + } + + @Override + public CarryOnData getCarryData() { + return data; + } + + @Override + public void setCarryData(CarryOnData data) { + this.data = data; + } +} diff --git a/Forge/src/main/java/tschipp/carryon/carry/CarryOnDataCapabilityProvider.java b/Forge/src/main/java/tschipp/carryon/carry/CarryOnDataCapabilityProvider.java new file mode 100644 index 0000000..e30ebdb --- /dev/null +++ b/Forge/src/main/java/tschipp/carryon/carry/CarryOnDataCapabilityProvider.java @@ -0,0 +1,38 @@ +package tschipp.carryon.carry; + +import net.minecraft.core.Direction; +import net.minecraft.core.HolderLookup; +import net.minecraft.nbt.CompoundTag; +import net.minecraft.nbt.NbtOps; +import net.minecraftforge.common.capabilities.Capability; +import net.minecraftforge.common.capabilities.CapabilityManager; +import net.minecraftforge.common.capabilities.CapabilityToken; +import net.minecraftforge.common.capabilities.ICapabilitySerializable; +import net.minecraftforge.common.util.LazyOptional; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; +import tschipp.carryon.common.carry.CarryOnData; + +public class CarryOnDataCapabilityProvider implements ICapabilitySerializable { + + public static final Capability CARRY_ON_DATA_CAPABILITY = CapabilityManager.get(new CapabilityToken() {}); + + private final CarryOnDataCapability impl = new CarryOnDataCapability(); + private final LazyOptional opt = LazyOptional.of(() -> impl); + + @Override + public @NotNull LazyOptional getCapability(@NotNull Capability cap, @Nullable Direction side) { + return cap == CARRY_ON_DATA_CAPABILITY ? opt.cast() : LazyOptional.empty(); + } + + @Override + public CompoundTag serializeNBT(HolderLookup.Provider registryAccess) { + return (CompoundTag) CarryOnData.CODEC.encodeStart(NbtOps.INSTANCE, impl.getCarryData()).getOrThrow(); + } + + @Override + public void deserializeNBT(HolderLookup.Provider registryAccess, CompoundTag nbt) { + CarryOnData data = CarryOnData.CODEC.parse(NbtOps.INSTANCE, nbt).getOrThrow(); + impl.setCarryData(data); + } +} diff --git a/Forge/src/main/java/tschipp/carryon/carry/ICarryOnDataCapability.java b/Forge/src/main/java/tschipp/carryon/carry/ICarryOnDataCapability.java new file mode 100644 index 0000000..49ab1f8 --- /dev/null +++ b/Forge/src/main/java/tschipp/carryon/carry/ICarryOnDataCapability.java @@ -0,0 +1,14 @@ +package tschipp.carryon.carry; + +import net.minecraftforge.common.capabilities.AutoRegisterCapability; +import tschipp.carryon.common.carry.CarryOnData; +import tschipp.carryon.common.carry.CarryOnDataManager; + +@AutoRegisterCapability +public interface ICarryOnDataCapability { + + CarryOnData getCarryData(); + + void setCarryData(CarryOnData data); + +} diff --git a/Forge/src/main/java/tschipp/carryon/events/CommonEvents.java b/Forge/src/main/java/tschipp/carryon/events/CommonEvents.java index 2e448ab..5ca7814 100644 --- a/Forge/src/main/java/tschipp/carryon/events/CommonEvents.java +++ b/Forge/src/main/java/tschipp/carryon/events/CommonEvents.java @@ -21,6 +21,7 @@ package tschipp.carryon.events; import net.minecraft.core.BlockPos; +import net.minecraft.resources.ResourceLocation; import net.minecraft.server.level.ServerPlayer; import net.minecraft.world.InteractionResult; import net.minecraft.world.entity.Entity; @@ -31,15 +32,18 @@ import net.minecraft.world.level.Level; import net.minecraft.world.level.ServerLevelAccessor; import net.minecraftforge.common.MinecraftForge; import net.minecraftforge.common.util.BlockSnapshot; +import net.minecraftforge.event.*; import net.minecraftforge.event.AddReloadListenerEvent; import net.minecraftforge.event.OnDatapackSyncEvent; import net.minecraftforge.event.RegisterCommandsEvent; import net.minecraftforge.event.TagsUpdatedEvent; import net.minecraftforge.event.TickEvent.Phase; import net.minecraftforge.event.TickEvent.ServerTickEvent; +import net.minecraftforge.event.entity.EntityJoinLevelEvent; 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; @@ -51,8 +55,10 @@ import net.minecraftforge.eventbus.api.Event.Result; import net.minecraftforge.eventbus.api.EventPriority; import net.minecraftforge.eventbus.api.SubscribeEvent; import net.minecraftforge.fml.common.Mod; +import oshi.jna.platform.mac.SystemB; import tschipp.carryon.CarryOnCommon; import tschipp.carryon.Constants; +import tschipp.carryon.carry.CarryOnDataCapabilityProvider; import tschipp.carryon.common.carry.CarryOnData; import tschipp.carryon.common.carry.CarryOnData.CarryType; import tschipp.carryon.common.carry.CarryOnDataManager; @@ -60,6 +66,8 @@ import tschipp.carryon.common.carry.PickupHandler; import tschipp.carryon.common.carry.PlacementHandler; import tschipp.carryon.common.scripting.ScriptReloadListener; import tschipp.carryon.config.ConfigLoader; +import tschipp.carryon.networking.ClientboundSyncCarryDataPacket; +import tschipp.carryon.platform.Services; @Mod.EventBusSubscriber(bus = Mod.EventBusSubscriber.Bus.FORGE, modid = Constants.MOD_ID) public class CommonEvents @@ -185,8 +193,16 @@ public class CommonEvents @SubscribeEvent public static void onClone(Clone event) { - if (!event.getOriginal().level().isClientSide) - PlacementHandler.placeCarriedOnDeath((ServerPlayer) event.getOriginal(), (ServerPlayer) event.getEntity(), event.isWasDeath()); + if (!event.getOriginal().level().isClientSide) { + Player newPlayer = event.getEntity(); + Player oldPlayer = event.getOriginal(); + oldPlayer.reviveCaps(); + + PlacementHandler.placeCarriedOnDeath((ServerPlayer) oldPlayer, (ServerPlayer) newPlayer, event.isWasDeath()); + + oldPlayer.invalidateCaps(); + + } } @SubscribeEvent @@ -218,4 +234,31 @@ public class CommonEvents CarryOnCommon.onPlayerAttacked(player); } + @SubscribeEvent + public static void onPlayerLoggedOut(PlayerEvent.PlayerLoggedOutEvent event) { + if(event.getEntity() instanceof ServerPlayer player) + CarryOnCommon.onRiderDisconnected(player); + } + + @SubscribeEvent + public static void onAttachCapabilities(AttachCapabilitiesEvent event) { + if (event.getObject() instanceof Player player) { + event.addCapability(ResourceLocation.fromNamespaceAndPath(Constants.MOD_ID, "carry_on_data"), new CarryOnDataCapabilityProvider()); + } + } + + @SubscribeEvent + public static void onStartTracking(PlayerEvent.StartTracking event) { + if(event.getEntity() instanceof ServerPlayer sp && event.getTarget() instanceof ServerPlayer target) { + Services.PLATFORM.sendPacketToPlayer(Constants.PACKET_ID_SYNC_CARRY_ON_DATA, new ClientboundSyncCarryDataPacket(sp.getId(), CarryOnDataManager.getCarryData(sp)), target); + } + } + + @SubscribeEvent + public static void onJoinWorld(EntityJoinLevelEvent event) { + if (event.getEntity() instanceof ServerPlayer sp) { + Services.PLATFORM.sendPacketToPlayer(Constants.PACKET_ID_SYNC_CARRY_ON_DATA, new ClientboundSyncCarryDataPacket(sp.getId(), CarryOnDataManager.getCarryData(sp)), sp); + } + } + } diff --git a/Forge/src/main/java/tschipp/carryon/networking/ClientboundSyncCarryDataPacket.java b/Forge/src/main/java/tschipp/carryon/networking/ClientboundSyncCarryDataPacket.java new file mode 100644 index 0000000..25e37c4 --- /dev/null +++ b/Forge/src/main/java/tschipp/carryon/networking/ClientboundSyncCarryDataPacket.java @@ -0,0 +1,36 @@ +package tschipp.carryon.networking; + +import net.minecraft.network.RegistryFriendlyByteBuf; +import net.minecraft.network.codec.ByteBufCodecs; +import net.minecraft.network.codec.StreamCodec; +import net.minecraft.network.protocol.common.custom.CustomPacketPayload; +import net.minecraft.world.entity.Entity; +import net.minecraft.world.entity.player.Player; +import tschipp.carryon.Constants; +import tschipp.carryon.common.carry.CarryOnData; +import tschipp.carryon.common.carry.CarryOnDataManager; +import tschipp.carryon.networking.clientbound.ClientboundStartRidingPacket; + +public record ClientboundSyncCarryDataPacket(int iden, CarryOnData data) implements PacketBase { + + public static final StreamCodec CODEC = StreamCodec.composite( + ByteBufCodecs.INT, ClientboundSyncCarryDataPacket::iden, + CarryOnData.STREAM_CODEC, ClientboundSyncCarryDataPacket::data, + ClientboundSyncCarryDataPacket::new + ); + + public static final CustomPacketPayload.Type TYPE = new Type<>(Constants.PACKET_ID_SYNC_CARRY_ON_DATA); + + @Override + public void handle(Player player) { + Entity e = player.level().getEntity(this.iden); + if(e instanceof Player p) { + CarryOnDataManager.setCarryData(p, data); + } + } + + @Override + public Type type() { + return TYPE; + } +} diff --git a/Forge/src/main/java/tschipp/carryon/platform/ForgePlatformHelper.java b/Forge/src/main/java/tschipp/carryon/platform/ForgePlatformHelper.java index 0d67a3d..54d6fbd 100644 --- a/Forge/src/main/java/tschipp/carryon/platform/ForgePlatformHelper.java +++ b/Forge/src/main/java/tschipp/carryon/platform/ForgePlatformHelper.java @@ -25,6 +25,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 net.minecraftforge.event.network.CustomPayloadEvent; @@ -34,8 +35,14 @@ import net.minecraftforge.network.NetworkDirection; import net.minecraftforge.network.PacketDistributor; import tschipp.carryon.CarryOnCommonClient; import tschipp.carryon.CarryOnForge; +import tschipp.carryon.Constants; +import tschipp.carryon.carry.CarryOnDataCapability; +import tschipp.carryon.carry.CarryOnDataCapabilityProvider; +import tschipp.carryon.carry.ICarryOnDataCapability; +import tschipp.carryon.common.carry.CarryOnData; import tschipp.carryon.config.BuiltConfig; import tschipp.carryon.config.forge.ConfigLoaderImpl; +import tschipp.carryon.networking.ClientboundSyncCarryDataPacket; import tschipp.carryon.networking.PacketBase; import tschipp.carryon.platform.services.IPlatformHelper; @@ -111,4 +118,19 @@ public class ForgePlatformHelper implements IPlatformHelper { { CarryOnForge.network.send(packet, PacketDistributor.PLAYER.with(player)); } + + @Override + public CarryOnData getCarryData(Player player) { + var cap = player.getCapability(CarryOnDataCapabilityProvider.CARRY_ON_DATA_CAPABILITY).orElse(new CarryOnDataCapability()); + return cap.getCarryData(); + } + + @Override + public void setCarryData(Player player, CarryOnData data) { + var cap = player.getCapability(CarryOnDataCapabilityProvider.CARRY_ON_DATA_CAPABILITY).orElse(new CarryOnDataCapability()); + cap.setCarryData(data); + if(!player.level().isClientSide) { + sendPacketToAllPlayers(Constants.PACKET_ID_SYNC_SCRIPTS, new ClientboundSyncCarryDataPacket(player.getId(), data), (ServerLevel) player.level()); + } + } } diff --git a/NeoForge/src/main/java/tschipp/carryon/CarryOnNeoForge.java b/NeoForge/src/main/java/tschipp/carryon/CarryOnNeoForge.java index f10e1ec..0984056 100644 --- a/NeoForge/src/main/java/tschipp/carryon/CarryOnNeoForge.java +++ b/NeoForge/src/main/java/tschipp/carryon/CarryOnNeoForge.java @@ -20,19 +20,38 @@ package tschipp.carryon; +import net.minecraft.nbt.CompoundTag; import net.neoforged.bus.api.IEventBus; import net.neoforged.bus.api.SubscribeEvent; import net.neoforged.fml.ModContainer; import net.neoforged.fml.common.Mod; import net.neoforged.fml.event.lifecycle.FMLCommonSetupEvent; +import net.neoforged.neoforge.attachment.AttachmentType; +import net.neoforged.neoforge.client.gui.ConfigurationScreen; import net.neoforged.neoforge.common.NeoForge; import net.neoforged.neoforge.network.event.RegisterPayloadHandlersEvent; import net.neoforged.neoforge.network.registration.PayloadRegistrar; +import net.neoforged.neoforge.registries.DeferredRegister; +import net.neoforged.neoforge.registries.NeoForgeRegistries; +import tschipp.carryon.carry.CarryOnDataSyncHandler; +import tschipp.carryon.common.carry.CarryOnData; import tschipp.carryon.config.neoforge.ConfigLoaderImpl; +import java.util.function.Supplier; + @Mod(Constants.MOD_ID) public class CarryOnNeoForge { + private static final DeferredRegister> ATTACHMENT_TYPES = DeferredRegister.create(NeoForgeRegistries.ATTACHMENT_TYPES, Constants.MOD_ID); + + public static final Supplier> CARRY_ON_DATA_ATTACHMENT = ATTACHMENT_TYPES.register( + "carry_on_data", + () -> AttachmentType.builder(() -> new CarryOnData(new CompoundTag())) + .sync(new CarryOnDataSyncHandler()) + .serialize(CarryOnData.CODEC.fieldOf(CarryOnData.SERIALIZATION_KEY)) + .build() + ); + public CarryOnNeoForge(ModContainer container) { // This method is invoked by the Forge mod loader when it is ready @@ -44,6 +63,8 @@ public class CarryOnNeoForge { container.getEventBus().addListener(this::registerPackets); ConfigLoaderImpl.initialize(container); + + ATTACHMENT_TYPES.register(container.getEventBus()); } private void setup(final FMLCommonSetupEvent event) diff --git a/NeoForge/src/main/java/tschipp/carryon/carry/CarryOnDataSyncHandler.java b/NeoForge/src/main/java/tschipp/carryon/carry/CarryOnDataSyncHandler.java new file mode 100644 index 0000000..f9d8901 --- /dev/null +++ b/NeoForge/src/main/java/tschipp/carryon/carry/CarryOnDataSyncHandler.java @@ -0,0 +1,26 @@ +package tschipp.carryon.carry; + +import net.minecraft.network.RegistryFriendlyByteBuf; +import net.minecraft.server.level.ServerPlayer; +import net.neoforged.neoforge.attachment.IAttachmentHolder; +import org.jetbrains.annotations.Nullable; +import tschipp.carryon.common.carry.CarryOnData; + +public class CarryOnDataSyncHandler implements AttachmentSyncHandler { + @Override + public void write(RegistryFriendlyByteBuf registryFriendlyByteBuf, CarryOnData carryOnData, boolean b) { + CarryOnData.STREAM_CODEC.encode(registryFriendlyByteBuf, carryOnData); + } + + @Override + public @Nullable CarryOnData read(IAttachmentHolder iAttachmentHolder, RegistryFriendlyByteBuf registryFriendlyByteBuf, @Nullable CarryOnData carryOnData) { + return CarryOnData.STREAM_CODEC.decode(registryFriendlyByteBuf); + } + + @Override + public boolean sendToPlayer(IAttachmentHolder holder, ServerPlayer to) { + if (to.connection == null) + return false; + return AttachmentSyncHandler.super.sendToPlayer(holder, to); + } +} diff --git a/NeoForge/src/main/java/tschipp/carryon/platform/NeoForgePlatformHelper.java b/NeoForge/src/main/java/tschipp/carryon/platform/NeoForgePlatformHelper.java index 410896c..8315834 100644 --- a/NeoForge/src/main/java/tschipp/carryon/platform/NeoForgePlatformHelper.java +++ b/NeoForge/src/main/java/tschipp/carryon/platform/NeoForgePlatformHelper.java @@ -20,6 +20,7 @@ package tschipp.carryon.platform; +import net.minecraft.nbt.CompoundTag; import io.netty.buffer.ByteBuf; import net.minecraft.network.FriendlyByteBuf; import net.minecraft.network.RegistryFriendlyByteBuf; @@ -36,6 +37,10 @@ import net.neoforged.neoforge.network.PacketDistributor; import net.neoforged.neoforge.network.handling.IPayloadHandler; import net.neoforged.neoforge.network.registration.PayloadRegistrar; import tschipp.carryon.CarryOnCommonClient; +import tschipp.carryon.CarryOnNeoForge; +import tschipp.carryon.CarryOnNeoForgeClient; +import tschipp.carryon.common.carry.CarryOnData; +import tschipp.carryon.common.carry.CarryOnData; import tschipp.carryon.config.BuiltConfig; import tschipp.carryon.config.neoforge.ConfigLoaderImpl; import tschipp.carryon.networking.PacketBase; @@ -100,11 +105,21 @@ public class NeoForgePlatformHelper implements IPlatformHelper { @Override public void sendPacketToServer(ResourceLocation id, PacketBase packet) { - PacketDistributor.sendToServer(packet); + CarryOnNeoForgeClient.sendPacketToServer(packet); } @Override public void sendPacketToPlayer(ResourceLocation id, PacketBase packet, ServerPlayer player) { PacketDistributor.sendToPlayer(player, packet); } + + @Override + public CarryOnData getCarryData(Player player) { + return player.getData(CarryOnNeoForge.CARRY_ON_DATA_ATTACHMENT); + } + + @Override + public void setCarryData(Player player, CarryOnData data) { + player.setData(CarryOnNeoForge.CARRY_ON_DATA_ATTACHMENT, data); + } }