mirror of
https://github.com/architectury/architectury-api.git
synced 2026-03-30 13:05:25 -05:00
[ci skip] Port to NeoForge 24w14a
Signed-off-by: shedaniel <daniel@shedaniel.me>
This commit is contained in:
@@ -46,9 +46,9 @@ public interface LootEvent {
|
||||
*
|
||||
* <h2>Example: adding diamonds as a drop for dirt</h2>
|
||||
* <pre>{@code
|
||||
* LootEvent.MODIFY_LOOT_TABLE.register((lootTables, id, context, builtin) -> {
|
||||
* LootEvent.MODIFY_LOOT_TABLE.register((key, context, builtin) -> {
|
||||
* // Check that the loot table is dirt and built-in
|
||||
* if (builtin && Blocks.DIRT.getLootTable().equals(id)) {
|
||||
* if (builtin && Blocks.DIRT.getLootTable().equals(key)) {
|
||||
* // Create a loot pool with a single item entry of Items.DIAMOND
|
||||
* LootPool.Builder pool = LootPool.lootPool().add(LootItem.lootTableItem(Items.DIAMOND));
|
||||
* context.addPool(pool);
|
||||
@@ -58,7 +58,7 @@ public interface LootEvent {
|
||||
*
|
||||
* @see ModifyLootTable#modifyLootTable(ResourceKey, LootTableModificationContext, boolean)
|
||||
*/
|
||||
// Event<ModifyLootTable> MODIFY_LOOT_TABLE = EventFactory.createLoop();
|
||||
Event<ModifyLootTable> MODIFY_LOOT_TABLE = EventFactory.createLoop();
|
||||
|
||||
@FunctionalInterface
|
||||
interface ModifyLootTable {
|
||||
|
||||
@@ -19,7 +19,6 @@
|
||||
|
||||
package dev.architectury.fluid;
|
||||
|
||||
import com.google.common.collect.Iterators;
|
||||
import com.mojang.serialization.Codec;
|
||||
import dev.architectury.hooks.fluid.FluidStackHooks;
|
||||
import dev.architectury.injectables.annotations.ExpectPlatform;
|
||||
@@ -35,7 +34,8 @@ import net.minecraft.world.level.material.Fluids;
|
||||
import org.jetbrains.annotations.ApiStatus;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.*;
|
||||
import java.util.Objects;
|
||||
import java.util.Optional;
|
||||
import java.util.function.BiFunction;
|
||||
import java.util.function.Function;
|
||||
import java.util.function.Supplier;
|
||||
@@ -66,100 +66,6 @@ public final class FluidStack implements DataComponentHolder {
|
||||
throw new AssertionError();
|
||||
}
|
||||
|
||||
@Override
|
||||
public DataComponentMap getComponents() {
|
||||
return new DataComponentMap() {
|
||||
@Nullable
|
||||
@Override
|
||||
public <T> T get(DataComponentType<? extends T> type) {
|
||||
return getPatch().get(type).orElse(null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Set<DataComponentType<?>> keySet() {
|
||||
return new AbstractSet<>() {
|
||||
@Override
|
||||
public Iterator<DataComponentType<?>> iterator() {
|
||||
return Iterators.transform(getPatch().entrySet().iterator(), Map.Entry::getKey);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int size() {
|
||||
return getPatch().entrySet().size();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean contains(Object o) {
|
||||
if (!(o instanceof DataComponentType<?> type)) return false;
|
||||
return getPatch().get(type).isPresent();
|
||||
}
|
||||
};
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
public <T> T set(DataComponentType<? super T> dataComponentType, @Nullable T object) {
|
||||
T previous = (T) get(dataComponentType);
|
||||
DataComponentPatch.Builder builder = DataComponentPatch.builder();
|
||||
for (TypedDataComponent<?> component : getComponents()) {
|
||||
if (component.type() != dataComponentType) {
|
||||
builder.set(component);
|
||||
}
|
||||
}
|
||||
if (object != null) {
|
||||
builder.set(dataComponentType, object);
|
||||
}
|
||||
setPatch(builder.build());
|
||||
return previous;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public <T, U> T update(DataComponentType<T> dataComponentType, T object, U object2, BiFunction<T, U, T> biFunction) {
|
||||
return this.set(dataComponentType, biFunction.apply(this.getOrDefault(dataComponentType, object), object2));
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public <T> T update(DataComponentType<T> dataComponentType, T object, UnaryOperator<T> unaryOperator) {
|
||||
return this.set(dataComponentType, unaryOperator.apply(this.getOrDefault(dataComponentType, object)));
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public <T> T remove(DataComponentType<? extends T> dataComponentType) {
|
||||
return this.set(dataComponentType, null);
|
||||
}
|
||||
|
||||
public void applyComponents(DataComponentPatch dataComponentPatch) {
|
||||
DataComponentPatch.Builder builder = DataComponentPatch.builder();
|
||||
for (TypedDataComponent<?> component : getComponents()) {
|
||||
builder.set(component);
|
||||
}
|
||||
for (Map.Entry<DataComponentType<?>, Optional<?>> entry : dataComponentPatch.entrySet()) {
|
||||
if (entry.getValue().isPresent()) {
|
||||
//noinspection rawtypes
|
||||
builder.set((DataComponentType) entry.getKey(), entry.getValue().get());
|
||||
} else {
|
||||
builder.remove(entry.getKey());
|
||||
}
|
||||
}
|
||||
setPatch(builder.build());
|
||||
}
|
||||
|
||||
public void applyComponents(DataComponentMap dataComponentMap) {
|
||||
DataComponentPatch.Builder builder = DataComponentPatch.builder();
|
||||
for (TypedDataComponent<?> component : getComponents()) {
|
||||
builder.set(component);
|
||||
}
|
||||
for (TypedDataComponent<?> entry : dataComponentMap) {
|
||||
if (entry.value() != null) {
|
||||
//noinspection rawtypes
|
||||
builder.set((DataComponentType) entry.type(), entry.value());
|
||||
} else {
|
||||
builder.remove(entry.type());
|
||||
}
|
||||
}
|
||||
setPatch(builder.build());
|
||||
}
|
||||
|
||||
@ApiStatus.Internal
|
||||
public interface FluidStackAdapter<T> {
|
||||
T create(Supplier<Fluid> fluid, long amount, @Nullable DataComponentPatch patch);
|
||||
@@ -174,7 +80,19 @@ public final class FluidStack implements DataComponentHolder {
|
||||
|
||||
DataComponentPatch getPatch(T value);
|
||||
|
||||
void setPatch(T value, DataComponentPatch patch);
|
||||
PatchedDataComponentMap getComponents(T value);
|
||||
|
||||
void applyComponents(T value, DataComponentPatch patch);
|
||||
|
||||
void applyComponents(T value, DataComponentMap patch);
|
||||
|
||||
@Nullable <D> D set(T value, DataComponentType<? super D> type, @Nullable D component);
|
||||
|
||||
@Nullable <D> D remove(T value, DataComponentType<? extends D> type);
|
||||
|
||||
@Nullable <D> D update(T value, DataComponentType<D> type, D component, UnaryOperator<D> updater);
|
||||
|
||||
@Nullable <D, U> D update(T value, DataComponentType<D> type, D component, U updateContext, BiFunction<D, U, D> updater);
|
||||
|
||||
T copy(T value);
|
||||
|
||||
@@ -260,8 +178,37 @@ public final class FluidStack implements DataComponentHolder {
|
||||
return ADAPTER.getPatch(value);
|
||||
}
|
||||
|
||||
public void setPatch(DataComponentPatch patch) {
|
||||
ADAPTER.setPatch(value, patch);
|
||||
@Override
|
||||
public PatchedDataComponentMap getComponents() {
|
||||
return ADAPTER.getComponents(value);
|
||||
}
|
||||
|
||||
public void applyComponents(DataComponentPatch patch) {
|
||||
ADAPTER.applyComponents(value, patch);
|
||||
}
|
||||
|
||||
public void applyComponents(DataComponentMap patch) {
|
||||
ADAPTER.applyComponents(value, patch);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public <T> T set(DataComponentType<? super T> type, @Nullable T component) {
|
||||
return ADAPTER.set(value, type, component);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public <T> T remove(DataComponentType<? extends T> type) {
|
||||
return ADAPTER.remove(value, type);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public <T> T update(DataComponentType<T> type, T component, UnaryOperator<T> updater) {
|
||||
return ADAPTER.update(value, type, component, updater);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public <T, U> T update(DataComponentType<T> type, T component, U updateContext, BiFunction<T, U, T> updater) {
|
||||
return ADAPTER.update(value, type, component, updateContext, updater);
|
||||
}
|
||||
|
||||
public Component getName() {
|
||||
|
||||
@@ -0,0 +1,215 @@
|
||||
/*
|
||||
* This file is part of architectury.
|
||||
* Copyright (C) 2020, 2021, 2022 architectury
|
||||
*
|
||||
* 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 dev.architectury.impl;
|
||||
|
||||
import com.google.common.base.Suppliers;
|
||||
import dev.architectury.networking.NetworkManager;
|
||||
import dev.architectury.networking.transformers.PacketSink;
|
||||
import dev.architectury.networking.transformers.PacketTransformer;
|
||||
import io.netty.buffer.ByteBuf;
|
||||
import io.netty.buffer.ByteBufUtil;
|
||||
import io.netty.buffer.Unpooled;
|
||||
import net.fabricmc.api.EnvType;
|
||||
import net.fabricmc.api.Environment;
|
||||
import net.minecraft.core.RegistryAccess;
|
||||
import net.minecraft.network.RegistryFriendlyByteBuf;
|
||||
import net.minecraft.network.codec.ByteBufCodecs;
|
||||
import net.minecraft.network.codec.StreamCodec;
|
||||
import net.minecraft.network.protocol.Packet;
|
||||
import net.minecraft.network.protocol.common.custom.CustomPacketPayload;
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
import org.jetbrains.annotations.ApiStatus;
|
||||
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
import java.util.function.Supplier;
|
||||
|
||||
@ApiStatus.Internal
|
||||
public class NetworkAggregator {
|
||||
public static final Supplier<Adaptor> ADAPTOR = Suppliers.memoize(() -> {
|
||||
try {
|
||||
Method adaptor = NetworkManager.class.getDeclaredMethod("getAdaptor");
|
||||
adaptor.setAccessible(true);
|
||||
return (Adaptor) adaptor.invoke(null);
|
||||
} catch (Throwable throwable) {
|
||||
throw new RuntimeException(throwable);
|
||||
}
|
||||
});
|
||||
public static final Map<ResourceLocation, CustomPacketPayload.Type<BufCustomPacketPayload>> C2S_TYPE = new HashMap<>();
|
||||
public static final Map<ResourceLocation, CustomPacketPayload.Type<BufCustomPacketPayload>> S2C_TYPE = new HashMap<>();
|
||||
public static final Map<ResourceLocation, NetworkManager.NetworkReceiver<?>> C2S_RECEIVER = new HashMap<>();
|
||||
public static final Map<ResourceLocation, NetworkManager.NetworkReceiver<?>> S2C_RECEIVER = new HashMap<>();
|
||||
public static final Map<ResourceLocation, StreamCodec<ByteBuf, ?>> C2S_CODECS = new HashMap<>();
|
||||
public static final Map<ResourceLocation, StreamCodec<ByteBuf, ?>> S2C_CODECS = new HashMap<>();
|
||||
public static final Map<ResourceLocation, PacketTransformer> C2S_TRANSFORMERS = new HashMap<>();
|
||||
public static final Map<ResourceLocation, PacketTransformer> S2C_TRANSFORMERS = new HashMap<>();
|
||||
|
||||
public static void registerReceiver(NetworkManager.Side side, ResourceLocation id, List<PacketTransformer> packetTransformers, NetworkManager.NetworkReceiver<RegistryFriendlyByteBuf> receiver) {
|
||||
CustomPacketPayload.Type<BufCustomPacketPayload> type = new CustomPacketPayload.Type<>(id);
|
||||
if (side == NetworkManager.Side.C2S) {
|
||||
C2S_TYPE.put(id, type);
|
||||
registerC2SReceiver(type, BufCustomPacketPayload.streamCodec(type), packetTransformers, (value, context) -> {
|
||||
RegistryFriendlyByteBuf buf = new RegistryFriendlyByteBuf(Unpooled.wrappedBuffer(value.payload()), context.registryAccess());
|
||||
receiver.receive(buf, context);
|
||||
buf.release();
|
||||
});
|
||||
} else if (side == NetworkManager.Side.S2C) {
|
||||
S2C_TYPE.put(id, type);
|
||||
registerS2CReceiver(type, BufCustomPacketPayload.streamCodec(type), packetTransformers, (value, context) -> {
|
||||
RegistryFriendlyByteBuf buf = new RegistryFriendlyByteBuf(Unpooled.wrappedBuffer(value.payload()), context.registryAccess());
|
||||
receiver.receive(buf, context);
|
||||
buf.release();
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
public static <T extends CustomPacketPayload> void registerReceiver(NetworkManager.Side side, CustomPacketPayload.Type<T> type, StreamCodec<? super RegistryFriendlyByteBuf, T> codec, List<PacketTransformer> packetTransformers, NetworkManager.NetworkReceiver<T> receiver) {
|
||||
Objects.requireNonNull(type, "Cannot register receiver with a null type!");
|
||||
packetTransformers = Objects.requireNonNullElse(packetTransformers, List.of());
|
||||
Objects.requireNonNull(receiver, "Cannot register a null receiver!");
|
||||
if (side == NetworkManager.Side.C2S) {
|
||||
registerC2SReceiver(type, codec, packetTransformers, receiver);
|
||||
} else if (side == NetworkManager.Side.S2C) {
|
||||
registerS2CReceiver(type, codec, packetTransformers, receiver);
|
||||
}
|
||||
}
|
||||
|
||||
private static <T extends CustomPacketPayload> void registerC2SReceiver(CustomPacketPayload.Type<T> type, StreamCodec<? super RegistryFriendlyByteBuf, T> codec, List<PacketTransformer> packetTransformers, NetworkManager.NetworkReceiver<T> receiver) {
|
||||
PacketTransformer transformer = PacketTransformer.concat(packetTransformers);
|
||||
C2S_RECEIVER.put(type.id(), receiver);
|
||||
C2S_CODECS.put(type.id(), (StreamCodec<ByteBuf, ?>) codec);
|
||||
C2S_TRANSFORMERS.put(type.id(), transformer);
|
||||
ADAPTOR.get().registerC2S((CustomPacketPayload.Type<BufCustomPacketPayload>) type, BufCustomPacketPayload.streamCodec((CustomPacketPayload.Type<BufCustomPacketPayload>) type), (payload, context) -> {
|
||||
RegistryFriendlyByteBuf buf = new RegistryFriendlyByteBuf(Unpooled.wrappedBuffer(payload.payload()), context.registryAccess());
|
||||
transformer.inbound(NetworkManager.Side.C2S, type.id(), buf, context, (side, id1, buf1) -> {
|
||||
NetworkManager.NetworkReceiver<T> networkReceiver = (NetworkManager.NetworkReceiver<T>) (side == NetworkManager.Side.C2S ? C2S_RECEIVER.get(id1) : S2C_RECEIVER.get(id1));
|
||||
if (networkReceiver == null) {
|
||||
throw new IllegalArgumentException("Network Receiver not found! " + id1);
|
||||
}
|
||||
T actualPayload = codec.decode(buf1);
|
||||
networkReceiver.receive(actualPayload, context);
|
||||
});
|
||||
buf.release();
|
||||
});
|
||||
}
|
||||
|
||||
private static <T extends CustomPacketPayload> void registerS2CReceiver(CustomPacketPayload.Type<T> type, StreamCodec<? super RegistryFriendlyByteBuf, T> codec, List<PacketTransformer> packetTransformers, NetworkManager.NetworkReceiver<T> receiver) {
|
||||
PacketTransformer transformer = PacketTransformer.concat(packetTransformers);
|
||||
S2C_RECEIVER.put(type.id(), receiver);
|
||||
S2C_CODECS.put(type.id(), (StreamCodec<ByteBuf, ?>) codec);
|
||||
S2C_TRANSFORMERS.put(type.id(), transformer);
|
||||
ADAPTOR.get().registerS2C((CustomPacketPayload.Type<BufCustomPacketPayload>) type, BufCustomPacketPayload.streamCodec((CustomPacketPayload.Type<BufCustomPacketPayload>) type), (payload, context) -> {
|
||||
RegistryFriendlyByteBuf buf = new RegistryFriendlyByteBuf(Unpooled.wrappedBuffer(payload.payload()), context.registryAccess());
|
||||
transformer.inbound(NetworkManager.Side.S2C, type.id(), buf, context, (side, id1, buf1) -> {
|
||||
NetworkManager.NetworkReceiver<T> networkReceiver = (NetworkManager.NetworkReceiver<T>) (side == NetworkManager.Side.C2S ? C2S_RECEIVER.get(id1) : S2C_RECEIVER.get(id1));
|
||||
if (networkReceiver == null) {
|
||||
throw new IllegalArgumentException("Network Receiver not found! " + id1);
|
||||
}
|
||||
T actualPayload = codec.decode(buf1);
|
||||
networkReceiver.receive(actualPayload, context);
|
||||
});
|
||||
buf.release();
|
||||
});
|
||||
}
|
||||
|
||||
public static void collectPackets(PacketSink sink, NetworkManager.Side side, ResourceLocation id, RegistryFriendlyByteBuf buf) {
|
||||
if (side == NetworkManager.Side.C2S) {
|
||||
collectPackets(sink, side, new BufCustomPacketPayload(C2S_TYPE.get(id), ByteBufUtil.getBytes(buf)), buf.registryAccess());
|
||||
} else {
|
||||
collectPackets(sink, side, new BufCustomPacketPayload(S2C_TYPE.get(id), ByteBufUtil.getBytes(buf)), buf.registryAccess());
|
||||
}
|
||||
}
|
||||
|
||||
public static <T extends CustomPacketPayload> void collectPackets(PacketSink sink, NetworkManager.Side side, T payload, RegistryAccess access) {
|
||||
CustomPacketPayload.Type<T> type = (CustomPacketPayload.Type<T>) payload.type();
|
||||
PacketTransformer transformer = side == NetworkManager.Side.C2S ? C2S_TRANSFORMERS.get(type.id()) : S2C_TRANSFORMERS.get(type.id());
|
||||
StreamCodec<ByteBuf, T> codec = (StreamCodec<ByteBuf, T>) (side == NetworkManager.Side.C2S ? C2S_CODECS.get(type.id()) : S2C_CODECS.get(type.id()));
|
||||
RegistryFriendlyByteBuf buf = new RegistryFriendlyByteBuf(Unpooled.buffer(), access);
|
||||
codec.encode(buf, payload);
|
||||
|
||||
if (transformer != null) {
|
||||
transformer.outbound(side, type.id(), buf, (side1, id1, buf1) -> {
|
||||
if (side == NetworkManager.Side.C2S) {
|
||||
CustomPacketPayload.Type<BufCustomPacketPayload> type1 = C2S_TYPE.getOrDefault(id1, (CustomPacketPayload.Type<BufCustomPacketPayload>) type);
|
||||
sink.accept(toPacket(side1, new BufCustomPacketPayload(type1, ByteBufUtil.getBytes(buf1))));
|
||||
} else if (side == NetworkManager.Side.S2C) {
|
||||
CustomPacketPayload.Type<BufCustomPacketPayload> type1 = S2C_TYPE.getOrDefault(id1, (CustomPacketPayload.Type<BufCustomPacketPayload>) type);
|
||||
sink.accept(toPacket(side1, new BufCustomPacketPayload(type1, ByteBufUtil.getBytes(buf1))));
|
||||
}
|
||||
});
|
||||
} else {
|
||||
sink.accept(toPacket(side, new BufCustomPacketPayload((CustomPacketPayload.Type<BufCustomPacketPayload>) type, ByteBufUtil.getBytes(buf))));
|
||||
}
|
||||
buf.release();
|
||||
}
|
||||
|
||||
public static <T extends CustomPacketPayload> Packet<?> toPacket(NetworkManager.Side side, T payload) {
|
||||
if (side == NetworkManager.Side.C2S) {
|
||||
return ADAPTOR.get().toC2SPacket(payload);
|
||||
} else if (side == NetworkManager.Side.S2C) {
|
||||
return ADAPTOR.get().toS2CPacket(payload);
|
||||
}
|
||||
|
||||
throw new IllegalArgumentException("Invalid side: " + side);
|
||||
}
|
||||
|
||||
public static void registerS2CType(ResourceLocation id, List<PacketTransformer> packetTransformers) {
|
||||
CustomPacketPayload.Type<BufCustomPacketPayload> type = new CustomPacketPayload.Type<>(id);
|
||||
S2C_TYPE.put(id, type);
|
||||
registerS2CType(type, BufCustomPacketPayload.streamCodec(type), packetTransformers);
|
||||
}
|
||||
|
||||
public static <T extends CustomPacketPayload> void registerS2CType(CustomPacketPayload.Type<T> type, StreamCodec<? super RegistryFriendlyByteBuf, T> codec, List<PacketTransformer> packetTransformers) {
|
||||
Objects.requireNonNull(type, "Cannot register a null type!");
|
||||
packetTransformers = Objects.requireNonNullElse(packetTransformers, List.of());
|
||||
S2C_CODECS.put(type.id(), (StreamCodec<ByteBuf, ?>) codec);
|
||||
S2C_TRANSFORMERS.put(type.id(), PacketTransformer.concat(packetTransformers));
|
||||
ADAPTOR.get().registerS2CType((CustomPacketPayload.Type<BufCustomPacketPayload>) type, BufCustomPacketPayload.streamCodec((CustomPacketPayload.Type<BufCustomPacketPayload>) type));
|
||||
}
|
||||
|
||||
public interface Adaptor {
|
||||
<T extends CustomPacketPayload> void registerC2S(CustomPacketPayload.Type<T> type, StreamCodec<? super RegistryFriendlyByteBuf, T> codec, NetworkManager.NetworkReceiver<T> receiver);
|
||||
|
||||
@Environment(EnvType.CLIENT)
|
||||
<T extends CustomPacketPayload> void registerS2C(CustomPacketPayload.Type<T> type, StreamCodec<? super RegistryFriendlyByteBuf, T> codec, NetworkManager.NetworkReceiver<T> receiver);
|
||||
|
||||
<T extends CustomPacketPayload> Packet<?> toC2SPacket(T payload);
|
||||
|
||||
@Environment(EnvType.CLIENT)
|
||||
<T extends CustomPacketPayload> Packet<?> toS2CPacket(T payload);
|
||||
|
||||
<T extends CustomPacketPayload> void registerS2CType(CustomPacketPayload.Type<T> type, StreamCodec<? super RegistryFriendlyByteBuf, T> codec);
|
||||
}
|
||||
|
||||
public record BufCustomPacketPayload(Type<BufCustomPacketPayload> _type,
|
||||
byte[] payload) implements CustomPacketPayload {
|
||||
@Override
|
||||
public Type<? extends CustomPacketPayload> type() {
|
||||
return this._type();
|
||||
}
|
||||
|
||||
public static StreamCodec<ByteBuf, BufCustomPacketPayload> streamCodec(Type<BufCustomPacketPayload> type) {
|
||||
return ByteBufCodecs.BYTE_ARRAY.map(bytes -> new BufCustomPacketPayload(type, bytes), BufCustomPacketPayload::payload);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -27,12 +27,16 @@ import io.netty.buffer.Unpooled;
|
||||
import net.fabricmc.api.EnvType;
|
||||
import net.fabricmc.api.Environment;
|
||||
import net.minecraft.client.Minecraft;
|
||||
import net.minecraft.client.multiplayer.ClientPacketListener;
|
||||
import net.minecraft.core.RegistryAccess;
|
||||
import net.minecraft.network.FriendlyByteBuf;
|
||||
import net.minecraft.network.RegistryFriendlyByteBuf;
|
||||
import net.minecraft.network.protocol.Packet;
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
import net.minecraft.server.level.ServerPlayer;
|
||||
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.Iterator;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
import java.util.UUID;
|
||||
@@ -60,7 +64,7 @@ public final class NetworkChannel {
|
||||
var s = UUID.nameUUIDFromBytes(type.getName().getBytes(StandardCharsets.UTF_8)).toString().replace("-", "");
|
||||
var info = new MessageInfo<T>(new ResourceLocation(id + "/" + s), encoder, decoder, messageConsumer);
|
||||
encoders.put(type, info);
|
||||
NetworkManager.NetworkReceiver receiver = (buf, context) -> {
|
||||
NetworkManager.NetworkReceiver<RegistryFriendlyByteBuf> receiver = (buf, context) -> {
|
||||
info.messageConsumer.accept(info.decoder.apply(buf), () -> context);
|
||||
};
|
||||
NetworkManager.registerReceiver(NetworkManager.c2s(), info.packetId, receiver);
|
||||
@@ -78,19 +82,21 @@ public final class NetworkChannel {
|
||||
return h;
|
||||
}
|
||||
|
||||
public <T> Packet<?> toPacket(NetworkManager.Side side, T message) {
|
||||
public <T> Packet<?> toPacket(NetworkManager.Side side, T message, RegistryAccess access) {
|
||||
var messageInfo = (MessageInfo<T>) Objects.requireNonNull(encoders.get(message.getClass()), "Unknown message type! " + message);
|
||||
var buf = new FriendlyByteBuf(Unpooled.buffer());
|
||||
var buf = new RegistryFriendlyByteBuf(Unpooled.buffer(), access);
|
||||
messageInfo.encoder.accept(message, buf);
|
||||
return NetworkManager.toPacket(side, messageInfo.packetId, buf);
|
||||
}
|
||||
|
||||
public <T> void sendToPlayer(ServerPlayer player, T message) {
|
||||
Objects.requireNonNull(player, "Unable to send packet to a 'null' player!").connection.send(toPacket(NetworkManager.s2c(), message));
|
||||
Objects.requireNonNull(player, "Unable to send packet to a 'null' player!").connection.send(toPacket(NetworkManager.s2c(), message, player.registryAccess()));
|
||||
}
|
||||
|
||||
public <T> void sendToPlayers(Iterable<ServerPlayer> players, T message) {
|
||||
var packet = toPacket(NetworkManager.s2c(), message);
|
||||
Iterator<ServerPlayer> iterator = players.iterator();
|
||||
if (!iterator.hasNext()) return;
|
||||
var packet = toPacket(NetworkManager.s2c(), message, iterator.next().registryAccess());
|
||||
for (var player : players) {
|
||||
Objects.requireNonNull(player, "Unable to send packet to a 'null' player!").connection.send(packet);
|
||||
}
|
||||
@@ -98,8 +104,9 @@ public final class NetworkChannel {
|
||||
|
||||
@Environment(EnvType.CLIENT)
|
||||
public <T> void sendToServer(T message) {
|
||||
if (Minecraft.getInstance().getConnection() != null) {
|
||||
Minecraft.getInstance().getConnection().send(toPacket(NetworkManager.c2s(), message));
|
||||
ClientPacketListener connection = Minecraft.getInstance().getConnection();
|
||||
if (connection != null) {
|
||||
connection.send(toPacket(NetworkManager.c2s(), message, connection.registryAccess()));
|
||||
} else {
|
||||
throw new IllegalStateException("Unable to send packet to the server while not in game!");
|
||||
}
|
||||
|
||||
@@ -19,16 +19,22 @@
|
||||
|
||||
package dev.architectury.networking;
|
||||
|
||||
import dev.architectury.impl.NetworkAggregator;
|
||||
import dev.architectury.injectables.annotations.ExpectPlatform;
|
||||
import dev.architectury.networking.transformers.PacketCollector;
|
||||
import dev.architectury.networking.transformers.PacketSink;
|
||||
import dev.architectury.networking.transformers.PacketTransformer;
|
||||
import dev.architectury.networking.transformers.SinglePacketCollector;
|
||||
import dev.architectury.utils.Env;
|
||||
import dev.architectury.utils.GameInstance;
|
||||
import net.fabricmc.api.EnvType;
|
||||
import net.fabricmc.api.Environment;
|
||||
import net.minecraft.network.FriendlyByteBuf;
|
||||
import net.minecraft.client.multiplayer.ClientPacketListener;
|
||||
import net.minecraft.core.RegistryAccess;
|
||||
import net.minecraft.network.RegistryFriendlyByteBuf;
|
||||
import net.minecraft.network.codec.StreamCodec;
|
||||
import net.minecraft.network.protocol.Packet;
|
||||
import net.minecraft.network.protocol.common.custom.CustomPacketPayload;
|
||||
import net.minecraft.network.protocol.game.ClientGamePacketListener;
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
import net.minecraft.server.level.ServerPlayer;
|
||||
@@ -37,53 +43,112 @@ import net.minecraft.world.entity.player.Player;
|
||||
import org.jetbrains.annotations.ApiStatus;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
|
||||
public final class NetworkManager {
|
||||
public static void registerReceiver(Side side, ResourceLocation id, NetworkReceiver receiver) {
|
||||
/**
|
||||
* For S2C types, {@link #registerReceiver} should be called on the client side,
|
||||
* while {@link #registerS2CPayloadType} should be called on the server side.
|
||||
*/
|
||||
public static void registerS2CPayloadType(ResourceLocation id) {
|
||||
NetworkAggregator.registerS2CType(id, List.of());
|
||||
}
|
||||
|
||||
/**
|
||||
* For S2C types, {@link #registerReceiver} should be called on the client side,
|
||||
* while {@link #registerS2CPayloadType} should be called on the server side.
|
||||
*/
|
||||
public static <T extends CustomPacketPayload> void registerS2CPayloadType(CustomPacketPayload.Type<T> type, StreamCodec<? super RegistryFriendlyByteBuf, T> codec) {
|
||||
NetworkAggregator.registerS2CType(type, codec, List.of());
|
||||
}
|
||||
|
||||
/**
|
||||
* For S2C types, {@link #registerReceiver} should be called on the client side,
|
||||
* while {@link #registerS2CPayloadType} should be called on the server side.
|
||||
*/
|
||||
public static void registerS2CPayloadType(ResourceLocation id, List<PacketTransformer> packetTransformers) {
|
||||
NetworkAggregator.registerS2CType(id, packetTransformers);
|
||||
}
|
||||
|
||||
/**
|
||||
* For S2C types, {@link #registerReceiver} should be called on the client side,
|
||||
* while {@link #registerS2CPayloadType} should be called on the server side.
|
||||
*/
|
||||
public static <T extends CustomPacketPayload> void registerS2CPayloadType(CustomPacketPayload.Type<T> type, StreamCodec<? super RegistryFriendlyByteBuf, T> codec, List<PacketTransformer> packetTransformers) {
|
||||
NetworkAggregator.registerS2CType(type, codec, packetTransformers);
|
||||
}
|
||||
|
||||
public static void registerReceiver(Side side, ResourceLocation id, NetworkReceiver<RegistryFriendlyByteBuf> receiver) {
|
||||
registerReceiver(side, id, Collections.emptyList(), receiver);
|
||||
}
|
||||
|
||||
@ExpectPlatform
|
||||
@ApiStatus.Experimental
|
||||
public static void registerReceiver(Side side, ResourceLocation id, List<PacketTransformer> packetTransformers, NetworkReceiver receiver) {
|
||||
throw new AssertionError();
|
||||
public static void registerReceiver(Side side, ResourceLocation id, List<PacketTransformer> packetTransformers, NetworkReceiver<RegistryFriendlyByteBuf> receiver) {
|
||||
NetworkAggregator.registerReceiver(side, id, packetTransformers, receiver);
|
||||
}
|
||||
|
||||
public static <T extends CustomPacketPayload> void registerReceiver(Side side, CustomPacketPayload.Type<T> id, StreamCodec<? super RegistryFriendlyByteBuf, T> codec, NetworkReceiver<T> receiver) {
|
||||
registerReceiver(side, id, codec, Collections.emptyList(), receiver);
|
||||
}
|
||||
|
||||
@ApiStatus.Experimental
|
||||
public static <T extends CustomPacketPayload> void registerReceiver(Side side, CustomPacketPayload.Type<T> id, StreamCodec<? super RegistryFriendlyByteBuf, T> codec, List<PacketTransformer> packetTransformers, NetworkReceiver<T> receiver) {
|
||||
NetworkAggregator.registerReceiver(side, id, codec, packetTransformers, receiver);
|
||||
}
|
||||
|
||||
@Deprecated
|
||||
@ApiStatus.ScheduledForRemoval
|
||||
public static Packet<?> toPacket(Side side, ResourceLocation id, FriendlyByteBuf buf) {
|
||||
public static Packet<?> toPacket(Side side, ResourceLocation id, RegistryFriendlyByteBuf buf) {
|
||||
SinglePacketCollector sink = new SinglePacketCollector(null);
|
||||
collectPackets(sink, side, id, buf);
|
||||
return sink.getPacket();
|
||||
}
|
||||
|
||||
@Deprecated
|
||||
@ApiStatus.ScheduledForRemoval
|
||||
public static List<Packet<?>> toPackets(Side side, ResourceLocation id, FriendlyByteBuf buf) {
|
||||
public static List<Packet<?>> toPackets(Side side, ResourceLocation id, RegistryFriendlyByteBuf buf) {
|
||||
PacketCollector sink = new PacketCollector(null);
|
||||
collectPackets(sink, side, id, buf);
|
||||
return sink.collect();
|
||||
}
|
||||
|
||||
@ExpectPlatform
|
||||
public static void collectPackets(PacketSink sink, Side side, ResourceLocation id, FriendlyByteBuf buf) {
|
||||
throw new AssertionError();
|
||||
public static void collectPackets(PacketSink sink, Side side, ResourceLocation id, RegistryFriendlyByteBuf buf) {
|
||||
NetworkAggregator.collectPackets(sink, side, id, buf);
|
||||
}
|
||||
|
||||
public static void sendToPlayer(ServerPlayer player, ResourceLocation id, FriendlyByteBuf buf) {
|
||||
public static <T extends CustomPacketPayload> void collectPackets(PacketSink sink, Side side, T payload, RegistryAccess access) {
|
||||
NetworkAggregator.collectPackets(sink, side, payload, access);
|
||||
}
|
||||
|
||||
public static void sendToPlayer(ServerPlayer player, ResourceLocation id, RegistryFriendlyByteBuf buf) {
|
||||
collectPackets(PacketSink.ofPlayer(player), serverToClient(), id, buf);
|
||||
}
|
||||
|
||||
public static void sendToPlayers(Iterable<ServerPlayer> players, ResourceLocation id, FriendlyByteBuf buf) {
|
||||
public static void sendToPlayers(Iterable<ServerPlayer> players, ResourceLocation id, RegistryFriendlyByteBuf buf) {
|
||||
collectPackets(PacketSink.ofPlayers(players), serverToClient(), id, buf);
|
||||
}
|
||||
|
||||
@Environment(EnvType.CLIENT)
|
||||
public static void sendToServer(ResourceLocation id, FriendlyByteBuf buf) {
|
||||
public static void sendToServer(ResourceLocation id, RegistryFriendlyByteBuf buf) {
|
||||
collectPackets(PacketSink.client(), clientToServer(), id, buf);
|
||||
}
|
||||
|
||||
public static <T extends CustomPacketPayload> void sendToPlayer(ServerPlayer player, T payload) {
|
||||
collectPackets(PacketSink.ofPlayer(player), serverToClient(), payload, player.registryAccess());
|
||||
}
|
||||
|
||||
public static <T extends CustomPacketPayload> void sendToPlayers(Iterable<ServerPlayer> players, T payload) {
|
||||
Iterator<ServerPlayer> iterator = players.iterator();
|
||||
if (!iterator.hasNext()) return;
|
||||
collectPackets(PacketSink.ofPlayers(players), serverToClient(), payload, iterator.next().registryAccess());
|
||||
}
|
||||
|
||||
@Environment(EnvType.CLIENT)
|
||||
public static <T extends CustomPacketPayload> void sendToServer(T payload) {
|
||||
ClientPacketListener connection = GameInstance.getClient().getConnection();
|
||||
if (connection == null) return;
|
||||
collectPackets(PacketSink.client(), clientToServer(), payload, connection.registryAccess());
|
||||
}
|
||||
|
||||
@Environment(EnvType.CLIENT)
|
||||
@ExpectPlatform
|
||||
public static boolean canServerReceive(ResourceLocation id) {
|
||||
@@ -112,9 +177,14 @@ public final class NetworkManager {
|
||||
throw new AssertionError();
|
||||
}
|
||||
|
||||
@ExpectPlatform
|
||||
private static NetworkAggregator.Adaptor getAdaptor() {
|
||||
throw new AssertionError();
|
||||
}
|
||||
|
||||
@FunctionalInterface
|
||||
public interface NetworkReceiver {
|
||||
void receive(FriendlyByteBuf buf, PacketContext context);
|
||||
public interface NetworkReceiver<T> {
|
||||
void receive(T value, PacketContext context);
|
||||
}
|
||||
|
||||
public interface PacketContext {
|
||||
@@ -124,6 +194,8 @@ public final class NetworkManager {
|
||||
|
||||
Env getEnvironment();
|
||||
|
||||
RegistryAccess registryAccess();
|
||||
|
||||
default EnvType getEnv() {
|
||||
return getEnvironment().toPlatform();
|
||||
}
|
||||
|
||||
@@ -26,6 +26,7 @@ import net.fabricmc.api.Environment;
|
||||
import net.minecraft.client.Minecraft;
|
||||
import net.minecraft.core.registries.BuiltInRegistries;
|
||||
import net.minecraft.network.FriendlyByteBuf;
|
||||
import net.minecraft.network.RegistryFriendlyByteBuf;
|
||||
import net.minecraft.network.protocol.Packet;
|
||||
import net.minecraft.network.protocol.game.ClientGamePacketListener;
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
@@ -41,7 +42,7 @@ public class SpawnEntityPacket {
|
||||
if (entity.level().isClientSide()) {
|
||||
throw new IllegalStateException("SpawnPacketUtil.create called on the logical client!");
|
||||
}
|
||||
var buffer = new FriendlyByteBuf(Unpooled.buffer());
|
||||
var buffer = new RegistryFriendlyByteBuf(Unpooled.buffer(), entity.registryAccess());
|
||||
buffer.writeVarInt(BuiltInRegistries.ENTITY_TYPE.getId(entity.getType()));
|
||||
buffer.writeUUID(entity.getUUID());
|
||||
buffer.writeVarInt(entity.getId());
|
||||
@@ -62,6 +63,10 @@ public class SpawnEntityPacket {
|
||||
return (Packet<ClientGamePacketListener>) NetworkManager.toPacket(NetworkManager.s2c(), PACKET_ID, buffer);
|
||||
}
|
||||
|
||||
public static void register() {
|
||||
NetworkManager.registerS2CPayloadType(PACKET_ID);
|
||||
}
|
||||
|
||||
|
||||
@Environment(EnvType.CLIENT)
|
||||
public static class Client {
|
||||
|
||||
@@ -33,7 +33,7 @@ public abstract class BaseC2SMessage extends Message {
|
||||
@Environment(EnvType.CLIENT)
|
||||
public final void sendToServer() {
|
||||
if (Minecraft.getInstance().getConnection() != null) {
|
||||
Minecraft.getInstance().getConnection().send(toPacket());
|
||||
Minecraft.getInstance().getConnection().send(toPacket(Minecraft.getInstance().level.registryAccess()));
|
||||
} else {
|
||||
throw new IllegalStateException("Unable to send packet to the server while not in game!");
|
||||
}
|
||||
|
||||
@@ -44,7 +44,7 @@ public abstract class BaseS2CMessage extends Message {
|
||||
* @param player the player
|
||||
*/
|
||||
public final void sendTo(ServerPlayer player) {
|
||||
sendTo(player, toPacket());
|
||||
sendTo(player, toPacket(player.registryAccess()));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -53,7 +53,8 @@ public abstract class BaseS2CMessage extends Message {
|
||||
* @param players the players
|
||||
*/
|
||||
public final void sendTo(Iterable<ServerPlayer> players) {
|
||||
Packet<?> packet = toPacket();
|
||||
if (!players.iterator().hasNext()) return;
|
||||
Packet<?> packet = toPacket(players.iterator().next().registryAccess());
|
||||
|
||||
for (ServerPlayer player : players) {
|
||||
sendTo(player, packet);
|
||||
@@ -84,7 +85,7 @@ public abstract class BaseS2CMessage extends Message {
|
||||
* @param chunk the listened chunk
|
||||
*/
|
||||
public final void sendToChunkListeners(LevelChunk chunk) {
|
||||
Packet<?> packet = toPacket();
|
||||
Packet<?> packet = toPacket(chunk.getLevel().registryAccess());
|
||||
((ServerChunkCache) chunk.getLevel().getChunkSource()).chunkMap.getPlayers(chunk.getPos(), false).forEach(e -> sendTo(e, packet));
|
||||
}
|
||||
}
|
||||
@@ -21,7 +21,8 @@ package dev.architectury.networking.simple;
|
||||
|
||||
import dev.architectury.networking.NetworkManager;
|
||||
import io.netty.buffer.Unpooled;
|
||||
import net.minecraft.network.FriendlyByteBuf;
|
||||
import net.minecraft.core.RegistryAccess;
|
||||
import net.minecraft.network.RegistryFriendlyByteBuf;
|
||||
import net.minecraft.network.protocol.Packet;
|
||||
|
||||
/**
|
||||
@@ -48,7 +49,7 @@ public abstract class Message {
|
||||
*
|
||||
* @param buf the byte buffer
|
||||
*/
|
||||
public abstract void write(FriendlyByteBuf buf);
|
||||
public abstract void write(RegistryFriendlyByteBuf buf);
|
||||
|
||||
/**
|
||||
* Handles this message when it is received.
|
||||
@@ -62,8 +63,8 @@ public abstract class Message {
|
||||
*
|
||||
* @return the converted {@link Packet}
|
||||
*/
|
||||
public final Packet<?> toPacket() {
|
||||
FriendlyByteBuf buf = new FriendlyByteBuf(Unpooled.buffer());
|
||||
public final Packet<?> toPacket(RegistryAccess access) {
|
||||
RegistryFriendlyByteBuf buf = new RegistryFriendlyByteBuf(Unpooled.buffer(), access);
|
||||
write(buf);
|
||||
return NetworkManager.toPacket(getType().getSide(), getType().getId(), buf);
|
||||
}
|
||||
|
||||
@@ -20,10 +20,10 @@
|
||||
package dev.architectury.networking.simple;
|
||||
|
||||
import dev.architectury.networking.NetworkManager;
|
||||
import net.minecraft.network.FriendlyByteBuf;
|
||||
import net.minecraft.network.RegistryFriendlyByteBuf;
|
||||
|
||||
/**
|
||||
* Decodes a {@link Message} from a {@link FriendlyByteBuf}.
|
||||
* Decodes a {@link Message} from a {@link RegistryFriendlyByteBuf}.
|
||||
*
|
||||
* @param <T> the message type handled by this decoder
|
||||
* @author LatvianModder
|
||||
@@ -36,17 +36,17 @@ public interface MessageDecoder<T extends Message> {
|
||||
* @param buf the byte buffer
|
||||
* @return the decoded instance
|
||||
*/
|
||||
T decode(FriendlyByteBuf buf);
|
||||
T decode(RegistryFriendlyByteBuf buf);
|
||||
|
||||
/**
|
||||
* Creates a network receiver from this decoder.
|
||||
*
|
||||
* <p>The returned receiver will first {@linkplain #decode(FriendlyByteBuf) decode a message}
|
||||
* <p>The returned receiver will first {@linkplain #decode(RegistryFriendlyByteBuf) decode a message}
|
||||
* and then call {@link Message#handle(NetworkManager.PacketContext)} on the decoded message.
|
||||
*
|
||||
* @return the created receiver
|
||||
*/
|
||||
default NetworkManager.NetworkReceiver createReceiver() {
|
||||
default NetworkManager.NetworkReceiver<RegistryFriendlyByteBuf> createReceiver() {
|
||||
return (buf, context) -> {
|
||||
Message packet = decode(buf);
|
||||
context.queue(() -> packet.handle(context));
|
||||
|
||||
@@ -23,6 +23,7 @@ import dev.architectury.networking.NetworkManager;
|
||||
import dev.architectury.networking.transformers.PacketTransformer;
|
||||
import dev.architectury.platform.Platform;
|
||||
import dev.architectury.utils.Env;
|
||||
import net.minecraft.network.RegistryFriendlyByteBuf;
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
import org.jetbrains.annotations.ApiStatus;
|
||||
|
||||
@@ -77,7 +78,7 @@ public class SimpleNetworkManager {
|
||||
MessageType messageType = new MessageType(this, new ResourceLocation(namespace, id), NetworkManager.s2c());
|
||||
|
||||
if (Platform.getEnvironment() == Env.CLIENT) {
|
||||
NetworkManager.NetworkReceiver receiver = decoder.createReceiver();
|
||||
NetworkManager.NetworkReceiver<RegistryFriendlyByteBuf> receiver = decoder.createReceiver();
|
||||
NetworkManager.registerReceiver(NetworkManager.s2c(), messageType.getId(), transformers, receiver);
|
||||
}
|
||||
|
||||
@@ -107,7 +108,7 @@ public class SimpleNetworkManager {
|
||||
@ApiStatus.Experimental
|
||||
public MessageType registerC2S(String id, MessageDecoder<BaseC2SMessage> decoder, List<PacketTransformer> transformers) {
|
||||
MessageType messageType = new MessageType(this, new ResourceLocation(namespace, id), NetworkManager.c2s());
|
||||
NetworkManager.NetworkReceiver receiver = decoder.createReceiver();
|
||||
NetworkManager.NetworkReceiver<RegistryFriendlyByteBuf> receiver = decoder.createReceiver();
|
||||
NetworkManager.registerReceiver(NetworkManager.c2s(), messageType.getId(), transformers, receiver);
|
||||
return messageType;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,21 @@
|
||||
/*
|
||||
* This file is part of architectury.
|
||||
* Copyright (C) 2020, 2021, 2022 architectury
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
@Deprecated(forRemoval = true)
|
||||
package dev.architectury.networking.simple;
|
||||
@@ -20,7 +20,7 @@
|
||||
package dev.architectury.networking.transformers;
|
||||
|
||||
import dev.architectury.networking.NetworkManager;
|
||||
import net.minecraft.network.FriendlyByteBuf;
|
||||
import net.minecraft.network.RegistryFriendlyByteBuf;
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
import org.jetbrains.annotations.ApiStatus;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
@@ -31,24 +31,24 @@ import java.util.List;
|
||||
|
||||
@ApiStatus.Experimental
|
||||
public interface PacketTransformer {
|
||||
void inbound(NetworkManager.Side side, ResourceLocation id, FriendlyByteBuf buf, NetworkManager.PacketContext context, TransformationSink sink);
|
||||
void inbound(NetworkManager.Side side, ResourceLocation id, RegistryFriendlyByteBuf buf, NetworkManager.PacketContext context, TransformationSink sink);
|
||||
|
||||
void outbound(NetworkManager.Side side, ResourceLocation id, FriendlyByteBuf buf, TransformationSink sink);
|
||||
void outbound(NetworkManager.Side side, ResourceLocation id, RegistryFriendlyByteBuf buf, TransformationSink sink);
|
||||
|
||||
@FunctionalInterface
|
||||
interface TransformationSink {
|
||||
void accept(NetworkManager.Side side, ResourceLocation id, FriendlyByteBuf buf);
|
||||
void accept(NetworkManager.Side side, ResourceLocation id, RegistryFriendlyByteBuf buf);
|
||||
}
|
||||
|
||||
static PacketTransformer none() {
|
||||
return new PacketTransformer() {
|
||||
@Override
|
||||
public void inbound(NetworkManager.Side side, ResourceLocation id, FriendlyByteBuf buf, NetworkManager.PacketContext context, TransformationSink sink) {
|
||||
public void inbound(NetworkManager.Side side, ResourceLocation id, RegistryFriendlyByteBuf buf, NetworkManager.PacketContext context, TransformationSink sink) {
|
||||
sink.accept(side, id, buf);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void outbound(NetworkManager.Side side, ResourceLocation id, FriendlyByteBuf buf, TransformationSink sink) {
|
||||
public void outbound(NetworkManager.Side side, ResourceLocation id, RegistryFriendlyByteBuf buf, TransformationSink sink) {
|
||||
sink.accept(side, id, buf);
|
||||
}
|
||||
};
|
||||
@@ -62,16 +62,16 @@ public interface PacketTransformer {
|
||||
}
|
||||
return new PacketTransformer() {
|
||||
@Override
|
||||
public void inbound(NetworkManager.Side side, ResourceLocation id, FriendlyByteBuf buf, NetworkManager.PacketContext context, TransformationSink sink) {
|
||||
public void inbound(NetworkManager.Side side, ResourceLocation id, RegistryFriendlyByteBuf buf, NetworkManager.PacketContext context, TransformationSink sink) {
|
||||
traverse(side, id, buf, context, sink, true, 0);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void outbound(NetworkManager.Side side, ResourceLocation id, FriendlyByteBuf buf, TransformationSink sink) {
|
||||
public void outbound(NetworkManager.Side side, ResourceLocation id, RegistryFriendlyByteBuf buf, TransformationSink sink) {
|
||||
traverse(side, id, buf, null, sink, false, 0);
|
||||
}
|
||||
|
||||
private void traverse(NetworkManager.Side side, ResourceLocation id, FriendlyByteBuf buf, @Nullable NetworkManager.PacketContext context, TransformationSink outerSink, boolean inbound, int index) {
|
||||
private void traverse(NetworkManager.Side side, ResourceLocation id, RegistryFriendlyByteBuf buf, @Nullable NetworkManager.PacketContext context, TransformationSink outerSink, boolean inbound, int index) {
|
||||
if (transformers instanceof List) {
|
||||
if (((List<? extends PacketTransformer>) transformers).size() > index) {
|
||||
PacketTransformer transformer = ((List<? extends PacketTransformer>) transformers).get(index);
|
||||
|
||||
@@ -28,7 +28,7 @@ import io.netty.buffer.ByteBuf;
|
||||
import io.netty.buffer.Unpooled;
|
||||
import net.fabricmc.api.EnvType;
|
||||
import net.fabricmc.api.Environment;
|
||||
import net.minecraft.network.FriendlyByteBuf;
|
||||
import net.minecraft.network.RegistryFriendlyByteBuf;
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
import org.apache.logging.log4j.LogManager;
|
||||
import org.apache.logging.log4j.Logger;
|
||||
@@ -81,7 +81,7 @@ public class SplitPacketTransformer implements PacketTransformer {
|
||||
private static class PartData {
|
||||
private final ResourceLocation id;
|
||||
private final int partsExpected;
|
||||
private final List<FriendlyByteBuf> parts;
|
||||
private final List<RegistryFriendlyByteBuf> parts;
|
||||
|
||||
public PartData(ResourceLocation id, int partsExpected) {
|
||||
this.id = id;
|
||||
@@ -109,7 +109,7 @@ public class SplitPacketTransformer implements PacketTransformer {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void inbound(NetworkManager.Side side, ResourceLocation id, FriendlyByteBuf buf, NetworkManager.PacketContext context, TransformationSink sink) {
|
||||
public void inbound(NetworkManager.Side side, ResourceLocation id, RegistryFriendlyByteBuf buf, NetworkManager.PacketContext context, TransformationSink sink) {
|
||||
PartKey key = side == NetworkManager.Side.S2C ? new PartKey(side, null) : new PartKey(side, context.getPlayer().getUUID());
|
||||
PartData data;
|
||||
switch (buf.readByte()) {
|
||||
@@ -128,7 +128,7 @@ public class SplitPacketTransformer implements PacketTransformer {
|
||||
} else if (!data.id.equals(id)) {
|
||||
LOGGER.warn("Received invalid PART packet for SplitPacketTransformer with packet id " + id + " for side " + side + ", id in cache is " + data.id);
|
||||
buf.release();
|
||||
for (FriendlyByteBuf part : data.parts) {
|
||||
for (RegistryFriendlyByteBuf part : data.parts) {
|
||||
if (part != buf) {
|
||||
part.release();
|
||||
}
|
||||
@@ -146,7 +146,7 @@ public class SplitPacketTransformer implements PacketTransformer {
|
||||
} else if (!data.id.equals(id)) {
|
||||
LOGGER.warn("Received invalid END packet for SplitPacketTransformer with packet id " + id + " for side " + side + ", id in cache is " + data.id);
|
||||
buf.release();
|
||||
for (FriendlyByteBuf part : data.parts) {
|
||||
for (RegistryFriendlyByteBuf part : data.parts) {
|
||||
if (part != buf) {
|
||||
part.release();
|
||||
}
|
||||
@@ -158,13 +158,13 @@ public class SplitPacketTransformer implements PacketTransformer {
|
||||
}
|
||||
if (data.parts.size() != data.partsExpected) {
|
||||
LOGGER.warn("Received invalid END packet for SplitPacketTransformer with packet id " + id + " for side " + side + " with size " + data.parts + ", parts expected is " + data.partsExpected);
|
||||
for (FriendlyByteBuf part : data.parts) {
|
||||
for (RegistryFriendlyByteBuf part : data.parts) {
|
||||
if (part != buf) {
|
||||
part.release();
|
||||
}
|
||||
}
|
||||
} else {
|
||||
FriendlyByteBuf byteBuf = new FriendlyByteBuf(Unpooled.wrappedBuffer(data.parts.toArray(new ByteBuf[0])));
|
||||
RegistryFriendlyByteBuf byteBuf = new RegistryFriendlyByteBuf(Unpooled.wrappedBuffer(data.parts.toArray(new ByteBuf[0])), buf.registryAccess());
|
||||
sink.accept(side, data.id, byteBuf);
|
||||
byteBuf.release();
|
||||
}
|
||||
@@ -179,18 +179,18 @@ public class SplitPacketTransformer implements PacketTransformer {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void outbound(NetworkManager.Side side, ResourceLocation id, FriendlyByteBuf buf, TransformationSink sink) {
|
||||
public void outbound(NetworkManager.Side side, ResourceLocation id, RegistryFriendlyByteBuf buf, TransformationSink sink) {
|
||||
int maxSize = (side == NetworkManager.Side.C2S ? 32767 : 1048576) - 1 - 20 - id.toString().getBytes(StandardCharsets.UTF_8).length;
|
||||
if (buf.readableBytes() <= maxSize) {
|
||||
ByteBuf stateBuf = Unpooled.buffer(1);
|
||||
stateBuf.writeByte(ONLY);
|
||||
FriendlyByteBuf packetBuffer = new FriendlyByteBuf(Unpooled.wrappedBuffer(stateBuf, buf));
|
||||
RegistryFriendlyByteBuf packetBuffer = new RegistryFriendlyByteBuf(Unpooled.wrappedBuffer(stateBuf, buf), buf.registryAccess());
|
||||
sink.accept(side, id, packetBuffer);
|
||||
} else {
|
||||
int partSize = maxSize - 4;
|
||||
int parts = (int) Math.ceil(buf.readableBytes() / (float) partSize);
|
||||
for (int i = 0; i < parts; i++) {
|
||||
FriendlyByteBuf packetBuffer = new FriendlyByteBuf(Unpooled.buffer());
|
||||
RegistryFriendlyByteBuf packetBuffer = new RegistryFriendlyByteBuf(Unpooled.buffer(), buf.registryAccess());
|
||||
if (i == 0) {
|
||||
packetBuffer.writeByte(START);
|
||||
packetBuffer.writeInt(parts);
|
||||
|
||||
Reference in New Issue
Block a user