mirror of
https://github.com/architectury/architectury-api.git
synced 2026-03-28 03:56:59 -05:00
Fix breakage in NeoForge 20.5.14, fix crash when registering packets on Fabric, fix players getting kicked when a S2C packet is sent to them. (#499)
* Fix #497 * Fix #496 * Fix #498 * Add test for #498 * Update architectury.mixins.json
This commit is contained in:
@@ -26,8 +26,6 @@ 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;
|
||||
@@ -190,12 +188,10 @@ public class NetworkAggregator {
|
||||
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);
|
||||
|
||||
@@ -63,10 +63,23 @@ public class NetworkManagerImpl {
|
||||
public <T extends CustomPacketPayload> void registerS2C(CustomPacketPayload.Type<T> type, StreamCodec<? super RegistryFriendlyByteBuf, T> codec, NetworkReceiver<T> receiver) {
|
||||
LOGGER.info("Registering S2C receiver with id {}", type.id());
|
||||
PayloadTypeRegistry.playS2C().register(type, codec);
|
||||
ClientPlayNetworking.registerGlobalReceiver(type, (payload, fabricContext) -> {
|
||||
ClientPlayNetworking.registerGlobalReceiver(type, new ClientPlayPayloadHandler<>(receiver));
|
||||
}
|
||||
|
||||
// Lambda methods aren't included in @EnvType, so this inelegant solution is used instead.
|
||||
@Environment(EnvType.CLIENT)
|
||||
class ClientPlayPayloadHandler<T extends CustomPacketPayload> implements ClientPlayNetworking.PlayPayloadHandler<T> {
|
||||
private final NetworkReceiver<T> receiver;
|
||||
|
||||
ClientPlayPayloadHandler(NetworkReceiver<T> receiver) {
|
||||
this.receiver = receiver;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void receive(T payload, ClientPlayNetworking.Context fabricContext) {
|
||||
var context = context(fabricContext.player(), fabricContext.client(), true);
|
||||
receiver.receive(payload, context);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -19,7 +19,7 @@ fabric_api_version=0.97.6+1.20.5
|
||||
mod_menu_version=10.0.0-beta.1
|
||||
|
||||
forge_version=50.0.0
|
||||
neoforge_version=20.5.0-beta
|
||||
neoforge_version=20.5.20-beta
|
||||
|
||||
# Set to empty if not snapshots
|
||||
neoforge_pr=
|
||||
|
||||
@@ -26,6 +26,6 @@ import java.util.function.Supplier;
|
||||
|
||||
public class ArchitecturyLiquidBlock extends LiquidBlock {
|
||||
public ArchitecturyLiquidBlock(Supplier<? extends FlowingFluid> fluid, Properties properties) {
|
||||
super(fluid, properties);
|
||||
super(fluid.get(), properties);
|
||||
}
|
||||
}
|
||||
@@ -36,7 +36,7 @@ public class ArchitecturyBucketItem extends BucketItem {
|
||||
private static final Logger LOGGER = LogManager.getLogger(ArchitecturyBucketItem.class);
|
||||
|
||||
public ArchitecturyBucketItem(Supplier<? extends Fluid> fluid, Properties properties) {
|
||||
super(fluid, properties);
|
||||
super(fluid.get(), properties);
|
||||
EventBusesHooks.whenAvailable(ArchitecturyConstants.MOD_ID, bus -> {
|
||||
bus.<RegisterCapabilitiesEvent>addListener(event -> {
|
||||
if (BuiltInRegistries.ITEM.containsValue(this)) {
|
||||
|
||||
@@ -28,6 +28,6 @@ import java.util.function.Supplier;
|
||||
|
||||
public class ArchitecturyMobBucketItem extends MobBucketItem {
|
||||
public ArchitecturyMobBucketItem(Supplier<? extends EntityType<?>> entity, Supplier<? extends Fluid> fluid, Supplier<? extends SoundEvent> sound, Properties properties) {
|
||||
super(entity, fluid, sound, properties);
|
||||
super(entity.get(), fluid.get(), sound.get(), properties);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -39,7 +39,7 @@ import net.neoforged.bus.api.EventPriority;
|
||||
import net.neoforged.bus.api.SubscribeEvent;
|
||||
import net.neoforged.fml.event.lifecycle.FMLClientSetupEvent;
|
||||
import net.neoforged.neoforge.client.event.*;
|
||||
import net.neoforged.neoforge.event.TickEvent;
|
||||
import net.neoforged.neoforge.client.event.ClientTickEvent;
|
||||
import net.neoforged.neoforge.event.entity.player.ItemTooltipEvent;
|
||||
import net.neoforged.neoforge.event.entity.player.PlayerInteractEvent;
|
||||
import net.neoforged.neoforge.event.level.LevelEvent;
|
||||
@@ -52,11 +52,13 @@ public class EventHandlerImplClient {
|
||||
}
|
||||
|
||||
@SubscribeEvent(priority = EventPriority.HIGH)
|
||||
public static void event(TickEvent.ClientTickEvent event) {
|
||||
if (event.phase == TickEvent.Phase.START)
|
||||
ClientTickEvent.CLIENT_PRE.invoker().tick(Minecraft.getInstance());
|
||||
else if (event.phase == TickEvent.Phase.END)
|
||||
ClientTickEvent.CLIENT_POST.invoker().tick(Minecraft.getInstance());
|
||||
public static void event(ClientTickEvent.Pre event) {
|
||||
dev.architectury.event.events.client.ClientTickEvent.CLIENT_PRE.invoker().tick(Minecraft.getInstance());
|
||||
}
|
||||
|
||||
@SubscribeEvent(priority = EventPriority.HIGH)
|
||||
public static void event(ClientTickEvent.Post event) {
|
||||
dev.architectury.event.events.client.ClientTickEvent.CLIENT_POST.invoker().tick(Minecraft.getInstance());
|
||||
}
|
||||
|
||||
@SubscribeEvent(priority = EventPriority.HIGH)
|
||||
|
||||
@@ -35,16 +35,14 @@ import net.minecraft.world.level.LevelAccessor;
|
||||
import net.neoforged.bus.api.Event;
|
||||
import net.neoforged.bus.api.EventPriority;
|
||||
import net.neoforged.bus.api.SubscribeEvent;
|
||||
import net.neoforged.fml.LogicalSide;
|
||||
import net.neoforged.fml.event.lifecycle.FMLCommonSetupEvent;
|
||||
import net.neoforged.neoforge.event.CommandEvent;
|
||||
import net.neoforged.neoforge.event.LootTableLoadEvent;
|
||||
import net.neoforged.neoforge.event.RegisterCommandsEvent;
|
||||
import net.neoforged.neoforge.event.ServerChatEvent;
|
||||
import net.neoforged.neoforge.event.TickEvent.LevelTickEvent;
|
||||
import net.neoforged.neoforge.event.TickEvent.Phase;
|
||||
import net.neoforged.neoforge.event.TickEvent.PlayerTickEvent;
|
||||
import net.neoforged.neoforge.event.TickEvent.ServerTickEvent;
|
||||
import net.neoforged.neoforge.event.tick.LevelTickEvent;
|
||||
import net.neoforged.neoforge.event.tick.PlayerTickEvent;
|
||||
import net.neoforged.neoforge.event.tick.ServerTickEvent;
|
||||
import net.neoforged.neoforge.event.entity.EntityJoinLevelEvent;
|
||||
import net.neoforged.neoforge.event.entity.item.ItemTossEvent;
|
||||
import net.neoforged.neoforge.event.entity.living.AnimalTameEvent;
|
||||
@@ -65,20 +63,26 @@ import net.neoforged.neoforge.server.ServerLifecycleHooks;
|
||||
|
||||
public class EventHandlerImplCommon {
|
||||
@SubscribeEvent(priority = EventPriority.HIGH)
|
||||
public static void event(ServerTickEvent event) {
|
||||
if (event.phase == Phase.START)
|
||||
TickEvent.SERVER_PRE.invoker().tick(ServerLifecycleHooks.getCurrentServer());
|
||||
else if (event.phase == Phase.END)
|
||||
TickEvent.SERVER_POST.invoker().tick(ServerLifecycleHooks.getCurrentServer());
|
||||
public static void event(ServerTickEvent.Pre event) {
|
||||
TickEvent.SERVER_PRE.invoker().tick(ServerLifecycleHooks.getCurrentServer());
|
||||
}
|
||||
|
||||
@SubscribeEvent(priority = EventPriority.HIGH)
|
||||
public static void event(LevelTickEvent event) {
|
||||
if (event.side == LogicalSide.SERVER) {
|
||||
if (event.phase == Phase.START)
|
||||
TickEvent.SERVER_LEVEL_PRE.invoker().tick((ServerLevel) event.level);
|
||||
else if (event.phase == Phase.END)
|
||||
TickEvent.SERVER_LEVEL_POST.invoker().tick((ServerLevel) event.level);
|
||||
public static void event(ServerTickEvent.Post event) {
|
||||
TickEvent.SERVER_POST.invoker().tick(ServerLifecycleHooks.getCurrentServer());
|
||||
}
|
||||
|
||||
@SubscribeEvent(priority = EventPriority.HIGH)
|
||||
public static void event(LevelTickEvent.Pre event) {
|
||||
if (!event.getLevel().isClientSide()) {
|
||||
TickEvent.SERVER_LEVEL_PRE.invoker().tick((ServerLevel) event.getLevel());
|
||||
}
|
||||
}
|
||||
|
||||
@SubscribeEvent(priority = EventPriority.HIGH)
|
||||
public static void event(LevelTickEvent.Post event) {
|
||||
if (!event.getLevel().isClientSide()) {
|
||||
TickEvent.SERVER_LEVEL_POST.invoker().tick((ServerLevel) event.getLevel());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -133,12 +137,13 @@ public class EventHandlerImplCommon {
|
||||
}
|
||||
|
||||
@SubscribeEvent(priority = EventPriority.HIGH)
|
||||
public static void event(PlayerTickEvent event) {
|
||||
if (event.phase == Phase.START) {
|
||||
TickEvent.PLAYER_PRE.invoker().tick(event.player);
|
||||
} else if (event.phase == Phase.END) {
|
||||
TickEvent.PLAYER_POST.invoker().tick(event.player);
|
||||
}
|
||||
public static void event(PlayerTickEvent.Pre event) {
|
||||
TickEvent.PLAYER_PRE.invoker().tick(event.getEntity());
|
||||
}
|
||||
|
||||
@SubscribeEvent(priority = EventPriority.HIGH)
|
||||
public static void event(PlayerTickEvent.Post event) {
|
||||
TickEvent.PLAYER_POST.invoker().tick(event.getEntity());
|
||||
}
|
||||
|
||||
@SubscribeEvent(priority = EventPriority.HIGH)
|
||||
|
||||
@@ -19,11 +19,12 @@
|
||||
|
||||
package dev.architectury.hooks.fluid.forge;
|
||||
|
||||
import dev.architectury.mixin.forge.neoforge.LiquidBlockAccessor;
|
||||
import net.minecraft.world.level.block.LiquidBlock;
|
||||
import net.minecraft.world.level.material.FlowingFluid;
|
||||
|
||||
public class LiquidBlockHooksImpl {
|
||||
public static FlowingFluid getFluid(LiquidBlock block) {
|
||||
return block.getFluid();
|
||||
return ((LiquidBlockAccessor) block).getFluid();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,31 @@
|
||||
/*
|
||||
* 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.mixin.forge.neoforge;
|
||||
|
||||
import net.minecraft.world.level.block.LiquidBlock;
|
||||
import net.minecraft.world.level.material.FlowingFluid;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.gen.Accessor;
|
||||
|
||||
@Mixin(LiquidBlock.class)
|
||||
public interface LiquidBlockAccessor {
|
||||
@Accessor("fluid")
|
||||
FlowingFluid getFluid();
|
||||
}
|
||||
@@ -10,6 +10,7 @@
|
||||
"MixinMinecraft"
|
||||
],
|
||||
"mixins": [
|
||||
"neoforge.LiquidBlockAccessor",
|
||||
"neoforge.MixinChunkSerializer",
|
||||
"MixinFallingBlockEntity",
|
||||
"MixinItemExtension",
|
||||
|
||||
@@ -20,19 +20,17 @@
|
||||
package dev.architectury.test.networking;
|
||||
|
||||
import dev.architectury.event.events.client.ClientPlayerEvent;
|
||||
import dev.architectury.event.events.common.PlayerEvent;
|
||||
import dev.architectury.networking.NetworkManager;
|
||||
import dev.architectury.networking.simple.MessageType;
|
||||
import dev.architectury.networking.simple.SimpleNetworkManager;
|
||||
import dev.architectury.networking.transformers.SplitPacketTransformer;
|
||||
import dev.architectury.test.TestMod;
|
||||
import io.netty.buffer.Unpooled;
|
||||
import net.minecraft.network.FriendlyByteBuf;
|
||||
import net.minecraft.network.RegistryFriendlyByteBuf;
|
||||
import net.minecraft.network.codec.ByteBufCodecs;
|
||||
import net.minecraft.network.codec.StreamCodec;
|
||||
import net.minecraft.network.protocol.common.custom.CustomPacketPayload;
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
import net.minecraft.util.ExtraCodecs;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
|
||||
import java.util.Collections;
|
||||
@@ -47,6 +45,8 @@ public interface TestModNet {
|
||||
// An example Server to Client message
|
||||
MessageType SYNC_DATA = NET.registerS2C("sync_data", SyncDataMessage::new);
|
||||
ResourceLocation BIG_DATA = new ResourceLocation(TestMod.MOD_ID, "big_data");
|
||||
ResourceLocation SERVER_TO_CLIENT_TEST = new ResourceLocation(TestMod.MOD_ID, "s2c_test");
|
||||
CustomPacketPayload.Type<ServerToClientTestPayload> SERVER_TO_CLIENT_TEST_PAYLOAD = new CustomPacketPayload.Type<>(new ResourceLocation(TestMod.MOD_ID, "s2c_test_payload"));
|
||||
CustomPacketPayload.Type<BigDataPayload> BIG_DATA_PAYLOAD = new CustomPacketPayload.Type<>(new ResourceLocation(TestMod.MOD_ID, "big_data_payload"));
|
||||
String BIG_STRING = StringUtils.repeat('a', 100000);
|
||||
|
||||
@@ -82,6 +82,37 @@ public interface TestModNet {
|
||||
throw new AssertionError(value.data());
|
||||
}
|
||||
});
|
||||
|
||||
NetworkManager.registerReceiver(NetworkManager.Side.S2C, SERVER_TO_CLIENT_TEST, (buf, context) -> {
|
||||
long num = buf.readLong();
|
||||
if (num == 0xA4C5E75EC7941L) {
|
||||
TestMod.SINK.accept("S2C worked!, 0xA4C5E75EC7941L");
|
||||
} else {
|
||||
throw new AssertionError(num);
|
||||
}
|
||||
});
|
||||
|
||||
NetworkManager.registerReceiver(NetworkManager.Side.S2C, SERVER_TO_CLIENT_TEST_PAYLOAD, new StreamCodec<>() {
|
||||
@Override
|
||||
public ServerToClientTestPayload decode(RegistryFriendlyByteBuf object) {
|
||||
return new ServerToClientTestPayload(object.readLong());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void encode(RegistryFriendlyByteBuf object, ServerToClientTestPayload payload) {
|
||||
object.writeLong(payload.num);
|
||||
}
|
||||
}, (value, context) -> {
|
||||
if (value.num() == 0xA4C5E75EC7941L) {
|
||||
TestMod.SINK.accept("S2C worked!, 0xA4C5E75EC7941L");
|
||||
} else {
|
||||
throw new AssertionError(value.num());
|
||||
}
|
||||
});
|
||||
|
||||
PlayerEvent.PLAYER_JOIN.register(player -> {
|
||||
NetworkManager.sendToPlayer(player, new ServerToClientTestPayload(0xA4C5E75EC7941L));
|
||||
});
|
||||
}
|
||||
|
||||
static void initializeClient() {
|
||||
@@ -101,4 +132,11 @@ public interface TestModNet {
|
||||
return TestModNet.BIG_DATA_PAYLOAD;
|
||||
}
|
||||
}
|
||||
|
||||
record ServerToClientTestPayload(long num) implements CustomPacketPayload {
|
||||
@Override
|
||||
public Type<? extends CustomPacketPayload> type() {
|
||||
return TestModNet.SERVER_TO_CLIENT_TEST_PAYLOAD;
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user