2323
2424package me .shedaniel .rei .plugin .common .displays .tag ;
2525
26+ import com .google .common .collect .Maps ;
2627import com .mojang .serialization .DataResult ;
2728import dev .architectury .event .events .client .ClientLifecycleEvent ;
28- import dev .architectury .impl .NetworkAggregator ;
2929import dev .architectury .networking .NetworkManager ;
30- import dev .architectury .networking .transformers .SplitPacketTransformer ;
31- import dev .architectury .platform .Platform ;
3230import dev .architectury .utils .Env ;
3331import dev .architectury .utils .EnvExecutor ;
34- import io .netty .buffer .Unpooled ;
3532import it .unimi .dsi .fastutil .ints .IntArrayList ;
3633import it .unimi .dsi .fastutil .ints .IntList ;
37- import me .shedaniel .rei .api .common .display . basic . BasicDisplay ;
34+ import me .shedaniel .rei .api .common .util . UUIDUtils ;
3835import net .fabricmc .api .EnvType ;
3936import net .fabricmc .api .Environment ;
4037import net .minecraft .client .Minecraft ;
4138import net .minecraft .core .Holder ;
4239import net .minecraft .core .HolderSet ;
4340import net .minecraft .core .Registry ;
4441import net .minecraft .core .registries .BuiltInRegistries ;
45- import net .minecraft .network .FriendlyByteBuf ;
4642import net .minecraft .network .RegistryFriendlyByteBuf ;
43+ import net .minecraft .network .codec .ByteBufCodecs ;
44+ import net .minecraft .network .codec .StreamCodec ;
45+ import net .minecraft .network .protocol .common .custom .CustomPacketPayload ;
4746import net .minecraft .resources .ResourceKey ;
4847import net .minecraft .resources .ResourceLocation ;
4948import net .minecraft .server .level .ServerPlayer ;
5049import net .minecraft .tags .TagKey ;
5150import org .jetbrains .annotations .ApiStatus ;
51+ import org .jetbrains .annotations .NotNull ;
5252
5353import java .util .*;
5454import java .util .concurrent .ConcurrentHashMap ;
5757
5858@ ApiStatus .Internal
5959public class TagNodes {
60- public static final ResourceLocation REQUEST_TAGS_PACKET_C2S = ResourceLocation .fromNamespaceAndPath ("roughlyenoughitems" , "request_tags_c2s" );
61- public static final ResourceLocation REQUEST_TAGS_PACKET_S2C = ResourceLocation .fromNamespaceAndPath ("roughlyenoughitems" , "request_tags_s2c" );
60+ public static final ResourceLocation REQUEST_TAGS_C2S_PACKET_ID = ResourceLocation .fromNamespaceAndPath ("roughlyenoughitems" , "request_tags_c2s" );
61+ public static final ResourceLocation REQUEST_TAGS_S2C_PACKET_ID = ResourceLocation .fromNamespaceAndPath ("roughlyenoughitems" , "request_tags_s2c" );
62+
63+ public static final CustomPacketPayload .Type <C2STagDataPacket > REQUEST_TAGS_C2S_PACKET_TYPE = new CustomPacketPayload .Type <>(REQUEST_TAGS_C2S_PACKET_ID );
64+ public static final CustomPacketPayload .Type <S2CTagDataPacket > REQUEST_TAGS_S2C_PACKET_TYPE = new CustomPacketPayload .Type <>(REQUEST_TAGS_S2C_PACKET_ID );
6265
6366 public static final Map <String , ResourceKey <? extends Registry <?>>> TAG_DIR_MAP = new HashMap <>();
6467 public static final ThreadLocal <String > CURRENT_TAG_DIR = new ThreadLocal <>();
@@ -88,78 +91,72 @@ public record RawTagData(List<ResourceLocation> otherElements, List<ResourceLoca
8891 }
8992
9093 public record TagData (IntList otherElements , List <ResourceLocation > otherTags ) {
91- private static TagData fromNetwork ( FriendlyByteBuf buf ) {
92- int count = buf . readVarInt ();
93- IntList otherElements = new IntArrayList ( count + 1 );
94- for ( int i = 0 ; i < count ; i ++) {
95- otherElements . add ( buf . readVarInt () );
96- }
97- count = buf . readVarInt ();
98- List < ResourceLocation > otherTags = new ArrayList <>( count + 1 );
99- for ( int i = 0 ; i < count ; i ++) {
100- otherTags . add ( buf . readResourceLocation ());
101- }
102- return new TagData ( otherElements , otherTags );
103- }
94+ public static final StreamCodec < RegistryFriendlyByteBuf , TagData > STREAM_CODEC = StreamCodec . composite (
95+ ByteBufCodecs . collection ( IntArrayList :: new , ByteBufCodecs . VAR_INT ), TagData :: otherElements ,
96+ ByteBufCodecs . collection ( ArrayList :: new , ResourceLocation . STREAM_CODEC ), TagData :: otherTags ,
97+ TagData :: new
98+ );
99+ }
100+
101+ public record C2STagDataPacket ( UUID uuid , ResourceLocation registryName ) implements CustomPacketPayload {
102+ public static final StreamCodec < RegistryFriendlyByteBuf , C2STagDataPacket > STREAM_CODEC = StreamCodec . composite (
103+ UUIDUtils . STREAM_CODEC , C2STagDataPacket :: uuid ,
104+ ResourceLocation . STREAM_CODEC , C2STagDataPacket :: registryName ,
105+ C2STagDataPacket :: new
106+ );
104107
105- private void toNetwork (FriendlyByteBuf buf ) {
106- buf .writeVarInt (otherElements .size ());
107- for (int integer : otherElements ) {
108- buf .writeVarInt (integer );
109- }
110- buf .writeVarInt (otherTags .size ());
111- for (ResourceLocation tag : otherTags ) {
112- writeResourceLocation (buf , tag );
113- }
108+ @ Override
109+ public @ NotNull Type <? extends CustomPacketPayload > type () {
110+ return REQUEST_TAGS_C2S_PACKET_TYPE ;
114111 }
115112 }
116113
117- private static void writeResourceLocation (FriendlyByteBuf buf , ResourceLocation location ) {
118- if (location .getNamespace ().equals ("minecraft" )) {
119- buf .writeUtf (location .getPath ());
120- } else {
121- buf .writeUtf (location .toString ());
114+ public record S2CTagDataPacket (UUID uuid , Map <ResourceLocation , TagData > map ) implements CustomPacketPayload {
115+ public static final StreamCodec <RegistryFriendlyByteBuf , S2CTagDataPacket > STREAM_CODEC = StreamCodec .composite (
116+ UUIDUtils .STREAM_CODEC , S2CTagDataPacket ::uuid ,
117+ ByteBufCodecs .map (
118+ Maps ::newHashMapWithExpectedSize ,
119+ ResourceLocation .STREAM_CODEC ,
120+ TagData .STREAM_CODEC
121+ ), S2CTagDataPacket ::map ,
122+ S2CTagDataPacket ::new
123+ );
124+
125+ @ Override
126+ public @ NotNull Type <? extends CustomPacketPayload > type () {
127+ return REQUEST_TAGS_S2C_PACKET_TYPE ;
122128 }
123129 }
124130
125131 public static void init () {
126132 EnvExecutor .runInEnv (Env .CLIENT , () -> Client ::init );
127-
128- // Fix for TagNodes not being loaded on the server
129- // A bit hacky as it uses Architectury's internal API, but this class needs rewriting to use codecs due to the deprecation of the old serialization system anyway.
130- if (Platform .getEnvironment () != Env .CLIENT ) {
131- NetworkAggregator .registerS2CType (REQUEST_TAGS_PACKET_S2C , Collections .singletonList (new SplitPacketTransformer ()));
132- }
133+ EnvExecutor .runInEnv (Env .SERVER , () -> Server ::init );
133134
134- NetworkManager .registerReceiver (NetworkManager .c2s (), REQUEST_TAGS_PACKET_C2S , Collections .singletonList (new SplitPacketTransformer ()), (buf , context ) -> {
135- UUID uuid = buf .readUUID ();
136- ResourceKey <? extends Registry <?>> resourceKey = ResourceKey .createRegistryKey (buf .readResourceLocation ());
137- RegistryFriendlyByteBuf newBuf = new RegistryFriendlyByteBuf (Unpooled .buffer (), context .registryAccess ());
138- newBuf .writeUUID (uuid );
139- Map <ResourceLocation , TagData > dataMap = TAG_DATA_MAP .getOrDefault (resourceKey , Collections .emptyMap ());
140- newBuf .writeInt (dataMap .size ());
141- for (Map .Entry <ResourceLocation , TagData > entry : dataMap .entrySet ()) {
142- writeResourceLocation (newBuf , entry .getKey ());
143- entry .getValue ().toNetwork (newBuf );
144- }
145- NetworkManager .sendToPlayer ((ServerPlayer ) context .getPlayer (), REQUEST_TAGS_PACKET_S2C , newBuf );
146- });
135+ NetworkManager .registerReceiver (
136+ NetworkManager .c2s (),
137+ REQUEST_TAGS_C2S_PACKET_TYPE ,
138+ C2STagDataPacket .STREAM_CODEC ,
139+ (C2STagDataPacket payload , NetworkManager .PacketContext context ) -> {
140+ ResourceKey <? extends Registry <?>> registryKey = ResourceKey .createRegistryKey (payload .registryName );
141+ Map <ResourceLocation , TagData > dataMap = TAG_DATA_MAP .getOrDefault (registryKey , Collections .emptyMap ());
142+ var packet = new S2CTagDataPacket (payload .uuid , dataMap );
143+ NetworkManager .sendToPlayer ((ServerPlayer ) context .getPlayer (), packet );
144+ }
145+ );
147146 }
148147
149148 @ Environment (EnvType .CLIENT )
150149 public static void requestTagData (ResourceKey <? extends Registry <?>> resourceKey , Consumer <DataResult <Map <ResourceLocation , TagData >>> callback ) {
151150 if (Minecraft .getInstance ().getSingleplayerServer () != null ) {
152151 callback .accept (DataResult .success (TAG_DATA_MAP .get (resourceKey )));
153- } else if (!NetworkManager .canServerReceive (REQUEST_TAGS_PACKET_C2S )) {
152+ } else if (!NetworkManager .canServerReceive (REQUEST_TAGS_C2S_PACKET_ID )) {
154153 callback .accept (DataResult .error (() -> "Cannot request tags from server" ));
155154 } else if (requestedTags .containsKey (resourceKey )) {
156155 requestedTags .get (resourceKey ).accept (callback );
157156 callback .accept (DataResult .success (TAG_DATA_MAP .getOrDefault (resourceKey , Collections .emptyMap ())));
158157 } else {
159- RegistryFriendlyByteBuf buf = new RegistryFriendlyByteBuf (Unpooled .buffer (), BasicDisplay .registryAccess ());
160158 UUID uuid = UUID .randomUUID ();
161- buf .writeUUID (uuid );
162- buf .writeResourceLocation (resourceKey .location ());
159+ var packet = new C2STagDataPacket (uuid , resourceKey .location ());
163160 Client .nextUUID = uuid ;
164161 Client .nextResourceKey = resourceKey ;
165162 List <Consumer <DataResult <Map <ResourceLocation , TagData >>>> callbacks = new CopyOnWriteArrayList <>();
@@ -171,7 +168,13 @@ public static void requestTagData(ResourceKey<? extends Registry<?>> resourceKey
171168 }
172169 };
173170 requestedTags .put (resourceKey , callbacks ::add );
174- NetworkManager .sendToServer (REQUEST_TAGS_PACKET_C2S , buf );
171+ NetworkManager .sendToServer (packet );
172+ }
173+ }
174+
175+ private static class Server {
176+ private static void init () {
177+ NetworkManager .registerS2CPayloadType (REQUEST_TAGS_S2C_PACKET_TYPE , S2CTagDataPacket .STREAM_CODEC );
175178 }
176179 }
177180
@@ -184,23 +187,22 @@ private static void init() {
184187 ClientLifecycleEvent .CLIENT_LEVEL_LOAD .register (world -> {
185188 requestedTags .clear ();
186189 });
187- NetworkManager .registerReceiver (NetworkManager .s2c (), REQUEST_TAGS_PACKET_S2C , (buf , context ) -> {
188- UUID uuid = buf .readUUID ();
189- if (nextUUID .equals (uuid )) {
190- Map <ResourceLocation , TagData > map = new HashMap <>();
191- int count = buf .readInt ();
192- for (int i = 0 ; i < count ; i ++) {
193- map .put (buf .readResourceLocation (), TagData .fromNetwork (buf ));
190+
191+ NetworkManager .registerReceiver (
192+ NetworkManager .s2c (),
193+ REQUEST_TAGS_S2C_PACKET_TYPE ,
194+ S2CTagDataPacket .STREAM_CODEC ,
195+ (S2CTagDataPacket payload , NetworkManager .PacketContext context ) -> {
196+ if (!nextUUID .equals (payload .uuid )) return ;
197+
198+ TAG_DATA_MAP .put (nextResourceKey , payload .map );
199+ nextCallback .accept (DataResult .success (payload .map ));
200+
201+ nextUUID = null ;
202+ nextResourceKey = null ;
203+ nextCallback = null ;
194204 }
195-
196- TAG_DATA_MAP .put (nextResourceKey , map );
197- nextCallback .accept (DataResult .success (map ));
198-
199- nextUUID = null ;
200- nextResourceKey = null ;
201- nextCallback = null ;
202- }
203- });
205+ );
204206 }
205207 }
206208
@@ -232,7 +234,8 @@ private static <T> Optional<DataResult<TagNode<T>>> resolveTag(TagKey<T> tagKey,
232234 Optional <DataResult <TagNode <T >>> resultOptional = resolveTag (childTagKey , registry , tagDataMap );
233235 if (resultOptional .isPresent ()) {
234236 DataResult <TagNode <T >> result = resultOptional .get ();
235- if (result .error ().isPresent ()) return Optional .of (DataResult .error (() -> result .error ().get ().message ()));
237+ if (result .error ().isPresent ())
238+ return Optional .of (DataResult .error (() -> result .error ().get ().message ()));
236239 self .addChild (result .result ().get ());
237240 }
238241 }
0 commit comments