switched to PacketHandler system akin to Mojang PacketListener

This commit is contained in:
CreepyCre 2021-02-13 20:08:08 +01:00
parent d53dfce015
commit 56e7b367a0
8 changed files with 211 additions and 82 deletions

View file

@ -7,8 +7,7 @@ import java.util.UUID;
import me.sargunvohra.mcmods.autoconfig1u.AutoConfig;
import me.sargunvohra.mcmods.autoconfig1u.ConfigHolder;
import net.fabricmc.fabric.api.event.player.AttackBlockCallback;
import net.fabricmc.fabric.api.networking.v1.ServerPlayNetworking;
import net.minecraft.server.network.ServerPlayNetworkHandler;
import net.fabricmc.fabric.api.networking.v1.ServerPlayConnectionEvents;
import me.sargunvohra.mcmods.autoconfig1u.serializer.JanksonConfigSerializer;
import org.dimdev.dimdoors.block.ModBlocks;
@ -18,8 +17,8 @@ import org.dimdev.dimdoors.entity.ModEntityTypes;
import org.dimdev.dimdoors.entity.stat.ModStats;
import org.dimdev.dimdoors.fluid.ModFluids;
import org.dimdev.dimdoors.item.ModItems;
import org.dimdev.dimdoors.item.RiftConfigurationToolItem;
import org.dimdev.dimdoors.network.c2s.HitBlockS2CPacket;
import org.dimdev.dimdoors.listener.AttackBlockCallbackListener;
import org.dimdev.dimdoors.network.ServerPacketHandler;
import org.dimdev.dimdoors.particle.ModParticleTypes;
import org.dimdev.dimdoors.pockets.SchematicHandler;
import org.dimdev.dimdoors.pockets.SchematicV2Handler;
@ -46,7 +45,7 @@ import net.fabricmc.fabric.api.event.lifecycle.v1.ServerLifecycleEvents;
public class DimensionalDoorsInitializer implements ModInitializer {
public static final Identifier MONOLITH_PARTICLE_PACKET = new Identifier("dimdoors", "monolith_particle_packet");
public static final ConfigHolder<ModConfig> CONFIG_MANAGER = AutoConfig.register(ModConfig.class, JanksonConfigSerializer::new);
private static Map<UUID, ServerPlayNetworkHandler> UUID_SERVER_PLAY_NETWORK_HANDLER_MAP = new HashMap<>();
private static Map<UUID, ServerPacketHandler> UUID_SERVER_PACKET_HANDLER_MAP = new HashMap<>();
private static MinecraftServer server;
@NotNull
@ -93,8 +92,18 @@ public class DimensionalDoorsInitializer implements ModInitializer {
SchematicV2Handler.getInstance().load();
SchematicHandler.INSTANCE.loadSchematics();
AttackBlockCallback.EVENT.register(RiftConfigurationToolItem::onAttackBlockCallback);
registerListeners();
}
ServerPlayNetworking.registerGlobalReceiver(HitBlockS2CPacket.ID, RiftConfigurationToolItem::receiveHitBlock);
private void registerListeners() {
ServerPlayConnectionEvents.JOIN.register((handler, sender, server) -> {
UUID_SERVER_PACKET_HANDLER_MAP.put(handler.player.getUuid(), new ServerPacketHandler(handler, server));
});
ServerPlayConnectionEvents.DISCONNECT.register((handler, server) -> {
UUID_SERVER_PACKET_HANDLER_MAP.remove(handler.player.getUuid()).unregister();
});
AttackBlockCallback.EVENT.register(new AttackBlockCallbackListener());
}
}

View file

@ -0,0 +1,24 @@
package org.dimdev.dimdoors.item;
import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.item.Item;
import net.minecraft.util.Hand;
import net.minecraft.util.TypedActionResult;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.Direction;
import net.minecraft.world.World;
public class ModItem extends Item {
public ModItem(Settings settings) {
super(settings);
}
// TODO: add javadocs
// true -> send packet to server
// false -> don't send packet to server
// boolean value currently does nothing server-side
public TypedActionResult<Boolean> onAttackBlock(World world, PlayerEntity player, Hand hand, BlockPos pos, Direction direction) {
return TypedActionResult.pass(false);
}
}

View file

