From c90a97294ab76faeaaa6e6d4013842f4f64332c6 Mon Sep 17 00:00:00 2001 From: Moulberry Date: Wed, 6 Sep 2023 10:34:53 +0800 Subject: [PATCH] Refactor lambda listeners into classes --- build.gradle.kts | 7 +- .../com/moulberry/axiom/AxiomConstants.java | 22 ++ .../java/com/moulberry/axiom/AxiomPaper.java | 212 +----------------- .../moulberry/axiom/buffer/BlockBuffer.java | 27 +-- .../axiom/packet/HelloPacketListener.java | 98 ++++++++ .../axiom/packet/SetBlockPacketListener.java | 32 ++- .../packet/SetEditorViewsPacketListener.java | 41 ++++ .../packet/SetFlySpeedPacketListener.java | 24 ++ .../packet/SetGamemodePacketListener.java | 24 ++ .../packet/SetHotbarSlotPacketListener.java | 36 +++ .../SwitchActiveHotbarPacketListener.java | 59 +++++ .../axiom/packet/TeleportPacketListener.java | 39 ++++ 12 files changed, 377 insertions(+), 244 deletions(-) create mode 100644 src/main/java/com/moulberry/axiom/AxiomConstants.java create mode 100644 src/main/java/com/moulberry/axiom/packet/HelloPacketListener.java create mode 100644 src/main/java/com/moulberry/axiom/packet/SetEditorViewsPacketListener.java create mode 100644 src/main/java/com/moulberry/axiom/packet/SetFlySpeedPacketListener.java create mode 100644 src/main/java/com/moulberry/axiom/packet/SetGamemodePacketListener.java create mode 100644 src/main/java/com/moulberry/axiom/packet/SetHotbarSlotPacketListener.java create mode 100644 src/main/java/com/moulberry/axiom/packet/SwitchActiveHotbarPacketListener.java create mode 100644 src/main/java/com/moulberry/axiom/packet/TeleportPacketListener.java diff --git a/build.gradle.kts b/build.gradle.kts index 468881e..c0ee842 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -7,8 +7,8 @@ plugins { id("com.github.johnrengelman.shadow") version "8.1.1" } -group = "com.moulberry.com.moulberry.axiom" -version = "1.0.0-SNAPSHOT" +group = "com.moulberry.axiom" +version = "1.1.0" description = "Serverside component for Axiom on Paper" java { @@ -24,6 +24,9 @@ repositories { dependencies { paperweight.paperDevBundle("1.20.1-R0.1-SNAPSHOT") implementation("xyz.jpenilla:reflection-remapper:0.1.0-SNAPSHOT") + + // Zstd Compression Library + implementation("com.github.luben:zstd-jni:1.5.5-4") } tasks { diff --git a/src/main/java/com/moulberry/axiom/AxiomConstants.java b/src/main/java/com/moulberry/axiom/AxiomConstants.java new file mode 100644 index 0000000..a80c6cd --- /dev/null +++ b/src/main/java/com/moulberry/axiom/AxiomConstants.java @@ -0,0 +1,22 @@ +package com.moulberry.axiom; + +import net.minecraft.core.BlockPos; +import org.bukkit.NamespacedKey; + +public class AxiomConstants { + + public static final long MIN_POSITION_LONG = BlockPos.asLong(-33554432, -2048, -33554432); + static { + if (MIN_POSITION_LONG != 0b1000000000000000000000000010000000000000000000000000100000000000L) { + throw new Error("BlockPos representation changed!"); + } + } + + public static final int API_VERSION = 4; + public static final NamespacedKey ACTIVE_HOTBAR_INDEX = new NamespacedKey("axiom", "active_hotbar_index"); + public static final NamespacedKey HOTBAR_DATA = new NamespacedKey("axiom", "hotbar_data"); + + public static final NamespacedKey ACTIVE_VIEW = new NamespacedKey("axiom", "active_view"); + public static final NamespacedKey VIEWS = new NamespacedKey("axiom", "views"); + +} diff --git a/src/main/java/com/moulberry/axiom/AxiomPaper.java b/src/main/java/com/moulberry/axiom/AxiomPaper.java index eff5682..8ad8238 100644 --- a/src/main/java/com/moulberry/axiom/AxiomPaper.java +++ b/src/main/java/com/moulberry/axiom/AxiomPaper.java @@ -1,61 +1,31 @@ package com.moulberry.axiom; -import com.moulberry.axiom.packet.AxiomBigPayloadHandler; -import com.moulberry.axiom.packet.SetBlockBufferPacketListener; -import com.moulberry.axiom.packet.SetBlockPacketListener; -import com.moulberry.axiom.persistence.ItemStackDataType; -import com.moulberry.axiom.persistence.UUIDDataType; +import com.moulberry.axiom.packet.*; import io.netty.buffer.Unpooled; import io.netty.channel.Channel; import io.papermc.paper.event.player.PlayerFailMoveEvent; import io.papermc.paper.network.ChannelInitializeListener; import io.papermc.paper.network.ChannelInitializeListenerHolder; import net.kyori.adventure.key.Key; -import net.kyori.adventure.text.Component; -import net.minecraft.core.BlockPos; -import net.minecraft.core.registries.Registries; import net.minecraft.network.Connection; import net.minecraft.network.ConnectionProtocol; import net.minecraft.network.FriendlyByteBuf; import net.minecraft.network.protocol.Packet; import net.minecraft.network.protocol.PacketFlow; import net.minecraft.network.protocol.game.ServerboundCustomPayloadPacket; -import net.minecraft.resources.ResourceKey; -import net.minecraft.world.level.GameType; -import net.minecraft.world.level.Level; import org.bukkit.*; -import org.bukkit.craftbukkit.v1_20_R1.entity.CraftPlayer; -import org.bukkit.craftbukkit.v1_20_R1.inventory.CraftItemStack; import org.bukkit.entity.Player; import org.bukkit.event.EventHandler; import org.bukkit.event.Listener; -import org.bukkit.inventory.ItemStack; -import org.bukkit.persistence.PersistentDataContainer; -import org.bukkit.persistence.PersistentDataType; import org.bukkit.plugin.java.JavaPlugin; import org.checkerframework.checker.nullness.qual.NonNull; import java.util.HashSet; -import java.util.List; import java.util.Map; import java.util.UUID; public class AxiomPaper extends JavaPlugin implements Listener { - public static final long MIN_POSITION_LONG = BlockPos.asLong(-33554432, -2048, -33554432); - static { - if (MIN_POSITION_LONG != 0b1000000000000000000000000010000000000000000000000000100000000000L) { - throw new Error("BlockPos representation changed!"); - } - } - - private static final int API_VERSION = 4; - private static final NamespacedKey ACTIVE_HOTBAR_INDEX = new NamespacedKey("axiom", "active_hotbar_index"); - private static final NamespacedKey HOTBAR_DATA = new NamespacedKey("axiom", "hotbar_data"); - - private static final NamespacedKey ACTIVE_VIEW = new NamespacedKey("axiom", "active_view"); - private static final NamespacedKey VIEWS = new NamespacedKey("axiom", "views"); - @Override public void onEnable() { Bukkit.getPluginManager().registerEvents(this, this); @@ -66,180 +36,14 @@ public class AxiomPaper extends JavaPlugin implements Listener { HashSet activeAxiomPlayers = new HashSet<>(); - Bukkit.getMessenger().registerIncomingPluginChannel(this, "axiom:hello", (channel, player, message) -> { - if (!player.hasPermission("axiom.*")) { - return; - } - - FriendlyByteBuf friendlyByteBuf = new FriendlyByteBuf(Unpooled.wrappedBuffer(message)); - int apiVersion = friendlyByteBuf.readVarInt(); - friendlyByteBuf.readNbt(); // Discard - - if (apiVersion != API_VERSION) { - player.kick(Component.text("Unsupported Axiom API Version. Server supports " + API_VERSION + - ", while client is " + apiVersion)); - 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.writeBoolean(false); // No source info - buf.writeBoolean(false); // No source settings - buf.writeVarInt(5); // Maximum Reach - buf.writeVarInt(16); // Max editor views - buf.writeBoolean(true); // Editable Views - player.sendPluginMessage(this, "axiom:enable", buf.accessByteBufWithCorrectSize()); - - // Initialize Hotbars - PersistentDataContainer container = player.getPersistentDataContainer(); - int activeHotbarIndex = container.getOrDefault(ACTIVE_HOTBAR_INDEX, PersistentDataType.BYTE, (byte) 0); - PersistentDataContainer hotbarItems = container.get(HOTBAR_DATA, PersistentDataType.TAG_CONTAINER); - if (hotbarItems != null) { - buf = new FriendlyByteBuf(Unpooled.buffer()); - buf.writeByte((byte) activeHotbarIndex); - for (int i=0; i<9*9; i++) { - // Ignore selected hotbar - if (i / 9 == activeHotbarIndex) { - buf.writeItem(net.minecraft.world.item.ItemStack.EMPTY); - } else { - ItemStack stack = hotbarItems.get(new NamespacedKey("axiom", "slot_"+i), ItemStackDataType.INSTANCE); - buf.writeItem(CraftItemStack.asNMSCopy(stack)); - } - } - player.sendPluginMessage(this, "axiom:initialize_hotbars", buf.accessByteBufWithCorrectSize()); - } - - // Initialize Views - UUID activeView = container.get(ACTIVE_VIEW, UUIDDataType.INSTANCE); - if (activeView != null) { - buf = new FriendlyByteBuf(Unpooled.buffer()); - buf.writeUUID(activeView); - - PersistentDataContainer[] views = container.get(VIEWS, PersistentDataType.TAG_CONTAINER_ARRAY); - buf.writeVarInt(views.length); - for (PersistentDataContainer view : views) { - View.load(view).write(buf); - } - - player.sendPluginMessage(this, "axiom:set_editor_views", buf.accessByteBufWithCorrectSize()); - } - }); - Bukkit.getMessenger().registerIncomingPluginChannel(this, "axiom:set_gamemode", (channel, player, message) -> { - if (!player.hasPermission("axiom.*")) { - return; - } - - FriendlyByteBuf friendlyByteBuf = new FriendlyByteBuf(Unpooled.wrappedBuffer(message)); - GameType gameType = GameType.byId(friendlyByteBuf.readByte()); - ((CraftPlayer)player).getHandle().setGameMode(gameType); - }); - Bukkit.getMessenger().registerIncomingPluginChannel(this, "axiom:set_fly_speed", (channel, player, message) -> { - if (!player.hasPermission("axiom.*")) { - return; - } - - FriendlyByteBuf friendlyByteBuf = new FriendlyByteBuf(Unpooled.wrappedBuffer(message)); - float flySpeed = friendlyByteBuf.readFloat(); - ((CraftPlayer)player).getHandle().getAbilities().setFlyingSpeed(flySpeed); - }); + Bukkit.getMessenger().registerIncomingPluginChannel(this, "axiom:hello", new HelloPacketListener(this, activeAxiomPlayers)); + Bukkit.getMessenger().registerIncomingPluginChannel(this, "axiom:set_gamemode", new SetGamemodePacketListener()); + Bukkit.getMessenger().registerIncomingPluginChannel(this, "axiom:set_fly_speed", new SetFlySpeedPacketListener()); Bukkit.getMessenger().registerIncomingPluginChannel(this, "axiom:set_block", new SetBlockPacketListener(this)); - Bukkit.getMessenger().registerIncomingPluginChannel(this, "axiom:set_hotbar_slot", (channel, player, message) -> { - if (!player.hasPermission("axiom.*")) { - return; - } - - FriendlyByteBuf friendlyByteBuf = new FriendlyByteBuf(Unpooled.wrappedBuffer(message)); - int index = friendlyByteBuf.readByte(); - if (index < 0 || index >= 9*9) return; - net.minecraft.world.item.ItemStack nmsStack = friendlyByteBuf.readItem(); - - PersistentDataContainer container = player.getPersistentDataContainer(); - PersistentDataContainer hotbarItems = container.get(HOTBAR_DATA, PersistentDataType.TAG_CONTAINER); - if (hotbarItems == null) hotbarItems = container.getAdapterContext().newPersistentDataContainer(); - hotbarItems.set(new NamespacedKey("axiom", "slot_"+index), ItemStackDataType.INSTANCE, CraftItemStack.asCraftMirror(nmsStack)); - container.set(HOTBAR_DATA, PersistentDataType.TAG_CONTAINER, hotbarItems); - }); - Bukkit.getMessenger().registerIncomingPluginChannel(this, "axiom:switch_active_hotbar", (channel, player, message) -> { - if (!player.hasPermission("axiom.*")) { - return; - } - - FriendlyByteBuf friendlyByteBuf = new FriendlyByteBuf(Unpooled.wrappedBuffer(message)); - int oldHotbarIndex = friendlyByteBuf.readByte(); - int activeHotbarIndex = friendlyByteBuf.readByte(); - - ItemStack[] hotbarItems = new ItemStack[9]; - for (int i=0; i<9; i++) { - hotbarItems[i] = CraftItemStack.asCraftMirror(friendlyByteBuf.readItem()); - } - - PersistentDataContainer container = player.getPersistentDataContainer(); - PersistentDataContainer containerHotbarItems = container.get(HOTBAR_DATA, PersistentDataType.TAG_CONTAINER); - if (containerHotbarItems == null) containerHotbarItems = container.getAdapterContext().newPersistentDataContainer(); - - for (int i=0; i<9; i++) { - if (oldHotbarIndex != activeHotbarIndex) { - int index = oldHotbarIndex*9 + i; - ItemStack stack = player.getInventory().getItem(i); - if (stack == null) { - stack = new ItemStack(Material.AIR); - } else { - stack = stack.clone(); - } - containerHotbarItems.set(new NamespacedKey("axiom", "slot_"+index), ItemStackDataType.INSTANCE, stack); - } - int index = activeHotbarIndex*9 + i; - containerHotbarItems.set(new NamespacedKey("axiom", "slot_"+index), ItemStackDataType.INSTANCE, hotbarItems[i].clone()); - if (player.getGameMode() == GameMode.CREATIVE) player.getInventory().setItem(i, hotbarItems[i]); - } - - container.set(HOTBAR_DATA, PersistentDataType.TAG_CONTAINER, containerHotbarItems); - container.set(ACTIVE_HOTBAR_INDEX, PersistentDataType.BYTE, (byte) activeHotbarIndex); - }); - Bukkit.getMessenger().registerIncomingPluginChannel(this, "axiom:teleport", (channel, player, message) -> { - if (!player.hasPermission("axiom.*")) { - return; - } - - FriendlyByteBuf friendlyByteBuf = new FriendlyByteBuf(Unpooled.wrappedBuffer(message)); - ResourceKey resourceKey = friendlyByteBuf.readResourceKey(Registries.DIMENSION); - double x = friendlyByteBuf.readDouble(); - double y = friendlyByteBuf.readDouble(); - double z = friendlyByteBuf.readDouble(); - float yRot = friendlyByteBuf.readFloat(); - float xRot = friendlyByteBuf.readFloat(); - - NamespacedKey namespacedKey = new NamespacedKey(resourceKey.location().getNamespace(), resourceKey.location().getPath()); - World world = Bukkit.getWorld(namespacedKey); - if (world != null) { - player.teleport(new Location(world, x, y, z, yRot, xRot)); - } - }); - Bukkit.getMessenger().registerIncomingPluginChannel(this, "axiom:set_editor_views", (channel, player, message) -> { - if (!player.hasPermission("axiom.*")) { - return; - } - - FriendlyByteBuf friendlyByteBuf = new FriendlyByteBuf(Unpooled.wrappedBuffer(message)); - UUID uuid = friendlyByteBuf.readUUID(); - List views = friendlyByteBuf.readList(View::read); - - PersistentDataContainer container = player.getPersistentDataContainer(); - container.set(ACTIVE_VIEW, UUIDDataType.INSTANCE, uuid); - - PersistentDataContainer[] containerArray = new PersistentDataContainer[views.size()]; - for (int i = 0; i < views.size(); i++) { - PersistentDataContainer viewContainer = container.getAdapterContext().newPersistentDataContainer(); - views.get(i).save(viewContainer); - containerArray[i] = viewContainer; - } - container.set(VIEWS, PersistentDataType.TAG_CONTAINER_ARRAY, containerArray); - }); + Bukkit.getMessenger().registerIncomingPluginChannel(this, "axiom:set_hotbar_slot", new SetHotbarSlotPacketListener()); + Bukkit.getMessenger().registerIncomingPluginChannel(this, "axiom:switch_active_hotbar", new SwitchActiveHotbarPacketListener()); + Bukkit.getMessenger().registerIncomingPluginChannel(this, "axiom:teleport", new TeleportPacketListener()); + Bukkit.getMessenger().registerIncomingPluginChannel(this, "axiom:set_editor_views", new SetEditorViewsPacketListener()); SetBlockBufferPacketListener setBlockBufferPacketListener = new SetBlockBufferPacketListener(this); diff --git a/src/main/java/com/moulberry/axiom/buffer/BlockBuffer.java b/src/main/java/com/moulberry/axiom/buffer/BlockBuffer.java index cb3f90c..77992d3 100644 --- a/src/main/java/com/moulberry/axiom/buffer/BlockBuffer.java +++ b/src/main/java/com/moulberry/axiom/buffer/BlockBuffer.java @@ -1,9 +1,11 @@ package com.moulberry.axiom.buffer; +import com.moulberry.axiom.AxiomConstants; import com.moulberry.axiom.AxiomPaper; import it.unimi.dsi.fastutil.longs.Long2ObjectMap; import it.unimi.dsi.fastutil.longs.Long2ObjectOpenHashMap; import it.unimi.dsi.fastutil.objects.ObjectSet; +import it.unimi.dsi.fastutil.shorts.Short2ObjectMap; import net.minecraft.core.BlockPos; import net.minecraft.network.FriendlyByteBuf; import net.minecraft.world.level.block.Block; @@ -18,8 +20,7 @@ public class BlockBuffer { private final Long2ObjectMap> values; private PalettedContainer last = null; - private long lastId = AxiomPaper.MIN_POSITION_LONG; - private int count; + private long lastId = AxiomConstants.MIN_POSITION_LONG; public BlockBuffer() { this.values = new Long2ObjectOpenHashMap<>(); @@ -29,17 +30,13 @@ public class BlockBuffer { this.values = values; } - public int getCount() { - return this.count; - } - public void save(FriendlyByteBuf friendlyByteBuf) { for (Long2ObjectMap.Entry> entry : this.entrySet()) { friendlyByteBuf.writeLong(entry.getLongKey()); entry.getValue().write(friendlyByteBuf); } - friendlyByteBuf.writeLong(AxiomPaper.MIN_POSITION_LONG); + friendlyByteBuf.writeLong(AxiomConstants.MIN_POSITION_LONG); } public static BlockBuffer load(FriendlyByteBuf friendlyByteBuf) { @@ -47,7 +44,7 @@ public class BlockBuffer { while (true) { long index = friendlyByteBuf.readLong(); - if (index == AxiomPaper.MIN_POSITION_LONG) break; + if (index == AxiomConstants.MIN_POSITION_LONG) break; PalettedContainer palettedContainer = buffer.getOrCreateSection(index); palettedContainer.read(friendlyByteBuf); @@ -58,7 +55,7 @@ public class BlockBuffer { public void clear() { this.last = null; - this.lastId = AxiomPaper.MIN_POSITION_LONG; + this.lastId = AxiomConstants.MIN_POSITION_LONG; this.values.clear(); } @@ -79,23 +76,11 @@ public class BlockBuffer { public void set(int x, int y, int z, BlockState state) { var container = this.getOrCreateSectionForCoord(x, y, z); var old = container.getAndSet(x & 0xF, y & 0xF, z & 0xF, state); - - if (old == EMPTY_STATE) { - if (state != EMPTY_STATE) this.count += 1; - } else if (state == EMPTY_STATE) { - this.count -= 1; - } } public void set(int cx, int cy, int cz, int lx, int ly, int lz, BlockState state) { var container = this.getOrCreateSection(BlockPos.asLong(cx, cy, cz)); var old = container.getAndSet(lx, ly, lz, state); - - if (old == EMPTY_STATE) { - if (state != EMPTY_STATE) this.count += 1; - } else if (state == EMPTY_STATE) { - this.count -= 1; - } } public BlockState remove(int x, int y, int z) { diff --git a/src/main/java/com/moulberry/axiom/packet/HelloPacketListener.java b/src/main/java/com/moulberry/axiom/packet/HelloPacketListener.java new file mode 100644 index 0000000..63041a1 --- /dev/null +++ b/src/main/java/com/moulberry/axiom/packet/HelloPacketListener.java @@ -0,0 +1,98 @@ +package com.moulberry.axiom.packet; + +import com.moulberry.axiom.AxiomConstants; +import com.moulberry.axiom.AxiomPaper; +import com.moulberry.axiom.View; +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.NamespacedKey; +import org.bukkit.craftbukkit.v1_20_R1.inventory.CraftItemStack; +import org.bukkit.entity.Player; +import org.bukkit.inventory.ItemStack; +import org.bukkit.persistence.PersistentDataContainer; +import org.bukkit.persistence.PersistentDataType; +import org.bukkit.plugin.messaging.PluginMessageListener; +import org.jetbrains.annotations.NotNull; + +import java.util.Set; +import java.util.UUID; + +public class HelloPacketListener implements PluginMessageListener { + + private final AxiomPaper plugin; + private final Set activeAxiomPlayers; + + public HelloPacketListener(AxiomPaper plugin, Set activeAxiomPlayers) { + this.plugin = plugin; + this.activeAxiomPlayers = activeAxiomPlayers; + } + + @Override + public void onPluginMessageReceived(@NotNull String channel, @NotNull Player player, @NotNull byte[] message) { + if (!player.hasPermission("axiom.*")) { + return; + } + + FriendlyByteBuf friendlyByteBuf = new FriendlyByteBuf(Unpooled.wrappedBuffer(message)); + int apiVersion = friendlyByteBuf.readVarInt(); + friendlyByteBuf.readNbt(); // Discard + + if (apiVersion != AxiomConstants.API_VERSION) { + player.kick(Component.text("Unsupported Axiom API Version. Server supports " + AxiomConstants.API_VERSION + + ", while client is " + apiVersion)); + 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.writeBoolean(false); // No source info + buf.writeBoolean(false); // No source settings + buf.writeVarInt(5); // Maximum Reach + buf.writeVarInt(16); // Max editor views + buf.writeBoolean(true); // Editable Views + player.sendPluginMessage(this.plugin, "axiom:enable", buf.accessByteBufWithCorrectSize()); + + // Initialize Hotbars + PersistentDataContainer container = player.getPersistentDataContainer(); + int activeHotbarIndex = container.getOrDefault(AxiomConstants.ACTIVE_HOTBAR_INDEX, PersistentDataType.BYTE, (byte) 0); + PersistentDataContainer hotbarItems = container.get(AxiomConstants.HOTBAR_DATA, PersistentDataType.TAG_CONTAINER); + if (hotbarItems != null) { + buf = new FriendlyByteBuf(Unpooled.buffer()); + buf.writeByte((byte) activeHotbarIndex); + for (int i=0; i<9*9; i++) { + // Ignore selected hotbar + if (i / 9 == activeHotbarIndex) { + buf.writeItem(net.minecraft.world.item.ItemStack.EMPTY); + } else { + ItemStack stack = hotbarItems.get(new NamespacedKey("axiom", "slot_"+i), ItemStackDataType.INSTANCE); + buf.writeItem(CraftItemStack.asNMSCopy(stack)); + } + } + player.sendPluginMessage(this.plugin, "axiom:initialize_hotbars", buf.accessByteBufWithCorrectSize()); + } + + // Initialize Views + UUID activeView = container.get(AxiomConstants.ACTIVE_VIEW, UUIDDataType.INSTANCE); + if (activeView != null) { + buf = new FriendlyByteBuf(Unpooled.buffer()); + buf.writeUUID(activeView); + + PersistentDataContainer[] views = container.get(AxiomConstants.VIEWS, PersistentDataType.TAG_CONTAINER_ARRAY); + buf.writeVarInt(views.length); + for (PersistentDataContainer view : views) { + View.load(view).write(buf); + } + + player.sendPluginMessage(this.plugin, "axiom:set_editor_views", buf.accessByteBufWithCorrectSize()); + } + } + +} diff --git a/src/main/java/com/moulberry/axiom/packet/SetBlockPacketListener.java b/src/main/java/com/moulberry/axiom/packet/SetBlockPacketListener.java index 44ae910..a5aa974 100644 --- a/src/main/java/com/moulberry/axiom/packet/SetBlockPacketListener.java +++ b/src/main/java/com/moulberry/axiom/packet/SetBlockPacketListener.java @@ -111,25 +111,23 @@ public class SetBlockPacketListener implements PluginMessageListener { if (blockEntity != null) { chunk.addAndRegisterBlockEntity(blockEntity); } + } else if (blockEntity.getType().isValid(blockState)) { + // Block entity is here and the type is correct + // Just update the state and ticker and move on + blockEntity.setBlockState(blockState); + + try { + this.updateBlockEntityTicker.invoke(chunk, blockEntity); + } catch (IllegalAccessException | InvocationTargetException e) { + throw new RuntimeException(e); + } } else { - if (blockEntity.getType().isValid(blockState)) { - // Block entity is here and the type is correct - // Just update the state and ticker and move on - blockEntity.setBlockState(blockState); + // Block entity type isn't correct, we need to recreate it + chunk.removeBlockEntity(blockPos); - try { - this.updateBlockEntityTicker.invoke(chunk, blockEntity); - } catch (IllegalAccessException | InvocationTargetException e) { - throw new RuntimeException(e); - } - } else { - // Block entity type isn't correct, we need to recreate it - chunk.removeBlockEntity(blockPos); - - blockEntity = ((EntityBlock)block).newBlockEntity(blockPos, blockState); - if (blockEntity != null) { - chunk.addAndRegisterBlockEntity(blockEntity); - } + blockEntity = ((EntityBlock)block).newBlockEntity(blockPos, blockState); + if (blockEntity != null) { + chunk.addAndRegisterBlockEntity(blockEntity); } } } else if (old.hasBlockEntity()) { diff --git a/src/main/java/com/moulberry/axiom/packet/SetEditorViewsPacketListener.java b/src/main/java/com/moulberry/axiom/packet/SetEditorViewsPacketListener.java new file mode 100644 index 0000000..1fd9bda --- /dev/null +++ b/src/main/java/com/moulberry/axiom/packet/SetEditorViewsPacketListener.java @@ -0,0 +1,41 @@ +package com.moulberry.axiom.packet; + +import com.moulberry.axiom.AxiomConstants; +import com.moulberry.axiom.View; +import com.moulberry.axiom.persistence.UUIDDataType; +import io.netty.buffer.Unpooled; +import net.minecraft.network.FriendlyByteBuf; +import org.bukkit.entity.Player; +import org.bukkit.persistence.PersistentDataContainer; +import org.bukkit.persistence.PersistentDataType; +import org.bukkit.plugin.messaging.PluginMessageListener; +import org.jetbrains.annotations.NotNull; + +import java.util.List; +import java.util.UUID; + +public class SetEditorViewsPacketListener implements PluginMessageListener { + + @Override + public void onPluginMessageReceived(@NotNull String channel, @NotNull Player player, @NotNull byte[] message) { + if (!player.hasPermission("axiom.*")) { + return; + } + + FriendlyByteBuf friendlyByteBuf = new FriendlyByteBuf(Unpooled.wrappedBuffer(message)); + UUID uuid = friendlyByteBuf.readUUID(); + List views = friendlyByteBuf.readList(View::read); + + PersistentDataContainer container = player.getPersistentDataContainer(); + container.set(AxiomConstants.ACTIVE_VIEW, UUIDDataType.INSTANCE, uuid); + + PersistentDataContainer[] containerArray = new PersistentDataContainer[views.size()]; + for (int i = 0; i < views.size(); i++) { + PersistentDataContainer viewContainer = container.getAdapterContext().newPersistentDataContainer(); + views.get(i).save(viewContainer); + containerArray[i] = viewContainer; + } + container.set(AxiomConstants.VIEWS, PersistentDataType.TAG_CONTAINER_ARRAY, containerArray); + } + +} diff --git a/src/main/java/com/moulberry/axiom/packet/SetFlySpeedPacketListener.java b/src/main/java/com/moulberry/axiom/packet/SetFlySpeedPacketListener.java new file mode 100644 index 0000000..e355a61 --- /dev/null +++ b/src/main/java/com/moulberry/axiom/packet/SetFlySpeedPacketListener.java @@ -0,0 +1,24 @@ +package com.moulberry.axiom.packet; + +import io.netty.buffer.Unpooled; +import net.minecraft.network.FriendlyByteBuf; +import net.minecraft.world.level.GameType; +import org.bukkit.craftbukkit.v1_20_R1.entity.CraftPlayer; +import org.bukkit.entity.Player; +import org.bukkit.plugin.messaging.PluginMessageListener; +import org.jetbrains.annotations.NotNull; + +public class SetFlySpeedPacketListener implements PluginMessageListener { + + @Override + public void onPluginMessageReceived(@NotNull String channel, @NotNull Player player, @NotNull byte[] message) { + if (!player.hasPermission("axiom.*")) { + return; + } + + FriendlyByteBuf friendlyByteBuf = new FriendlyByteBuf(Unpooled.wrappedBuffer(message)); + float flySpeed = friendlyByteBuf.readFloat(); + ((CraftPlayer)player).getHandle().getAbilities().setFlyingSpeed(flySpeed); + } + +} diff --git a/src/main/java/com/moulberry/axiom/packet/SetGamemodePacketListener.java b/src/main/java/com/moulberry/axiom/packet/SetGamemodePacketListener.java new file mode 100644 index 0000000..638203b --- /dev/null +++ b/src/main/java/com/moulberry/axiom/packet/SetGamemodePacketListener.java @@ -0,0 +1,24 @@ +package com.moulberry.axiom.packet; + +import io.netty.buffer.Unpooled; +import net.minecraft.network.FriendlyByteBuf; +import net.minecraft.world.level.GameType; +import org.bukkit.craftbukkit.v1_20_R1.entity.CraftPlayer; +import org.bukkit.entity.Player; +import org.bukkit.plugin.messaging.PluginMessageListener; +import org.jetbrains.annotations.NotNull; + +public class SetGamemodePacketListener implements PluginMessageListener { + + @Override + public void onPluginMessageReceived(@NotNull String channel, @NotNull Player player, @NotNull byte[] message) { + if (!player.hasPermission("axiom.*")) { + return; + } + + FriendlyByteBuf friendlyByteBuf = new FriendlyByteBuf(Unpooled.wrappedBuffer(message)); + GameType gameType = GameType.byId(friendlyByteBuf.readByte()); + ((CraftPlayer)player).getHandle().setGameMode(gameType); + } + +} diff --git a/src/main/java/com/moulberry/axiom/packet/SetHotbarSlotPacketListener.java b/src/main/java/com/moulberry/axiom/packet/SetHotbarSlotPacketListener.java new file mode 100644 index 0000000..a91cd63 --- /dev/null +++ b/src/main/java/com/moulberry/axiom/packet/SetHotbarSlotPacketListener.java @@ -0,0 +1,36 @@ +package com.moulberry.axiom.packet; + +import com.moulberry.axiom.AxiomConstants; +import com.moulberry.axiom.persistence.ItemStackDataType; +import io.netty.buffer.Unpooled; +import net.minecraft.network.FriendlyByteBuf; +import org.bukkit.NamespacedKey; +import org.bukkit.craftbukkit.v1_20_R1.entity.CraftPlayer; +import org.bukkit.craftbukkit.v1_20_R1.inventory.CraftItemStack; +import org.bukkit.entity.Player; +import org.bukkit.persistence.PersistentDataContainer; +import org.bukkit.persistence.PersistentDataType; +import org.bukkit.plugin.messaging.PluginMessageListener; +import org.jetbrains.annotations.NotNull; + +public class SetHotbarSlotPacketListener implements PluginMessageListener { + + @Override + public void onPluginMessageReceived(@NotNull String channel, @NotNull Player player, @NotNull byte[] message) { + if (!player.hasPermission("axiom.*")) { + return; + } + + FriendlyByteBuf friendlyByteBuf = new FriendlyByteBuf(Unpooled.wrappedBuffer(message)); + int index = friendlyByteBuf.readByte(); + if (index < 0 || index >= 9*9) return; + net.minecraft.world.item.ItemStack nmsStack = friendlyByteBuf.readItem(); + + PersistentDataContainer container = player.getPersistentDataContainer(); + PersistentDataContainer hotbarItems = container.get(AxiomConstants.HOTBAR_DATA, PersistentDataType.TAG_CONTAINER); + if (hotbarItems == null) hotbarItems = container.getAdapterContext().newPersistentDataContainer(); + hotbarItems.set(new NamespacedKey("axiom", "slot_"+index), ItemStackDataType.INSTANCE, CraftItemStack.asCraftMirror(nmsStack)); + container.set(AxiomConstants.HOTBAR_DATA, PersistentDataType.TAG_CONTAINER, hotbarItems); + } + +} diff --git a/src/main/java/com/moulberry/axiom/packet/SwitchActiveHotbarPacketListener.java b/src/main/java/com/moulberry/axiom/packet/SwitchActiveHotbarPacketListener.java new file mode 100644 index 0000000..38badf8 --- /dev/null +++ b/src/main/java/com/moulberry/axiom/packet/SwitchActiveHotbarPacketListener.java @@ -0,0 +1,59 @@ +package com.moulberry.axiom.packet; + +import com.moulberry.axiom.AxiomConstants; +import com.moulberry.axiom.persistence.ItemStackDataType; +import io.netty.buffer.Unpooled; +import net.minecraft.network.FriendlyByteBuf; +import org.bukkit.GameMode; +import org.bukkit.Material; +import org.bukkit.NamespacedKey; +import org.bukkit.craftbukkit.v1_20_R1.inventory.CraftItemStack; +import org.bukkit.entity.Player; +import org.bukkit.inventory.ItemStack; +import org.bukkit.persistence.PersistentDataContainer; +import org.bukkit.persistence.PersistentDataType; +import org.bukkit.plugin.messaging.PluginMessageListener; +import org.jetbrains.annotations.NotNull; + +public class SwitchActiveHotbarPacketListener implements PluginMessageListener { + + @Override + public void onPluginMessageReceived(@NotNull String channel, @NotNull Player player, @NotNull byte[] message) { + if (!player.hasPermission("axiom.*")) { + return; + } + + FriendlyByteBuf friendlyByteBuf = new FriendlyByteBuf(Unpooled.wrappedBuffer(message)); + int oldHotbarIndex = friendlyByteBuf.readByte(); + int activeHotbarIndex = friendlyByteBuf.readByte(); + + ItemStack[] hotbarItems = new ItemStack[9]; + for (int i=0; i<9; i++) { + hotbarItems[i] = CraftItemStack.asCraftMirror(friendlyByteBuf.readItem()); + } + + PersistentDataContainer container = player.getPersistentDataContainer(); + PersistentDataContainer containerHotbarItems = container.get(AxiomConstants.HOTBAR_DATA, PersistentDataType.TAG_CONTAINER); + if (containerHotbarItems == null) containerHotbarItems = container.getAdapterContext().newPersistentDataContainer(); + + for (int i=0; i<9; i++) { + if (oldHotbarIndex != activeHotbarIndex) { + int index = oldHotbarIndex*9 + i; + ItemStack stack = player.getInventory().getItem(i); + if (stack == null) { + stack = new ItemStack(Material.AIR); + } else { + stack = stack.clone(); + } + containerHotbarItems.set(new NamespacedKey("axiom", "slot_"+index), ItemStackDataType.INSTANCE, stack); + } + int index = activeHotbarIndex*9 + i; + containerHotbarItems.set(new NamespacedKey("axiom", "slot_"+index), ItemStackDataType.INSTANCE, hotbarItems[i].clone()); + if (player.getGameMode() == GameMode.CREATIVE) player.getInventory().setItem(i, hotbarItems[i]); + } + + container.set(AxiomConstants.HOTBAR_DATA, PersistentDataType.TAG_CONTAINER, containerHotbarItems); + container.set(AxiomConstants.ACTIVE_HOTBAR_INDEX, PersistentDataType.BYTE, (byte) activeHotbarIndex); + } + +} diff --git a/src/main/java/com/moulberry/axiom/packet/TeleportPacketListener.java b/src/main/java/com/moulberry/axiom/packet/TeleportPacketListener.java new file mode 100644 index 0000000..81b07a9 --- /dev/null +++ b/src/main/java/com/moulberry/axiom/packet/TeleportPacketListener.java @@ -0,0 +1,39 @@ +package com.moulberry.axiom.packet; + +import io.netty.buffer.Unpooled; +import net.minecraft.core.registries.Registries; +import net.minecraft.network.FriendlyByteBuf; +import net.minecraft.resources.ResourceKey; +import net.minecraft.world.level.Level; +import org.bukkit.Bukkit; +import org.bukkit.Location; +import org.bukkit.NamespacedKey; +import org.bukkit.World; +import org.bukkit.entity.Player; +import org.bukkit.plugin.messaging.PluginMessageListener; +import org.jetbrains.annotations.NotNull; + +public class TeleportPacketListener implements PluginMessageListener { + + @Override + public void onPluginMessageReceived(@NotNull String channel, @NotNull Player player, @NotNull byte[] message) { + if (!player.hasPermission("axiom.*")) { + return; + } + + FriendlyByteBuf friendlyByteBuf = new FriendlyByteBuf(Unpooled.wrappedBuffer(message)); + ResourceKey resourceKey = friendlyByteBuf.readResourceKey(Registries.DIMENSION); + double x = friendlyByteBuf.readDouble(); + double y = friendlyByteBuf.readDouble(); + double z = friendlyByteBuf.readDouble(); + float yRot = friendlyByteBuf.readFloat(); + float xRot = friendlyByteBuf.readFloat(); + + NamespacedKey namespacedKey = new NamespacedKey(resourceKey.location().getNamespace(), resourceKey.location().getPath()); + World world = Bukkit.getWorld(namespacedKey); + if (world != null) { + player.teleport(new Location(world, x, y, z, yRot, xRot)); + } + } + +}