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 @@ -23,6 +23,7 @@
package org.ladysnake.cca.api.v3.component;

import io.netty.buffer.Unpooled;
import net.fabricmc.fabric.api.networking.v1.PacketByteBufs;
import net.fabricmc.fabric.api.networking.v1.ServerPlayNetworking;
import net.fabricmc.loader.api.FabricLoader;
import net.minecraft.network.PacketCallbacks;
Expand Down Expand Up @@ -200,24 +201,26 @@ public void syncWith(ServerPlayerEntity player, ComponentProvider provider) {
@ApiStatus.Experimental
public void syncWith(ServerPlayerEntity player, ComponentProvider provider, ComponentPacketWriter writer, PlayerSyncPredicate predicate) {
if (predicate.shouldSyncWith(player)) {
RegistryByteBuf buf = new RegistryByteBuf(Unpooled.buffer(), player.getEntityWorld().getRegistryManager());
writer.writeSyncPacket(buf, player);
CustomPayload payload = provider.toComponentPacket(this, predicate.isRequiredOnClient(), buf);

if (payload != null) {
if (ServerPlayNetworking.canSend(player, payload.getId())) {
ServerPlayNetworking.getSender(player).sendPacket(payload, PacketCallbacks.always(buf::release));
} else {
if (predicate.isRequiredOnClient()) {
String specificMod = FabricLoader.getInstance().getModContainer(this.id.getNamespace()).map(c -> c.getMetadata().getName() + " and ").orElse("");
player.networkHandler.disconnect(Text.literal(
"This server requires " + specificMod + "Cardinal Components API " +
"(unhandled packet: " + payload.getId().id() + ")" +
ComponentsInternals.getClientOptionalModAdvice()));
RegistryByteBuf buf = new RegistryByteBuf(PacketByteBufs.create(), player.getEntityWorld().getRegistryManager());
try {
writer.writeSyncPacket(buf, player);
CustomPayload payload = provider.toComponentPacket(this, predicate.isRequiredOnClient(), buf);
if (payload != null) {
if (ServerPlayNetworking.canSend(player, payload.getId())) {
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, PacketCallbacks.always(buf::release));
} else {
if (predicate.isRequiredOnClient()) {
String specificMod = FabricLoader.getInstance().getModContainer(this.id.getNamespace()).map(c -> c.getMetadata().getName() + " and ").orElse("");
player.networkHandler.disconnect(Text.literal(
"This server requires " + specificMod + "Cardinal Components API " +
"(unhandled packet: " + payload.getId().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.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 java.util.List;

Expand Down Expand Up @@ -67,7 +66,7 @@ default Iterable<ServerPlayerEntity> 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 CustomPayload} 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.DisconnectionInfo;
import net.minecraft.network.RegistryByteBuf;
import net.minecraft.network.packet.CustomPayload;
import net.minecraft.text.Text;
import org.ladysnake.cca.api.v3.component.Component;
Expand All @@ -38,15 +40,19 @@ 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 RegistryByteBuf(Unpooled.wrappedBuffer(payload.rawPayload()), ctx.client().world.getRegistryManager());
try {
synced.applySyncPacket(buf);
}
finally {
buf.release();
}
}
});
} catch (UnknownComponentException e) {
ctx.player().networkHandler.onDisconnected(new DisconnectionInfo(Text.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,
RegistryByteBuf buf
byte[] rawPayload
) implements CustomPayload {
public static <T> CustomPayload.Id<ComponentUpdatePayload<T>> id(String path) {
return new CustomPayload.Id<>(Identifier.of("cardinal-components", path));
Expand All @@ -54,7 +54,7 @@ public static <T> PacketCodec<RegistryByteBuf, ComponentUpdatePayload<T>> codec(
targetDataCodec, ComponentUpdatePayload::targetData,
PacketCodecs.BOOLEAN, ComponentUpdatePayload::required,
Identifier.PACKET_CODEC, ComponentUpdatePayload::componentKeyId,
MorePacketCodecs.REG_BYTE_BUF, ComponentUpdatePayload::buf,
PacketCodecs.BYTE_ARRAY, ComponentUpdatePayload::rawPayload,
ComponentUpdatePayload::new
);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,17 +30,4 @@

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

public static final PacketCodec<RegistryByteBuf, RegistryByteBuf> REG_BYTE_BUF = PacketCodec.ofStatic(
(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 RegistryByteBuf(copy, buf.getRegistryManager());
}
);
}
Original file line number Diff line number Diff line change
Expand Up @@ -111,7 +111,7 @@ public Iterable<ServerPlayerEntity> getRecipientsForComponentSync() {
new BlockEntityAddress(this.getType(), this.getPos(), world.getRegistryKey()),
required,
key.getId(),
data
data.array()
);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,7 @@ public Iterable<ServerPlayerEntity> getRecipientsForComponentSync() {
this.getPos(),
required,
key.getId(),
data
data.array()
);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,6 @@
import net.fabricmc.fabric.api.networking.v1.PacketByteBufs;
import net.fabricmc.fabric.api.networking.v1.PacketSender;
import net.minecraft.client.MinecraftClient;
import net.minecraft.network.PacketCallbacks;
import net.minecraft.network.RegistryByteBuf;
import org.jetbrains.annotations.ApiStatus;
import org.ladysnake.cca.api.v3.component.Component;
Expand Down Expand Up @@ -82,7 +81,14 @@ default void sendC2SMessage(C2SComponentPacketWriter writer) {
static void sendC2SMessage(ComponentKey<?> key, C2SComponentPacketWriter writer) {
PacketSender sender = ClientPlayNetworking.getSender(); // checks that the player is in game
RegistryByteBuf buf = new RegistryByteBuf(PacketByteBufs.create(), Objects.requireNonNull(MinecraftClient.getInstance().getNetworkHandler()).getRegistryManager());
writer.writeC2SPacket(buf);
sender.sendPacket(new ComponentUpdatePayload<>(CardinalComponentsEntity.C2S_SELF_PACKET_ID, Unit.INSTANCE, true, key.getId(), buf), PacketCallbacks.always(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,6 +23,9 @@
package org.ladysnake.cca.internal.entity;

import com.mojang.datafixers.util.Unit;
import io.netty.buffer.ByteBuf;
import io.netty.buffer.Unpooled;
import io.netty.buffer.UnpooledDirectByteBuf;
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;
Expand All @@ -33,6 +36,8 @@
import net.minecraft.entity.LivingEntity;
import net.minecraft.entity.conversion.EntityConversionContext;
import net.minecraft.entity.conversion.EntityConversionType;
import net.minecraft.network.PacketByteBuf;
import net.minecraft.network.RegistryByteBuf;
import net.minecraft.network.codec.PacketCodecs;
import net.minecraft.network.packet.CustomPayload;
import net.minecraft.network.packet.s2c.common.CustomPayloadS2CPacket;
Expand Down Expand Up @@ -82,11 +87,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 RegistryByteBuf(Unpooled.wrappedBuffer(payload.rawPayload()), ctx.player().getRegistryManager());
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 +101,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 @@ -100,7 +100,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 @@ -95,7 +95,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 @@ -96,7 +96,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 @@ -92,7 +92,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 @@ -75,7 +75,7 @@ public <C extends AutoSyncedComponent> ComponentUpdatePayload<?> toComponentPack
Unit.INSTANCE,
required,
key.getId(),
data
data.array()
);
}
}
Loading