@ -6,7 +6,6 @@ import java.util.List;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.dimdev.dimdoors.block.entity.RiftBlockEntity;
import org.dimdev.dimdoors.network.c2s.HitBlockS2CPacket;
import org.dimdev.dimdoors.network.s2c.PlayerInventorySlotUpdateS2CPacket;
import org.dimdev.dimdoors.rift.targets.IdMarker;
import org.dimdev.dimdoors.util.EntityUtils;
@ -19,12 +18,9 @@ import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.item.Item;
import net.minecraft.item.ItemStack;
import net.minecraft.network.PacketByteBuf;
import net.minecraft.server.MinecraftServer;
import net.minecraft.server.network.ServerPlayNetworkHandler;
import net.minecraft.server.network.ServerPlayerEntity;
import net.minecraft.text.Text;
import net.minecraft.text.TranslatableText;
import net.minecraft.util.ActionResult;
import net.minecraft.util.Hand;
import net.minecraft.util.TypedActionResult;
import net.minecraft.util.hit.BlockHitResult;
@ -34,14 +30,12 @@ import net.minecraft.util.math.Direction;
import net.minecraft.world.World;
import net.fabricmc.api.Environment;
import net.fabricmc.fabric.api.client.networking.v1.ClientPlayNetworking;
import net.fabricmc.fabric.api.networking.v1.PacketByteBufs;
import net.fabricmc.fabric.api.networking.v1.PacketSender;
import net.fabricmc.fabric.api.networking.v1.ServerPlayNetworking;
import static net.fabricmc.api.EnvType.CLIENT;
public class RiftConfigurationToolItem extends Item {
public class RiftConfigurationToolItem extends ModItem {
private static final Logger LOGGER = LogManager.getLogger();
public static final String ID = "rift_configuration_tool";
@ -67,7 +61,7 @@ public class RiftConfigurationToolItem extends Item {
EntityUtils.chat(player, Text.of("Id: " + ((IdMarker) rift.getDestination()).getId()));
} else {
int id = counter.increment();
this.sync(stack, player, hand);
sync(stack, player, hand);
EntityUtils.chat(player, Text.of("Rift stripped of data and set to target id: " + id));
rift.setDestination(new IdMarker(id));
@ -82,53 +76,34 @@ public class RiftConfigurationToolItem extends Item {
return TypedActionResult.success(stack);
}
public static ActionResult onAttackBlockCallback(PlayerEntity player, World world, Hand hand, BlockPos pos, Direction direction) {
if (world.isClient && player.isSneaking() && player.getStackInHand(hand).getItem() instanceof RiftConfigurationToolItem) {
if (Counter.get(player.getStackInHand(hand)).count() != -1 || world.getBlockEntity(pos) instanceof RiftBlockEntity) {
HitBlockS2CPacket packet = new HitBlockS2CPacket(hand, pos, direction);
try {
PacketByteBuf buf = PacketByteBufs.create();
packet.write(buf);
ClientPlayNetworking.send(HitBlockS2CPacket.ID, buf);
} catch (IOException e) {
LOGGER.error(e);
return ActionResult.FAIL;
@Override
public TypedActionResult<Boolean> onAttackBlock(World world, PlayerEntity player, Hand hand, BlockPos pos, Direction direction) {
if (world.isClient) {
if (player.isSneaking() && Counter.get(player.getStackInHand(hand)).count() != -1 || world.getBlockEntity(pos) instanceof RiftBlockEntity) {
return TypedActionResult.success(true);
}
}
return ActionResult.SUCCESS;
}
return ActionResult.PASS;
}
public static void receiveHitBlock(MinecraftServer server, ServerPlayerEntity player, ServerPlayNetworkHandler networkHandler, PacketByteBuf buf, PacketSender sender) {
HitBlockS2CPacket packet = new HitBlockS2CPacket();
try {
packet.read(buf);
server.execute(() -> serverThreadReceiveHitBlock(player, packet.getHand(), packet.getPos()));
} catch (IOException e) {
LOGGER.error(e);
}
}
private static void serverThreadReceiveHitBlock(ServerPlayerEntity player, Hand hand, BlockPos pos) {
} else {
ItemStack stack = player.getStackInHand(hand);
if (player.isSneaking() && stack.getItem() instanceof RiftConfigurationToolItem) {
BlockEntity blockEntity = player.getServerWorld().getBlockEntity(pos);
if (player.isSneaking()) {
BlockEntity blockEntity = world.getBlockEntity(pos);
if (blockEntity instanceof RiftBlockEntity) {
RiftBlockEntity rift = (RiftBlockEntity) blockEntity;
if (!(rift.getDestination() instanceof IdMarker) || ((IdMarker) rift.getDestination()).getId() != -1) {
rift.setDestination(new IdMarker(-1));
EntityUtils.chat(player, Text.of("Rift stripped of data and set to invalid id: -1"));
return TypedActionResult.success(false);
}
} else if (Counter.get(stack).count() != -1) {
// Counter.get(stack).set(-1); TODO
((RiftConfigurationToolItem) stack.getItem()).sync(stack, player, hand);
sync(stack, player, hand);
EntityUtils.chat(player, Text.of("Counter has been reset."));
return TypedActionResult.success(false);
}
}
}
return TypedActionResult.pass(false);
}
@Override
@Environment(CLIENT)
@ -145,6 +120,7 @@ public class RiftConfigurationToolItem extends Item {
return defaultStack;
}
// TODO: put in ServerPacketHandler
private void sync(ItemStack stack, PlayerEntity player, Hand hand) {
ServerPlayerEntity serverPlayer = (ServerPlayerEntity) player;
PlayerInventorySlotUpdateS2CPacket packet;

View file

@ -0,0 +1,44 @@
package org.dimdev.dimdoors.listener;
import net.fabricmc.fabric.api.client.networking.v1.ClientPlayNetworking;
import net.fabricmc.fabric.api.event.player.AttackBlockCallback;
import net.fabricmc.fabric.api.networking.v1.PacketByteBufs;
import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.item.Item;
import net.minecraft.util.ActionResult;
import net.minecraft.util.Hand;
import net.minecraft.util.TypedActionResult;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.Direction;
import net.minecraft.world.World;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.dimdev.dimdoors.item.ModItem;
import org.dimdev.dimdoors.network.c2s.HitBlockWithItemC2SPacket;
import java.io.IOException;
public class AttackBlockCallbackListener implements AttackBlockCallback {
private static final Logger LOGGER = LogManager.getLogger();
@Override
public ActionResult interact(PlayerEntity player, World world, Hand hand, BlockPos pos, Direction direction) {
if (!world.isClient) return ActionResult.PASS;
Item item = player.getStackInHand(hand).getItem();
if (!(item instanceof ModItem)) {
return ActionResult.PASS;
}
TypedActionResult<Boolean> result = ((ModItem) item).onAttackBlock(world, player, hand, pos, direction);
if (result.getValue()) {
try {
ClientPlayNetworking.send(HitBlockWithItemC2SPacket.ID,
new HitBlockWithItemC2SPacket(hand, pos, direction).write(PacketByteBufs.create()));
} catch (IOException e) {
LOGGER.error(e);
return ActionResult.FAIL;
}
}
return result.getResult();
}
}

View file

@ -34,12 +34,12 @@ public abstract class PlayerEntityMixin extends LivingEntity {
cir.setReturnValue(false);
}
}
/*
@Inject(method = "onDeath", at = @At("HEAD"), cancellable = true)
public void checkDeath(DamageSource source, CallbackInfo ci) {
this.doOnDeathStuff(source, ci);
}
*/
@Unique
protected void doOnDeathStuff(DamageSource source, CallbackInfo ci) {
if (ModDimensions.isPocketDimension(this.world)) {

View file

@ -0,0 +1,75 @@
package org.dimdev.dimdoors.network;
import net.fabricmc.fabric.api.networking.v1.PacketSender;
import net.fabricmc.fabric.api.networking.v1.ServerPlayNetworking;
import net.minecraft.item.Item;
import net.minecraft.network.PacketByteBuf;
import net.minecraft.server.MinecraftServer;
import net.minecraft.server.network.ServerPlayNetworkHandler;
import net.minecraft.server.network.ServerPlayerEntity;
import net.minecraft.util.Hand;
import net.minecraft.util.Identifier;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.Direction;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.dimdev.dimdoors.item.ModItem;
import org.dimdev.dimdoors.network.c2s.HitBlockWithItemC2SPacket;
import java.io.IOException;
import java.util.HashSet;
import java.util.Set;
import java.util.function.Supplier;
// each client has their own corresponding ServerPacketHandler, so feel free to add client specific data in here
public class ServerPacketHandler {
private static final Logger LOGGER = LogManager.getLogger();
private final ServerPlayNetworkHandler networkHandler;
private final MinecraftServer server;
private final ServerPlayerEntity player;
private final Set<Identifier> registeredChannels = new HashSet<>();
private void registerModReceivers() {
registerReceiver(HitBlockWithItemC2SPacket.ID, HitBlockWithItemC2SPacket::new);
}
public ServerPacketHandler(ServerPlayNetworkHandler networkHandler, MinecraftServer server) {
this.networkHandler = networkHandler;
this.server = server;
this.player = networkHandler.player;
registerModReceivers();
}
private void registerReceiver(Identifier channelName, Supplier<? extends SimplePacket<ServerPacketHandler>> supplier) {
ServerPlayNetworking.registerReceiver(networkHandler, channelName,
(MinecraftServer server, ServerPlayerEntity player, ServerPlayNetworkHandler handler, PacketByteBuf buf, PacketSender responseSender) -> {
try {
supplier.get().read(buf).apply(this);
} catch (IOException e) {
LOGGER.error(e);
}
});
registeredChannels.add(channelName);
}
private void unregisterReceiver(Identifier channelName) {
ServerPlayNetworking.unregisterReceiver(networkHandler, channelName);
registeredChannels.remove(channelName);
}
public void unregister() {
new HashSet<>(registeredChannels).forEach(this::unregisterReceiver);
}
public void onAttackBlock(Hand hand, BlockPos pos, Direction direction) {
server.execute(() -> {
Item item = player.getStackInHand(hand).getItem();
if (item instanceof ModItem) {
((ModItem) item).onAttackBlock(player.world, player, hand, pos, direction);
}
});
}
}

View file

@ -0,0 +1,13 @@
package org.dimdev.dimdoors.network;
import net.minecraft.network.PacketByteBuf;
import java.io.IOException;
public interface SimplePacket<T> {
SimplePacket<T> read(PacketByteBuf buf) throws IOException;
PacketByteBuf write(PacketByteBuf buf) throws IOException;
void apply(T listener);
}

View file

@ -2,63 +2,51 @@ package org.dimdev.dimdoors.network.c2s;
import net.fabricmc.api.EnvType;
import net.fabricmc.api.Environment;
import net.minecraft.network.Packet;
import net.minecraft.network.PacketByteBuf;
import net.minecraft.network.listener.ClientPlayPacketListener;
import net.minecraft.util.Hand;
import net.minecraft.util.Identifier;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.Direction;
import org.dimdev.dimdoors.network.ServerPacketHandler;
import org.dimdev.dimdoors.network.SimplePacket;
import java.io.IOException;
// TODO: replace ClientPlayPackListener
public class HitBlockS2CPacket implements Packet<ClientPlayPacketListener> {
public class HitBlockWithItemC2SPacket implements SimplePacket<ServerPacketHandler> {
public static final Identifier ID = new Identifier("dimdoors:hit_block");
private Hand hand;
private BlockPos pos;
private Direction direction;
public HitBlockS2CPacket() {
public HitBlockWithItemC2SPacket() {
}
@Environment(EnvType.CLIENT)
public HitBlockS2CPacket(Hand hand, BlockPos pos, Direction direction) {
public HitBlockWithItemC2SPacket(Hand hand, BlockPos pos, Direction direction) {
this.hand = hand;
this.pos = pos;
this.direction = direction;
}
@Override
public void read(PacketByteBuf buf) throws IOException {
public SimplePacket<ServerPacketHandler> read(PacketByteBuf buf) throws IOException {
hand = buf.readEnumConstant(Hand.class);
pos = buf.readBlockPos();
direction = buf.readEnumConstant(Direction.class);
return this;
}
@Override
public void write(PacketByteBuf buf) throws IOException {
public PacketByteBuf write(PacketByteBuf buf) throws IOException {
buf.writeEnumConstant(hand);
buf.writeBlockPos(pos);
buf.writeEnumConstant(direction);
return buf;
}
@Override
public void apply(ClientPlayPacketListener listener) {
// TODO: write method
}
public Hand getHand() {
return hand;
}
public BlockPos getPos() {
return pos;
}
public Direction getDirection() {
return direction;
public void apply(ServerPacketHandler listener) {
listener.onAttackBlock(hand, pos, direction);
}
}