Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -203,23 +203,24 @@ public void syncWith(ServerPlayer player, ComponentProvider provider) {
public void syncWith(ServerPlayer player, ComponentProvider provider, ComponentPacketWriter writer, PlayerSyncPredicate predicate) {
if (predicate.shouldSyncWith(player)) {
RegistryFriendlyByteBuf buf = new RegistryFriendlyByteBuf(Unpooled.buffer(), player.level().registryAccess());
writer.writeSyncPacket(buf, player);
CustomPacketPayload payload = provider.toComponentPacket(this, predicate.isRequiredOnClient(), buf);

if (payload != null) {
if (ServerPlayNetworking.canSend(player, payload.type())) {
ServerPlayNetworking.getSender(player).sendPacket(payload, PacketSendListener.thenRun(buf::release));
} else {
if (predicate.isRequiredOnClient()) {
String specificMod = FabricLoader.getInstance().getModContainer(this.id.getNamespace()).map(c -> c.getMetadata().getName() + " and ").orElse("");
player.connection.disconnect(literal(
"This server requires " + specificMod + "Cardinal Components API " +
"(unhandled packet: " + payload.type().id() + ")" +
ComponentsInternals.getClientOptionalModAdvice()));
try {
writer.writeSyncPacket(buf, player);
CustomPacketPayload payload = provider.toComponentPacket(this, predicate.isRequiredOnClient(), buf);
if (payload != null) {
if (ServerPlayNetworking.canSend(player, payload.type())) {
buf.retain(); // only release the buffer after the packet is sent, in case an implementation retains a reference to it
ServerPlayNetworking.getSender(player).sendPacket(payload, PacketSendListener.thenRun(buf::release));
} else {
if (predicate.isRequiredOnClient()) {
String specificMod = FabricLoader.getInstance().getModContainer(this.id.getNamespace()).map(c -> c.getMetadata().getName() + " and ").orElse("");
player.connection.disconnect(literal(
"This server requires " + specificMod + "Cardinal Components API " +
"(unhandled packet: " + payload.type().id() + ")" +
ComponentsInternals.getClientOptionalModAdvice()));
}
}
buf.release();
}
} else {
} finally {
buf.release();
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,6 @@
import org.jspecify.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 java.util.List;

Expand Down Expand Up @@ -67,7 +66,7 @@ default Iterable<ServerPlayer> getRecipientsForComponentSync() {
* @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
* @return a {@link CustomPacketPayload} that has all the information required to perform the component sync
* @since 6.0.0
*/
@Nullable
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,10 @@
*/
package org.ladysnake.cca.internal.base;

import io.netty.buffer.Unpooled;
import net.fabricmc.fabric.api.client.networking.v1.ClientPlayNetworking;
import net.minecraft.network.DisconnectionDetails;
import net.minecraft.network.RegistryFriendlyByteBuf;
import net.minecraft.network.protocol.common.custom.CustomPacketPayload;
import org.ladysnake.cca.api.v3.component.sync.AutoSyncedComponent;
import org.ladysnake.cca.api.v8.component.CardinalComponent;
Expand All @@ -39,15 +41,18 @@ public static <T extends ComponentUpdatePayload<?>> void registerComponentSync(C
try {
getter.apply(payload, ctx).ifPresent(c -> {
if (c instanceof AutoSyncedComponent synced) {
synced.applySyncPacket(payload.buf());
var buf = new RegistryFriendlyByteBuf(Unpooled.wrappedBuffer(payload.rawPayload()), ctx.client().level.registryAccess());
try {
synced.applySyncPacket(buf);
} finally {
buf.release();
}
}
});
} catch (UnknownComponentException e) {
ctx.player().connection.onDisconnect(new DisconnectionDetails(literal(
e.getMessage() + "\n(you are probably missing a mod installed on the server)" + ComponentsInternals.getClientOptionalModAdvice())
));
} finally {
payload.buf().release();
}
});
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ public record ComponentUpdatePayload<T>(
T targetData,
boolean required,
Identifier componentKeyId,
RegistryFriendlyByteBuf buf
byte[] rawPayload
) implements CustomPacketPayload {
public static <T> CustomPacketPayload.Type<ComponentUpdatePayload<T>> id(String path) {
return new CustomPacketPayload.Type<>(Identifier.fromNamespaceAndPath("cardinal-components", path));
Expand All @@ -54,7 +54,7 @@ public static <T> StreamCodec<RegistryFriendlyByteBuf, ComponentUpdatePayload<T>
targetDataCodec, ComponentUpdatePayload::targetData,
ByteBufCodecs.BOOL, ComponentUpdatePayload::required,
Identifier.STREAM_CODEC, ComponentUpdatePayload::componentKeyId,
MorePacketCodecs.REG_BYTE_BUF, ComponentUpdatePayload::buf,
ByteBufCodecs.BYTE_ARRAY, ComponentUpdatePayload::rawPayload,
ComponentUpdatePayload::new
);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,23 +24,8 @@

import com.mojang.datafixers.util.Unit;
import io.netty.buffer.ByteBuf;
import io.netty.buffer.Unpooled;
import net.minecraft.network.RegistryFriendlyByteBuf;
import net.minecraft.network.codec.StreamCodec;

public final class MorePacketCodecs {
public static final StreamCodec<ByteBuf, Unit> EMPTY = StreamCodec.unit(Unit.INSTANCE);

public static final StreamCodec<RegistryFriendlyByteBuf, RegistryFriendlyByteBuf> REG_BYTE_BUF = StreamCodec.of(
(buf, value) -> {
buf.writeVarInt(value.readableBytes());
buf.writeBytes(value);
},
(buf) -> {
int readableBytes = buf.readVarInt();
ByteBuf copy = Unpooled.buffer(readableBytes, readableBytes);
buf.readBytes(copy, readableBytes);
return new RegistryFriendlyByteBuf(copy, buf.registryAccess());
}
);
}
Original file line number Diff line number Diff line change
Expand Up @@ -109,7 +109,7 @@ public Iterable<ServerPlayer> getRecipientsForComponentSync() {
new BlockEntityAddress(this.getType(), this.getBlockPos(), world.dimension()),
required,
key.getId(),
data
data.array()
);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,7 @@ public Iterable<ServerPlayer> getRecipientsForComponentSync() {
this.getPos(),
required,
key.getId(),
data
data.array()
);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@
* Produces and sends a C2S update packet using the given information
*
* @param writer a {@link C2SComponentPacketWriter} writing the component's data to the packet
* @implNote the default implementation should generally be overridden.

Check warning on line 63 in cardinal-components-entity/src/main/java/org/ladysnake/cca/api/v3/entity/C2SSelfMessagingComponent.java

View workflow job for this annotation

GitHub Actions / build

unknown tag. Unregistered custom tag?

Check warning on line 63 in cardinal-components-entity/src/main/java/org/ladysnake/cca/api/v3/entity/C2SSelfMessagingComponent.java

View workflow job for this annotation

GitHub Actions / build

unknown tag. Unregistered custom tag?
* It finds the component key through a reverse component lookup on the client's main player object,
* which is inefficient and may even produce incorrect results in some edge cases.
* @see #sendC2SMessage(ComponentKey, C2SComponentPacketWriter)
Expand All @@ -82,7 +82,13 @@
static void sendC2SMessage(ComponentKey<?> key, C2SComponentPacketWriter writer) {
PacketSender sender = ClientPlayNetworking.getSender(); // checks that the player is in game
RegistryFriendlyByteBuf buf = new RegistryFriendlyByteBuf(FriendlyByteBufs.create(), Objects.requireNonNull(Minecraft.getInstance().getConnection()).registryAccess());
writer.writeC2SPacket(buf);
sender.sendPacket(new ComponentUpdatePayload<>(CardinalComponentsEntity.C2S_SELF_PACKET_ID, Unit.INSTANCE, true, key.getId(), buf), PacketSendListener.thenRun(buf::release));
byte[] bytes;
try {
writer.writeC2SPacket(buf);
bytes = buf.array();
} finally {
buf.release();
}
sender.sendPacket(new ComponentUpdatePayload<>(CardinalComponentsEntity.C2S_SELF_PACKET_ID, Unit.INSTANCE, true, key.getId(), bytes));
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -23,13 +23,15 @@
package org.ladysnake.cca.internal.entity;

import com.mojang.datafixers.util.Unit;
import io.netty.buffer.Unpooled;
import net.fabricmc.fabric.api.entity.event.v1.ServerLivingEntityEvents;
import net.fabricmc.fabric.api.entity.event.v1.ServerPlayerEvents;
import net.fabricmc.fabric.api.event.lifecycle.v1.ServerEntityEvents;
import net.fabricmc.fabric.api.networking.v1.PayloadTypeRegistry;
import net.fabricmc.fabric.api.networking.v1.ServerPlayNetworking;
import net.fabricmc.loader.api.FabricLoader;
import net.minecraft.core.HolderLookup;
import net.minecraft.network.RegistryFriendlyByteBuf;
import net.minecraft.network.codec.ByteBufCodecs;
import net.minecraft.network.protocol.common.ClientboundCustomPayloadPacket;
import net.minecraft.network.protocol.common.custom.CustomPacketPayload;
Expand Down Expand Up @@ -82,11 +84,12 @@ public static void init() {
PlayerSyncCallback.EVENT.register(player -> syncEntityComponents(player, player));
TrackingStartCallback.EVENT.register(CardinalComponentsEntity::syncEntityComponents);
ServerPlayNetworking.registerGlobalReceiver(CardinalComponentsEntity.C2S_SELF_PACKET_ID, (payload, ctx) -> {
var buf = new RegistryFriendlyByteBuf(Unpooled.wrappedBuffer(payload.rawPayload()), ctx.player().registryAccess());
try {
Optional<ComponentKey<?>> componentKey = payload.componentKey();
if (componentKey.isPresent()) {
if (componentKey.get().getNullable(ctx.player()) instanceof C2SSelfMessagingComponent synced) {
synced.handleC2SMessage(payload.buf());
synced.handleC2SMessage(buf);
} else if (payload.required() && (unknownC2SPlayerComponents.add(payload.componentKeyId()) || FabricLoader.getInstance().isDevelopmentEnvironment())) {
// In prod, only log the first time an unknown component update is received
ComponentsInternals.LOGGER.warn("[Cardinal Components API] Received an update for component {} from player {}, but this component is not registered for player entities", payload.componentKeyId(), ctx.player());
Expand All @@ -95,7 +98,7 @@ public static void init() {
ComponentsInternals.LOGGER.warn("[Cardinal Components API] Received an update for unknown component {} from player {}", payload.componentKeyId(), ctx.player());
}
} finally {
payload.buf().release();
buf.release();
}
});
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -98,7 +98,7 @@ public <C extends AutoSyncedComponent> ComponentUpdatePayload<?> toComponentPack
this.getId(),
required,
key.getId(),
data
data.array()
);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,7 @@ public <C extends AutoSyncedComponent> ComponentUpdatePayload<?> toComponentPack
Unit.INSTANCE,
required,
key.getId(),
data
data.array()
);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,7 @@ public <C extends AutoSyncedComponent> ComponentUpdatePayload<?> toComponentPack
Unit.INSTANCE,
required,
key.getId(),
data
data.array()
);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,7 @@ public <C extends AutoSyncedComponent> ComponentUpdatePayload<?> toComponentPack
this.getName(),
required,
key.getId(),
data
data.array()
);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -96,7 +96,7 @@ public <C extends AutoSyncedComponent> ComponentUpdatePayload<?> toComponentPack
Unit.INSTANCE,
required,
key.getId(),
data
data.array()
);
}

Expand Down
Loading