From 9481cba44f0ebc54ee41deda8da1a64054b94b46 Mon Sep 17 00:00:00 2001 From: Pyrofab Date: Mon, 15 Apr 2024 22:10:28 +0200 Subject: [PATCH] Allow client-optional components --- .../cca/api/v3/component/ComponentKey.java | 13 +++++-- .../api/v3/component/ComponentProvider.java | 9 ++--- .../component/sync/PlayerSyncPredicate.java | 8 +++++ .../cca/internal/base/CcaClientInternals.java | 6 ++-- .../internal/base/ComponentUpdatePayload.java | 23 ++++++++++--- .../internal/base/ComponentsInternals.java | 5 +++ .../cca/internal/base/MorePacketCodecs.java | 34 ------------------- .../base/UnknownComponentException.java | 29 ++++++++++++++++ .../cca/internal/CcaBlockClient.java | 4 +-- .../mixin/block/common/MixinBlockEntity.java | 5 +-- .../cca/internal/chunk/CcaChunkClient.java | 4 +-- .../mixin/chunk/common/MixinWorldChunk.java | 5 +-- .../cca/internal/entity/CcaEntityClient.java | 4 ++- .../cca/mixin/entity/common/MixinEntity.java | 5 +-- .../api/v3/item/ItemComponentInitializer.java | 1 + .../cca/internal/level/CcaLevelClient.java | 4 ++- .../level/common/MixinLevelProperties.java | 5 +-- .../scoreboard/CcaScoreboardClient.java | 8 +++-- .../scoreboard/MixinServerScoreboard.java | 5 +-- .../cca/mixin/scoreboard/MixinTeam.java | 5 +-- cardinal-components-world/build.gradle.kts | 1 + .../cca/internal/world/CcaWorldClient.java | 4 ++- .../mixin/world/common/MixinServerWorld.java | 5 +-- .../ladysnake/cca/test/world/AmbientVita.java | 5 +++ 24 files changed, 127 insertions(+), 70 deletions(-) create mode 100644 cardinal-components-base/src/main/java/org/ladysnake/cca/internal/base/UnknownComponentException.java diff --git a/cardinal-components-base/src/main/java/org/ladysnake/cca/api/v3/component/ComponentKey.java b/cardinal-components-base/src/main/java/org/ladysnake/cca/api/v3/component/ComponentKey.java index fc6a172b..e1fdfdc1 100644 --- a/cardinal-components-base/src/main/java/org/ladysnake/cca/api/v3/component/ComponentKey.java +++ b/cardinal-components-base/src/main/java/org/ladysnake/cca/api/v3/component/ComponentKey.java @@ -31,6 +31,7 @@ import net.minecraft.network.codec.PacketCodecs; import net.minecraft.network.packet.CustomPayload; import net.minecraft.server.network.ServerPlayerEntity; +import net.minecraft.text.Text; import net.minecraft.util.Identifier; import org.jetbrains.annotations.ApiStatus; import org.jetbrains.annotations.Contract; @@ -38,6 +39,7 @@ import org.ladysnake.cca.api.v3.component.sync.AutoSyncedComponent; import org.ladysnake.cca.api.v3.component.sync.ComponentPacketWriter; import org.ladysnake.cca.api.v3.component.sync.PlayerSyncPredicate; +import org.ladysnake.cca.internal.base.ComponentsInternals; import org.ladysnake.cca.internal.base.asm.CcaBootstrap; import java.util.NoSuchElementException; @@ -209,10 +211,17 @@ public void syncWith(ServerPlayerEntity player, ComponentProvider provider, Comp if (predicate.shouldSyncWith(player)) { RegistryByteBuf buf = new RegistryByteBuf(Unpooled.buffer(), player.getServerWorld().getRegistryManager()); writer.writeSyncPacket(buf, player); - CustomPayload payload = provider.toComponentPacket(this, buf); + CustomPayload payload = provider.toComponentPacket(this, !predicate.isSyncOptional(), buf); if (payload != null) { - ServerPlayNetworking.getSender(player).sendPacket(payload, PacketCallbacks.always(buf::release)); + if (ServerPlayNetworking.canSend(player, payload.getId())) { + ServerPlayNetworking.getSender(player).sendPacket(payload, PacketCallbacks.always(buf::release)); + } else { + if (!predicate.isSyncOptional()) { + player.networkHandler.disconnect(Text.literal("This server requires Cardinal Components API (unhandled packet: " + payload.getId().id() + ")" + ComponentsInternals.getClientOptionalModAdvice())); + } + buf.release(); + } } else { buf.release(); } diff --git a/cardinal-components-base/src/main/java/org/ladysnake/cca/api/v3/component/ComponentProvider.java b/cardinal-components-base/src/main/java/org/ladysnake/cca/api/v3/component/ComponentProvider.java index 67030cd0..b96c446e 100644 --- a/cardinal-components-base/src/main/java/org/ladysnake/cca/api/v3/component/ComponentProvider.java +++ b/cardinal-components-base/src/main/java/org/ladysnake/cca/api/v3/component/ComponentProvider.java @@ -26,11 +26,11 @@ import net.minecraft.network.RegistryByteBuf; import net.minecraft.network.packet.CustomPayload; import net.minecraft.server.network.ServerPlayerEntity; +import org.jetbrains.annotations.Nullable; import org.ladysnake.cca.api.v3.component.sync.AutoSyncedComponent; import org.ladysnake.cca.api.v3.component.sync.PlayerSyncPredicate; import org.ladysnake.cca.internal.base.ComponentUpdatePayload; -import javax.annotation.Nullable; import java.util.List; /** @@ -64,13 +64,14 @@ default Iterable getRecipientsForComponentSync() { * *

It is the responsibility of the caller to {@link ByteBuf#release() release} the buffer after this method returns. * - * @param key the key describing the component being synchronized - * @param data the component's raw sync data + * @param key the key describing the component being synchronized + * @param required {@code true} if attempting to sync a component key unknown to the client should disconnect it + * @param data the component's raw sync data * @return a {@link ComponentUpdatePayload} that has all the information required to perform the component sync * @since 6.0.0 */ @Nullable - default CustomPayload toComponentPacket(ComponentKey key, RegistryByteBuf data) { + default CustomPayload toComponentPacket(ComponentKey key, boolean required, RegistryByteBuf data) { return null; } } diff --git a/cardinal-components-base/src/main/java/org/ladysnake/cca/api/v3/component/sync/PlayerSyncPredicate.java b/cardinal-components-base/src/main/java/org/ladysnake/cca/api/v3/component/sync/PlayerSyncPredicate.java index e5985b0c..e29e9d57 100644 --- a/cardinal-components-base/src/main/java/org/ladysnake/cca/api/v3/component/sync/PlayerSyncPredicate.java +++ b/cardinal-components-base/src/main/java/org/ladysnake/cca/api/v3/component/sync/PlayerSyncPredicate.java @@ -30,6 +30,14 @@ public interface PlayerSyncPredicate { @Contract(pure = true) boolean shouldSyncWith(ServerPlayerEntity player); + /** + * If this method returns {@code true} and a client cannot handle a sync packet, the sync will be skipped. + * Otherwise, a sync update will disconnect the client. + */ + default boolean isSyncOptional() { + return false; + } + static PlayerSyncPredicate all() { return p -> true; } diff --git a/cardinal-components-base/src/main/java/org/ladysnake/cca/internal/base/CcaClientInternals.java b/cardinal-components-base/src/main/java/org/ladysnake/cca/internal/base/CcaClientInternals.java index 8530d43b..f5737e7c 100644 --- a/cardinal-components-base/src/main/java/org/ladysnake/cca/internal/base/CcaClientInternals.java +++ b/cardinal-components-base/src/main/java/org/ladysnake/cca/internal/base/CcaClientInternals.java @@ -24,6 +24,7 @@ import net.fabricmc.fabric.api.client.networking.v1.ClientPlayNetworking; import net.minecraft.network.packet.CustomPayload; +import net.minecraft.text.Text; import org.ladysnake.cca.api.v3.component.Component; import org.ladysnake.cca.api.v3.component.sync.AutoSyncedComponent; @@ -31,7 +32,7 @@ import java.util.function.BiFunction; public final class CcaClientInternals { - public static > void registerComponentSync(CustomPayload.Id packetId, BiFunction> getter) { + public static > void registerComponentSync(CustomPayload.Id packetId, BiFunction> getter) { ClientPlayNetworking.registerGlobalReceiver(packetId, (payload, ctx) -> { try { getter.apply(payload, ctx).ifPresent(c -> { @@ -39,10 +40,11 @@ public static ( Id> id, T targetData, - ComponentKey componentKey, + boolean required, + Identifier componentKeyId, RegistryByteBuf buf ) implements CustomPayload { public static CustomPayload.Id> id(String path) { @@ -43,15 +49,24 @@ public static void register(Id> id, PacketCodec PacketCodec> codec(Id> id, PacketCodec targetDataCodec) { - return org.ladysnake.cca.internal.base.MorePacketCodecs.tuple( + return PacketCodec.tuple( PacketCodec.unit(id), ComponentUpdatePayload::id, targetDataCodec, ComponentUpdatePayload::targetData, - ComponentKey.PACKET_CODEC, ComponentUpdatePayload::componentKey, - org.ladysnake.cca.internal.base.MorePacketCodecs.REG_BYTE_BUF, ComponentUpdatePayload::buf, + PacketCodecs.BOOL, ComponentUpdatePayload::required, + Identifier.PACKET_CODEC, ComponentUpdatePayload::componentKeyId, + MorePacketCodecs.REG_BYTE_BUF, ComponentUpdatePayload::buf, ComponentUpdatePayload::new ); } + public Optional> componentKey() { + ComponentKey key = ComponentRegistry.get(this.componentKeyId()); + if (key == null && this.required()) { + throw new UnknownComponentException("Unknown component " + this.componentKeyId()); + } + return Optional.ofNullable(key); + } + @Override public Id getId() { return id; diff --git a/cardinal-components-base/src/main/java/org/ladysnake/cca/internal/base/ComponentsInternals.java b/cardinal-components-base/src/main/java/org/ladysnake/cca/internal/base/ComponentsInternals.java index 334806be..31c42673 100644 --- a/cardinal-components-base/src/main/java/org/ladysnake/cca/internal/base/ComponentsInternals.java +++ b/cardinal-components-base/src/main/java/org/ladysnake/cca/internal/base/ComponentsInternals.java @@ -26,6 +26,7 @@ import net.minecraft.util.Identifier; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; +import org.jetbrains.annotations.NotNull; import org.ladysnake.cca.api.v3.component.ComponentRegistry; import org.ladysnake.cca.internal.base.asm.StaticComponentLoadingException; @@ -93,4 +94,8 @@ public static void logDeserializationWarnings(Collection missedKeyIds) { } } } + + public static @NotNull String getClientOptionalModAdvice() { + return FabricLoader.getInstance().isDevelopmentEnvironment() ? "\n§eDEV ADVICE: If your mod is supposed to be client-optional, try overriding isSyncOptional() in your component." : ""; + } } diff --git a/cardinal-components-base/src/main/java/org/ladysnake/cca/internal/base/MorePacketCodecs.java b/cardinal-components-base/src/main/java/org/ladysnake/cca/internal/base/MorePacketCodecs.java index 5a4aeb4d..fc3655c4 100644 --- a/cardinal-components-base/src/main/java/org/ladysnake/cca/internal/base/MorePacketCodecs.java +++ b/cardinal-components-base/src/main/java/org/ladysnake/cca/internal/base/MorePacketCodecs.java @@ -22,7 +22,6 @@ */ package org.ladysnake.cca.internal.base; -import com.mojang.datafixers.util.Function4; import com.mojang.datafixers.util.Unit; import io.netty.buffer.ByteBuf; import io.netty.buffer.Unpooled; @@ -31,8 +30,6 @@ import net.minecraft.network.codec.PacketCodec; import net.minecraft.util.math.ChunkPos; -import java.util.function.Function; - public final class MorePacketCodecs { public static final PacketCodec EMPTY = PacketCodec.unit(Unit.INSTANCE); @@ -59,35 +56,4 @@ public final class MorePacketCodecs { PacketByteBuf::writeChunkPos, PacketByteBuf::readChunkPos ); - - /** - * {@return a codec for encoding three values} - */ - public static PacketCodec tuple( - PacketCodec codec1, - Function from1, - PacketCodec codec2, - Function from2, - PacketCodec codec3, - Function from3, - PacketCodec codec4, - Function from4, - Function4 to - ) { - return PacketCodec.ofStatic( - (buf, value) -> { - codec1.encode(buf, from1.apply(value)); - codec2.encode(buf, from2.apply(value)); - codec3.encode(buf, from3.apply(value)); - codec4.encode(buf, from4.apply(value)); - }, - (buf) -> { - T1 object2 = codec1.decode(buf); - T2 object3 = codec2.decode(buf); - T3 object4 = codec3.decode(buf); - T4 object5 = codec4.decode(buf); - return to.apply(object2, object3, object4, object5); - } - ); - } } diff --git a/cardinal-components-base/src/main/java/org/ladysnake/cca/internal/base/UnknownComponentException.java b/cardinal-components-base/src/main/java/org/ladysnake/cca/internal/base/UnknownComponentException.java new file mode 100644 index 00000000..e301b901 --- /dev/null +++ b/cardinal-components-base/src/main/java/org/ladysnake/cca/internal/base/UnknownComponentException.java @@ -0,0 +1,29 @@ +/* + * Cardinal-Components-API + * Copyright (C) 2019-2024 Ladysnake + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, + * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR + * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE + * OR OTHER DEALINGS IN THE SOFTWARE. + */ +package org.ladysnake.cca.internal.base; + +public class UnknownComponentException extends RuntimeException { + public UnknownComponentException(String message) { + super(message); + } +} diff --git a/cardinal-components-block/src/main/java/org/ladysnake/cca/internal/CcaBlockClient.java b/cardinal-components-block/src/main/java/org/ladysnake/cca/internal/CcaBlockClient.java index 7a30cd97..8b4ef6b0 100644 --- a/cardinal-components-block/src/main/java/org/ladysnake/cca/internal/CcaBlockClient.java +++ b/cardinal-components-block/src/main/java/org/ladysnake/cca/internal/CcaBlockClient.java @@ -31,11 +31,11 @@ public class CcaBlockClient { public static void initClient() { if (FabricLoader.getInstance().isModLoaded("fabric-networking-api-v1")) { CcaClientInternals.registerComponentSync(CardinalComponentsBlock.PACKET_ID, - (payload, ctx) -> payload.componentKey().maybeGet(payload.targetData().beType().get( + (payload, ctx) -> payload.componentKey().flatMap(key -> key.maybeGet(payload.targetData().beType().get( ctx.client().world, payload.targetData().bePos() )) - ); + )); } if (FabricLoader.getInstance().isModLoaded("fabric-lifecycle-events-v1")) { ClientBlockEntityEvents.BLOCK_ENTITY_LOAD.register((be, world) -> ((ComponentProvider) be).getComponentContainer().onServerLoad()); diff --git a/cardinal-components-block/src/main/java/org/ladysnake/cca/mixin/block/common/MixinBlockEntity.java b/cardinal-components-block/src/main/java/org/ladysnake/cca/mixin/block/common/MixinBlockEntity.java index 873ddbc8..de23dd30 100644 --- a/cardinal-components-block/src/main/java/org/ladysnake/cca/mixin/block/common/MixinBlockEntity.java +++ b/cardinal-components-block/src/main/java/org/ladysnake/cca/mixin/block/common/MixinBlockEntity.java @@ -101,11 +101,12 @@ public Iterable getRecipientsForComponentSync() { } @Override - public ComponentUpdatePayload toComponentPacket(ComponentKey key, RegistryByteBuf data) { + public ComponentUpdatePayload toComponentPacket(ComponentKey key, boolean required, RegistryByteBuf data) { return new ComponentUpdatePayload<>( CardinalComponentsBlock.PACKET_ID, new BlockEntityAddress(this.getType(), this.getPos()), - key, + required, + key.getId(), data ); } diff --git a/cardinal-components-chunk/src/main/java/org/ladysnake/cca/internal/chunk/CcaChunkClient.java b/cardinal-components-chunk/src/main/java/org/ladysnake/cca/internal/chunk/CcaChunkClient.java index 0413f84c..aef1b825 100644 --- a/cardinal-components-chunk/src/main/java/org/ladysnake/cca/internal/chunk/CcaChunkClient.java +++ b/cardinal-components-chunk/src/main/java/org/ladysnake/cca/internal/chunk/CcaChunkClient.java @@ -34,11 +34,11 @@ public static void initClient() { if (FabricLoader.getInstance().isModLoaded("fabric-networking-api-v1")) { CcaClientInternals.registerComponentSync( CardinalComponentsChunk.PACKET_ID, - (payload, ctx) -> payload.componentKey().maybeGet(Objects.requireNonNull(ctx.client().world).getChunk( + (payload, ctx) -> payload.componentKey().flatMap(key -> key.maybeGet(Objects.requireNonNull(ctx.client().world).getChunk( payload.targetData().x, payload.targetData().z )) - ); + )); } if (FabricLoader.getInstance().isModLoaded("fabric-lifecycle-events-v1")) { ClientChunkEvents.CHUNK_LOAD.register((world, chunk) -> ((ComponentProvider) chunk).getComponentContainer().onServerLoad()); diff --git a/cardinal-components-chunk/src/main/java/org/ladysnake/cca/mixin/chunk/common/MixinWorldChunk.java b/cardinal-components-chunk/src/main/java/org/ladysnake/cca/mixin/chunk/common/MixinWorldChunk.java index 19832844..01834376 100644 --- a/cardinal-components-chunk/src/main/java/org/ladysnake/cca/mixin/chunk/common/MixinWorldChunk.java +++ b/cardinal-components-chunk/src/main/java/org/ladysnake/cca/mixin/chunk/common/MixinWorldChunk.java @@ -69,11 +69,12 @@ public Iterable getRecipientsForComponentSync() { } @Override - public @javax.annotation.Nullable ComponentUpdatePayload toComponentPacket(ComponentKey key, RegistryByteBuf data) { + public @Nullable ComponentUpdatePayload toComponentPacket(ComponentKey key, boolean required, RegistryByteBuf data) { return new ComponentUpdatePayload<>( CardinalComponentsChunk.PACKET_ID, this.getPos(), - key, + required, + key.getId(), data ); } diff --git a/cardinal-components-entity/src/main/java/org/ladysnake/cca/internal/entity/CcaEntityClient.java b/cardinal-components-entity/src/main/java/org/ladysnake/cca/internal/entity/CcaEntityClient.java index 4f89e32c..97b060c5 100644 --- a/cardinal-components-entity/src/main/java/org/ladysnake/cca/internal/entity/CcaEntityClient.java +++ b/cardinal-components-entity/src/main/java/org/ladysnake/cca/internal/entity/CcaEntityClient.java @@ -34,7 +34,9 @@ public static void initClient() { if (FabricLoader.getInstance().isModLoaded("fabric-networking-api-v1")) { CcaClientInternals.registerComponentSync( CardinalComponentsEntity.PACKET_ID, - (payload, ctx) -> payload.componentKey().maybeGet(Objects.requireNonNull(ctx.client().world).getEntityById(payload.targetData())) + (payload, ctx) -> payload.componentKey().flatMap( + key -> key.maybeGet(Objects.requireNonNull(ctx.client().world).getEntityById(payload.targetData())) + ) ); } if (FabricLoader.getInstance().isModLoaded("fabric-lifecycle-events-v1")) { diff --git a/cardinal-components-entity/src/main/java/org/ladysnake/cca/mixin/entity/common/MixinEntity.java b/cardinal-components-entity/src/main/java/org/ladysnake/cca/mixin/entity/common/MixinEntity.java index 8eff7908..4c893bb6 100644 --- a/cardinal-components-entity/src/main/java/org/ladysnake/cca/mixin/entity/common/MixinEntity.java +++ b/cardinal-components-entity/src/main/java/org/ladysnake/cca/mixin/entity/common/MixinEntity.java @@ -93,11 +93,12 @@ public Iterable getRecipientsForComponentSync() { } @Override - public ComponentUpdatePayload toComponentPacket(ComponentKey key, RegistryByteBuf data) { + public ComponentUpdatePayload toComponentPacket(ComponentKey key, boolean required, RegistryByteBuf data) { return new ComponentUpdatePayload<>( CardinalComponentsEntity.PACKET_ID, this.getId(), - key, + required, + key.getId(), data ); } diff --git a/cardinal-components-item/src/main/java/org/ladysnake/cca/api/v3/item/ItemComponentInitializer.java b/cardinal-components-item/src/main/java/org/ladysnake/cca/api/v3/item/ItemComponentInitializer.java index 71cd2c3a..05dc33ac 100644 --- a/cardinal-components-item/src/main/java/org/ladysnake/cca/api/v3/item/ItemComponentInitializer.java +++ b/cardinal-components-item/src/main/java/org/ladysnake/cca/api/v3/item/ItemComponentInitializer.java @@ -38,6 +38,7 @@ public interface ItemComponentInitializer extends ComponentRegistrationInitializ * Called to register component migrations from CCA to {@link net.minecraft.component.DataComponentType}. * * @param registry an {@link ItemComponentMigrationRegistry} for component migrations + * @since 7.0.0 */ void registerItemComponentMigrations(ItemComponentMigrationRegistry registry); } diff --git a/cardinal-components-level/src/main/java/org/ladysnake/cca/internal/level/CcaLevelClient.java b/cardinal-components-level/src/main/java/org/ladysnake/cca/internal/level/CcaLevelClient.java index 9e33e823..f0db0c52 100644 --- a/cardinal-components-level/src/main/java/org/ladysnake/cca/internal/level/CcaLevelClient.java +++ b/cardinal-components-level/src/main/java/org/ladysnake/cca/internal/level/CcaLevelClient.java @@ -32,7 +32,9 @@ public static void initClient() { if (FabricLoader.getInstance().isModLoaded("fabric-networking-api-v1")) { CcaClientInternals.registerComponentSync( CardinalComponentsLevel.PACKET_ID, - (payload, ctx) -> payload.componentKey().maybeGet(Objects.requireNonNull(ctx.client().world).getLevelProperties()) + (payload, ctx) -> payload.componentKey().flatMap( + key -> key.maybeGet(Objects.requireNonNull(ctx.client().world).getLevelProperties()) + ) ); } } diff --git a/cardinal-components-level/src/main/java/org/ladysnake/cca/mixin/level/common/MixinLevelProperties.java b/cardinal-components-level/src/main/java/org/ladysnake/cca/mixin/level/common/MixinLevelProperties.java index 4f3a90a8..f369ff42 100644 --- a/cardinal-components-level/src/main/java/org/ladysnake/cca/mixin/level/common/MixinLevelProperties.java +++ b/cardinal-components-level/src/main/java/org/ladysnake/cca/mixin/level/common/MixinLevelProperties.java @@ -87,11 +87,12 @@ public Iterable getRecipientsForComponentSync() { } @Override - public ComponentUpdatePayload toComponentPacket(ComponentKey key, RegistryByteBuf data) { + public ComponentUpdatePayload toComponentPacket(ComponentKey key, boolean required, RegistryByteBuf data) { return new ComponentUpdatePayload<>( CardinalComponentsLevel.PACKET_ID, Unit.INSTANCE, - key, + required, + key.getId(), data ); } diff --git a/cardinal-components-scoreboard/src/main/java/org/ladysnake/cca/internal/scoreboard/CcaScoreboardClient.java b/cardinal-components-scoreboard/src/main/java/org/ladysnake/cca/internal/scoreboard/CcaScoreboardClient.java index a8164872..7bd120f8 100644 --- a/cardinal-components-scoreboard/src/main/java/org/ladysnake/cca/internal/scoreboard/CcaScoreboardClient.java +++ b/cardinal-components-scoreboard/src/main/java/org/ladysnake/cca/internal/scoreboard/CcaScoreboardClient.java @@ -32,11 +32,13 @@ public static void initClient() { if (FabricLoader.getInstance().isModLoaded("fabric-networking-api-v1")) { CcaClientInternals.registerComponentSync( CardinalComponentsScoreboard.TEAM_PACKET_ID, - (payload, ctx) -> payload.componentKey().maybeGet(Objects.requireNonNull(ctx.client().world).getScoreboard().getTeam(payload.targetData())) - ); + (payload, ctx) -> payload.componentKey().flatMap(key -> key.maybeGet(Objects.requireNonNull(ctx.client().world).getScoreboard().getTeam(payload.targetData())) + )); CcaClientInternals.registerComponentSync( CardinalComponentsScoreboard.SCOREBOARD_PACKET_ID, - (payload, ctx) -> payload.componentKey().maybeGet(Objects.requireNonNull(ctx.client().world).getScoreboard()) + (payload, ctx) -> payload.componentKey().flatMap( + key -> key.maybeGet(Objects.requireNonNull(ctx.client().world).getScoreboard()) + ) ); } } diff --git a/cardinal-components-scoreboard/src/main/java/org/ladysnake/cca/mixin/scoreboard/MixinServerScoreboard.java b/cardinal-components-scoreboard/src/main/java/org/ladysnake/cca/mixin/scoreboard/MixinServerScoreboard.java index 8dcf5951..729b3c04 100644 --- a/cardinal-components-scoreboard/src/main/java/org/ladysnake/cca/mixin/scoreboard/MixinServerScoreboard.java +++ b/cardinal-components-scoreboard/src/main/java/org/ladysnake/cca/mixin/scoreboard/MixinServerScoreboard.java @@ -67,11 +67,12 @@ public Iterable getRecipientsForComponentSync() { } @Override - public ComponentUpdatePayload toComponentPacket(ComponentKey key, RegistryByteBuf data) { + public ComponentUpdatePayload toComponentPacket(ComponentKey key, boolean required, RegistryByteBuf data) { return new ComponentUpdatePayload<>( CardinalComponentsScoreboard.SCOREBOARD_PACKET_ID, Unit.INSTANCE, - key, + required, + key.getId(), data ); } diff --git a/cardinal-components-scoreboard/src/main/java/org/ladysnake/cca/mixin/scoreboard/MixinTeam.java b/cardinal-components-scoreboard/src/main/java/org/ladysnake/cca/mixin/scoreboard/MixinTeam.java index d7555718..3555adeb 100644 --- a/cardinal-components-scoreboard/src/main/java/org/ladysnake/cca/mixin/scoreboard/MixinTeam.java +++ b/cardinal-components-scoreboard/src/main/java/org/ladysnake/cca/mixin/scoreboard/MixinTeam.java @@ -75,11 +75,12 @@ public Iterable getRecipientsForComponentSync() { } @Override - public ComponentUpdatePayload toComponentPacket(ComponentKey key, RegistryByteBuf data) { + public ComponentUpdatePayload toComponentPacket(ComponentKey key, boolean required, RegistryByteBuf data) { return new ComponentUpdatePayload<>( CardinalComponentsScoreboard.TEAM_PACKET_ID, this.getName(), - key, + required, + key.getId(), data ); } diff --git a/cardinal-components-world/build.gradle.kts b/cardinal-components-world/build.gradle.kts index 9ee03633..bfd1c5ef 100644 --- a/cardinal-components-world/build.gradle.kts +++ b/cardinal-components-world/build.gradle.kts @@ -3,5 +3,6 @@ dependencies { // (which we add to various classes through interface injection) api(project(path = ":cardinal-components-base", configuration = "namedElements")) annotationProcessor(project(path = ":cardinal-components-base", configuration = "namedElements")) + modLocalRuntime(fabricApi.module("fabric-gametest-api-v1", project.properties["fabric_api_version"].toString())) testmodImplementation(rootProject.project(":cardinal-components-base").sourceSets.testmod.get().output) } diff --git a/cardinal-components-world/src/main/java/org/ladysnake/cca/internal/world/CcaWorldClient.java b/cardinal-components-world/src/main/java/org/ladysnake/cca/internal/world/CcaWorldClient.java index 2613f421..5954a78e 100644 --- a/cardinal-components-world/src/main/java/org/ladysnake/cca/internal/world/CcaWorldClient.java +++ b/cardinal-components-world/src/main/java/org/ladysnake/cca/internal/world/CcaWorldClient.java @@ -30,7 +30,9 @@ public static void initClient() { if (FabricLoader.getInstance().isModLoaded("fabric-networking-api-v1")) { CcaClientInternals.registerComponentSync( CardinalComponentsWorld.PACKET_ID, - (payload, ctx) -> payload.componentKey().maybeGet(ctx.client().world) + (payload, ctx) -> payload.componentKey().flatMap( + key -> key.maybeGet(ctx.client().world) + ) ); } } diff --git a/cardinal-components-world/src/main/java/org/ladysnake/cca/mixin/world/common/MixinServerWorld.java b/cardinal-components-world/src/main/java/org/ladysnake/cca/mixin/world/common/MixinServerWorld.java index be0645b5..6848ec34 100644 --- a/cardinal-components-world/src/main/java/org/ladysnake/cca/mixin/world/common/MixinServerWorld.java +++ b/cardinal-components-world/src/main/java/org/ladysnake/cca/mixin/world/common/MixinServerWorld.java @@ -76,11 +76,12 @@ public Iterable getRecipientsForComponentSync() { } @Override - public ComponentUpdatePayload toComponentPacket(ComponentKey key, RegistryByteBuf data) { + public ComponentUpdatePayload toComponentPacket(ComponentKey key, boolean required, RegistryByteBuf data) { return new ComponentUpdatePayload<>( CardinalComponentsWorld.PACKET_ID, Unit.INSTANCE, - key, + required, + key.getId(), data ); } diff --git a/cardinal-components-world/src/testmod/java/org/ladysnake/cca/test/world/AmbientVita.java b/cardinal-components-world/src/testmod/java/org/ladysnake/cca/test/world/AmbientVita.java index cc56a8d7..a4176e31 100644 --- a/cardinal-components-world/src/testmod/java/org/ladysnake/cca/test/world/AmbientVita.java +++ b/cardinal-components-world/src/testmod/java/org/ladysnake/cca/test/world/AmbientVita.java @@ -76,6 +76,11 @@ public WorldVita(World world) { this.world = world; } + @Override + public boolean isSyncOptional() { + return true; + } + @Override public void syncWithAll(MinecraftServer server) { this.world.syncComponent(KEY);