diff --git a/src/main/java/com/moulberry/axiom/event/AxiomHandshakeEvent.java b/src/main/java/com/moulberry/axiom/event/AxiomHandshakeEvent.java new file mode 100644 index 0000000..735c762 --- /dev/null +++ b/src/main/java/com/moulberry/axiom/event/AxiomHandshakeEvent.java @@ -0,0 +1,52 @@ +package com.moulberry.axiom.event; + +import org.bukkit.entity.Player; +import org.bukkit.event.Cancellable; +import org.bukkit.event.Event; +import org.bukkit.event.HandlerList; +import org.jetbrains.annotations.NotNull; + +public class AxiomHandshakeEvent extends Event implements Cancellable { + + private static final HandlerList HANDLERS = new HandlerList(); + + private final Player player; + private boolean cancelled = false; + private int maxBufferSize = 0x100000; + + public AxiomHandshakeEvent(Player player) { + this.player = player; + } + + public Player getPlayer() { + return this.player; + } + + public int getMaxBufferSize() { + return this.maxBufferSize; + } + + public void setMaxBufferSize(int maxBufferSize) { + this.maxBufferSize = maxBufferSize; + } + + @Override + public boolean isCancelled() { + return this.cancelled; + } + + @Override + public void setCancelled(boolean cancel) { + this.cancelled = cancel; + } + + public static HandlerList getHandlerList() { + return HANDLERS; + } + + @Override + public @NotNull HandlerList getHandlers() { + return HANDLERS; + } + +} diff --git a/src/main/java/com/moulberry/axiom/event/AxiomModifyWorldEvent.java b/src/main/java/com/moulberry/axiom/event/AxiomModifyWorldEvent.java new file mode 100644 index 0000000..405948f --- /dev/null +++ b/src/main/java/com/moulberry/axiom/event/AxiomModifyWorldEvent.java @@ -0,0 +1,54 @@ +package com.moulberry.axiom.event; + +import org.bukkit.World; +import org.bukkit.entity.Player; +import org.bukkit.event.Cancellable; +import org.bukkit.event.Event; +import org.bukkit.event.HandlerList; +import org.jetbrains.annotations.NotNull; + +public class AxiomModifyWorldEvent extends Event implements Cancellable { + + private static final HandlerList HANDLERS = new HandlerList(); + + private final Player player; + private final World world; + private boolean cancelled; + + public AxiomModifyWorldEvent(Player player, World world) { + this.player = player; + this.world = world; + + // By default, changes are only allowed if the player is in the same world + // This behaviour can be changed by doing setCancelled(false) + this.cancelled = player.getWorld() != world; + } + + public World getWorld() { + return world; + } + + public Player getPlayer() { + return this.player; + } + + @Override + public boolean isCancelled() { + return this.cancelled; + } + + @Override + public void setCancelled(boolean cancel) { + this.cancelled = cancel; + } + + public static HandlerList getHandlerList() { + return HANDLERS; + } + + @Override + public @NotNull HandlerList getHandlers() { + return HANDLERS; + } + +} diff --git a/src/main/java/com/moulberry/axiom/packet/AxiomBigPayloadHandler.java b/src/main/java/com/moulberry/axiom/packet/AxiomBigPayloadHandler.java index 0d85bbc..ec19e9e 100644 --- a/src/main/java/com/moulberry/axiom/packet/AxiomBigPayloadHandler.java +++ b/src/main/java/com/moulberry/axiom/packet/AxiomBigPayloadHandler.java @@ -39,6 +39,7 @@ public class AxiomBigPayloadHandler extends ByteToMessageDecoder { ServerPlayer player = connection.getPlayer(); if (player != null && player.getBukkitEntity().hasPermission("axiom.*")) { listener.onReceive(player, buf); + in.readerIndex(in.writerIndex()); return; } } diff --git a/src/main/java/com/moulberry/axiom/packet/HelloPacketListener.java b/src/main/java/com/moulberry/axiom/packet/HelloPacketListener.java index 63041a1..e09e520 100644 --- a/src/main/java/com/moulberry/axiom/packet/HelloPacketListener.java +++ b/src/main/java/com/moulberry/axiom/packet/HelloPacketListener.java @@ -3,11 +3,13 @@ package com.moulberry.axiom.packet; import com.moulberry.axiom.AxiomConstants; import com.moulberry.axiom.AxiomPaper; import com.moulberry.axiom.View; +import com.moulberry.axiom.event.AxiomHandshakeEvent; import com.moulberry.axiom.persistence.ItemStackDataType; import com.moulberry.axiom.persistence.UUIDDataType; import io.netty.buffer.Unpooled; import net.kyori.adventure.text.Component; import net.minecraft.network.FriendlyByteBuf; +import org.bukkit.Bukkit; import org.bukkit.NamespacedKey; import org.bukkit.craftbukkit.v1_20_R1.inventory.CraftItemStack; import org.bukkit.entity.Player; @@ -46,13 +48,20 @@ public class HelloPacketListener implements PluginMessageListener { return; } + // Call handshake event + AxiomHandshakeEvent handshakeEvent = new AxiomHandshakeEvent(player); + Bukkit.getPluginManager().callEvent(handshakeEvent); + if (handshakeEvent.isCancelled()) { + return; + } + activeAxiomPlayers.add(player.getUniqueId()); // Enable FriendlyByteBuf buf = new FriendlyByteBuf(Unpooled.buffer()); buf.writeBoolean(true); buf.writeByte(0); // todo: world properties - buf.writeInt(0x100000); // Max Buffer Size + buf.writeInt(handshakeEvent.getMaxBufferSize()); // Max Buffer Size buf.writeBoolean(false); // No source info buf.writeBoolean(false); // No source settings buf.writeVarInt(5); // Maximum Reach diff --git a/src/main/java/com/moulberry/axiom/packet/SetBlockBufferPacketListener.java b/src/main/java/com/moulberry/axiom/packet/SetBlockBufferPacketListener.java index 97a515f..bac9c25 100644 --- a/src/main/java/com/moulberry/axiom/packet/SetBlockBufferPacketListener.java +++ b/src/main/java/com/moulberry/axiom/packet/SetBlockBufferPacketListener.java @@ -4,6 +4,7 @@ import com.moulberry.axiom.AxiomPaper; import com.moulberry.axiom.buffer.BiomeBuffer; import com.moulberry.axiom.buffer.BlockBuffer; import com.moulberry.axiom.buffer.CompressedBlockEntity; +import com.moulberry.axiom.event.AxiomModifyWorldEvent; import io.netty.buffer.Unpooled; import it.unimi.dsi.fastutil.longs.Long2ObjectMap; import it.unimi.dsi.fastutil.shorts.Short2ObjectMap; @@ -31,6 +32,10 @@ import net.minecraft.world.level.chunk.LevelChunkSection; import net.minecraft.world.level.chunk.PalettedContainer; import net.minecraft.world.level.levelgen.Heightmap; import net.minecraft.world.level.lighting.LightEngine; +import org.bukkit.Bukkit; +import org.bukkit.NamespacedKey; +import org.bukkit.World; +import org.bukkit.craftbukkit.v1_20_R1.CraftWorld; import org.bukkit.craftbukkit.v1_20_R1.entity.CraftPlayer; import org.bukkit.entity.Player; import org.bukkit.plugin.messaging.PluginMessageListener; @@ -66,6 +71,16 @@ public class SetBlockBufferPacketListener { if (server == null) return; ResourceKey worldKey = friendlyByteBuf.readResourceKey(Registries.DIMENSION); + NamespacedKey namespacedKey = new NamespacedKey(worldKey.location().getNamespace(), worldKey.location().getPath()); + World world = Bukkit.getWorld(namespacedKey); + if (world != null) { + AxiomModifyWorldEvent modifyWorldEvent = new AxiomModifyWorldEvent(player.getBukkitEntity(), world); + Bukkit.getPluginManager().callEvent(modifyWorldEvent); + if (modifyWorldEvent.isCancelled()) return; + } else { + return; + } + friendlyByteBuf.readUUID(); // Discard, we don't need to associate buffers boolean continuation = friendlyByteBuf.readBoolean(); diff --git a/src/main/java/com/moulberry/axiom/packet/SetBlockPacketListener.java b/src/main/java/com/moulberry/axiom/packet/SetBlockPacketListener.java index a5aa974..f1a5c7c 100644 --- a/src/main/java/com/moulberry/axiom/packet/SetBlockPacketListener.java +++ b/src/main/java/com/moulberry/axiom/packet/SetBlockPacketListener.java @@ -1,6 +1,7 @@ package com.moulberry.axiom.packet; import com.moulberry.axiom.AxiomPaper; +import com.moulberry.axiom.event.AxiomModifyWorldEvent; import io.netty.buffer.Unpooled; import net.minecraft.core.BlockPos; import net.minecraft.core.SectionPos; @@ -15,6 +16,7 @@ import net.minecraft.world.level.chunk.LevelChunk; import net.minecraft.world.level.chunk.LevelChunkSection; import net.minecraft.world.level.levelgen.Heightmap; import net.minecraft.world.level.lighting.LightEngine; +import org.bukkit.Bukkit; import org.bukkit.craftbukkit.v1_20_R1.entity.CraftPlayer; import org.bukkit.entity.Player; import org.bukkit.plugin.messaging.PluginMessageListener; @@ -52,6 +54,12 @@ public class SetBlockPacketListener implements PluginMessageListener { return; } + // Check if player is allowed to modify this world + AxiomModifyWorldEvent modifyWorldEvent = new AxiomModifyWorldEvent(bukkitPlayer, bukkitPlayer.getWorld()); + Bukkit.getPluginManager().callEvent(modifyWorldEvent); + if (modifyWorldEvent.isCancelled()) return; + + // Read packet FriendlyByteBuf friendlyByteBuf = new FriendlyByteBuf(Unpooled.wrappedBuffer(message)); BlockPos blockPos = friendlyByteBuf.readBlockPos(); BlockState blockState = friendlyByteBuf.readById(Block.BLOCK_STATE_REGISTRY); @@ -60,6 +68,7 @@ public class SetBlockPacketListener implements PluginMessageListener { ServerPlayer player = ((CraftPlayer)bukkitPlayer).getHandle(); + // Update blocks if (updateNeighbors) { player.level().setBlock(blockPos, blockState, 3); } else {