Skip to content

Commit

Permalink
Fix breakage in NeoForge 20.5.14, fix crash when registering packets …
Browse files Browse the repository at this point in the history
…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
  • Loading branch information
Jab125 authored Apr 29, 2024
1 parent 3f0bf22 commit 02c89ba
Show file tree
Hide file tree
Showing 12 changed files with 129 additions and 42 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -26,8 +26,6 @@
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;
Expand Down Expand Up @@ -190,12 +188,10 @@ public static <T extends CustomPacketPayload> void registerS2CType(CustomPacketP
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);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -63,10 +63,23 @@ public <T extends CustomPacketPayload> void registerC2S(CustomPacketPayload.Type
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
Expand Down
2 changes: 1 addition & 1 deletion gradle.properties
Original file line number Diff line number Diff line change
Expand Up @@ -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=
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,6 @@

public class ArchitecturyLiquidBlock extends LiquidBlock {
public ArchitecturyLiquidBlock(Supplier<? extends FlowingFluid> fluid, Properties properties) {
super(fluid, properties);
super(fluid.get(), properties);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -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)) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,6 @@

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);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@
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;
Expand All @@ -52,11 +52,13 @@ public static void event(ItemTooltipEvent event) {
}

@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)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,16 +35,14 @@
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;
Expand All @@ -65,20 +63,26 @@

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());
}
}

Expand Down Expand Up @@ -133,12 +137,13 @@ public static void event(CommandEvent event) {
}

@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)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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();
}
}
Original file line number Diff line number Diff line change
@@ -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();
}
1 change: 1 addition & 0 deletions neoforge/src/main/resources/architectury.mixins.json
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
"MixinMinecraft"
],
"mixins": [
"neoforge.LiquidBlockAccessor",
"neoforge.MixinChunkSerializer",
"MixinFallingBlockEntity",
"MixinItemExtension",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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);

Expand Down Expand Up @@ -82,6 +82,37 @@ public void encode(RegistryFriendlyByteBuf object, BigDataPayload payload) {
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() {
Expand All @@ -101,4 +132,11 @@ public Type<? extends CustomPacketPayload> type() {
return TestModNet.BIG_DATA_PAYLOAD;
}
}

record ServerToClientTestPayload(long num) implements CustomPacketPayload {
@Override
public Type<? extends CustomPacketPayload> type() {
return TestModNet.SERVER_TO_CLIENT_TEST_PAYLOAD;
}
}
}

0 comments on commit 02c89ba

Please sign in to comment.