diff --git a/common/src/main/java/me/shedaniel/architectury/networking/NetworkChannel.java b/common/src/main/java/me/shedaniel/architectury/networking/NetworkChannel.java index a38d23f1..75d8c282 100644 --- a/common/src/main/java/me/shedaniel/architectury/networking/NetworkChannel.java +++ b/common/src/main/java/me/shedaniel/architectury/networking/NetworkChannel.java @@ -19,11 +19,9 @@ package me.shedaniel.architectury.networking; -import com.google.common.collect.HashBasedTable; -import com.google.common.collect.Table; +import com.google.common.collect.Maps; +import com.mojang.datafixers.util.Pair; import io.netty.buffer.Unpooled; -import it.unimi.dsi.fastutil.ints.IntOpenHashSet; -import it.unimi.dsi.fastutil.ints.IntSet; import me.shedaniel.architectury.networking.NetworkManager.PacketContext; import me.shedaniel.architectury.platform.Platform; import me.shedaniel.architectury.utils.Env; @@ -34,8 +32,9 @@ import net.minecraft.network.FriendlyByteBuf; import net.minecraft.network.protocol.Packet; import net.minecraft.resources.ResourceLocation; import net.minecraft.server.level.ServerPlayer; -import org.apache.commons.lang3.tuple.Pair; +import org.apache.commons.lang3.StringUtils; +import java.util.Map; import java.util.Objects; import java.util.Optional; import java.util.function.BiConsumer; @@ -47,8 +46,7 @@ import java.util.function.Supplier; */ public final class NetworkChannel { private final ResourceLocation id; - private final IntSet takenIds = new IntOpenHashSet(); - private final Table, Pair>> encoders = HashBasedTable.create(); + private final Map, MessageInfo> encoders = Maps.newHashMap(); private NetworkChannel(ResourceLocation id) { this.id = id; @@ -60,70 +58,66 @@ public final class NetworkChannel { @Deprecated public void register(NetworkManager.Side side, Class type, BiConsumer encoder, Function decoder, BiConsumer> messageConsumer) { - register(Optional.empty(), type, encoder, decoder, messageConsumer); + register(type, encoder, decoder, messageConsumer); } @Deprecated public void register(Optional side, Class type, BiConsumer encoder, Function decoder, BiConsumer> messageConsumer) { - for (int i = 0; true; i++) { - if (!takenIds.contains(i)) { - register(side, i, type, encoder, decoder, messageConsumer); - break; - } - } + register(type, encoder, decoder, messageConsumer); } public void register(Class type, BiConsumer encoder, Function decoder, BiConsumer> messageConsumer) { - for (int i = 0; true; i++) { - if (!takenIds.contains(i)) { - register(i, type, encoder, decoder, messageConsumer); - break; - } + String s = StringUtils.leftPad(String.valueOf(hashCodeString(type.toString())), 10, '0'); + if (s.length() > 10) s = s.substring(0, 10); + MessageInfo info = new MessageInfo<>(new ResourceLocation(id + "_" + s), encoder, decoder, messageConsumer); + encoders.put(type, info); + NetworkManager.NetworkReceiver receiver = (buf, context) -> { + info.messageConsumer.accept(info.decoder.apply(buf), () -> context); + }; + NetworkManager.registerReceiver(NetworkManager.clientToServer(), info.packetId, receiver); + if (Platform.getEnvironment() == Env.CLIENT) { + NetworkManager.registerReceiver(NetworkManager.serverToClient(), info.packetId, receiver); } } + public static long hashCodeString(String str) { + long h = 0; + int length = str.length(); + for (int i = 0; i < length; i++) { + h = 31 * h + str.charAt(i); + } + return h; + } + + @Deprecated public void register(int id, Class type, BiConsumer encoder, Function decoder, BiConsumer> messageConsumer) { - register(Optional.empty(), id, type, encoder, decoder, messageConsumer); + register(type, encoder, decoder, messageConsumer); } @Deprecated public void register(NetworkManager.Side side, int id, Class type, BiConsumer encoder, Function decoder, BiConsumer> messageConsumer) { - register(Optional.ofNullable(side), id, type, encoder, decoder, messageConsumer); + register(type, encoder, decoder, messageConsumer); } @Deprecated public void register(Optional side, int id, Class type, BiConsumer encoder, Function decoder, BiConsumer> messageConsumer) { - takenIds.add(id); - ResourceLocation messageId = new ResourceLocation(this.id.getNamespace(), this.id.getPath() + "_" + id); - - if (Platform.getEnvironment() == Env.CLIENT) { - NetworkManager.registerReceiver(NetworkManager.s2c(), messageId, (buf, context) -> { - messageConsumer.accept(decoder.apply(buf), () -> context); - }); - } - encoders.put(NetworkManager.s2c(), type, Pair.of(messageId, encoder)); - - NetworkManager.registerReceiver(NetworkManager.c2s(), messageId, (buf, context) -> { - messageConsumer.accept(decoder.apply(buf), () -> context); - }); - encoders.put(NetworkManager.c2s(), type, Pair.of(messageId, encoder)); + register(type, encoder, decoder, messageConsumer); } - private Pair encode(NetworkManager.Side side, T message) { - Pair> pair = Objects.requireNonNull(encoders.get(side, message.getClass())); + private Pair, FriendlyByteBuf> encode(T message) { + MessageInfo messageInfo = (MessageInfo) Objects.requireNonNull(encoders.get(message.getClass())); FriendlyByteBuf buf = new FriendlyByteBuf(Unpooled.buffer()); - ((BiConsumer) pair.getRight()).accept(message, buf); - return Pair.of(pair.getLeft(), buf); + messageInfo.encoder.accept(message, buf); + return new Pair<>(messageInfo, buf); } public Packet toPacket(NetworkManager.Side side, T message) { - Pair encoded = encode(side, message); - return NetworkManager.toPacket(side, encoded.getLeft(), encoded.getRight()); + Pair, FriendlyByteBuf> encoded = encode(message); + return NetworkManager.toPacket(side, encoded.getFirst().packetId, encoded.getSecond()); } public void sendToPlayer(ServerPlayer player, T message) { - Pair encoded = encode(NetworkManager.s2c(), message); - NetworkManager.sendToPlayer(player, encoded.getLeft(), encoded.getRight()); + player.connection.send(toPacket(NetworkManager.s2c(), message)); } public void sendToPlayers(Iterable players, T message) { @@ -140,10 +134,24 @@ public final class NetworkChannel { @Environment(EnvType.CLIENT) public boolean canServerReceive(Class type) { - return NetworkManager.canServerReceive(encoders.get(NetworkManager.c2s(), type).getLeft()); + return NetworkManager.canServerReceive(encoders.get(type).packetId); } public boolean canPlayerReceive(ServerPlayer player, Class type) { - return NetworkManager.canPlayerReceive(player, encoders.get(NetworkManager.s2c(), type).getLeft()); + return NetworkManager.canPlayerReceive(player, encoders.get(type).packetId); + } + + private static final class MessageInfo { + private final ResourceLocation packetId; + private final BiConsumer encoder; + private final Function decoder; + private final BiConsumer> messageConsumer; + + public MessageInfo(ResourceLocation packetId, BiConsumer encoder, Function decoder, BiConsumer> messageConsumer) { + this.packetId = packetId; + this.encoder = encoder; + this.decoder = decoder; + this.messageConsumer = messageConsumer; + } } }