From 8c45a7b7d2e7ff67ef6bd03bda0097ec2d2ab9ef Mon Sep 17 00:00:00 2001 From: Russell Stout Date: Thu, 2 May 2024 10:01:07 -0500 Subject: [PATCH 01/22] Update README.md with FAQ about multiplayer issues --- README.md | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/README.md b/README.md index 6806e14..9965de8 100644 --- a/README.md +++ b/README.md @@ -6,3 +6,13 @@ Serverside component for Axiom ## Download https://modrinth.com/plugin/axiom-paper-plugin/ + +## FAQ + +**Axiom works in singleplayer but not when I connect to a multiplayer server running the Axiom Paper Plugin. What gives?** + +First, the player must be an op on the server. If the player does not have op permissions, run `/op `. This player must then disconnect from the server and reconnect. + +If you're using an alternative solution for permission management, you must give players the `axiom.*` permission. + +If players continue to have issues, they can run the `/whynoaxiom` command for more information. From 5ea1f321341779ecb63290677e1c1dd3bc5e3602 Mon Sep 17 00:00:00 2001 From: Moulberry Date: Fri, 3 May 2024 19:23:31 +0800 Subject: [PATCH 02/22] Partial ViaVersion support --- build.gradle.kts | 4 ++ .../java/com/moulberry/axiom/AxiomPaper.java | 11 ++++ .../com/moulberry/axiom/DisallowedBlocks.java | 1 + .../moulberry/axiom/buffer/BlockBuffer.java | 16 ++--- .../axiom/packet/AxiomBigPayloadHandler.java | 14 +++-- .../axiom/packet/HelloPacketListener.java | 62 +++++++++++++++---- .../RequestChunkDataPacketListener.java | 3 +- .../packet/SetBlockBufferPacketListener.java | 2 +- .../axiom/packet/SetBlockPacketListener.java | 12 +++- .../packet/UploadBlueprintPacketListener.java | 41 +++++++----- .../axiom/viaversion/ViaVersionHelper.java | 42 ++++++++++++- src/main/resources/plugin.yml | 4 +- 12 files changed, 165 insertions(+), 47 deletions(-) diff --git a/build.gradle.kts b/build.gradle.kts index 157957d..388f896 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -18,6 +18,7 @@ java { repositories { mavenCentral() + maven("https://repo.viaversion.com") maven("https://s01.oss.sonatype.org/content/repositories/snapshots/") maven("https://jitpack.io") maven("https://repo.papermc.io/repository/maven-public/") @@ -31,6 +32,9 @@ dependencies { // Zstd Compression Library implementation("com.github.luben:zstd-jni:1.5.5-4") + // ViaVersion support + compileOnly("com.viaversion:viaversion-api:4.9.4-SNAPSHOT") + // WorldGuard support compileOnly("com.sk89q.worldguard:worldguard-bukkit:7.1.0-SNAPSHOT") diff --git a/src/main/java/com/moulberry/axiom/AxiomPaper.java b/src/main/java/com/moulberry/axiom/AxiomPaper.java index 44f6919..a58d8fe 100644 --- a/src/main/java/com/moulberry/axiom/AxiomPaper.java +++ b/src/main/java/com/moulberry/axiom/AxiomPaper.java @@ -36,6 +36,7 @@ import org.bukkit.plugin.messaging.Messenger; import org.checkerframework.checker.nullness.qual.NonNull; import org.jetbrains.annotations.Nullable; +import java.io.FileReader; import java.io.IOException; import java.nio.file.Files; import java.nio.file.Path; @@ -49,6 +50,7 @@ public class AxiomPaper extends JavaPlugin implements Listener { public final Set activeAxiomPlayers = Collections.newSetFromMap(new ConcurrentHashMap<>()); public final Map playerBlockBufferRateLimiters = new ConcurrentHashMap<>(); public final Map playerRestrictions = new ConcurrentHashMap<>(); + public final Map> playerBlockRegistry = new ConcurrentHashMap<>(); public Configuration configuration; public IdMapper allowedBlockRegistry = null; @@ -265,6 +267,7 @@ public class AxiomPaper extends JavaPlugin implements Listener { activeAxiomPlayers.retainAll(stillActiveAxiomPlayers); playerBlockBufferRateLimiters.keySet().retainAll(stillActiveAxiomPlayers); playerRestrictions.keySet().retainAll(stillActiveAxiomPlayers); + playerBlockRegistry.keySet().retainAll(stillActiveAxiomPlayers); }, 20, 20); boolean sendMarkers = configuration.getBoolean("send-markers"); @@ -292,6 +295,14 @@ public class AxiomPaper extends JavaPlugin implements Listener { return this.playerBlockBufferRateLimiters.get(uuid); } + public boolean hasCustomBlockRegistry(UUID uuid) { + return this.playerBlockRegistry.containsKey(uuid); + } + + public IdMapper getBlockRegistry(UUID uuid) { + return this.playerBlockRegistry.getOrDefault(uuid, this.allowedBlockRegistry); + } + private final WeakHashMap worldProperties = new WeakHashMap<>(); public @Nullable ServerWorldPropertiesRegistry getWorldPropertiesIfPresent(World world) { diff --git a/src/main/java/com/moulberry/axiom/DisallowedBlocks.java b/src/main/java/com/moulberry/axiom/DisallowedBlocks.java index f80d2b8..ef4ab3a 100644 --- a/src/main/java/com/moulberry/axiom/DisallowedBlocks.java +++ b/src/main/java/com/moulberry/axiom/DisallowedBlocks.java @@ -3,6 +3,7 @@ package com.moulberry.axiom; import com.mojang.brigadier.StringReader; import com.mojang.datafixers.util.Either; import com.moulberry.axiom.buffer.BlockBuffer; +import com.viaversion.viaversion.api.data.Mappings; import net.minecraft.commands.arguments.blocks.BlockPredicateArgument; import net.minecraft.commands.arguments.blocks.BlockStateParser; import net.minecraft.core.IdMapper; diff --git a/src/main/java/com/moulberry/axiom/buffer/BlockBuffer.java b/src/main/java/com/moulberry/axiom/buffer/BlockBuffer.java index aa24244..b7fdcd7 100644 --- a/src/main/java/com/moulberry/axiom/buffer/BlockBuffer.java +++ b/src/main/java/com/moulberry/axiom/buffer/BlockBuffer.java @@ -9,6 +9,7 @@ import it.unimi.dsi.fastutil.objects.ObjectSet; import it.unimi.dsi.fastutil.shorts.Short2ObjectMap; import it.unimi.dsi.fastutil.shorts.Short2ObjectOpenHashMap; import net.minecraft.core.BlockPos; +import net.minecraft.core.IdMapper; import net.minecraft.network.FriendlyByteBuf; import net.minecraft.world.level.block.Blocks; import net.minecraft.world.level.block.state.BlockState; @@ -23,18 +24,16 @@ public class BlockBuffer { private final Long2ObjectMap> values; + private IdMapper registry; private PalettedContainer last = null; private long lastId = AxiomConstants.MIN_POSITION_LONG; private final Long2ObjectMap> blockEntities = new Long2ObjectOpenHashMap<>(); private long totalBlockEntities = 0; private long totalBlockEntityBytes = 0; - public BlockBuffer() { + public BlockBuffer(IdMapper registry) { this.values = new Long2ObjectOpenHashMap<>(); - } - - public BlockBuffer(Long2ObjectMap> values) { - this.values = values; + this.registry = registry; } public void save(FriendlyByteBuf friendlyByteBuf) { @@ -57,8 +56,9 @@ public class BlockBuffer { friendlyByteBuf.writeLong(AxiomConstants.MIN_POSITION_LONG); } - public static BlockBuffer load(FriendlyByteBuf friendlyByteBuf, @Nullable RateLimiter rateLimiter, AtomicBoolean reachedRateLimit) { - BlockBuffer buffer = new BlockBuffer(); + public static BlockBuffer load(FriendlyByteBuf friendlyByteBuf, @Nullable RateLimiter rateLimiter, AtomicBoolean reachedRateLimit, + IdMapper registry) { + BlockBuffer buffer = new BlockBuffer(registry); long totalBlockEntities = 0; long totalBlockEntityBytes = 0; @@ -177,7 +177,7 @@ public class BlockBuffer { public PalettedContainer getOrCreateSection(long id) { if (this.last == null || id != this.lastId) { this.lastId = id; - this.last = this.values.computeIfAbsent(id, k -> new PalettedContainer<>(AxiomPaper.PLUGIN.allowedBlockRegistry, + this.last = this.values.computeIfAbsent(id, k -> new PalettedContainer<>(this.registry, EMPTY_STATE, PalettedContainer.Strategy.SECTION_STATES)); } diff --git a/src/main/java/com/moulberry/axiom/packet/AxiomBigPayloadHandler.java b/src/main/java/com/moulberry/axiom/packet/AxiomBigPayloadHandler.java index 83eb52d..520bda6 100644 --- a/src/main/java/com/moulberry/axiom/packet/AxiomBigPayloadHandler.java +++ b/src/main/java/com/moulberry/axiom/packet/AxiomBigPayloadHandler.java @@ -62,8 +62,7 @@ public class AxiomBigPayloadHandler extends ByteToMessageDecoder { } else if (identifier.equals(UPLOAD_BLUEPRINT)) { ServerPlayer player = connection.getPlayer(); if (AxiomPaper.PLUGIN.canUseAxiom(player.getBukkitEntity())) { - player.getServer().execute(() -> uploadBlueprint.onReceive(player, buf)); - + uploadBlueprint.onReceive(player, buf); success = true; in.skipBytes(in.readableBytes()); return; @@ -74,8 +73,15 @@ public class AxiomBigPayloadHandler extends ByteToMessageDecoder { byte[] bytes = new byte[buf.writerIndex() - buf.readerIndex()]; buf.getBytes(buf.readerIndex(), bytes); - player.getServer().execute(() -> requestChunkDataPacketListener.onPluginMessageReceived( - identifier.toString(), player.getBukkitEntity(), bytes)); + player.getServer().execute(() -> { + try { + requestChunkDataPacketListener.onPluginMessageReceived( + identifier.toString(), player.getBukkitEntity(), bytes); + } catch (Throwable t) { + player.getBukkitEntity().kick(net.kyori.adventure.text.Component.text( + "An error occured while requesting chunk data: " + t.getMessage())); + } + }); success = true; in.skipBytes(in.readableBytes()); diff --git a/src/main/java/com/moulberry/axiom/packet/HelloPacketListener.java b/src/main/java/com/moulberry/axiom/packet/HelloPacketListener.java index 2553159..a182db8 100644 --- a/src/main/java/com/moulberry/axiom/packet/HelloPacketListener.java +++ b/src/main/java/com/moulberry/axiom/packet/HelloPacketListener.java @@ -1,15 +1,17 @@ package com.moulberry.axiom.packet; import com.google.common.util.concurrent.RateLimiter; -import com.moulberry.axiom.AxiomConstants; -import com.moulberry.axiom.AxiomPaper; -import com.moulberry.axiom.View; -import com.moulberry.axiom.WorldExtension; +import com.moulberry.axiom.*; import com.moulberry.axiom.blueprint.ServerBlueprintManager; import com.moulberry.axiom.event.AxiomHandshakeEvent; import com.moulberry.axiom.persistence.ItemStackDataType; import com.moulberry.axiom.persistence.UUIDDataType; +import com.moulberry.axiom.viaversion.ViaVersionHelper; import com.moulberry.axiom.world_properties.server.ServerWorldPropertiesRegistry; +import com.viaversion.viaversion.api.Via; +import com.viaversion.viaversion.api.data.*; +import com.viaversion.viaversion.api.protocol.version.ProtocolVersion; +import com.viaversion.viaversion.libs.opennbt.tag.builtin.CompoundTag; import io.netty.buffer.Unpooled; import net.kyori.adventure.text.Component; import net.kyori.adventure.text.format.NamedTextColor; @@ -52,18 +54,52 @@ public class HelloPacketListener implements PluginMessageListener { int serverDataVersion = SharedConstants.getCurrentVersion().getDataVersion().getVersion(); if (dataVersion != serverDataVersion) { - Component text = Component.text("Axiom: Incompatible data version detected (client " + dataVersion + - ", server " + serverDataVersion + "), are you using ViaVersion?"); + if (!Bukkit.getPluginManager().isPluginEnabled("ViaVersion")) { + Component text = Component.text("Axiom: Incompatible data version detected (client " + dataVersion + + ", server " + serverDataVersion + ")"); - String incompatibleDataVersion = plugin.configuration.getString("incompatible-data-version"); - if (incompatibleDataVersion == null) incompatibleDataVersion = "kick"; - if (incompatibleDataVersion.equals("warn")) { + String incompatibleDataVersion = plugin.configuration.getString("incompatible-data-version"); + if (incompatibleDataVersion == null) incompatibleDataVersion = "kick"; + if (incompatibleDataVersion.equals("warn")) { + player.sendMessage(text.color(NamedTextColor.RED)); + return; + } else if (!incompatibleDataVersion.equals("ignore")) { + player.kick(text); + return; + } + } else { +// int playerVersion = Via.getAPI().getPlayerVersion(player.getUniqueId()); +// if (ProtocolVersion.isRegistered(playerVersion)) { +// ProtocolVersion version = ProtocolVersion.getProtocol(playerVersion); +// String name = version.getName().split("/")[0]; +// +// +// } + + CompoundTag tag = MappingDataLoader.loadNBT("mappings-1.20.2to1.20.3.nbt"); + + if (tag == null) { + player.kick(Component.text("Axiom+ViaVersion: Failed to load mappings (1.20.2 <-> 1.20.3)")); + return; + } + + Mappings mappings = MappingDataLoader.loadMappings(tag, "blockstates"); + + if (mappings == null) { + player.kick(Component.text("Axiom+ViaVersion: Failed to load mapped blockstates (1.20.2 <-> 1.20.3")); + return; + } + + this.plugin.playerBlockRegistry.put(player.getUniqueId(), ViaVersionHelper.applyMappings(this.plugin.allowedBlockRegistry, + BiMappings.of(mappings).inverse())); + + Component text = Component.text("Axiom: Warning, client and server versions don't match. " + + "Axiom will try to use ViaVersion conversions, but this process may cause problems"); player.sendMessage(text.color(NamedTextColor.RED)); - return; - } else if (!incompatibleDataVersion.equals("ignore")) { - player.kick(text); - return; } +// inverse.getNewIdOrDefault() + + } if (apiVersion != AxiomConstants.API_VERSION) { diff --git a/src/main/java/com/moulberry/axiom/packet/RequestChunkDataPacketListener.java b/src/main/java/com/moulberry/axiom/packet/RequestChunkDataPacketListener.java index 8872b55..e406fa0 100644 --- a/src/main/java/com/moulberry/axiom/packet/RequestChunkDataPacketListener.java +++ b/src/main/java/com/moulberry/axiom/packet/RequestChunkDataPacketListener.java @@ -5,6 +5,7 @@ import com.moulberry.axiom.AxiomPaper; import com.moulberry.axiom.VersionHelper; import com.moulberry.axiom.buffer.CompressedBlockEntity; import com.moulberry.axiom.integration.plotsquared.PlotSquaredIntegration; +import com.viaversion.viaversion.api.Via; import io.netty.buffer.Unpooled; import it.unimi.dsi.fastutil.longs.*; import net.minecraft.core.BlockPos; @@ -46,7 +47,7 @@ public class RequestChunkDataPacketListener implements PluginMessageListener { FriendlyByteBuf friendlyByteBuf = new FriendlyByteBuf(Unpooled.wrappedBuffer(message)); long id = friendlyByteBuf.readLong(); - if (!this.plugin.canUseAxiom(bukkitPlayer)) { + if (!this.plugin.canUseAxiom(bukkitPlayer) || this.plugin.hasCustomBlockRegistry(bukkitPlayer.getUniqueId())) { // We always send an 'empty' response in order to make the client happy sendEmptyResponse(player, id); return; diff --git a/src/main/java/com/moulberry/axiom/packet/SetBlockBufferPacketListener.java b/src/main/java/com/moulberry/axiom/packet/SetBlockBufferPacketListener.java index 48615af..1722bf3 100644 --- a/src/main/java/com/moulberry/axiom/packet/SetBlockBufferPacketListener.java +++ b/src/main/java/com/moulberry/axiom/packet/SetBlockBufferPacketListener.java @@ -85,7 +85,7 @@ public class SetBlockBufferPacketListener { byte type = friendlyByteBuf.readByte(); if (type == 0) { AtomicBoolean reachedRateLimit = new AtomicBoolean(false); - BlockBuffer buffer = BlockBuffer.load(friendlyByteBuf, rateLimiter, reachedRateLimit); + BlockBuffer buffer = BlockBuffer.load(friendlyByteBuf, rateLimiter, reachedRateLimit, this.plugin.getBlockRegistry(player.getUUID())); if (reachedRateLimit.get()) { player.sendSystemMessage(Component.literal("[Axiom] Exceeded server rate-limit of " + (int)rateLimiter.getRate() + " sections per second") .withStyle(ChatFormatting.RED)); diff --git a/src/main/java/com/moulberry/axiom/packet/SetBlockPacketListener.java b/src/main/java/com/moulberry/axiom/packet/SetBlockPacketListener.java index 1a3ef52..8443817 100644 --- a/src/main/java/com/moulberry/axiom/packet/SetBlockPacketListener.java +++ b/src/main/java/com/moulberry/axiom/packet/SetBlockPacketListener.java @@ -7,6 +7,7 @@ import com.moulberry.axiom.integration.plotsquared.PlotSquaredIntegration; import io.netty.buffer.Unpooled; import net.minecraft.core.BlockPos; import net.minecraft.core.Holder; +import net.minecraft.core.IdMapper; import net.minecraft.core.SectionPos; import net.minecraft.network.FriendlyByteBuf; import net.minecraft.server.level.ServerLevel; @@ -79,8 +80,9 @@ public class SetBlockPacketListener implements PluginMessageListener { // Read packet FriendlyByteBuf friendlyByteBuf = new FriendlyByteBuf(Unpooled.wrappedBuffer(message)); IntFunction> mapFunction = FriendlyByteBuf.limitValue(Maps::newLinkedHashMapWithExpectedSize, 512); + IdMapper registry = this.plugin.getBlockRegistry(bukkitPlayer.getUniqueId()); Map blocks = friendlyByteBuf.readMap(mapFunction, - FriendlyByteBuf::readBlockPos, buf -> buf.readById(this.plugin.allowedBlockRegistry)); + FriendlyByteBuf::readBlockPos, buf -> buf.readById(registry)); boolean updateNeighbors = friendlyByteBuf.readBoolean(); int reason = friendlyByteBuf.readVarInt(); @@ -129,6 +131,10 @@ public class SetBlockPacketListener implements PluginMessageListener { BlockPos blockPos = entry.getKey(); BlockState blockState = entry.getValue(); + if (blockState == null) { + continue; + } + // Disallow in unloaded chunks if (!player.level().isLoaded(blockPos)) { continue; @@ -154,6 +160,10 @@ public class SetBlockPacketListener implements PluginMessageListener { BlockPos blockPos = entry.getKey(); BlockState blockState = entry.getValue(); + if (blockState == null) { + continue; + } + // Disallow in unloaded chunks if (!player.level().isLoaded(blockPos)) { continue; diff --git a/src/main/java/com/moulberry/axiom/packet/UploadBlueprintPacketListener.java b/src/main/java/com/moulberry/axiom/packet/UploadBlueprintPacketListener.java index e85270b..a2cb4bb 100644 --- a/src/main/java/com/moulberry/axiom/packet/UploadBlueprintPacketListener.java +++ b/src/main/java/com/moulberry/axiom/packet/UploadBlueprintPacketListener.java @@ -47,25 +47,34 @@ public class UploadBlueprintPacketListener { return; } - Path path = this.plugin.blueprintFolder.resolve(relative); + String pathName = pathStr.substring(0, pathStr.length()-3); - // Write file - try { - Files.createDirectories(path.getParent()); - } catch (IOException e) { - return; - } - try (OutputStream outputStream = new BufferedOutputStream(Files.newOutputStream(path))) { - BlueprintIo.writeRaw(outputStream, rawBlueprint); - } catch (IOException e) { - return; - } + serverPlayer.getServer().execute(() -> { + try { + Path path = this.plugin.blueprintFolder.resolve(relative); - // Update registry - registry.blueprints().put("/" + pathStr.substring(0, pathStr.length()-3), rawBlueprint); + // Write file + try { + Files.createDirectories(path.getParent()); + } catch (IOException e) { + return; + } + try (OutputStream outputStream = new BufferedOutputStream(Files.newOutputStream(path))) { + BlueprintIo.writeRaw(outputStream, rawBlueprint); + } catch (IOException e) { + return; + } - // Resend manifest - ServerBlueprintManager.sendManifest(serverPlayer.getServer().getPlayerList().getPlayers()); + // Update registry + registry.blueprints().put("/" + pathName, rawBlueprint); + + // Resend manifest + ServerBlueprintManager.sendManifest(serverPlayer.getServer().getPlayerList().getPlayers()); + } catch (Throwable t) { + serverPlayer.getBukkitEntity().kick(net.kyori.adventure.text.Component.text( + "An error occured while uploading blueprint: " + t.getMessage())); + } + }); } } diff --git a/src/main/java/com/moulberry/axiom/viaversion/ViaVersionHelper.java b/src/main/java/com/moulberry/axiom/viaversion/ViaVersionHelper.java index 3dcb8c3..ecba92a 100644 --- a/src/main/java/com/moulberry/axiom/viaversion/ViaVersionHelper.java +++ b/src/main/java/com/moulberry/axiom/viaversion/ViaVersionHelper.java @@ -1,2 +1,42 @@ -package com.moulberry.axiom.viaversion;public class ViaVersionHelper { +package com.moulberry.axiom.viaversion; + +import com.moulberry.axiom.buffer.BlockBuffer; +import com.viaversion.viaversion.api.data.BiMappings; +import com.viaversion.viaversion.api.data.Mappings; +import net.minecraft.core.IdMapper; +import net.minecraft.world.level.block.Block; +import net.minecraft.world.level.block.state.BlockState; + +public class ViaVersionHelper { + + public static IdMapper applyMappings(IdMapper registry, BiMappings mappings) { + IdMapper newBlockRegistry = new IdMapper<>(); + + // Add empty mappings for non-existent blocks + int size = mappings.mappedSize(); + for (int i = 0; i < size; i++) { + newBlockRegistry.addMapping(BlockBuffer.EMPTY_STATE, i); + } + + // Map blocks + for (int i = 0; i < registry.size(); i++) { + BlockState blockState = registry.byId(i); + + if (blockState != null) { + int newId = mappings.getNewId(i); + if (newId >= 0) { + newBlockRegistry.addMapping(blockState, newId); + } + } + } + + // Ensure block -> id is correct for the empty state + int newEmptyStateId = mappings.getNewId(registry.getId(BlockBuffer.EMPTY_STATE)); + if (newEmptyStateId >= 0) { + newBlockRegistry.addMapping(BlockBuffer.EMPTY_STATE, newEmptyStateId); + } + + return newBlockRegistry; + } + } diff --git a/src/main/resources/plugin.yml b/src/main/resources/plugin.yml index 53267da..2bbc099 100644 --- a/src/main/resources/plugin.yml +++ b/src/main/resources/plugin.yml @@ -8,7 +8,7 @@ api-version: "$apiVersion" permissions: axiom.*: description: Allows use of all default Axiom features - default: op + default: true # op axiom.entity.*: description: Allows use of all entity-related features (spawning, manipulating, deleting) @@ -22,7 +22,7 @@ permissions: axiom.allow_copying_other_plots: description: This permission allows users to copy other user's plots - default: true + default: false # true axiom.can_import_blocks: description: Allows players to import schematics/blueprints into Axiom default: true From 11b7db5743fdcbb530467b888115dffd78370feb Mon Sep 17 00:00:00 2001 From: Moulberry Date: Sat, 4 May 2024 19:08:27 +0800 Subject: [PATCH 03/22] ViaVersion support --- .../java/com/moulberry/axiom/AxiomPaper.java | 6 +- .../axiom/packet/AxiomBigPayloadHandler.java | 126 +++++++++++------- .../BlueprintRequestPacketListener.java | 7 + .../axiom/packet/HelloPacketListener.java | 82 ++++++------ .../RequestChunkDataPacketListener.java | 2 +- .../packet/SetBlockBufferPacketListener.java | 12 +- .../packet/SetHotbarSlotPacketListener.java | 3 +- .../SwitchActiveHotbarPacketListener.java | 2 +- .../packet/UploadBlueprintPacketListener.java | 7 + .../axiom/viaversion/ViaVersionHelper.java | 55 +++++++- 10 files changed, 199 insertions(+), 103 deletions(-) diff --git a/src/main/java/com/moulberry/axiom/AxiomPaper.java b/src/main/java/com/moulberry/axiom/AxiomPaper.java index a58d8fe..b8a85da 100644 --- a/src/main/java/com/moulberry/axiom/AxiomPaper.java +++ b/src/main/java/com/moulberry/axiom/AxiomPaper.java @@ -51,6 +51,7 @@ public class AxiomPaper extends JavaPlugin implements Listener { public final Map playerBlockBufferRateLimiters = new ConcurrentHashMap<>(); public final Map playerRestrictions = new ConcurrentHashMap<>(); public final Map> playerBlockRegistry = new ConcurrentHashMap<>(); + public final Set mismatchedDataVersionUsingViaVersion = Collections.newSetFromMap(new ConcurrentHashMap<>()); public Configuration configuration; public IdMapper allowedBlockRegistry = null; @@ -268,6 +269,7 @@ public class AxiomPaper extends JavaPlugin implements Listener { playerBlockBufferRateLimiters.keySet().retainAll(stillActiveAxiomPlayers); playerRestrictions.keySet().retainAll(stillActiveAxiomPlayers); playerBlockRegistry.keySet().retainAll(stillActiveAxiomPlayers); + mismatchedDataVersionUsingViaVersion.retainAll(stillActiveAxiomPlayers); }, 20, 20); boolean sendMarkers = configuration.getBoolean("send-markers"); @@ -295,8 +297,8 @@ public class AxiomPaper extends JavaPlugin implements Listener { return this.playerBlockBufferRateLimiters.get(uuid); } - public boolean hasCustomBlockRegistry(UUID uuid) { - return this.playerBlockRegistry.containsKey(uuid); + public boolean isMismatchedDataVersion(UUID uuid) { + return this.mismatchedDataVersionUsingViaVersion.contains(uuid); } public IdMapper getBlockRegistry(UUID uuid) { diff --git a/src/main/java/com/moulberry/axiom/packet/AxiomBigPayloadHandler.java b/src/main/java/com/moulberry/axiom/packet/AxiomBigPayloadHandler.java index 520bda6..3f3b004 100644 --- a/src/main/java/com/moulberry/axiom/packet/AxiomBigPayloadHandler.java +++ b/src/main/java/com/moulberry/axiom/packet/AxiomBigPayloadHandler.java @@ -11,6 +11,7 @@ import net.minecraft.network.FriendlyByteBuf; import net.minecraft.resources.ResourceLocation; import net.minecraft.server.level.ServerPlayer; +import java.io.IOException; import java.util.List; public class AxiomBigPayloadHandler extends ByteToMessageDecoder { @@ -35,65 +36,90 @@ public class AxiomBigPayloadHandler extends ByteToMessageDecoder { @Override protected void decode(ChannelHandlerContext ctx, ByteBuf in, List out) throws Exception { - // Don't process if channel isn't active - if (!ctx.channel().isActive()) { - in.skipBytes(in.readableBytes()); + // No bytes to read?! Go away + if (in.readableBytes() == 0) { return; } - int i = in.readableBytes(); - if (i != 0) { - int readerIndex = in.readerIndex(); - boolean success = false; - try { - FriendlyByteBuf buf = new FriendlyByteBuf(in); - int packetId = buf.readVarInt(); + // Don't handle if player doesn't have permission to use Axiom + ServerPlayer player = connection.getPlayer(); + if (player == null || !AxiomPaper.PLUGIN.canUseAxiom(player.getBukkitEntity())) { + ctx.fireChannelRead(in.retain()); - if (packetId == payloadId) { - ResourceLocation identifier = buf.readResourceLocation(); - if (identifier.equals(SET_BUFFER)) { - ServerPlayer player = connection.getPlayer(); - if (AxiomPaper.PLUGIN.canUseAxiom(player.getBukkitEntity())) { - setBlockBuffer.onReceive(player, buf); - success = true; - in.skipBytes(in.readableBytes()); - return; - } - } else if (identifier.equals(UPLOAD_BLUEPRINT)) { - ServerPlayer player = connection.getPlayer(); - if (AxiomPaper.PLUGIN.canUseAxiom(player.getBukkitEntity())) { - uploadBlueprint.onReceive(player, buf); - success = true; - in.skipBytes(in.readableBytes()); - return; - } - } else if (requestChunkDataPacketListener != null && identifier.equals(REQUEST_CHUNK_DATA)) { - ServerPlayer player = connection.getPlayer(); - if (AxiomPaper.PLUGIN.canUseAxiom(player.getBukkitEntity())) { - byte[] bytes = new byte[buf.writerIndex() - buf.readerIndex()]; - buf.getBytes(buf.readerIndex(), bytes); + // Skip remaining bytes + if (in.readableBytes() > 0) { + in.skipBytes(in.readableBytes()); + } + return; + } - player.getServer().execute(() -> { - try { - requestChunkDataPacketListener.onPluginMessageReceived( - identifier.toString(), player.getBukkitEntity(), bytes); - } catch (Throwable t) { - player.getBukkitEntity().kick(net.kyori.adventure.text.Component.text( - "An error occured while requesting chunk data: " + t.getMessage())); - } - }); + // Don't process if channel isn't active + if (!ctx.channel().isActive()) { + if (in.readableBytes() > 0) { + in.skipBytes(in.readableBytes()); + } + return; + } - success = true; - in.skipBytes(in.readableBytes()); - return; - } + int readerIndex = in.readerIndex(); + boolean success = false; + try { + FriendlyByteBuf buf = new FriendlyByteBuf(in); + int packetId = buf.readVarInt(); + + if (packetId == payloadId) { + ResourceLocation identifier = buf.readResourceLocation(); + if (identifier.equals(SET_BUFFER)) { + setBlockBuffer.onReceive(player, buf); + success = true; + if (in.readableBytes() > 0) { + throw new IOException("Axiom packet " + identifier + " was larger than I expected, found " + in.readableBytes() + + " bytes extra whilst reading packet"); } + return; + } else if (identifier.equals(UPLOAD_BLUEPRINT)) { + uploadBlueprint.onReceive(player, buf); + success = true; + if (in.readableBytes() > 0) { + throw new IOException("Axiom packet " + identifier + " was larger than I expected, found " + in.readableBytes() + + " bytes extra whilst reading packet"); + } + return; + } else if (requestChunkDataPacketListener != null && identifier.equals(REQUEST_CHUNK_DATA)) { + byte[] bytes = new byte[buf.writerIndex() - buf.readerIndex()]; + buf.getBytes(buf.readerIndex(), bytes); + + player.getServer().execute(() -> { + try { + requestChunkDataPacketListener.onPluginMessageReceived( + identifier.toString(), player.getBukkitEntity(), bytes); + } catch (Throwable t) { + player.getBukkitEntity().kick(net.kyori.adventure.text.Component.text( + "An error occured while requesting chunk data: " + t.getMessage())); + } + }); + + success = true; + if (in.readableBytes() > 0) { + in.skipBytes(in.readableBytes()); + } + return; } - } catch (Throwable ignored) { - } finally { - if (!success) { - in.readerIndex(readerIndex); + } + } catch (Throwable t) { + if (!(t instanceof IndexOutOfBoundsException)) { + // Skip remaining bytes + success = true; + if (in.readableBytes() > 0) { + in.skipBytes(in.readableBytes()); } + + // Throw error, will disconnect client + throw t; + } + } finally { + if (!success) { + in.readerIndex(readerIndex); } } diff --git a/src/main/java/com/moulberry/axiom/packet/BlueprintRequestPacketListener.java b/src/main/java/com/moulberry/axiom/packet/BlueprintRequestPacketListener.java index e563cb1..14f3f93 100644 --- a/src/main/java/com/moulberry/axiom/packet/BlueprintRequestPacketListener.java +++ b/src/main/java/com/moulberry/axiom/packet/BlueprintRequestPacketListener.java @@ -6,6 +6,8 @@ import com.moulberry.axiom.blueprint.RawBlueprint; import com.moulberry.axiom.blueprint.ServerBlueprintManager; import com.moulberry.axiom.blueprint.ServerBlueprintRegistry; import io.netty.buffer.Unpooled; +import net.kyori.adventure.text.Component; +import net.minecraft.SharedConstants; import net.minecraft.network.FriendlyByteBuf; import net.minecraft.resources.ResourceLocation; import org.bukkit.craftbukkit.v1_20_R3.entity.CraftPlayer; @@ -30,6 +32,11 @@ public class BlueprintRequestPacketListener implements PluginMessageListener { return; } + if (this.plugin.isMismatchedDataVersion(player.getUniqueId())) { + player.sendMessage(Component.text("Axiom+ViaVersion: This feature isn't supported. Switch your client version to " + SharedConstants.VERSION_STRING + " to use this")); + return; + } + FriendlyByteBuf friendlyByteBuf = new FriendlyByteBuf(Unpooled.wrappedBuffer(message)); String path = friendlyByteBuf.readUtf(); diff --git a/src/main/java/com/moulberry/axiom/packet/HelloPacketListener.java b/src/main/java/com/moulberry/axiom/packet/HelloPacketListener.java index a182db8..f30707c 100644 --- a/src/main/java/com/moulberry/axiom/packet/HelloPacketListener.java +++ b/src/main/java/com/moulberry/axiom/packet/HelloPacketListener.java @@ -10,13 +10,16 @@ import com.moulberry.axiom.viaversion.ViaVersionHelper; import com.moulberry.axiom.world_properties.server.ServerWorldPropertiesRegistry; import com.viaversion.viaversion.api.Via; import com.viaversion.viaversion.api.data.*; +import com.viaversion.viaversion.api.protocol.ProtocolPathEntry; import com.viaversion.viaversion.api.protocol.version.ProtocolVersion; import com.viaversion.viaversion.libs.opennbt.tag.builtin.CompoundTag; import io.netty.buffer.Unpooled; import net.kyori.adventure.text.Component; import net.kyori.adventure.text.format.NamedTextColor; import net.minecraft.SharedConstants; +import net.minecraft.core.IdMapper; import net.minecraft.network.FriendlyByteBuf; +import net.minecraft.world.level.block.state.BlockState; import org.bukkit.Bukkit; import org.bukkit.NamespacedKey; import org.bukkit.World; @@ -54,12 +57,13 @@ public class HelloPacketListener implements PluginMessageListener { int serverDataVersion = SharedConstants.getCurrentVersion().getDataVersion().getVersion(); if (dataVersion != serverDataVersion) { + String incompatibleDataVersion = plugin.configuration.getString("incompatible-data-version"); + if (incompatibleDataVersion == null) incompatibleDataVersion = "warn"; + if (!Bukkit.getPluginManager().isPluginEnabled("ViaVersion")) { Component text = Component.text("Axiom: Incompatible data version detected (client " + dataVersion + ", server " + serverDataVersion + ")"); - String incompatibleDataVersion = plugin.configuration.getString("incompatible-data-version"); - if (incompatibleDataVersion == null) incompatibleDataVersion = "kick"; if (incompatibleDataVersion.equals("warn")) { player.sendMessage(text.color(NamedTextColor.RED)); return; @@ -68,38 +72,32 @@ public class HelloPacketListener implements PluginMessageListener { return; } } else { -// int playerVersion = Via.getAPI().getPlayerVersion(player.getUniqueId()); -// if (ProtocolVersion.isRegistered(playerVersion)) { -// ProtocolVersion version = ProtocolVersion.getProtocol(playerVersion); -// String name = version.getName().split("/")[0]; -// -// -// } + int playerVersion = Via.getAPI().getPlayerVersion(player.getUniqueId()); - CompoundTag tag = MappingDataLoader.loadNBT("mappings-1.20.2to1.20.3.nbt"); + IdMapper mapper; + try { + mapper = ViaVersionHelper.getBlockRegistryForVersion(this.plugin.allowedBlockRegistry, playerVersion); + } catch (Exception e) { + String clientDescription = "client: " + ProtocolVersion.getProtocol(playerVersion); + String serverDescription = "server: " + ProtocolVersion.getProtocol(SharedConstants.getProtocolVersion()); + String description = clientDescription + " <-> " + serverDescription; + Component text = Component.text("Axiom+ViaVersion: " + e.getMessage() + " (" + description + ")"); - if (tag == null) { - player.kick(Component.text("Axiom+ViaVersion: Failed to load mappings (1.20.2 <-> 1.20.3)")); + if (incompatibleDataVersion.equals("warn")) { + player.sendMessage(text.color(NamedTextColor.RED)); + } else { + player.kick(text); + } return; } - Mappings mappings = MappingDataLoader.loadMappings(tag, "blockstates"); - - if (mappings == null) { - player.kick(Component.text("Axiom+ViaVersion: Failed to load mapped blockstates (1.20.2 <-> 1.20.3")); - return; - } - - this.plugin.playerBlockRegistry.put(player.getUniqueId(), ViaVersionHelper.applyMappings(this.plugin.allowedBlockRegistry, - BiMappings.of(mappings).inverse())); + this.plugin.playerBlockRegistry.put(player.getUniqueId(), mapper); + this.plugin.mismatchedDataVersionUsingViaVersion.add(player.getUniqueId()); Component text = Component.text("Axiom: Warning, client and server versions don't match. " + "Axiom will try to use ViaVersion conversions, but this process may cause problems"); player.sendMessage(text.color(NamedTextColor.RED)); } -// inverse.getNewIdOrDefault() - - } if (apiVersion != AxiomConstants.API_VERSION) { @@ -121,7 +119,7 @@ public class HelloPacketListener implements PluginMessageListener { Component text = Component.text("This server requires the use of Axiom 2.3 or later. Contact the server administrator if you believe this is unintentional"); String unsupportedRestrictions = plugin.configuration.getString("client-doesnt-support-restrictions"); - if (unsupportedRestrictions == null) unsupportedRestrictions = "kick"; + if (unsupportedRestrictions == null) unsupportedRestrictions = "warn"; if (unsupportedRestrictions.equals("warn")) { player.sendMessage(text.color(NamedTextColor.RED)); return; @@ -161,24 +159,26 @@ public class HelloPacketListener implements PluginMessageListener { // 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)); + if (!this.plugin.isMismatchedDataVersion(player.getUniqueId())) { + 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)); + } } - } - byte[] bytes = new byte[buf.writerIndex()]; - buf.getBytes(0, bytes); - player.sendPluginMessage(this.plugin, "axiom:initialize_hotbars", bytes); + byte[] bytes = new byte[buf.writerIndex()]; + buf.getBytes(0, bytes); + player.sendPluginMessage(this.plugin, "axiom:initialize_hotbars", bytes); + } } // Initialize Views diff --git a/src/main/java/com/moulberry/axiom/packet/RequestChunkDataPacketListener.java b/src/main/java/com/moulberry/axiom/packet/RequestChunkDataPacketListener.java index e406fa0..bf1a862 100644 --- a/src/main/java/com/moulberry/axiom/packet/RequestChunkDataPacketListener.java +++ b/src/main/java/com/moulberry/axiom/packet/RequestChunkDataPacketListener.java @@ -47,7 +47,7 @@ public class RequestChunkDataPacketListener implements PluginMessageListener { FriendlyByteBuf friendlyByteBuf = new FriendlyByteBuf(Unpooled.wrappedBuffer(message)); long id = friendlyByteBuf.readLong(); - if (!this.plugin.canUseAxiom(bukkitPlayer) || this.plugin.hasCustomBlockRegistry(bukkitPlayer.getUniqueId())) { + if (!this.plugin.canUseAxiom(bukkitPlayer) || this.plugin.isMismatchedDataVersion(bukkitPlayer.getUniqueId())) { // We always send an 'empty' response in order to make the client happy sendEmptyResponse(player, id); return; diff --git a/src/main/java/com/moulberry/axiom/packet/SetBlockBufferPacketListener.java b/src/main/java/com/moulberry/axiom/packet/SetBlockBufferPacketListener.java index 1722bf3..8497706 100644 --- a/src/main/java/com/moulberry/axiom/packet/SetBlockBufferPacketListener.java +++ b/src/main/java/com/moulberry/axiom/packet/SetBlockBufferPacketListener.java @@ -340,14 +340,14 @@ public class SetBlockBufferPacketListener { return; } - var chunk = (LevelChunk) world.getChunk(x >> 2, z >> 2, ChunkStatus.FULL, false); - if (chunk == null) return; - - var section = chunk.getSection(cy - minSection); - PalettedContainer> container = (PalettedContainer>) section.getBiomes(); - var holder = registry.getHolder(biome); if (holder.isPresent()) { + var chunk = (LevelChunk) world.getChunk(x >> 2, z >> 2, ChunkStatus.FULL, false); + if (chunk == null) return; + + var section = chunk.getSection(cy - minSection); + PalettedContainer> container = (PalettedContainer>) section.getBiomes(); + if (!Integration.canPlaceBlock(player.getBukkitEntity(), new Location(player.getBukkitEntity().getWorld(), x+1, y+1, z+1))) return; diff --git a/src/main/java/com/moulberry/axiom/packet/SetHotbarSlotPacketListener.java b/src/main/java/com/moulberry/axiom/packet/SetHotbarSlotPacketListener.java index aa414af..dc5c1a5 100644 --- a/src/main/java/com/moulberry/axiom/packet/SetHotbarSlotPacketListener.java +++ b/src/main/java/com/moulberry/axiom/packet/SetHotbarSlotPacketListener.java @@ -3,6 +3,7 @@ package com.moulberry.axiom.packet; import com.moulberry.axiom.AxiomConstants; import com.moulberry.axiom.AxiomPaper; import com.moulberry.axiom.persistence.ItemStackDataType; +import com.viaversion.viaversion.api.Via; import io.netty.buffer.Unpooled; import net.minecraft.network.FriendlyByteBuf; import org.bukkit.NamespacedKey; @@ -22,7 +23,7 @@ public class SetHotbarSlotPacketListener implements PluginMessageListener { @Override public void onPluginMessageReceived(@NotNull String channel, @NotNull Player player, @NotNull byte[] message) { - if (!this.plugin.canUseAxiom(player)) { + if (!this.plugin.canUseAxiom(player) || this.plugin.isMismatchedDataVersion(player.getUniqueId())) { return; } diff --git a/src/main/java/com/moulberry/axiom/packet/SwitchActiveHotbarPacketListener.java b/src/main/java/com/moulberry/axiom/packet/SwitchActiveHotbarPacketListener.java index 5307ec3..9700ad3 100644 --- a/src/main/java/com/moulberry/axiom/packet/SwitchActiveHotbarPacketListener.java +++ b/src/main/java/com/moulberry/axiom/packet/SwitchActiveHotbarPacketListener.java @@ -25,7 +25,7 @@ public class SwitchActiveHotbarPacketListener implements PluginMessageListener { @Override public void onPluginMessageReceived(@NotNull String channel, @NotNull Player player, @NotNull byte[] message) { - if (!this.plugin.canUseAxiom(player)) { + if (!this.plugin.canUseAxiom(player) || this.plugin.isMismatchedDataVersion(player.getUniqueId())) { return; } diff --git a/src/main/java/com/moulberry/axiom/packet/UploadBlueprintPacketListener.java b/src/main/java/com/moulberry/axiom/packet/UploadBlueprintPacketListener.java index a2cb4bb..96b63b9 100644 --- a/src/main/java/com/moulberry/axiom/packet/UploadBlueprintPacketListener.java +++ b/src/main/java/com/moulberry/axiom/packet/UploadBlueprintPacketListener.java @@ -5,7 +5,9 @@ import com.moulberry.axiom.blueprint.BlueprintIo; import com.moulberry.axiom.blueprint.RawBlueprint; import com.moulberry.axiom.blueprint.ServerBlueprintManager; import com.moulberry.axiom.blueprint.ServerBlueprintRegistry; +import net.minecraft.SharedConstants; import net.minecraft.network.FriendlyByteBuf; +import net.minecraft.network.chat.Component; import net.minecraft.server.level.ServerPlayer; import java.io.BufferedOutputStream; @@ -26,6 +28,11 @@ public class UploadBlueprintPacketListener { return; } + if (this.plugin.isMismatchedDataVersion(serverPlayer.getUUID())) { + serverPlayer.sendSystemMessage(Component.literal("Axiom+ViaVersion: This feature isn't supported. Switch your client version to " + SharedConstants.VERSION_STRING + " to use this")); + return; + } + ServerBlueprintRegistry registry = ServerBlueprintManager.getRegistry(); if (registry == null || this.plugin.blueprintFolder == null) { return; diff --git a/src/main/java/com/moulberry/axiom/viaversion/ViaVersionHelper.java b/src/main/java/com/moulberry/axiom/viaversion/ViaVersionHelper.java index ecba92a..7730fa3 100644 --- a/src/main/java/com/moulberry/axiom/viaversion/ViaVersionHelper.java +++ b/src/main/java/com/moulberry/axiom/viaversion/ViaVersionHelper.java @@ -1,15 +1,68 @@ package com.moulberry.axiom.viaversion; import com.moulberry.axiom.buffer.BlockBuffer; +import com.viaversion.viaversion.api.Via; import com.viaversion.viaversion.api.data.BiMappings; +import com.viaversion.viaversion.api.data.MappingData; import com.viaversion.viaversion.api.data.Mappings; +import com.viaversion.viaversion.api.protocol.ProtocolPathEntry; +import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap; +import net.kyori.adventure.text.Component; +import net.kyori.adventure.text.format.NamedTextColor; +import net.minecraft.SharedConstants; import net.minecraft.core.IdMapper; import net.minecraft.world.level.block.Block; import net.minecraft.world.level.block.state.BlockState; +import org.jetbrains.annotations.Nullable; + +import java.util.List; public class ViaVersionHelper { - public static IdMapper applyMappings(IdMapper registry, BiMappings mappings) { + private static final Int2ObjectOpenHashMap> blockRegistryCache = new Int2ObjectOpenHashMap<>(); + private static final Int2ObjectOpenHashMap blockRegistryErrorCache = new Int2ObjectOpenHashMap<>(); + + public static IdMapper getBlockRegistryForVersion(IdMapper mapper, int playerVersion) { + if (blockRegistryErrorCache.containsKey(playerVersion)) { + throw new RuntimeException(blockRegistryErrorCache.get(playerVersion)); + } + if (blockRegistryCache.containsKey(playerVersion)) { + return blockRegistryCache.get(playerVersion); + } + + List path = Via.getManager().getProtocolManager().getProtocolPath(playerVersion, + SharedConstants.getProtocolVersion()); + + if (path == null) { + blockRegistryErrorCache.put(playerVersion, "Failed to find protocol path"); + throw new RuntimeException("Failed to find protocol path"); + } + + for (int i = path.size()-1; i >= 0; i--) { + ProtocolPathEntry protocolPathEntry = path.get(i); + + MappingData mappingData = protocolPathEntry.protocol().getMappingData(); + + if (mappingData == null) { + blockRegistryErrorCache.put(playerVersion, "Failed to load mapping data (" + protocolPathEntry + ")"); + throw new RuntimeException("Failed to load mapping data (" + protocolPathEntry + ")"); + } + + Mappings blockStateMappings = mappingData.getBlockStateMappings(); + + if (blockStateMappings == null) { + blockRegistryErrorCache.put(playerVersion, "Failed to load BlockState mappings (" + protocolPathEntry + ")"); + throw new RuntimeException("Failed to load BlockState mappings (" + protocolPathEntry + ")"); + } + + mapper = ViaVersionHelper.applyMappings(mapper, blockStateMappings); + } + + blockRegistryCache.put(playerVersion, mapper); + return mapper; + } + + public static IdMapper applyMappings(IdMapper registry, Mappings mappings) { IdMapper newBlockRegistry = new IdMapper<>(); // Add empty mappings for non-existent blocks From aa4979557963e93154d8f9d5a9d200a8549c552a Mon Sep 17 00:00:00 2001 From: Moulberry Date: Sat, 4 May 2024 20:19:28 +0800 Subject: [PATCH 04/22] Add /axiompaperdebug command --- build.gradle.kts | 1 + .../java/com/moulberry/axiom/AxiomPaper.java | 16 ++ .../com/moulberry/axiom/Restrictions.java | 12 ++ .../axiom/commands/AxiomDebugCommand.java | 139 ++++++++++++++++++ .../worldguard/WorldGuardIntegrationImpl.java | 22 +-- src/main/resources/plugin.yml | 6 +- 6 files changed, 185 insertions(+), 11 deletions(-) create mode 100644 src/main/java/com/moulberry/axiom/commands/AxiomDebugCommand.java diff --git a/build.gradle.kts b/build.gradle.kts index 388f896..105c802 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -28,6 +28,7 @@ repositories { dependencies { paperweight.paperDevBundle("1.20.4-R0.1-SNAPSHOT") implementation("xyz.jpenilla:reflection-remapper:0.1.0-SNAPSHOT") + implementation("org.incendo:cloud-paper:2.0.0-beta.2") // Zstd Compression Library implementation("com.github.luben:zstd-jni:1.5.5-4") diff --git a/src/main/java/com/moulberry/axiom/AxiomPaper.java b/src/main/java/com/moulberry/axiom/AxiomPaper.java index b8a85da..e0fe969 100644 --- a/src/main/java/com/moulberry/axiom/AxiomPaper.java +++ b/src/main/java/com/moulberry/axiom/AxiomPaper.java @@ -3,6 +3,7 @@ package com.moulberry.axiom; import com.google.common.util.concurrent.RateLimiter; import com.moulberry.axiom.blueprint.ServerBlueprintManager; import com.moulberry.axiom.buffer.CompressedBlockEntity; +import com.moulberry.axiom.commands.AxiomDebugCommand; import com.moulberry.axiom.event.AxiomCreateWorldPropertiesEvent; import com.moulberry.axiom.event.AxiomModifyWorldEvent; import com.moulberry.axiom.integration.plotsquared.PlotSquaredIntegration; @@ -26,6 +27,7 @@ import net.minecraft.network.protocol.common.ServerboundCustomPayloadPacket; import net.minecraft.server.MinecraftServer; import net.minecraft.world.level.block.state.BlockState; import org.bukkit.*; +import org.bukkit.command.CommandSender; import org.bukkit.configuration.Configuration; import org.bukkit.entity.Player; import org.bukkit.event.EventHandler; @@ -34,6 +36,9 @@ import org.bukkit.event.player.PlayerChangedWorldEvent; import org.bukkit.plugin.java.JavaPlugin; import org.bukkit.plugin.messaging.Messenger; import org.checkerframework.checker.nullness.qual.NonNull; +import org.incendo.cloud.bukkit.CloudBukkitCapabilities; +import org.incendo.cloud.execution.ExecutionCoordinator; +import org.incendo.cloud.paper.PaperCommandManager; import org.jetbrains.annotations.Nullable; import java.io.FileReader; @@ -279,6 +284,17 @@ public class AxiomPaper extends JavaPlugin implements Listener { Bukkit.getScheduler().scheduleSyncRepeatingTask(this, () -> { WorldExtension.tick(MinecraftServer.getServer(), sendMarkers, maxChunkRelightsPerTick, maxChunkSendsPerTick); }, 1, 1); + + PaperCommandManager manager = PaperCommandManager.createNative( + this, + ExecutionCoordinator.simpleCoordinator() + ); + + if (manager.hasCapability(CloudBukkitCapabilities.NATIVE_BRIGADIER)) { + manager.registerBrigadier(); + } + + AxiomDebugCommand.register(this, manager); } public boolean logLargeBlockBufferChanges() { diff --git a/src/main/java/com/moulberry/axiom/Restrictions.java b/src/main/java/com/moulberry/axiom/Restrictions.java index 5dd0180..4b6c25c 100644 --- a/src/main/java/com/moulberry/axiom/Restrictions.java +++ b/src/main/java/com/moulberry/axiom/Restrictions.java @@ -61,4 +61,16 @@ public class Restrictions { } } + @Override + public String toString() { + return "Restrictions{" + + "canImportBlocks=" + canImportBlocks + + ", canUseEditor=" + canUseEditor + + ", canEditDisplayEntities=" + canEditDisplayEntities + + ", maxSectionsPerSecond=" + maxSectionsPerSecond + + ", boundsMin=" + boundsMin + + ", boundsMax=" + boundsMax + + ", lastPlotBounds=" + lastPlotBounds + + '}'; + } } diff --git a/src/main/java/com/moulberry/axiom/commands/AxiomDebugCommand.java b/src/main/java/com/moulberry/axiom/commands/AxiomDebugCommand.java new file mode 100644 index 0000000..5172953 --- /dev/null +++ b/src/main/java/com/moulberry/axiom/commands/AxiomDebugCommand.java @@ -0,0 +1,139 @@ +package com.moulberry.axiom.commands; + +import com.moulberry.axiom.AxiomPaper; +import com.moulberry.axiom.Restrictions; +import com.moulberry.axiom.integration.Integration; +import com.moulberry.axiom.integration.plotsquared.PlotSquaredIntegration; +import com.moulberry.axiom.integration.worldguard.WorldGuardIntegration; +import net.kyori.adventure.text.Component; +import org.bukkit.block.Block; +import org.bukkit.command.CommandSender; +import org.bukkit.entity.Player; +import org.incendo.cloud.Command; +import org.incendo.cloud.bukkit.BukkitCommandManager; +import org.incendo.cloud.parser.standard.EnumParser; +import org.incendo.cloud.parser.standard.StringParser; +import org.incendo.cloud.permission.PredicatePermission; + +import java.util.UUID; + +public class AxiomDebugCommand { + + /** + * Command requires either the axiom.debug permission or for you to have the UUID d0e05de7-6067-454d-beae-c6d19d886191 + * The command isn't capable of modifying the world, only checking various properties for debugging purposes + * It should be 100% safe to give to any player, but is locked behind some restrictions due to the potential + * for lagging the server by spamming certain commands + */ + + private static final UUID MOULBERRY_UUID = UUID.fromString("d0e05de7-6067-454d-beae-c6d19d886191"); + + public static void register(AxiomPaper axiomPaper, BukkitCommandManager manager) { + manager.command( + base(manager, "hasAxiomPermission").handler(context -> { + boolean hasAxiomPermission = axiomPaper.hasAxiomPermission(context.sender()); + context.sender().sendMessage(Component.text("hasAxiomPermission: " + hasAxiomPermission)); + }) + ); + manager.command( + base(manager, "canUseAxiom").handler(context -> { + boolean canUseAxiom = axiomPaper.canUseAxiom(context.sender()); + context.sender().sendMessage(Component.text("canUseAxiom: " + canUseAxiom)); + }) + ); + manager.command( + base(manager, "isMismatchedDataVersion").handler(context -> { + boolean isMismatchedDataVersion = axiomPaper.isMismatchedDataVersion(context.sender().getUniqueId()); + context.sender().sendMessage(Component.text("isMismatchedDataVersion: " + isMismatchedDataVersion)); + }) + ); + manager.command( + base(manager, "canModifyWorld").handler(context -> { + boolean canModifyWorld = axiomPaper.canModifyWorld(context.sender(), context.sender().getWorld()); + context.sender().sendMessage(Component.text("canModifyWorld: " + canModifyWorld)); + }) + ); + manager.command( + base(manager, "isClientListening").required("channel", StringParser.greedyStringParser()).handler(context -> { + String channel = context.get("channel"); + boolean isClientListening = context.sender().getListeningPluginChannels().contains(channel); + context.sender().sendMessage(Component.text("listening to " + channel +": " + isClientListening)); + }) + ); + manager.command( + base(manager, "hasPermission").required("permission", StringParser.greedyStringParser()).handler(context -> { + String permission = context.get("permission"); + boolean hasPermission = context.sender().hasPermission(permission); + context.sender().sendMessage(Component.text("has permission " + permission +": " + hasPermission)); + }) + ); + manager.command( + base(manager, "getRestrictions").handler(context -> { + Restrictions restrictions = axiomPaper.playerRestrictions.get(context.sender().getUniqueId()); + if (restrictions == null) { + context.sender().sendMessage(Component.text("no restrictions")); + } else { + context.sender().sendMessage(Component.text("restrictions: " + restrictions)); + } + }) + ); + enum IntegrationType { + PLOT_SQUARED, + WORLD_GUARD + } + manager.command( + base(manager, "canBreakBlockAtCurrentPosition").optional("type", EnumParser.enumParser(IntegrationType.class)).handler(context -> { + IntegrationType integrationType = (IntegrationType) context.optional("type").orElse(null); + + Block block = context.sender().getWorld().getBlockAt(context.sender().getLocation()); + + boolean canBreakBlock; + if (integrationType == IntegrationType.PLOT_SQUARED) { + canBreakBlock = PlotSquaredIntegration.canBreakBlock(context.sender(), block); + } else if (integrationType == IntegrationType.WORLD_GUARD) { + canBreakBlock = WorldGuardIntegration.canBreakBlock(context.sender(), block.getLocation()); + } else { + canBreakBlock = Integration.canBreakBlock(context.sender(), block); + } + context.sender().sendMessage(Component.text("canBreakBlock: " + canBreakBlock)); + }) + ); + manager.command( + base(manager, "canPlaceBlockAtCurrentPosition").optional("type", EnumParser.enumParser(IntegrationType.class)).handler(context -> { + IntegrationType integrationType = (IntegrationType) context.optional("type").orElse(null); + + boolean canPlaceBlock; + if (integrationType == IntegrationType.PLOT_SQUARED) { + canPlaceBlock = PlotSquaredIntegration.canPlaceBlock(context.sender(), context.sender().getLocation()); + } else if (integrationType == IntegrationType.WORLD_GUARD) { + canPlaceBlock = WorldGuardIntegration.canPlaceBlock(context.sender(), context.sender().getLocation()); + } else { + canPlaceBlock = Integration.canPlaceBlock(context.sender(), context.sender().getLocation()); + } + context.sender().sendMessage(Component.text("canPlaceBlock: " + canPlaceBlock)); + }) + ); + manager.command( + base(manager, "isPlotWorld").handler(context -> { + boolean isPlotWorld = PlotSquaredIntegration.isPlotWorld(context.sender().getWorld()); + context.sender().sendMessage(Component.text("isPlotWorld: " + isPlotWorld)); + }) + ); + manager.command( + base(manager, "getCurrentEditablePlot").handler(context -> { + PlotSquaredIntegration.PlotBounds plotBounds = PlotSquaredIntegration.getCurrentEditablePlot(context.sender()); + context.sender().sendMessage(Component.text("plotBounds: " + plotBounds)); + }) + ); + } + + private static Command.Builder base(BukkitCommandManager manager, String subcommand) { + return manager.commandBuilder("axiompaperdebug") + .literal(subcommand) + .senderType(Player.class) + .permission(PredicatePermission.of(sender -> sender.hasPermission("axiom.debug") || sender.getUniqueId().equals(MOULBERRY_UUID))); + } + + + +} diff --git a/src/main/java/com/moulberry/axiom/integration/worldguard/WorldGuardIntegrationImpl.java b/src/main/java/com/moulberry/axiom/integration/worldguard/WorldGuardIntegrationImpl.java index 3110655..4787e18 100644 --- a/src/main/java/com/moulberry/axiom/integration/worldguard/WorldGuardIntegrationImpl.java +++ b/src/main/java/com/moulberry/axiom/integration/worldguard/WorldGuardIntegrationImpl.java @@ -34,15 +34,19 @@ public class WorldGuardIntegrationImpl { private static boolean testBuild(Player player, org.bukkit.Location loc, StateFlag flag) { WorldGuardPlatform platform = WorldGuard.getInstance().getPlatform(); + com.sk89q.worldedit.world.World worldEditWorld = BukkitAdapter.adapt(loc.getWorld()); + LocalPlayer worldGuardPlayer = WorldGuardPlugin.inst().wrapPlayer(player); + + if (platform.getSessionManager().hasBypass(worldGuardPlayer, worldEditWorld)) { + return true; + } + RegionContainer regionContainer = platform.getRegionContainer(); if (regionContainer == null) { return true; } RegionQuery query = regionContainer.createQuery(); - - LocalPlayer worldGuardPlayer = WorldGuardPlugin.inst().wrapPlayer(player); - return query.testBuild(BukkitAdapter.adapt(loc), worldGuardPlayer, flag); } @@ -118,12 +122,12 @@ public class WorldGuardIntegrationImpl { BlockVector3 regionMin = region.getMinimumPoint(); BlockVector3 regionMax = region.getMaximumPoint(); - int regionMinX = Math.max(regionMin.getBlockX(), cx*16) - minX; - int regionMinY = Math.max(regionMin.getBlockY(), cy*16) - minY; - int regionMinZ = Math.max(regionMin.getBlockZ(), cz*16) - minZ; - int regionMaxX = Math.min(regionMax.getBlockX(), cx*16+15) - minX; - int regionMaxY = Math.min(regionMax.getBlockY(), cy*16+15) - minY; - int regionMaxZ = Math.min(regionMax.getBlockZ(), cz*16+15) - minZ; + int regionMinX = Math.max(regionMin.getX(), cx*16) - minX; + int regionMinY = Math.max(regionMin.getY(), cy*16) - minY; + int regionMinZ = Math.max(regionMin.getZ(), cz*16) - minZ; + int regionMaxX = Math.min(regionMax.getX(), cx*16+15) - minX; + int regionMaxY = Math.min(regionMax.getY(), cy*16+15) - minY; + int regionMaxZ = Math.min(regionMax.getZ(), cz*16+15) - minZ; Box box = new Box(regionMinX, regionMinY, regionMinZ, regionMaxX, regionMaxY, regionMaxZ); if (value == StateFlag.State.DENY) { diff --git a/src/main/resources/plugin.yml b/src/main/resources/plugin.yml index 2bbc099..8afb8ab 100644 --- a/src/main/resources/plugin.yml +++ b/src/main/resources/plugin.yml @@ -8,8 +8,10 @@ api-version: "$apiVersion" permissions: axiom.*: description: Allows use of all default Axiom features - default: true # op - + default: op + axiom.debug: + description: Allows use of the /axiompaperdebug command + default: op axiom.entity.*: description: Allows use of all entity-related features (spawning, manipulating, deleting) default: op From b52638f44403d60042b2492204081ec4b128a945 Mon Sep 17 00:00:00 2001 From: Moulberry Date: Sat, 4 May 2024 21:25:21 +0800 Subject: [PATCH 05/22] Convert NBT tags between 1.20.1 <-> 1.20.2 --- .../axiom/packet/HelloPacketListener.java | 5 +- .../ManipulateEntityPacketListener.java | 7 +- .../packet/SetBlockBufferPacketListener.java | 3 +- .../packet/SpawnEntityPacketListener.java | 11 ++- .../axiom/viaversion/ViaVersionHelper.java | 69 +++++++++++++++++++ 5 files changed, 84 insertions(+), 11 deletions(-) diff --git a/src/main/java/com/moulberry/axiom/packet/HelloPacketListener.java b/src/main/java/com/moulberry/axiom/packet/HelloPacketListener.java index f30707c..77bcf31 100644 --- a/src/main/java/com/moulberry/axiom/packet/HelloPacketListener.java +++ b/src/main/java/com/moulberry/axiom/packet/HelloPacketListener.java @@ -12,12 +12,15 @@ import com.viaversion.viaversion.api.Via; import com.viaversion.viaversion.api.data.*; import com.viaversion.viaversion.api.protocol.ProtocolPathEntry; import com.viaversion.viaversion.api.protocol.version.ProtocolVersion; +import com.viaversion.viaversion.api.type.ByteBufReader; +import com.viaversion.viaversion.api.type.Type; import com.viaversion.viaversion.libs.opennbt.tag.builtin.CompoundTag; import io.netty.buffer.Unpooled; import net.kyori.adventure.text.Component; import net.kyori.adventure.text.format.NamedTextColor; import net.minecraft.SharedConstants; import net.minecraft.core.IdMapper; +import net.minecraft.nbt.NbtIo; import net.minecraft.network.FriendlyByteBuf; import net.minecraft.world.level.block.state.BlockState; import org.bukkit.Bukkit; @@ -53,7 +56,7 @@ public class HelloPacketListener implements PluginMessageListener { FriendlyByteBuf friendlyByteBuf = new FriendlyByteBuf(Unpooled.wrappedBuffer(message)); int apiVersion = friendlyByteBuf.readVarInt(); int dataVersion = friendlyByteBuf.readVarInt(); - friendlyByteBuf.readNbt(); // Discard + ViaVersionHelper.skipTagUnknown(friendlyByteBuf, player); int serverDataVersion = SharedConstants.getCurrentVersion().getDataVersion().getVersion(); if (dataVersion != serverDataVersion) { diff --git a/src/main/java/com/moulberry/axiom/packet/ManipulateEntityPacketListener.java b/src/main/java/com/moulberry/axiom/packet/ManipulateEntityPacketListener.java index 63d7f31..8db9526 100644 --- a/src/main/java/com/moulberry/axiom/packet/ManipulateEntityPacketListener.java +++ b/src/main/java/com/moulberry/axiom/packet/ManipulateEntityPacketListener.java @@ -4,6 +4,7 @@ import com.moulberry.axiom.AxiomPaper; import com.moulberry.axiom.NbtSanitization; import com.moulberry.axiom.integration.Integration; import com.moulberry.axiom.integration.plotsquared.PlotSquaredIntegration; +import com.moulberry.axiom.viaversion.ViaVersionHelper; import io.netty.buffer.Unpooled; import net.minecraft.core.BlockPos; import net.minecraft.core.Direction; @@ -46,7 +47,7 @@ public class ManipulateEntityPacketListener implements PluginMessageListener { public record ManipulateEntry(UUID uuid, @Nullable Set relativeMovementSet, @Nullable Vec3 position, float yaw, float pitch, CompoundTag merge, PassengerManipulation passengerManipulation, List passengers) { - public static ManipulateEntry read(FriendlyByteBuf friendlyByteBuf) { + public static ManipulateEntry read(FriendlyByteBuf friendlyByteBuf, Player player) { UUID uuid = friendlyByteBuf.readUUID(); int flags = friendlyByteBuf.readByte(); @@ -61,7 +62,7 @@ public class ManipulateEntityPacketListener implements PluginMessageListener { pitch = friendlyByteBuf.readFloat(); } - CompoundTag nbt = friendlyByteBuf.readNbt(); + CompoundTag nbt = ViaVersionHelper.readTagUnknown(friendlyByteBuf, player); PassengerManipulation passengerManipulation = friendlyByteBuf.readEnum(PassengerManipulation.class); List passengers = List.of(); @@ -93,7 +94,7 @@ public class ManipulateEntityPacketListener implements PluginMessageListener { FriendlyByteBuf friendlyByteBuf = new FriendlyByteBuf(Unpooled.wrappedBuffer(message)); List entries = friendlyByteBuf.readCollection(FriendlyByteBuf.limitValue(ArrayList::new, 1000), - ManipulateEntry::read); + buf -> ManipulateEntry.read(buf, player)); ServerLevel serverLevel = ((CraftWorld)player.getWorld()).getHandle(); diff --git a/src/main/java/com/moulberry/axiom/packet/SetBlockBufferPacketListener.java b/src/main/java/com/moulberry/axiom/packet/SetBlockBufferPacketListener.java index 8497706..aaf85f7 100644 --- a/src/main/java/com/moulberry/axiom/packet/SetBlockBufferPacketListener.java +++ b/src/main/java/com/moulberry/axiom/packet/SetBlockBufferPacketListener.java @@ -9,6 +9,7 @@ import com.moulberry.axiom.buffer.CompressedBlockEntity; import com.moulberry.axiom.integration.Integration; import com.moulberry.axiom.integration.SectionPermissionChecker; import com.moulberry.axiom.integration.plotsquared.PlotSquaredIntegration; +import com.moulberry.axiom.viaversion.ViaVersionHelper; import it.unimi.dsi.fastutil.longs.Long2ObjectMap; import it.unimi.dsi.fastutil.shorts.Short2ObjectMap; import net.minecraft.ChatFormatting; @@ -77,7 +78,7 @@ public class SetBlockBufferPacketListener { boolean continuation = friendlyByteBuf.readBoolean(); if (!continuation) { - friendlyByteBuf.readNbt(); // Discard sourceInfo + ViaVersionHelper.skipTagUnknown(friendlyByteBuf, player.getBukkitEntity()); } RateLimiter rateLimiter = this.plugin.getBlockBufferRateLimiter(player.getUUID()); diff --git a/src/main/java/com/moulberry/axiom/packet/SpawnEntityPacketListener.java b/src/main/java/com/moulberry/axiom/packet/SpawnEntityPacketListener.java index bf8ea46..ebfbaf1 100644 --- a/src/main/java/com/moulberry/axiom/packet/SpawnEntityPacketListener.java +++ b/src/main/java/com/moulberry/axiom/packet/SpawnEntityPacketListener.java @@ -4,6 +4,7 @@ import com.moulberry.axiom.AxiomPaper; import com.moulberry.axiom.NbtSanitization; import com.moulberry.axiom.integration.Integration; import com.moulberry.axiom.integration.plotsquared.PlotSquaredIntegration; +import com.moulberry.axiom.viaversion.ViaVersionHelper; import io.netty.buffer.Unpooled; import net.minecraft.core.BlockPos; import net.minecraft.core.Direction; @@ -38,11 +39,6 @@ public class SpawnEntityPacketListener implements PluginMessageListener { private record SpawnEntry(UUID newUuid, double x, double y, double z, float yaw, float pitch, @Nullable UUID copyFrom, CompoundTag tag) { - public SpawnEntry(FriendlyByteBuf friendlyByteBuf) { - this(friendlyByteBuf.readUUID(), friendlyByteBuf.readDouble(), friendlyByteBuf.readDouble(), - friendlyByteBuf.readDouble(), friendlyByteBuf.readFloat(), friendlyByteBuf.readFloat(), - friendlyByteBuf.readNullable(FriendlyByteBuf::readUUID), friendlyByteBuf.readNbt()); - } } private static final Rotation[] ROTATION_VALUES = Rotation.values(); @@ -62,7 +58,10 @@ public class SpawnEntityPacketListener implements PluginMessageListener { } FriendlyByteBuf friendlyByteBuf = new FriendlyByteBuf(Unpooled.wrappedBuffer(message)); - List entries = friendlyByteBuf.readCollection(FriendlyByteBuf.limitValue(ArrayList::new, 1000), SpawnEntry::new); + List entries = friendlyByteBuf.readCollection(FriendlyByteBuf.limitValue(ArrayList::new, 1000), + buf -> new SpawnEntry(buf.readUUID(), buf.readDouble(), buf.readDouble(), + buf.readDouble(), buf.readFloat(), buf.readFloat(), + buf.readNullable(FriendlyByteBuf::readUUID), ViaVersionHelper.readTagUnknown(buf, player))); ServerLevel serverLevel = ((CraftWorld)player.getWorld()).getHandle(); diff --git a/src/main/java/com/moulberry/axiom/viaversion/ViaVersionHelper.java b/src/main/java/com/moulberry/axiom/viaversion/ViaVersionHelper.java index 7730fa3..53d03be 100644 --- a/src/main/java/com/moulberry/axiom/viaversion/ViaVersionHelper.java +++ b/src/main/java/com/moulberry/axiom/viaversion/ViaVersionHelper.java @@ -6,13 +6,22 @@ import com.viaversion.viaversion.api.data.BiMappings; import com.viaversion.viaversion.api.data.MappingData; import com.viaversion.viaversion.api.data.Mappings; import com.viaversion.viaversion.api.protocol.ProtocolPathEntry; +import com.viaversion.viaversion.api.protocol.version.ProtocolVersion; +import com.viaversion.viaversion.api.type.Type; +import io.netty.buffer.ByteBuf; +import io.netty.buffer.Unpooled; import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap; import net.kyori.adventure.text.Component; import net.kyori.adventure.text.format.NamedTextColor; import net.minecraft.SharedConstants; import net.minecraft.core.IdMapper; +import net.minecraft.nbt.CompoundTag; +import net.minecraft.network.FriendlyByteBuf; +import net.minecraft.world.item.ItemStack; import net.minecraft.world.level.block.Block; import net.minecraft.world.level.block.state.BlockState; +import org.bukkit.Bukkit; +import org.bukkit.entity.Player; import org.jetbrains.annotations.Nullable; import java.util.List; @@ -92,4 +101,64 @@ public class ViaVersionHelper { return newBlockRegistry; } + private static final int UNNAMED_COMPOUND_TAG_CHANGE_VERSION = ProtocolVersion.v1_20_2.getVersion(); + + public static void skipTagUnknown(FriendlyByteBuf friendlyByteBuf, Player player) { + if (Bukkit.getPluginManager().isPluginEnabled("ViaVersion")) { + int playerVersion = Via.getAPI().getPlayerVersion(player.getUniqueId()); + try { + ViaVersionHelper.skipTagViaVersion(friendlyByteBuf, playerVersion); + } catch (Exception e) { + throw new RuntimeException(e); + } + } else { + friendlyByteBuf.readNbt(); // Discard + } + } + + public static CompoundTag readTagUnknown(FriendlyByteBuf friendlyByteBuf, Player player) { + if (Bukkit.getPluginManager().isPluginEnabled("ViaVersion")) { + int playerVersion = Via.getAPI().getPlayerVersion(player.getUniqueId()); + try { + return ViaVersionHelper.readTagViaVersion(friendlyByteBuf, playerVersion); + } catch (Exception e) { + throw new RuntimeException(e); + } + } else { + return friendlyByteBuf.readNbt(); + } + } + + public static void skipTagViaVersion(FriendlyByteBuf friendlyByteBuf, int playerVersion) throws Exception { + getTagType(playerVersion).read(friendlyByteBuf); + } + + public static CompoundTag readTagViaVersion(FriendlyByteBuf friendlyByteBuf, int playerVersion) throws Exception { + Type from = getTagType(playerVersion); + Type to = getTagType(SharedConstants.getProtocolVersion()); + + return readTagViaVersion(friendlyByteBuf, from, to); + } + + private static Type getTagType(int version) { + if (version < UNNAMED_COMPOUND_TAG_CHANGE_VERSION) { + return Type.NAMED_COMPOUND_TAG; + } else { + return Type.COMPOUND_TAG; + } + } + + private static CompoundTag readTagViaVersion(FriendlyByteBuf friendlyByteBuf, + Type from, + Type to) throws Exception { + if (from == to) { + return friendlyByteBuf.readNbt(); + } + + com.viaversion.viaversion.libs.opennbt.tag.builtin.CompoundTag tag = from.read(friendlyByteBuf); + ByteBuf buffer = Unpooled.buffer(); + to.write(buffer, tag); + return new FriendlyByteBuf(buffer).readNbt(); + } + } From 1962e877c6cac1bf3d0e622c5d22863fb4540ec3 Mon Sep 17 00:00:00 2001 From: Moulberry Date: Sat, 4 May 2024 22:00:28 +0800 Subject: [PATCH 06/22] Bump ViaVersion and clean up imports --- build.gradle.kts | 2 +- .../moulberry/axiom/packet/HelloPacketListener.java | 2 +- .../moulberry/axiom/viaversion/ViaVersionHelper.java | 12 +++--------- 3 files changed, 5 insertions(+), 11 deletions(-) diff --git a/build.gradle.kts b/build.gradle.kts index 105c802..c38834c 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -34,7 +34,7 @@ dependencies { implementation("com.github.luben:zstd-jni:1.5.5-4") // ViaVersion support - compileOnly("com.viaversion:viaversion-api:4.9.4-SNAPSHOT") + compileOnly("com.viaversion:viaversion-api:4.10.1-SNAPSHOT") // WorldGuard support compileOnly("com.sk89q.worldguard:worldguard-bukkit:7.1.0-SNAPSHOT") diff --git a/src/main/java/com/moulberry/axiom/packet/HelloPacketListener.java b/src/main/java/com/moulberry/axiom/packet/HelloPacketListener.java index 77bcf31..f6b17ac 100644 --- a/src/main/java/com/moulberry/axiom/packet/HelloPacketListener.java +++ b/src/main/java/com/moulberry/axiom/packet/HelloPacketListener.java @@ -56,7 +56,7 @@ public class HelloPacketListener implements PluginMessageListener { FriendlyByteBuf friendlyByteBuf = new FriendlyByteBuf(Unpooled.wrappedBuffer(message)); int apiVersion = friendlyByteBuf.readVarInt(); int dataVersion = friendlyByteBuf.readVarInt(); - ViaVersionHelper.skipTagUnknown(friendlyByteBuf, player); + // note - skipping NBT here. friendlyByteBuf.readNBT(); int serverDataVersion = SharedConstants.getCurrentVersion().getDataVersion().getVersion(); if (dataVersion != serverDataVersion) { diff --git a/src/main/java/com/moulberry/axiom/viaversion/ViaVersionHelper.java b/src/main/java/com/moulberry/axiom/viaversion/ViaVersionHelper.java index 53d03be..d3cafab 100644 --- a/src/main/java/com/moulberry/axiom/viaversion/ViaVersionHelper.java +++ b/src/main/java/com/moulberry/axiom/viaversion/ViaVersionHelper.java @@ -1,8 +1,8 @@ package com.moulberry.axiom.viaversion; +import com.moulberry.axiom.AxiomPaper; import com.moulberry.axiom.buffer.BlockBuffer; import com.viaversion.viaversion.api.Via; -import com.viaversion.viaversion.api.data.BiMappings; import com.viaversion.viaversion.api.data.MappingData; import com.viaversion.viaversion.api.data.Mappings; import com.viaversion.viaversion.api.protocol.ProtocolPathEntry; @@ -11,18 +11,12 @@ import com.viaversion.viaversion.api.type.Type; import io.netty.buffer.ByteBuf; import io.netty.buffer.Unpooled; import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap; -import net.kyori.adventure.text.Component; -import net.kyori.adventure.text.format.NamedTextColor; import net.minecraft.SharedConstants; import net.minecraft.core.IdMapper; import net.minecraft.nbt.CompoundTag; import net.minecraft.network.FriendlyByteBuf; -import net.minecraft.world.item.ItemStack; -import net.minecraft.world.level.block.Block; import net.minecraft.world.level.block.state.BlockState; -import org.bukkit.Bukkit; import org.bukkit.entity.Player; -import org.jetbrains.annotations.Nullable; import java.util.List; @@ -104,7 +98,7 @@ public class ViaVersionHelper { private static final int UNNAMED_COMPOUND_TAG_CHANGE_VERSION = ProtocolVersion.v1_20_2.getVersion(); public static void skipTagUnknown(FriendlyByteBuf friendlyByteBuf, Player player) { - if (Bukkit.getPluginManager().isPluginEnabled("ViaVersion")) { + if (AxiomPaper.PLUGIN.isMismatchedDataVersion(player.getUniqueId())) { int playerVersion = Via.getAPI().getPlayerVersion(player.getUniqueId()); try { ViaVersionHelper.skipTagViaVersion(friendlyByteBuf, playerVersion); @@ -117,7 +111,7 @@ public class ViaVersionHelper { } public static CompoundTag readTagUnknown(FriendlyByteBuf friendlyByteBuf, Player player) { - if (Bukkit.getPluginManager().isPluginEnabled("ViaVersion")) { + if (AxiomPaper.PLUGIN.isMismatchedDataVersion(player.getUniqueId())) { int playerVersion = Via.getAPI().getPlayerVersion(player.getUniqueId()); try { return ViaVersionHelper.readTagViaVersion(friendlyByteBuf, playerVersion); From cdee54d807348be191281b418d81cabf7fa81953 Mon Sep 17 00:00:00 2001 From: Moulberry Date: Sat, 4 May 2024 22:10:26 +0800 Subject: [PATCH 07/22] Add try-catch to all bukkit plugin message handlers to kick player --- .../axiom/packet/BlueprintRequestPacketListener.java | 8 ++++++++ .../axiom/packet/DeleteEntityPacketListener.java | 9 +++++++++ .../moulberry/axiom/packet/HelloPacketListener.java | 8 ++++++++ .../axiom/packet/ManipulateEntityPacketListener.java | 9 +++++++++ .../axiom/packet/MarkerNbtRequestPacketListener.java | 9 +++++++++ .../axiom/packet/RequestChunkDataPacketListener.java | 11 ++++++++++- .../axiom/packet/SetBlockPacketListener.java | 11 ++++++++++- .../axiom/packet/SetEditorViewsPacketListener.java | 9 +++++++++ .../axiom/packet/SetFlySpeedPacketListener.java | 9 +++++++++ .../axiom/packet/SetGamemodePacketListener.java | 9 +++++++++ .../axiom/packet/SetHotbarSlotPacketListener.java | 9 +++++++++ .../moulberry/axiom/packet/SetTimePacketListener.java | 9 +++++++++ .../axiom/packet/SetWorldPropertyListener.java | 9 +++++++++ .../axiom/packet/SpawnEntityPacketListener.java | 9 +++++++++ .../packet/SwitchActiveHotbarPacketListener.java | 9 +++++++++ .../axiom/packet/TeleportPacketListener.java | 9 +++++++++ 16 files changed, 144 insertions(+), 2 deletions(-) diff --git a/src/main/java/com/moulberry/axiom/packet/BlueprintRequestPacketListener.java b/src/main/java/com/moulberry/axiom/packet/BlueprintRequestPacketListener.java index 14f3f93..cd23dd3 100644 --- a/src/main/java/com/moulberry/axiom/packet/BlueprintRequestPacketListener.java +++ b/src/main/java/com/moulberry/axiom/packet/BlueprintRequestPacketListener.java @@ -28,6 +28,14 @@ public class BlueprintRequestPacketListener implements PluginMessageListener { @Override public void onPluginMessageReceived(@NotNull String channel, @NotNull Player player, @NotNull byte[] message) { + try { + this.process(player, message); + } catch (Throwable t) { + player.kick(Component.text("Error while processing packet " + channel + ": " + t.getMessage())); + } + } + + private void process(Player player, byte[] message) { if (!this.plugin.canUseAxiom(player)) { return; } diff --git a/src/main/java/com/moulberry/axiom/packet/DeleteEntityPacketListener.java b/src/main/java/com/moulberry/axiom/packet/DeleteEntityPacketListener.java index 2402d71..4e60979 100644 --- a/src/main/java/com/moulberry/axiom/packet/DeleteEntityPacketListener.java +++ b/src/main/java/com/moulberry/axiom/packet/DeleteEntityPacketListener.java @@ -4,6 +4,7 @@ import com.moulberry.axiom.AxiomPaper; import com.moulberry.axiom.integration.Integration; import com.moulberry.axiom.integration.plotsquared.PlotSquaredIntegration; import io.netty.buffer.Unpooled; +import net.kyori.adventure.text.Component; import net.minecraft.network.FriendlyByteBuf; import net.minecraft.server.level.ServerLevel; import net.minecraft.world.entity.Entity; @@ -26,6 +27,14 @@ public class DeleteEntityPacketListener implements PluginMessageListener { @Override public void onPluginMessageReceived(@NotNull String channel, @NotNull Player player, @NotNull byte[] message) { + try { + this.process(player, message); + } catch (Throwable t) { + player.kick(Component.text("Error while processing packet " + channel + ": " + t.getMessage())); + } + } + + private void process(Player player, byte[] message) { if (!this.plugin.canUseAxiom(player)) { return; } diff --git a/src/main/java/com/moulberry/axiom/packet/HelloPacketListener.java b/src/main/java/com/moulberry/axiom/packet/HelloPacketListener.java index f6b17ac..36ab08b 100644 --- a/src/main/java/com/moulberry/axiom/packet/HelloPacketListener.java +++ b/src/main/java/com/moulberry/axiom/packet/HelloPacketListener.java @@ -49,6 +49,14 @@ public class HelloPacketListener implements PluginMessageListener { @Override public void onPluginMessageReceived(@NotNull String channel, @NotNull Player player, @NotNull byte[] message) { + try { + this.process(player, message); + } catch (Throwable t) { + player.kick(Component.text("Error while processing packet " + channel + ": " + t.getMessage())); + } + } + + private void process(Player player, byte[] message) { if (!this.plugin.hasAxiomPermission(player)) { return; } diff --git a/src/main/java/com/moulberry/axiom/packet/ManipulateEntityPacketListener.java b/src/main/java/com/moulberry/axiom/packet/ManipulateEntityPacketListener.java index 8db9526..1e84e75 100644 --- a/src/main/java/com/moulberry/axiom/packet/ManipulateEntityPacketListener.java +++ b/src/main/java/com/moulberry/axiom/packet/ManipulateEntityPacketListener.java @@ -6,6 +6,7 @@ import com.moulberry.axiom.integration.Integration; import com.moulberry.axiom.integration.plotsquared.PlotSquaredIntegration; import com.moulberry.axiom.viaversion.ViaVersionHelper; import io.netty.buffer.Unpooled; +import net.kyori.adventure.text.Component; import net.minecraft.core.BlockPos; import net.minecraft.core.Direction; import net.minecraft.nbt.CompoundTag; @@ -80,6 +81,14 @@ public class ManipulateEntityPacketListener implements PluginMessageListener { @Override public void onPluginMessageReceived(@NotNull String channel, @NotNull Player player, @NotNull byte[] message) { + try { + this.process(player, message); + } catch (Throwable t) { + player.kick(Component.text("Error while processing packet " + channel + ": " + t.getMessage())); + } + } + + private void process(Player player, byte[] message) { if (!this.plugin.canUseAxiom(player)) { return; } diff --git a/src/main/java/com/moulberry/axiom/packet/MarkerNbtRequestPacketListener.java b/src/main/java/com/moulberry/axiom/packet/MarkerNbtRequestPacketListener.java index ff640c0..b572bce 100644 --- a/src/main/java/com/moulberry/axiom/packet/MarkerNbtRequestPacketListener.java +++ b/src/main/java/com/moulberry/axiom/packet/MarkerNbtRequestPacketListener.java @@ -3,6 +3,7 @@ package com.moulberry.axiom.packet; import com.moulberry.axiom.AxiomPaper; import com.moulberry.axiom.marker.MarkerData; import io.netty.buffer.Unpooled; +import net.kyori.adventure.text.Component; import net.minecraft.nbt.CompoundTag; import net.minecraft.network.FriendlyByteBuf; import net.minecraft.server.level.ServerLevel; @@ -24,6 +25,14 @@ public class MarkerNbtRequestPacketListener implements PluginMessageListener { @Override public void onPluginMessageReceived(@NotNull String channel, @NotNull Player player, @NotNull byte[] message) { + try { + this.process(player, message); + } catch (Throwable t) { + player.kick(Component.text("Error while processing packet " + channel + ": " + t.getMessage())); + } + } + + private void process(Player player, byte[] message) { if (!this.plugin.canUseAxiom(player)) { return; } diff --git a/src/main/java/com/moulberry/axiom/packet/RequestChunkDataPacketListener.java b/src/main/java/com/moulberry/axiom/packet/RequestChunkDataPacketListener.java index bf1a862..516ef53 100644 --- a/src/main/java/com/moulberry/axiom/packet/RequestChunkDataPacketListener.java +++ b/src/main/java/com/moulberry/axiom/packet/RequestChunkDataPacketListener.java @@ -8,6 +8,7 @@ import com.moulberry.axiom.integration.plotsquared.PlotSquaredIntegration; import com.viaversion.viaversion.api.Via; import io.netty.buffer.Unpooled; import it.unimi.dsi.fastutil.longs.*; +import net.kyori.adventure.text.Component; import net.minecraft.core.BlockPos; import net.minecraft.core.registries.Registries; import net.minecraft.nbt.CompoundTag; @@ -42,7 +43,15 @@ public class RequestChunkDataPacketListener implements PluginMessageListener { } @Override - public void onPluginMessageReceived(@NotNull String channel, @NotNull Player bukkitPlayer, @NotNull byte[] message) { + public void onPluginMessageReceived(@NotNull String channel, @NotNull Player player, @NotNull byte[] message) { + try { + this.process(player, message); + } catch (Throwable t) { + player.kick(Component.text("Error while processing packet " + channel + ": " + t.getMessage())); + } + } + + private void process(Player bukkitPlayer, byte[] message) { ServerPlayer player = ((CraftPlayer)bukkitPlayer).getHandle(); FriendlyByteBuf friendlyByteBuf = new FriendlyByteBuf(Unpooled.wrappedBuffer(message)); long id = friendlyByteBuf.readLong(); diff --git a/src/main/java/com/moulberry/axiom/packet/SetBlockPacketListener.java b/src/main/java/com/moulberry/axiom/packet/SetBlockPacketListener.java index 8443817..91c3856 100644 --- a/src/main/java/com/moulberry/axiom/packet/SetBlockPacketListener.java +++ b/src/main/java/com/moulberry/axiom/packet/SetBlockPacketListener.java @@ -5,6 +5,7 @@ import com.moulberry.axiom.AxiomPaper; import com.moulberry.axiom.integration.Integration; import com.moulberry.axiom.integration.plotsquared.PlotSquaredIntegration; import io.netty.buffer.Unpooled; +import net.kyori.adventure.text.Component; import net.minecraft.core.BlockPos; import net.minecraft.core.Holder; import net.minecraft.core.IdMapper; @@ -68,7 +69,15 @@ public class SetBlockPacketListener implements PluginMessageListener { } @Override - public void onPluginMessageReceived(@NotNull String channel, @NotNull Player bukkitPlayer, @NotNull byte[] message) { + public void onPluginMessageReceived(@NotNull String channel, @NotNull Player player, @NotNull byte[] message) { + try { + this.process(player, message); + } catch (Throwable t) { + player.kick(Component.text("Error while processing packet " + channel + ": " + t.getMessage())); + } + } + + private void process(Player bukkitPlayer, byte[] message) { if (!this.plugin.canUseAxiom(bukkitPlayer)) { return; } diff --git a/src/main/java/com/moulberry/axiom/packet/SetEditorViewsPacketListener.java b/src/main/java/com/moulberry/axiom/packet/SetEditorViewsPacketListener.java index ce1465a..4bfc76f 100644 --- a/src/main/java/com/moulberry/axiom/packet/SetEditorViewsPacketListener.java +++ b/src/main/java/com/moulberry/axiom/packet/SetEditorViewsPacketListener.java @@ -6,6 +6,7 @@ import com.moulberry.axiom.AxiomPaper; import com.moulberry.axiom.View; 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.entity.Player; import org.bukkit.persistence.PersistentDataContainer; @@ -26,6 +27,14 @@ public class SetEditorViewsPacketListener implements PluginMessageListener { @Override public void onPluginMessageReceived(@NotNull String channel, @NotNull Player player, @NotNull byte[] message) { + try { + this.process(player, message); + } catch (Throwable t) { + player.kick(Component.text("Error while processing packet " + channel + ": " + t.getMessage())); + } + } + + private void process(Player player, byte[] message) { if (!this.plugin.canUseAxiom(player)) { return; } diff --git a/src/main/java/com/moulberry/axiom/packet/SetFlySpeedPacketListener.java b/src/main/java/com/moulberry/axiom/packet/SetFlySpeedPacketListener.java index 8feb59a..ecf9ec4 100644 --- a/src/main/java/com/moulberry/axiom/packet/SetFlySpeedPacketListener.java +++ b/src/main/java/com/moulberry/axiom/packet/SetFlySpeedPacketListener.java @@ -3,6 +3,7 @@ package com.moulberry.axiom.packet; import com.moulberry.axiom.AxiomPaper; import com.moulberry.axiom.event.AxiomFlySpeedChangeEvent; import io.netty.buffer.Unpooled; +import net.kyori.adventure.text.Component; import net.minecraft.network.FriendlyByteBuf; import org.bukkit.Bukkit; import org.bukkit.craftbukkit.v1_20_R3.entity.CraftPlayer; @@ -19,6 +20,14 @@ public class SetFlySpeedPacketListener implements PluginMessageListener { @Override public void onPluginMessageReceived(@NotNull String channel, @NotNull Player player, @NotNull byte[] message) { + try { + this.process(player, message); + } catch (Throwable t) { + player.kick(Component.text("Error while processing packet " + channel + ": " + t.getMessage())); + } + } + + private void process(Player player, byte[] message) { if (!this.plugin.canUseAxiom(player)) { return; } diff --git a/src/main/java/com/moulberry/axiom/packet/SetGamemodePacketListener.java b/src/main/java/com/moulberry/axiom/packet/SetGamemodePacketListener.java index 0251410..cdafc54 100644 --- a/src/main/java/com/moulberry/axiom/packet/SetGamemodePacketListener.java +++ b/src/main/java/com/moulberry/axiom/packet/SetGamemodePacketListener.java @@ -3,6 +3,7 @@ package com.moulberry.axiom.packet; import com.moulberry.axiom.AxiomPaper; import com.moulberry.axiom.event.AxiomGameModeChangeEvent; import io.netty.buffer.Unpooled; +import net.kyori.adventure.text.Component; import net.minecraft.network.FriendlyByteBuf; import net.minecraft.world.level.GameType; import org.bukkit.Bukkit; @@ -21,6 +22,14 @@ public class SetGamemodePacketListener implements PluginMessageListener { @Override public void onPluginMessageReceived(@NotNull String channel, @NotNull Player player, @NotNull byte[] message) { + try { + this.process(player, message); + } catch (Throwable t) { + player.kick(Component.text("Error while processing packet " + channel + ": " + t.getMessage())); + } + } + + private void process(Player player, byte[] message) { if (!this.plugin.canUseAxiom(player)) { return; } diff --git a/src/main/java/com/moulberry/axiom/packet/SetHotbarSlotPacketListener.java b/src/main/java/com/moulberry/axiom/packet/SetHotbarSlotPacketListener.java index dc5c1a5..99f9327 100644 --- a/src/main/java/com/moulberry/axiom/packet/SetHotbarSlotPacketListener.java +++ b/src/main/java/com/moulberry/axiom/packet/SetHotbarSlotPacketListener.java @@ -5,6 +5,7 @@ import com.moulberry.axiom.AxiomPaper; import com.moulberry.axiom.persistence.ItemStackDataType; import com.viaversion.viaversion.api.Via; 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_R3.inventory.CraftItemStack; @@ -23,6 +24,14 @@ public class SetHotbarSlotPacketListener implements PluginMessageListener { @Override public void onPluginMessageReceived(@NotNull String channel, @NotNull Player player, @NotNull byte[] message) { + try { + this.process(player, message); + } catch (Throwable t) { + player.kick(Component.text("Error while processing packet " + channel + ": " + t.getMessage())); + } + } + + private void process(Player player, byte[] message) { if (!this.plugin.canUseAxiom(player) || this.plugin.isMismatchedDataVersion(player.getUniqueId())) { return; } diff --git a/src/main/java/com/moulberry/axiom/packet/SetTimePacketListener.java b/src/main/java/com/moulberry/axiom/packet/SetTimePacketListener.java index 11ce53d..c6ccb82 100644 --- a/src/main/java/com/moulberry/axiom/packet/SetTimePacketListener.java +++ b/src/main/java/com/moulberry/axiom/packet/SetTimePacketListener.java @@ -4,6 +4,7 @@ import com.moulberry.axiom.AxiomPaper; import com.moulberry.axiom.event.AxiomTimeChangeEvent; import com.moulberry.axiom.integration.plotsquared.PlotSquaredIntegration; import io.netty.buffer.Unpooled; +import net.kyori.adventure.text.Component; import net.minecraft.core.registries.Registries; import net.minecraft.network.FriendlyByteBuf; import net.minecraft.resources.ResourceKey; @@ -25,6 +26,14 @@ public class SetTimePacketListener implements PluginMessageListener { @Override public void onPluginMessageReceived(@NotNull String channel, @NotNull Player player, @NotNull byte[] message) { + try { + this.process(player, message); + } catch (Throwable t) { + player.kick(Component.text("Error while processing packet " + channel + ": " + t.getMessage())); + } + } + + private void process(Player player, byte[] message) { if (!this.plugin.canUseAxiom(player)) { return; } diff --git a/src/main/java/com/moulberry/axiom/packet/SetWorldPropertyListener.java b/src/main/java/com/moulberry/axiom/packet/SetWorldPropertyListener.java index a6b4691..5b23f3d 100644 --- a/src/main/java/com/moulberry/axiom/packet/SetWorldPropertyListener.java +++ b/src/main/java/com/moulberry/axiom/packet/SetWorldPropertyListener.java @@ -5,6 +5,7 @@ import com.moulberry.axiom.integration.plotsquared.PlotSquaredIntegration; import com.moulberry.axiom.world_properties.server.ServerWorldPropertiesRegistry; import com.moulberry.axiom.world_properties.server.ServerWorldPropertyHolder; import io.netty.buffer.Unpooled; +import net.kyori.adventure.text.Component; import net.minecraft.network.FriendlyByteBuf; import net.minecraft.resources.ResourceLocation; import org.bukkit.entity.Player; @@ -20,6 +21,14 @@ public class SetWorldPropertyListener implements PluginMessageListener { @Override public void onPluginMessageReceived(@NotNull String channel, @NotNull Player player, @NotNull byte[] message) { + try { + this.process(player, message); + } catch (Throwable t) { + player.kick(Component.text("Error while processing packet " + channel + ": " + t.getMessage())); + } + } + + private void process(Player player, byte[] message) { if (!this.plugin.canUseAxiom(player)) { return; } diff --git a/src/main/java/com/moulberry/axiom/packet/SpawnEntityPacketListener.java b/src/main/java/com/moulberry/axiom/packet/SpawnEntityPacketListener.java index ebfbaf1..7e2d419 100644 --- a/src/main/java/com/moulberry/axiom/packet/SpawnEntityPacketListener.java +++ b/src/main/java/com/moulberry/axiom/packet/SpawnEntityPacketListener.java @@ -6,6 +6,7 @@ import com.moulberry.axiom.integration.Integration; import com.moulberry.axiom.integration.plotsquared.PlotSquaredIntegration; import com.moulberry.axiom.viaversion.ViaVersionHelper; import io.netty.buffer.Unpooled; +import net.kyori.adventure.text.Component; import net.minecraft.core.BlockPos; import net.minecraft.core.Direction; import net.minecraft.nbt.CompoundTag; @@ -45,6 +46,14 @@ public class SpawnEntityPacketListener implements PluginMessageListener { @Override public void onPluginMessageReceived(@NotNull String channel, @NotNull Player player, @NotNull byte[] message) { + try { + this.process(player, message); + } catch (Throwable t) { + player.kick(Component.text("Error while processing packet " + channel + ": " + t.getMessage())); + } + } + + private void process(Player player, byte[] message) { if (!this.plugin.canUseAxiom(player)) { return; } diff --git a/src/main/java/com/moulberry/axiom/packet/SwitchActiveHotbarPacketListener.java b/src/main/java/com/moulberry/axiom/packet/SwitchActiveHotbarPacketListener.java index 9700ad3..13c2861 100644 --- a/src/main/java/com/moulberry/axiom/packet/SwitchActiveHotbarPacketListener.java +++ b/src/main/java/com/moulberry/axiom/packet/SwitchActiveHotbarPacketListener.java @@ -4,6 +4,7 @@ import com.moulberry.axiom.AxiomConstants; import com.moulberry.axiom.AxiomPaper; import com.moulberry.axiom.persistence.ItemStackDataType; import io.netty.buffer.Unpooled; +import net.kyori.adventure.text.Component; import net.minecraft.network.FriendlyByteBuf; import org.bukkit.GameMode; import org.bukkit.Material; @@ -25,6 +26,14 @@ public class SwitchActiveHotbarPacketListener implements PluginMessageListener { @Override public void onPluginMessageReceived(@NotNull String channel, @NotNull Player player, @NotNull byte[] message) { + try { + this.process(player, message); + } catch (Throwable t) { + player.kick(Component.text("Error while processing packet " + channel + ": " + t.getMessage())); + } + } + + private void process(Player player, byte[] message) { if (!this.plugin.canUseAxiom(player) || this.plugin.isMismatchedDataVersion(player.getUniqueId())) { return; } diff --git a/src/main/java/com/moulberry/axiom/packet/TeleportPacketListener.java b/src/main/java/com/moulberry/axiom/packet/TeleportPacketListener.java index a36a277..54ec61f 100644 --- a/src/main/java/com/moulberry/axiom/packet/TeleportPacketListener.java +++ b/src/main/java/com/moulberry/axiom/packet/TeleportPacketListener.java @@ -4,6 +4,7 @@ import com.moulberry.axiom.AxiomPaper; import com.moulberry.axiom.event.AxiomUnknownTeleportEvent; import com.moulberry.axiom.event.AxiomTeleportEvent; import io.netty.buffer.Unpooled; +import net.kyori.adventure.text.Component; import net.minecraft.core.registries.Registries; import net.minecraft.network.FriendlyByteBuf; import net.minecraft.resources.ResourceKey; @@ -24,6 +25,14 @@ public class TeleportPacketListener implements PluginMessageListener { @Override public void onPluginMessageReceived(@NotNull String channel, @NotNull Player player, @NotNull byte[] message) { + try { + this.process(player, message); + } catch (Throwable t) { + player.kick(Component.text("Error while processing packet " + channel + ": " + t.getMessage())); + } + } + + private void process(Player player, byte[] message) { if (!this.plugin.canUseAxiom(player)) { return; } From 6e55a9016c2b37aa45f6d499675e30aa7ebbf135 Mon Sep 17 00:00:00 2001 From: Moulberry Date: Sat, 4 May 2024 23:13:31 +0800 Subject: [PATCH 08/22] Update to 1.20.6 --- build.gradle.kts | 16 +++--- .../java/com/moulberry/axiom/AxiomPaper.java | 49 ++++++++++--------- .../com/moulberry/axiom/VersionHelper.java | 5 +- .../com/moulberry/axiom/WorldExtension.java | 8 +-- .../axiom/blueprint/BlueprintIo.java | 5 +- .../blueprint/ServerBlueprintManager.java | 2 +- .../PlotSquaredIntegrationImpl.java | 12 ++--- .../worldguard/WorldGuardIntegrationImpl.java | 12 ++--- .../BlueprintRequestPacketListener.java | 2 +- .../axiom/packet/CustomByteArrayPayload.java | 12 ----- .../packet/DeleteEntityPacketListener.java | 4 +- .../axiom/packet/HelloPacketListener.java | 16 +++--- .../ManipulateEntityPacketListener.java | 4 +- .../MarkerNbtRequestPacketListener.java | 2 +- .../RequestChunkDataPacketListener.java | 8 +-- .../packet/SetBlockBufferPacketListener.java | 4 +- .../axiom/packet/SetBlockPacketListener.java | 8 +-- .../packet/SetFlySpeedPacketListener.java | 2 +- .../packet/SetGamemodePacketListener.java | 2 +- .../packet/SetHotbarSlotPacketListener.java | 9 ++-- .../axiom/packet/SetTimePacketListener.java | 2 +- .../packet/SpawnEntityPacketListener.java | 4 +- .../SwitchActiveHotbarPacketListener.java | 8 +-- .../axiom/packet/TeleportPacketListener.java | 4 +- .../axiom/persistence/ItemStackDataType.java | 10 ++-- .../WorldPropertyDataType.java | 8 +-- .../server/ServerWorldPropertiesRegistry.java | 2 +- .../server/ServerWorldPropertyBase.java | 2 +- .../server/ServerWorldPropertyHolder.java | 2 +- 29 files changed, 111 insertions(+), 113 deletions(-) delete mode 100644 src/main/java/com/moulberry/axiom/packet/CustomByteArrayPayload.java diff --git a/build.gradle.kts b/build.gradle.kts index c38834c..5235057 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -1,10 +1,10 @@ plugins { `java-library` - id("io.papermc.paperweight.userdev") version "1.5.11" - id("xyz.jpenilla.run-paper") version "2.2.2" // Adds runServer and runMojangMappedServer tasks for testing + id("io.papermc.paperweight.userdev") version "1.6.3" + id("xyz.jpenilla.run-paper") version "2.2.4" // Adds runServer and runMojangMappedServer tasks for testing // Shades and relocates dependencies into our plugin jar. See https://imperceptiblethoughts.com/shadow/introduction/ - id("com.github.johnrengelman.shadow") version "8.1.1" + id("io.github.goooler.shadow") version "8.1.7" } group = "com.moulberry.axiom" @@ -12,8 +12,8 @@ version = "1.5.9" description = "Serverside component for Axiom on Paper" java { - // Configure the java toolchain. This allows gradle to auto-provision JDK 17 on systems that only have JDK 8 installed for example. - toolchain.languageVersion.set(JavaLanguageVersion.of(17)) + // Configure the java toolchain. This allows gradle to auto-provision JDK 21 on systems that only have JDK 11 installed for example. + toolchain.languageVersion.set(JavaLanguageVersion.of(21)) } repositories { @@ -26,9 +26,9 @@ repositories { } dependencies { - paperweight.paperDevBundle("1.20.4-R0.1-SNAPSHOT") + paperweight.paperDevBundle("1.20.6-R0.1-SNAPSHOT") implementation("xyz.jpenilla:reflection-remapper:0.1.0-SNAPSHOT") - implementation("org.incendo:cloud-paper:2.0.0-beta.2") + implementation("org.incendo:cloud-paper:2.0.0-SNAPSHOT") // Zstd Compression Library implementation("com.github.luben:zstd-jni:1.5.5-4") @@ -56,7 +56,7 @@ tasks { // Set the release flag. This configures what version bytecode the compiler will emit, as well as what JDK APIs are usable. // See https://openjdk.java.net/jeps/247 for more information. - options.release.set(17) + options.release.set(21) } javadoc { options.encoding = Charsets.UTF_8.name() // We want UTF-8 for everything diff --git a/src/main/java/com/moulberry/axiom/AxiomPaper.java b/src/main/java/com/moulberry/axiom/AxiomPaper.java index e0fe969..6c782c6 100644 --- a/src/main/java/com/moulberry/axiom/AxiomPaper.java +++ b/src/main/java/com/moulberry/axiom/AxiomPaper.java @@ -9,6 +9,7 @@ import com.moulberry.axiom.event.AxiomModifyWorldEvent; import com.moulberry.axiom.integration.plotsquared.PlotSquaredIntegration; import com.moulberry.axiom.packet.*; import com.moulberry.axiom.world_properties.server.ServerWorldPropertiesRegistry; +import io.netty.buffer.ByteBuf; import io.netty.buffer.Unpooled; import io.netty.channel.Channel; import io.papermc.paper.event.player.PlayerFailMoveEvent; @@ -18,12 +19,15 @@ import io.papermc.paper.network.ChannelInitializeListenerHolder; import net.kyori.adventure.key.Key; import net.minecraft.core.BlockPos; import net.minecraft.core.IdMapper; -import net.minecraft.network.Connection; -import net.minecraft.network.ConnectionProtocol; -import net.minecraft.network.FriendlyByteBuf; +import net.minecraft.network.*; import net.minecraft.network.protocol.Packet; import net.minecraft.network.protocol.PacketFlow; import net.minecraft.network.protocol.common.ServerboundCustomPayloadPacket; +import net.minecraft.network.protocol.common.custom.CustomPacketPayload; +import net.minecraft.network.protocol.common.custom.DiscardedPayload; +import net.minecraft.network.protocol.game.GameProtocols; +import net.minecraft.network.protocol.game.ServerGamePacketListener; +import net.minecraft.resources.ResourceLocation; import net.minecraft.server.MinecraftServer; import net.minecraft.world.level.block.state.BlockState; import org.bukkit.*; @@ -159,21 +163,16 @@ public class AxiomPaper extends JavaPlugin implements Listener { RequestChunkDataPacketListener requestChunkDataPacketListener = allowLargeChunkDataRequest ? new RequestChunkDataPacketListener(this) : null; + // Hack to figure out the id of the CustomPayload packet + ProtocolInfo protocol = GameProtocols.SERVERBOUND.bind(k -> new RegistryFriendlyByteBuf(k, + MinecraftServer.getServer().registryAccess())); + RegistryFriendlyByteBuf friendlyByteBuf = new RegistryFriendlyByteBuf(Unpooled.buffer(), MinecraftServer.getServer().registryAccess()); + protocol.codec().encode(friendlyByteBuf, new ServerboundCustomPayloadPacket(new DiscardedPayload(new ResourceLocation("dummy"), Unpooled.buffer()))); + int payloadId = friendlyByteBuf.readVarInt(); + ChannelInitializeListenerHolder.addListener(Key.key("axiom:handle_big_payload"), new ChannelInitializeListener() { @Override public void afterInitChannel(@NonNull Channel channel) { - var packets = ConnectionProtocol.PLAY.getPacketsByIds(PacketFlow.SERVERBOUND); - int payloadId = -1; - for (Map.Entry>> entry : packets.entrySet()) { - if (entry.getValue() == ServerboundCustomPayloadPacket.class) { - payloadId = entry.getKey(); - break; - } - } - if (payloadId < 0) { - throw new RuntimeException("Failed to find ServerboundCustomPayloadPacket id"); - } - Connection connection = (Connection) channel.pipeline().get("packet_handler"); channel.pipeline().addBefore("decoder", "axiom-big-payload-handler", new AxiomBigPayloadHandler(payloadId, connection, setBlockBufferPacketListener, @@ -285,16 +284,20 @@ public class AxiomPaper extends JavaPlugin implements Listener { WorldExtension.tick(MinecraftServer.getServer(), sendMarkers, maxChunkRelightsPerTick, maxChunkSendsPerTick); }, 1, 1); - PaperCommandManager manager = PaperCommandManager.createNative( - this, - ExecutionCoordinator.simpleCoordinator() - ); + try { + PaperCommandManager manager = PaperCommandManager.createNative( + this, + ExecutionCoordinator.simpleCoordinator() + ); - if (manager.hasCapability(CloudBukkitCapabilities.NATIVE_BRIGADIER)) { - manager.registerBrigadier(); + if (manager.hasCapability(CloudBukkitCapabilities.NATIVE_BRIGADIER)) { + manager.registerBrigadier(); + } + + AxiomDebugCommand.register(this, manager); + } catch (Exception e) { + e.printStackTrace(); } - - AxiomDebugCommand.register(this, manager); } public boolean logLargeBlockBufferChanges() { diff --git a/src/main/java/com/moulberry/axiom/VersionHelper.java b/src/main/java/com/moulberry/axiom/VersionHelper.java index 2729968..902c9f0 100644 --- a/src/main/java/com/moulberry/axiom/VersionHelper.java +++ b/src/main/java/com/moulberry/axiom/VersionHelper.java @@ -1,14 +1,15 @@ package com.moulberry.axiom; -import com.moulberry.axiom.packet.CustomByteArrayPayload; +import io.netty.buffer.Unpooled; import net.minecraft.network.protocol.common.ClientboundCustomPayloadPacket; +import net.minecraft.network.protocol.common.custom.DiscardedPayload; import net.minecraft.resources.ResourceLocation; import net.minecraft.server.level.ServerPlayer; public class VersionHelper { public static void sendCustomPayload(ServerPlayer serverPlayer, ResourceLocation id, byte[] data) { - serverPlayer.connection.send(new ClientboundCustomPayloadPacket(new CustomByteArrayPayload(id, data))); + serverPlayer.connection.send(new ClientboundCustomPayloadPacket(new DiscardedPayload(id, Unpooled.wrappedBuffer(data)))); } } diff --git a/src/main/java/com/moulberry/axiom/WorldExtension.java b/src/main/java/com/moulberry/axiom/WorldExtension.java index 2152bb2..7f610a8 100644 --- a/src/main/java/com/moulberry/axiom/WorldExtension.java +++ b/src/main/java/com/moulberry/axiom/WorldExtension.java @@ -16,8 +16,8 @@ import net.minecraft.world.level.ChunkPos; import net.minecraft.world.level.Level; import net.minecraft.world.level.chunk.LevelChunk; import org.bukkit.World; -import org.bukkit.craftbukkit.v1_20_R3.CraftWorld; -import org.bukkit.craftbukkit.v1_20_R3.entity.CraftPlayer; +import org.bukkit.craftbukkit.CraftWorld; +import org.bukkit.craftbukkit.entity.CraftPlayer; import org.bukkit.entity.Player; import java.util.*; @@ -65,7 +65,7 @@ public class WorldExtension { FriendlyByteBuf buf = new FriendlyByteBuf(Unpooled.buffer()); buf.writeCollection(markerData, MarkerData::write); - buf.writeCollection(Set.of(), FriendlyByteBuf::writeUUID); + buf.writeCollection(Set.of(), (buffer, uuid) -> buffer.writeUUID(uuid)); byte[] bytes = new byte[buf.writerIndex()]; buf.getBytes(0, bytes); @@ -106,7 +106,7 @@ public class WorldExtension { if (!changedData.isEmpty() || !oldUuids.isEmpty()) { FriendlyByteBuf buf = new FriendlyByteBuf(Unpooled.buffer()); buf.writeCollection(changedData, MarkerData::write); - buf.writeCollection(oldUuids, FriendlyByteBuf::writeUUID); + buf.writeCollection(oldUuids, (buffer, uuid) -> buffer.writeUUID(uuid)); byte[] bytes = new byte[buf.writerIndex()]; buf.getBytes(0, bytes); diff --git a/src/main/java/com/moulberry/axiom/blueprint/BlueprintIo.java b/src/main/java/com/moulberry/axiom/blueprint/BlueprintIo.java index 59bb487..01f56df 100644 --- a/src/main/java/com/moulberry/axiom/blueprint/BlueprintIo.java +++ b/src/main/java/com/moulberry/axiom/blueprint/BlueprintIo.java @@ -128,7 +128,7 @@ public class BlueprintIo { CompoundTag blockStates = compoundTag.getCompound("BlockStates"); blockStates = DFUHelper.updatePalettedContainer(blockStates, dataVersion); PalettedContainer container = BLOCK_STATE_CODEC.parse(NbtOps.INSTANCE, blockStates) - .getOrThrow(false, err -> {}); + .getOrThrow(); map.put(BlockPos.asLong(cx, cy, cz), container); } } @@ -205,8 +205,7 @@ public class BlueprintIo { tag.putInt("X", cx); tag.putInt("Y", cy); tag.putInt("Z", cz); - Tag encoded = BlueprintIo.BLOCK_STATE_CODEC.encodeStart(NbtOps.INSTANCE, container) - .getOrThrow(false, err -> {}); + Tag encoded = BlueprintIo.BLOCK_STATE_CODEC.encodeStart(NbtOps.INSTANCE, container).getOrThrow(); tag.put("BlockStates", encoded); savedBlockRegions.add(tag); } diff --git a/src/main/java/com/moulberry/axiom/blueprint/ServerBlueprintManager.java b/src/main/java/com/moulberry/axiom/blueprint/ServerBlueprintManager.java index daec893..d6939cd 100644 --- a/src/main/java/com/moulberry/axiom/blueprint/ServerBlueprintManager.java +++ b/src/main/java/com/moulberry/axiom/blueprint/ServerBlueprintManager.java @@ -6,7 +6,7 @@ import io.netty.buffer.Unpooled; import net.minecraft.network.FriendlyByteBuf; import net.minecraft.resources.ResourceLocation; import net.minecraft.server.level.ServerPlayer; -import org.bukkit.craftbukkit.v1_20_R3.entity.CraftPlayer; +import org.bukkit.craftbukkit.entity.CraftPlayer; import java.io.BufferedInputStream; import java.io.IOException; diff --git a/src/main/java/com/moulberry/axiom/integration/plotsquared/PlotSquaredIntegrationImpl.java b/src/main/java/com/moulberry/axiom/integration/plotsquared/PlotSquaredIntegrationImpl.java index 87fa49e..d9ea465 100644 --- a/src/main/java/com/moulberry/axiom/integration/plotsquared/PlotSquaredIntegrationImpl.java +++ b/src/main/java/com/moulberry/axiom/integration/plotsquared/PlotSquaredIntegrationImpl.java @@ -220,12 +220,12 @@ public class PlotSquaredIntegrationImpl { BlockVector3 minPoint = region.getMinimumPoint(); BlockVector3 maxPoint = region.getMaximumPoint(); - int minPlotX = Math.max(minPoint.getX(), minX); - int minPlotY = Math.max(minPoint.getY(), minY); - int minPlotZ = Math.max(minPoint.getZ(), minZ); - int maxPlotX = Math.min(maxPoint.getX(), maxX); - int maxPlotY = Math.min(maxPoint.getY(), maxY); - int maxPlotZ = Math.min(maxPoint.getZ(), maxZ); + int minPlotX = Math.max(minPoint.x(), minX); + int minPlotY = Math.max(minPoint.y(), minY); + int minPlotZ = Math.max(minPoint.z(), minZ); + int maxPlotX = Math.min(maxPoint.x(), maxX); + int maxPlotY = Math.min(maxPoint.y(), maxY); + int maxPlotZ = Math.min(maxPoint.z(), maxZ); if (minPlotX > maxPlotX) continue; if (minPlotY > maxPlotY) continue; diff --git a/src/main/java/com/moulberry/axiom/integration/worldguard/WorldGuardIntegrationImpl.java b/src/main/java/com/moulberry/axiom/integration/worldguard/WorldGuardIntegrationImpl.java index 4787e18..1eb3d07 100644 --- a/src/main/java/com/moulberry/axiom/integration/worldguard/WorldGuardIntegrationImpl.java +++ b/src/main/java/com/moulberry/axiom/integration/worldguard/WorldGuardIntegrationImpl.java @@ -122,12 +122,12 @@ public class WorldGuardIntegrationImpl { BlockVector3 regionMin = region.getMinimumPoint(); BlockVector3 regionMax = region.getMaximumPoint(); - int regionMinX = Math.max(regionMin.getX(), cx*16) - minX; - int regionMinY = Math.max(regionMin.getY(), cy*16) - minY; - int regionMinZ = Math.max(regionMin.getZ(), cz*16) - minZ; - int regionMaxX = Math.min(regionMax.getX(), cx*16+15) - minX; - int regionMaxY = Math.min(regionMax.getY(), cy*16+15) - minY; - int regionMaxZ = Math.min(regionMax.getZ(), cz*16+15) - minZ; + int regionMinX = Math.max(regionMin.x(), cx*16) - minX; + int regionMinY = Math.max(regionMin.y(), cy*16) - minY; + int regionMinZ = Math.max(regionMin.z(), cz*16) - minZ; + int regionMaxX = Math.min(regionMax.x(), cx*16+15) - minX; + int regionMaxY = Math.min(regionMax.y(), cy*16+15) - minY; + int regionMaxZ = Math.min(regionMax.z(), cz*16+15) - minZ; Box box = new Box(regionMinX, regionMinY, regionMinZ, regionMaxX, regionMaxY, regionMaxZ); if (value == StateFlag.State.DENY) { diff --git a/src/main/java/com/moulberry/axiom/packet/BlueprintRequestPacketListener.java b/src/main/java/com/moulberry/axiom/packet/BlueprintRequestPacketListener.java index cd23dd3..6d3741e 100644 --- a/src/main/java/com/moulberry/axiom/packet/BlueprintRequestPacketListener.java +++ b/src/main/java/com/moulberry/axiom/packet/BlueprintRequestPacketListener.java @@ -10,7 +10,7 @@ import net.kyori.adventure.text.Component; import net.minecraft.SharedConstants; import net.minecraft.network.FriendlyByteBuf; import net.minecraft.resources.ResourceLocation; -import org.bukkit.craftbukkit.v1_20_R3.entity.CraftPlayer; +import org.bukkit.craftbukkit.entity.CraftPlayer; import org.bukkit.entity.Player; import org.bukkit.plugin.messaging.PluginMessageListener; import org.jetbrains.annotations.NotNull; diff --git a/src/main/java/com/moulberry/axiom/packet/CustomByteArrayPayload.java b/src/main/java/com/moulberry/axiom/packet/CustomByteArrayPayload.java deleted file mode 100644 index cb2bcd7..0000000 --- a/src/main/java/com/moulberry/axiom/packet/CustomByteArrayPayload.java +++ /dev/null @@ -1,12 +0,0 @@ -package com.moulberry.axiom.packet; - -import net.minecraft.network.FriendlyByteBuf; -import net.minecraft.network.protocol.common.custom.CustomPacketPayload; -import net.minecraft.resources.ResourceLocation; - -public record CustomByteArrayPayload(ResourceLocation id, byte[] bytes) implements CustomPacketPayload { - @Override - public void write(FriendlyByteBuf buf) { - buf.writeBytes(bytes); - } -} diff --git a/src/main/java/com/moulberry/axiom/packet/DeleteEntityPacketListener.java b/src/main/java/com/moulberry/axiom/packet/DeleteEntityPacketListener.java index 4e60979..bfddcb0 100644 --- a/src/main/java/com/moulberry/axiom/packet/DeleteEntityPacketListener.java +++ b/src/main/java/com/moulberry/axiom/packet/DeleteEntityPacketListener.java @@ -9,7 +9,7 @@ import net.minecraft.network.FriendlyByteBuf; import net.minecraft.server.level.ServerLevel; import net.minecraft.world.entity.Entity; import net.minecraft.world.entity.EntityType; -import org.bukkit.craftbukkit.v1_20_R3.CraftWorld; +import org.bukkit.craftbukkit.CraftWorld; import org.bukkit.entity.Player; import org.bukkit.plugin.messaging.PluginMessageListener; import org.jetbrains.annotations.NotNull; @@ -49,7 +49,7 @@ public class DeleteEntityPacketListener implements PluginMessageListener { FriendlyByteBuf friendlyByteBuf = new FriendlyByteBuf(Unpooled.wrappedBuffer(message)); List delete = friendlyByteBuf.readCollection(FriendlyByteBuf.limitValue(ArrayList::new, 1000), - FriendlyByteBuf::readUUID); + buf -> buf.readUUID()); ServerLevel serverLevel = ((CraftWorld)player.getWorld()).getHandle(); diff --git a/src/main/java/com/moulberry/axiom/packet/HelloPacketListener.java b/src/main/java/com/moulberry/axiom/packet/HelloPacketListener.java index 36ab08b..0bdfcac 100644 --- a/src/main/java/com/moulberry/axiom/packet/HelloPacketListener.java +++ b/src/main/java/com/moulberry/axiom/packet/HelloPacketListener.java @@ -22,12 +22,14 @@ import net.minecraft.SharedConstants; import net.minecraft.core.IdMapper; import net.minecraft.nbt.NbtIo; import net.minecraft.network.FriendlyByteBuf; +import net.minecraft.network.RegistryFriendlyByteBuf; +import net.minecraft.server.MinecraftServer; import net.minecraft.world.level.block.state.BlockState; import org.bukkit.Bukkit; import org.bukkit.NamespacedKey; import org.bukkit.World; -import org.bukkit.craftbukkit.v1_20_R3.entity.CraftPlayer; -import org.bukkit.craftbukkit.v1_20_R3.inventory.CraftItemStack; +import org.bukkit.craftbukkit.entity.CraftPlayer; +import org.bukkit.craftbukkit.inventory.CraftItemStack; import org.bukkit.entity.Player; import org.bukkit.inventory.ItemStack; import org.bukkit.persistence.PersistentDataContainer; @@ -155,7 +157,7 @@ public class HelloPacketListener implements PluginMessageListener { } // Enable - FriendlyByteBuf buf = new FriendlyByteBuf(Unpooled.buffer()); + RegistryFriendlyByteBuf buf = new RegistryFriendlyByteBuf(Unpooled.buffer(), MinecraftServer.getServer().registryAccess()); buf.writeBoolean(true); buf.writeInt(handshakeEvent.getMaxBufferSize()); // Max Buffer Size buf.writeBoolean(false); // No source info @@ -174,15 +176,15 @@ public class HelloPacketListener implements PluginMessageListener { 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 = new RegistryFriendlyByteBuf(Unpooled.buffer(), MinecraftServer.getServer().registryAccess()); 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); + net.minecraft.world.item.ItemStack.OPTIONAL_STREAM_CODEC.encode(buf, net.minecraft.world.item.ItemStack.EMPTY); } else { ItemStack stack = hotbarItems.get(new NamespacedKey("axiom", "slot_"+i), ItemStackDataType.INSTANCE); - buf.writeItem(CraftItemStack.asNMSCopy(stack)); + net.minecraft.world.item.ItemStack.OPTIONAL_STREAM_CODEC.encode(buf, CraftItemStack.asNMSCopy(stack)); } } @@ -195,7 +197,7 @@ public class HelloPacketListener implements PluginMessageListener { // Initialize Views UUID activeView = container.get(AxiomConstants.ACTIVE_VIEW, UUIDDataType.INSTANCE); if (activeView != null) { - buf = new FriendlyByteBuf(Unpooled.buffer()); + buf = new RegistryFriendlyByteBuf(Unpooled.buffer(), MinecraftServer.getServer().registryAccess()); buf.writeUUID(activeView); PersistentDataContainer[] views = container.get(AxiomConstants.VIEWS, PersistentDataType.TAG_CONTAINER_ARRAY); diff --git a/src/main/java/com/moulberry/axiom/packet/ManipulateEntityPacketListener.java b/src/main/java/com/moulberry/axiom/packet/ManipulateEntityPacketListener.java index 1e84e75..c382666 100644 --- a/src/main/java/com/moulberry/axiom/packet/ManipulateEntityPacketListener.java +++ b/src/main/java/com/moulberry/axiom/packet/ManipulateEntityPacketListener.java @@ -21,7 +21,7 @@ import net.minecraft.world.entity.decoration.ItemFrame; import net.minecraft.world.level.block.Rotation; import net.minecraft.world.phys.Vec3; import org.bukkit.Location; -import org.bukkit.craftbukkit.v1_20_R3.CraftWorld; +import org.bukkit.craftbukkit.CraftWorld; import org.bukkit.entity.Player; import org.bukkit.plugin.messaging.PluginMessageListener; import org.jetbrains.annotations.NotNull; @@ -69,7 +69,7 @@ public class ManipulateEntityPacketListener implements PluginMessageListener { List passengers = List.of(); if (passengerManipulation == PassengerManipulation.ADD_LIST || passengerManipulation == PassengerManipulation.REMOVE_LIST) { passengers = friendlyByteBuf.readCollection(FriendlyByteBuf.limitValue(ArrayList::new, 1000), - FriendlyByteBuf::readUUID); + buffer -> buffer.readUUID()); } return new ManipulateEntry(uuid, relativeMovementSet, position, yaw, pitch, nbt, diff --git a/src/main/java/com/moulberry/axiom/packet/MarkerNbtRequestPacketListener.java b/src/main/java/com/moulberry/axiom/packet/MarkerNbtRequestPacketListener.java index b572bce..1856c13 100644 --- a/src/main/java/com/moulberry/axiom/packet/MarkerNbtRequestPacketListener.java +++ b/src/main/java/com/moulberry/axiom/packet/MarkerNbtRequestPacketListener.java @@ -9,7 +9,7 @@ import net.minecraft.network.FriendlyByteBuf; import net.minecraft.server.level.ServerLevel; import net.minecraft.world.entity.Entity; import net.minecraft.world.entity.Marker; -import org.bukkit.craftbukkit.v1_20_R3.CraftWorld; +import org.bukkit.craftbukkit.CraftWorld; import org.bukkit.entity.Player; import org.bukkit.plugin.messaging.PluginMessageListener; import org.jetbrains.annotations.NotNull; diff --git a/src/main/java/com/moulberry/axiom/packet/RequestChunkDataPacketListener.java b/src/main/java/com/moulberry/axiom/packet/RequestChunkDataPacketListener.java index 516ef53..0aae6cd 100644 --- a/src/main/java/com/moulberry/axiom/packet/RequestChunkDataPacketListener.java +++ b/src/main/java/com/moulberry/axiom/packet/RequestChunkDataPacketListener.java @@ -22,11 +22,11 @@ import net.minecraft.server.level.ServerPlayer; import net.minecraft.world.level.Level; import net.minecraft.world.level.block.entity.BlockEntity; import net.minecraft.world.level.block.state.BlockState; -import net.minecraft.world.level.chunk.ChunkStatus; +import net.minecraft.world.level.chunk.status.ChunkStatus; import net.minecraft.world.level.chunk.LevelChunk; import net.minecraft.world.level.chunk.LevelChunkSection; import net.minecraft.world.level.chunk.PalettedContainer; -import org.bukkit.craftbukkit.v1_20_R3.entity.CraftPlayer; +import org.bukkit.craftbukkit.entity.CraftPlayer; import org.bukkit.entity.Player; import org.bukkit.plugin.messaging.PluginMessageListener; import org.jetbrains.annotations.NotNull; @@ -115,7 +115,7 @@ public class RequestChunkDataPacketListener implements PluginMessageListener { BlockEntity blockEntity = chunk.getBlockEntity(mutableBlockPos, LevelChunk.EntityCreationType.IMMEDIATE); if (blockEntity != null) { - CompoundTag tag = blockEntity.saveWithoutMetadata(); + CompoundTag tag = blockEntity.saveWithoutMetadata(player.registryAccess()); blockEntityMap.put(pos, CompressedBlockEntity.compress(tag, baos)); } } @@ -154,7 +154,7 @@ public class RequestChunkDataPacketListener implements PluginMessageListener { mutableBlockPos.set(sx*16 + x, sy*16 + y, sz*16 + z); BlockEntity blockEntity = chunk.getBlockEntity(mutableBlockPos, LevelChunk.EntityCreationType.CHECK); if (blockEntity != null) { - CompoundTag tag = blockEntity.saveWithoutMetadata(); + CompoundTag tag = blockEntity.saveWithoutMetadata(player.registryAccess()); blockEntityMap.put(mutableBlockPos.asLong(), CompressedBlockEntity.compress(tag, baos)); } } diff --git a/src/main/java/com/moulberry/axiom/packet/SetBlockBufferPacketListener.java b/src/main/java/com/moulberry/axiom/packet/SetBlockBufferPacketListener.java index aaf85f7..8b42520 100644 --- a/src/main/java/com/moulberry/axiom/packet/SetBlockBufferPacketListener.java +++ b/src/main/java/com/moulberry/axiom/packet/SetBlockBufferPacketListener.java @@ -34,7 +34,7 @@ import net.minecraft.world.level.block.Block; import net.minecraft.world.level.block.EntityBlock; import net.minecraft.world.level.block.entity.BlockEntity; import net.minecraft.world.level.block.state.BlockState; -import net.minecraft.world.level.chunk.ChunkStatus; +import net.minecraft.world.level.chunk.status.ChunkStatus; import net.minecraft.world.level.chunk.LevelChunk; import net.minecraft.world.level.chunk.LevelChunkSection; import net.minecraft.world.level.chunk.PalettedContainer; @@ -282,7 +282,7 @@ public class SetBlockBufferPacketListener { int key = x | (y << 4) | (z << 8); CompressedBlockEntity savedBlockEntity = blockEntityChunkMap.get((short) key); if (savedBlockEntity != null) { - blockEntity.load(savedBlockEntity.decompress()); + blockEntity.loadWithComponents(savedBlockEntity.decompress(), player.registryAccess()); } } } else if (old.hasBlockEntity()) { diff --git a/src/main/java/com/moulberry/axiom/packet/SetBlockPacketListener.java b/src/main/java/com/moulberry/axiom/packet/SetBlockPacketListener.java index 91c3856..98b289e 100644 --- a/src/main/java/com/moulberry/axiom/packet/SetBlockPacketListener.java +++ b/src/main/java/com/moulberry/axiom/packet/SetBlockPacketListener.java @@ -31,9 +31,9 @@ import net.minecraft.world.phys.HitResult; import net.minecraft.world.phys.Vec3; import org.bukkit.Location; import org.bukkit.block.BlockFace; -import org.bukkit.craftbukkit.v1_20_R3.CraftWorld; -import org.bukkit.craftbukkit.v1_20_R3.block.CraftBlock; -import org.bukkit.craftbukkit.v1_20_R3.entity.CraftPlayer; +import org.bukkit.craftbukkit.CraftWorld; +import org.bukkit.craftbukkit.block.CraftBlock; +import org.bukkit.craftbukkit.entity.CraftPlayer; import org.bukkit.entity.Player; import org.bukkit.event.block.Action; import org.bukkit.event.player.PlayerInteractEvent; @@ -91,7 +91,7 @@ public class SetBlockPacketListener implements PluginMessageListener { IntFunction> mapFunction = FriendlyByteBuf.limitValue(Maps::newLinkedHashMapWithExpectedSize, 512); IdMapper registry = this.plugin.getBlockRegistry(bukkitPlayer.getUniqueId()); Map blocks = friendlyByteBuf.readMap(mapFunction, - FriendlyByteBuf::readBlockPos, buf -> buf.readById(registry)); + buf -> buf.readBlockPos(), buf -> buf.readById(registry::byIdOrThrow)); boolean updateNeighbors = friendlyByteBuf.readBoolean(); int reason = friendlyByteBuf.readVarInt(); diff --git a/src/main/java/com/moulberry/axiom/packet/SetFlySpeedPacketListener.java b/src/main/java/com/moulberry/axiom/packet/SetFlySpeedPacketListener.java index ecf9ec4..e488f3b 100644 --- a/src/main/java/com/moulberry/axiom/packet/SetFlySpeedPacketListener.java +++ b/src/main/java/com/moulberry/axiom/packet/SetFlySpeedPacketListener.java @@ -6,7 +6,7 @@ import io.netty.buffer.Unpooled; import net.kyori.adventure.text.Component; import net.minecraft.network.FriendlyByteBuf; import org.bukkit.Bukkit; -import org.bukkit.craftbukkit.v1_20_R3.entity.CraftPlayer; +import org.bukkit.craftbukkit.entity.CraftPlayer; import org.bukkit.entity.Player; import org.bukkit.plugin.messaging.PluginMessageListener; import org.jetbrains.annotations.NotNull; diff --git a/src/main/java/com/moulberry/axiom/packet/SetGamemodePacketListener.java b/src/main/java/com/moulberry/axiom/packet/SetGamemodePacketListener.java index cdafc54..be24422 100644 --- a/src/main/java/com/moulberry/axiom/packet/SetGamemodePacketListener.java +++ b/src/main/java/com/moulberry/axiom/packet/SetGamemodePacketListener.java @@ -8,7 +8,7 @@ import net.minecraft.network.FriendlyByteBuf; import net.minecraft.world.level.GameType; import org.bukkit.Bukkit; import org.bukkit.GameMode; -import org.bukkit.craftbukkit.v1_20_R3.entity.CraftPlayer; +import org.bukkit.craftbukkit.entity.CraftPlayer; import org.bukkit.entity.Player; import org.bukkit.plugin.messaging.PluginMessageListener; import org.jetbrains.annotations.NotNull; diff --git a/src/main/java/com/moulberry/axiom/packet/SetHotbarSlotPacketListener.java b/src/main/java/com/moulberry/axiom/packet/SetHotbarSlotPacketListener.java index 99f9327..685a7f0 100644 --- a/src/main/java/com/moulberry/axiom/packet/SetHotbarSlotPacketListener.java +++ b/src/main/java/com/moulberry/axiom/packet/SetHotbarSlotPacketListener.java @@ -7,8 +7,11 @@ import com.viaversion.viaversion.api.Via; import io.netty.buffer.Unpooled; import net.kyori.adventure.text.Component; import net.minecraft.network.FriendlyByteBuf; +import net.minecraft.network.RegistryFriendlyByteBuf; +import net.minecraft.world.item.ItemStack; import org.bukkit.NamespacedKey; -import org.bukkit.craftbukkit.v1_20_R3.inventory.CraftItemStack; +import org.bukkit.craftbukkit.entity.CraftPlayer; +import org.bukkit.craftbukkit.inventory.CraftItemStack; import org.bukkit.entity.Player; import org.bukkit.persistence.PersistentDataContainer; import org.bukkit.persistence.PersistentDataType; @@ -36,10 +39,10 @@ public class SetHotbarSlotPacketListener implements PluginMessageListener { return; } - FriendlyByteBuf friendlyByteBuf = new FriendlyByteBuf(Unpooled.wrappedBuffer(message)); + RegistryFriendlyByteBuf friendlyByteBuf = new RegistryFriendlyByteBuf(Unpooled.wrappedBuffer(message), ((CraftPlayer)player).getHandle().registryAccess()); int index = friendlyByteBuf.readByte(); if (index < 0 || index >= 9*9) return; - net.minecraft.world.item.ItemStack nmsStack = friendlyByteBuf.readItem(); + net.minecraft.world.item.ItemStack nmsStack = ItemStack.OPTIONAL_STREAM_CODEC.decode(friendlyByteBuf); PersistentDataContainer container = player.getPersistentDataContainer(); PersistentDataContainer hotbarItems = container.get(AxiomConstants.HOTBAR_DATA, PersistentDataType.TAG_CONTAINER); diff --git a/src/main/java/com/moulberry/axiom/packet/SetTimePacketListener.java b/src/main/java/com/moulberry/axiom/packet/SetTimePacketListener.java index c6ccb82..a3b0c7b 100644 --- a/src/main/java/com/moulberry/axiom/packet/SetTimePacketListener.java +++ b/src/main/java/com/moulberry/axiom/packet/SetTimePacketListener.java @@ -12,7 +12,7 @@ import net.minecraft.server.level.ServerLevel; import net.minecraft.world.level.GameRules; import net.minecraft.world.level.Level; import org.bukkit.Bukkit; -import org.bukkit.craftbukkit.v1_20_R3.CraftWorld; +import org.bukkit.craftbukkit.CraftWorld; import org.bukkit.entity.Player; import org.bukkit.plugin.messaging.PluginMessageListener; import org.jetbrains.annotations.NotNull; diff --git a/src/main/java/com/moulberry/axiom/packet/SpawnEntityPacketListener.java b/src/main/java/com/moulberry/axiom/packet/SpawnEntityPacketListener.java index 7e2d419..a9ea16e 100644 --- a/src/main/java/com/moulberry/axiom/packet/SpawnEntityPacketListener.java +++ b/src/main/java/com/moulberry/axiom/packet/SpawnEntityPacketListener.java @@ -20,7 +20,7 @@ import net.minecraft.world.level.Level; import net.minecraft.world.level.block.Rotation; import net.minecraft.world.phys.Vec3; import org.bukkit.Location; -import org.bukkit.craftbukkit.v1_20_R3.CraftWorld; +import org.bukkit.craftbukkit.CraftWorld; import org.bukkit.entity.Player; import org.bukkit.plugin.messaging.PluginMessageListener; import org.jetbrains.annotations.NotNull; @@ -70,7 +70,7 @@ public class SpawnEntityPacketListener implements PluginMessageListener { List entries = friendlyByteBuf.readCollection(FriendlyByteBuf.limitValue(ArrayList::new, 1000), buf -> new SpawnEntry(buf.readUUID(), buf.readDouble(), buf.readDouble(), buf.readDouble(), buf.readFloat(), buf.readFloat(), - buf.readNullable(FriendlyByteBuf::readUUID), ViaVersionHelper.readTagUnknown(buf, player))); + buf.readNullable(buffer -> buffer.readUUID()), ViaVersionHelper.readTagUnknown(buf, player))); ServerLevel serverLevel = ((CraftWorld)player.getWorld()).getHandle(); diff --git a/src/main/java/com/moulberry/axiom/packet/SwitchActiveHotbarPacketListener.java b/src/main/java/com/moulberry/axiom/packet/SwitchActiveHotbarPacketListener.java index 13c2861..90a7338 100644 --- a/src/main/java/com/moulberry/axiom/packet/SwitchActiveHotbarPacketListener.java +++ b/src/main/java/com/moulberry/axiom/packet/SwitchActiveHotbarPacketListener.java @@ -6,10 +6,12 @@ import com.moulberry.axiom.persistence.ItemStackDataType; import io.netty.buffer.Unpooled; import net.kyori.adventure.text.Component; import net.minecraft.network.FriendlyByteBuf; +import net.minecraft.network.RegistryFriendlyByteBuf; import org.bukkit.GameMode; import org.bukkit.Material; import org.bukkit.NamespacedKey; -import org.bukkit.craftbukkit.v1_20_R3.inventory.CraftItemStack; +import org.bukkit.craftbukkit.entity.CraftPlayer; +import org.bukkit.craftbukkit.inventory.CraftItemStack; import org.bukkit.entity.Player; import org.bukkit.inventory.ItemStack; import org.bukkit.persistence.PersistentDataContainer; @@ -38,13 +40,13 @@ public class SwitchActiveHotbarPacketListener implements PluginMessageListener { return; } - FriendlyByteBuf friendlyByteBuf = new FriendlyByteBuf(Unpooled.wrappedBuffer(message)); + RegistryFriendlyByteBuf friendlyByteBuf = new RegistryFriendlyByteBuf(Unpooled.wrappedBuffer(message), ((CraftPlayer)player).getHandle().registryAccess()); 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()); + hotbarItems[i] = CraftItemStack.asCraftMirror(net.minecraft.world.item.ItemStack.OPTIONAL_STREAM_CODEC.decode(friendlyByteBuf)); } PersistentDataContainer container = player.getPersistentDataContainer(); diff --git a/src/main/java/com/moulberry/axiom/packet/TeleportPacketListener.java b/src/main/java/com/moulberry/axiom/packet/TeleportPacketListener.java index 54ec61f..cdb93b5 100644 --- a/src/main/java/com/moulberry/axiom/packet/TeleportPacketListener.java +++ b/src/main/java/com/moulberry/axiom/packet/TeleportPacketListener.java @@ -10,8 +10,8 @@ import net.minecraft.network.FriendlyByteBuf; import net.minecraft.resources.ResourceKey; import net.minecraft.world.level.Level; import org.bukkit.*; -import org.bukkit.craftbukkit.v1_20_R3.entity.CraftPlayer; -import org.bukkit.craftbukkit.v1_20_R3.util.CraftNamespacedKey; +import org.bukkit.craftbukkit.entity.CraftPlayer; +import org.bukkit.craftbukkit.util.CraftNamespacedKey; import org.bukkit.entity.Player; import org.bukkit.plugin.messaging.PluginMessageListener; import org.jetbrains.annotations.NotNull; diff --git a/src/main/java/com/moulberry/axiom/persistence/ItemStackDataType.java b/src/main/java/com/moulberry/axiom/persistence/ItemStackDataType.java index 14a2fe6..963d503 100644 --- a/src/main/java/com/moulberry/axiom/persistence/ItemStackDataType.java +++ b/src/main/java/com/moulberry/axiom/persistence/ItemStackDataType.java @@ -1,8 +1,9 @@ package com.moulberry.axiom.persistence; import net.minecraft.nbt.CompoundTag; -import org.bukkit.craftbukkit.v1_20_R3.inventory.CraftItemStack; -import org.bukkit.craftbukkit.v1_20_R3.persistence.CraftPersistentDataContainer; +import net.minecraft.server.MinecraftServer; +import org.bukkit.craftbukkit.inventory.CraftItemStack; +import org.bukkit.craftbukkit.persistence.CraftPersistentDataContainer; import org.bukkit.inventory.ItemStack; import org.bukkit.persistence.PersistentDataAdapterContext; import org.bukkit.persistence.PersistentDataContainer; @@ -28,8 +29,7 @@ public class ItemStackDataType implements PersistentDataType { if (value == null) value = Items.AIR; FriendlyByteBuf buf = new FriendlyByteBuf(Unpooled.buffer(8)); - buf.writeId(BuiltInRegistries.ITEM, value); + buf.writeById(BuiltInRegistries.ITEM::getIdOrThrow, value); byte[] bytes = new byte[buf.writerIndex()]; buf.getBytes(0, bytes); @@ -97,7 +97,7 @@ public abstract class WorldPropertyDataType { @Override public Item deserialize(byte[] bytes) { FriendlyByteBuf buf = new FriendlyByteBuf(Unpooled.wrappedBuffer(bytes)); - return buf.readById(BuiltInRegistries.ITEM); + return buf.readById(BuiltInRegistries.ITEM::byIdOrThrow); } }; @@ -112,7 +112,7 @@ public abstract class WorldPropertyDataType { if (value == null) value = Blocks.AIR; FriendlyByteBuf buf = new FriendlyByteBuf(Unpooled.buffer(8)); - buf.writeId(BuiltInRegistries.BLOCK, value); + buf.writeById(BuiltInRegistries.BLOCK::getIdOrThrow, value); byte[] bytes = new byte[buf.writerIndex()]; buf.getBytes(0, bytes); @@ -122,7 +122,7 @@ public abstract class WorldPropertyDataType { @Override public Block deserialize(byte[] bytes) { FriendlyByteBuf buf = new FriendlyByteBuf(Unpooled.wrappedBuffer(bytes)); - return buf.readById(BuiltInRegistries.BLOCK); + return buf.readById(BuiltInRegistries.BLOCK::byIdOrThrow); } }; diff --git a/src/main/java/com/moulberry/axiom/world_properties/server/ServerWorldPropertiesRegistry.java b/src/main/java/com/moulberry/axiom/world_properties/server/ServerWorldPropertiesRegistry.java index 09e0b9d..f8fa272 100644 --- a/src/main/java/com/moulberry/axiom/world_properties/server/ServerWorldPropertiesRegistry.java +++ b/src/main/java/com/moulberry/axiom/world_properties/server/ServerWorldPropertiesRegistry.java @@ -9,7 +9,7 @@ import net.minecraft.server.level.ServerLevel; import org.bukkit.GameRule; import org.bukkit.NamespacedKey; import org.bukkit.World; -import org.bukkit.craftbukkit.v1_20_R3.CraftWorld; +import org.bukkit.craftbukkit.CraftWorld; import org.bukkit.entity.Player; import org.bukkit.plugin.Plugin; diff --git a/src/main/java/com/moulberry/axiom/world_properties/server/ServerWorldPropertyBase.java b/src/main/java/com/moulberry/axiom/world_properties/server/ServerWorldPropertyBase.java index 2d7837b..9a3c300 100644 --- a/src/main/java/com/moulberry/axiom/world_properties/server/ServerWorldPropertyBase.java +++ b/src/main/java/com/moulberry/axiom/world_properties/server/ServerWorldPropertyBase.java @@ -6,7 +6,7 @@ import com.moulberry.axiom.world_properties.WorldPropertyWidgetType; import net.minecraft.resources.ResourceLocation; import org.bukkit.NamespacedKey; import org.bukkit.World; -import org.bukkit.craftbukkit.v1_20_R3.util.CraftNamespacedKey; +import org.bukkit.craftbukkit.util.CraftNamespacedKey; import org.bukkit.entity.Player; public abstract class ServerWorldPropertyBase { diff --git a/src/main/java/com/moulberry/axiom/world_properties/server/ServerWorldPropertyHolder.java b/src/main/java/com/moulberry/axiom/world_properties/server/ServerWorldPropertyHolder.java index 0755b69..28cfbe0 100644 --- a/src/main/java/com/moulberry/axiom/world_properties/server/ServerWorldPropertyHolder.java +++ b/src/main/java/com/moulberry/axiom/world_properties/server/ServerWorldPropertyHolder.java @@ -9,7 +9,7 @@ import net.minecraft.network.FriendlyByteBuf; import net.minecraft.resources.ResourceLocation; import org.bukkit.NamespacedKey; import org.bukkit.World; -import org.bukkit.craftbukkit.v1_20_R3.util.CraftNamespacedKey; +import org.bukkit.craftbukkit.util.CraftNamespacedKey; import org.bukkit.entity.Player; import java.util.Objects; From 5f38507962ad3cd538129fbcd43437d1458c236b Mon Sep 17 00:00:00 2001 From: Moulberry Date: Sat, 4 May 2024 23:14:35 +0800 Subject: [PATCH 09/22] Bump version to 1.5.10 --- build.gradle.kts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.gradle.kts b/build.gradle.kts index 5235057..4ca6b26 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -8,7 +8,7 @@ plugins { } group = "com.moulberry.axiom" -version = "1.5.9" +version = "1.5.10" description = "Serverside component for Axiom on Paper" java { From 12fe46f4b0184c6a1a31783a69accb15585f4013 Mon Sep 17 00:00:00 2001 From: Moulberry Date: Sat, 4 May 2024 23:36:47 +0800 Subject: [PATCH 10/22] Fix SectionPermissionChecker combination --- .../axiom/integration/SectionPermissionChecker.java | 8 ++++++-- src/main/resources/plugin.yml | 2 +- 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/src/main/java/com/moulberry/axiom/integration/SectionPermissionChecker.java b/src/main/java/com/moulberry/axiom/integration/SectionPermissionChecker.java index 97f4eb5..50f1a5d 100644 --- a/src/main/java/com/moulberry/axiom/integration/SectionPermissionChecker.java +++ b/src/main/java/com/moulberry/axiom/integration/SectionPermissionChecker.java @@ -13,10 +13,10 @@ public interface SectionPermissionChecker { if (first.noneAllowed() || second.noneAllowed()) { return NONE_ALLOWED; } - if (first.allAllowed()) { + if (first == ALL_ALLOWED) { return second; } - if (second.allAllowed()) { + if (second == ALL_ALLOWED) { return first; } @@ -25,6 +25,10 @@ public interface SectionPermissionChecker { return NONE_ALLOWED; } + if (first.allAllowed() && second.allAllowed()) { + return new AllAllowedInBox(intersect); + } + return new SectionPermissionChecker() { @Override public boolean allAllowed() { diff --git a/src/main/resources/plugin.yml b/src/main/resources/plugin.yml index 8afb8ab..2531c61 100644 --- a/src/main/resources/plugin.yml +++ b/src/main/resources/plugin.yml @@ -24,7 +24,7 @@ permissions: axiom.allow_copying_other_plots: description: This permission allows users to copy other user's plots - default: false # true + default: true axiom.can_import_blocks: description: Allows players to import schematics/blueprints into Axiom default: true From cdcf1220bd7f637c17eed7e668055441cf798b92 Mon Sep 17 00:00:00 2001 From: Moulberry Date: Wed, 8 May 2024 18:58:18 +0800 Subject: [PATCH 11/22] Separate ViaVersion methods to avoid ClassNotFoundExceptions --- .../ManipulateEntityPacketListener.java | 3 +- .../packet/SetBlockBufferPacketListener.java | 5 +-- .../packet/SpawnEntityPacketListener.java | 3 +- .../viaversion/UnknownVersionHelper.java | 34 ++++++++++++++++ .../axiom/viaversion/ViaVersionHelper.java | 40 +++++-------------- 5 files changed, 50 insertions(+), 35 deletions(-) create mode 100644 src/main/java/com/moulberry/axiom/viaversion/UnknownVersionHelper.java diff --git a/src/main/java/com/moulberry/axiom/packet/ManipulateEntityPacketListener.java b/src/main/java/com/moulberry/axiom/packet/ManipulateEntityPacketListener.java index c382666..af926a5 100644 --- a/src/main/java/com/moulberry/axiom/packet/ManipulateEntityPacketListener.java +++ b/src/main/java/com/moulberry/axiom/packet/ManipulateEntityPacketListener.java @@ -4,6 +4,7 @@ import com.moulberry.axiom.AxiomPaper; import com.moulberry.axiom.NbtSanitization; import com.moulberry.axiom.integration.Integration; import com.moulberry.axiom.integration.plotsquared.PlotSquaredIntegration; +import com.moulberry.axiom.viaversion.UnknownVersionHelper; import com.moulberry.axiom.viaversion.ViaVersionHelper; import io.netty.buffer.Unpooled; import net.kyori.adventure.text.Component; @@ -63,7 +64,7 @@ public class ManipulateEntityPacketListener implements PluginMessageListener { pitch = friendlyByteBuf.readFloat(); } - CompoundTag nbt = ViaVersionHelper.readTagUnknown(friendlyByteBuf, player); + CompoundTag nbt = UnknownVersionHelper.readTagUnknown(friendlyByteBuf, player); PassengerManipulation passengerManipulation = friendlyByteBuf.readEnum(PassengerManipulation.class); List passengers = List.of(); diff --git a/src/main/java/com/moulberry/axiom/packet/SetBlockBufferPacketListener.java b/src/main/java/com/moulberry/axiom/packet/SetBlockBufferPacketListener.java index 8b42520..4e45325 100644 --- a/src/main/java/com/moulberry/axiom/packet/SetBlockBufferPacketListener.java +++ b/src/main/java/com/moulberry/axiom/packet/SetBlockBufferPacketListener.java @@ -8,8 +8,7 @@ import com.moulberry.axiom.buffer.BlockBuffer; import com.moulberry.axiom.buffer.CompressedBlockEntity; import com.moulberry.axiom.integration.Integration; import com.moulberry.axiom.integration.SectionPermissionChecker; -import com.moulberry.axiom.integration.plotsquared.PlotSquaredIntegration; -import com.moulberry.axiom.viaversion.ViaVersionHelper; +import com.moulberry.axiom.viaversion.UnknownVersionHelper; import it.unimi.dsi.fastutil.longs.Long2ObjectMap; import it.unimi.dsi.fastutil.shorts.Short2ObjectMap; import net.minecraft.ChatFormatting; @@ -78,7 +77,7 @@ public class SetBlockBufferPacketListener { boolean continuation = friendlyByteBuf.readBoolean(); if (!continuation) { - ViaVersionHelper.skipTagUnknown(friendlyByteBuf, player.getBukkitEntity()); + UnknownVersionHelper.skipTagUnknown(friendlyByteBuf, player.getBukkitEntity()); } RateLimiter rateLimiter = this.plugin.getBlockBufferRateLimiter(player.getUUID()); diff --git a/src/main/java/com/moulberry/axiom/packet/SpawnEntityPacketListener.java b/src/main/java/com/moulberry/axiom/packet/SpawnEntityPacketListener.java index a9ea16e..b643781 100644 --- a/src/main/java/com/moulberry/axiom/packet/SpawnEntityPacketListener.java +++ b/src/main/java/com/moulberry/axiom/packet/SpawnEntityPacketListener.java @@ -4,6 +4,7 @@ import com.moulberry.axiom.AxiomPaper; import com.moulberry.axiom.NbtSanitization; import com.moulberry.axiom.integration.Integration; import com.moulberry.axiom.integration.plotsquared.PlotSquaredIntegration; +import com.moulberry.axiom.viaversion.UnknownVersionHelper; import com.moulberry.axiom.viaversion.ViaVersionHelper; import io.netty.buffer.Unpooled; import net.kyori.adventure.text.Component; @@ -70,7 +71,7 @@ public class SpawnEntityPacketListener implements PluginMessageListener { List entries = friendlyByteBuf.readCollection(FriendlyByteBuf.limitValue(ArrayList::new, 1000), buf -> new SpawnEntry(buf.readUUID(), buf.readDouble(), buf.readDouble(), buf.readDouble(), buf.readFloat(), buf.readFloat(), - buf.readNullable(buffer -> buffer.readUUID()), ViaVersionHelper.readTagUnknown(buf, player))); + buf.readNullable(buffer -> buffer.readUUID()), UnknownVersionHelper.readTagUnknown(buf, player))); ServerLevel serverLevel = ((CraftWorld)player.getWorld()).getHandle(); diff --git a/src/main/java/com/moulberry/axiom/viaversion/UnknownVersionHelper.java b/src/main/java/com/moulberry/axiom/viaversion/UnknownVersionHelper.java new file mode 100644 index 0000000..aaa7dca --- /dev/null +++ b/src/main/java/com/moulberry/axiom/viaversion/UnknownVersionHelper.java @@ -0,0 +1,34 @@ +package com.moulberry.axiom.viaversion; + +import com.moulberry.axiom.AxiomPaper; +import net.minecraft.nbt.CompoundTag; +import net.minecraft.network.FriendlyByteBuf; +import org.bukkit.entity.Player; + +public class UnknownVersionHelper { + + public static void skipTagUnknown(FriendlyByteBuf friendlyByteBuf, Player player) { + if (AxiomPaper.PLUGIN.isMismatchedDataVersion(player.getUniqueId())) { + try { + ViaVersionHelper.skipTagViaVersion(friendlyByteBuf, player); + } catch (Exception e) { + throw new RuntimeException(e); + } + } else { + friendlyByteBuf.readNbt(); // Discard + } + } + + public static CompoundTag readTagUnknown(FriendlyByteBuf friendlyByteBuf, Player player) { + if (AxiomPaper.PLUGIN.isMismatchedDataVersion(player.getUniqueId())) { + try { + return ViaVersionHelper.readTagViaVersion(friendlyByteBuf, player); + } catch (Exception e) { + throw new RuntimeException(e); + } + } else { + return friendlyByteBuf.readNbt(); + } + } + +} diff --git a/src/main/java/com/moulberry/axiom/viaversion/ViaVersionHelper.java b/src/main/java/com/moulberry/axiom/viaversion/ViaVersionHelper.java index d3cafab..cfd0685 100644 --- a/src/main/java/com/moulberry/axiom/viaversion/ViaVersionHelper.java +++ b/src/main/java/com/moulberry/axiom/viaversion/ViaVersionHelper.java @@ -6,9 +6,7 @@ import com.viaversion.viaversion.api.Via; import com.viaversion.viaversion.api.data.MappingData; import com.viaversion.viaversion.api.data.Mappings; import com.viaversion.viaversion.api.protocol.ProtocolPathEntry; -import com.viaversion.viaversion.api.protocol.version.ProtocolVersion; import com.viaversion.viaversion.api.type.Type; -import io.netty.buffer.ByteBuf; import io.netty.buffer.Unpooled; import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap; import net.minecraft.SharedConstants; @@ -65,7 +63,7 @@ public class ViaVersionHelper { return mapper; } - public static IdMapper applyMappings(IdMapper registry, Mappings mappings) { + private static IdMapper applyMappings(IdMapper registry, Mappings mappings) { IdMapper newBlockRegistry = new IdMapper<>(); // Add empty mappings for non-existent blocks @@ -95,38 +93,20 @@ public class ViaVersionHelper { return newBlockRegistry; } - private static final int UNNAMED_COMPOUND_TAG_CHANGE_VERSION = ProtocolVersion.v1_20_2.getVersion(); + private static final int UNNAMED_COMPOUND_TAG_CHANGE_VERSION = 764; // 1.20.2 - public static void skipTagUnknown(FriendlyByteBuf friendlyByteBuf, Player player) { - if (AxiomPaper.PLUGIN.isMismatchedDataVersion(player.getUniqueId())) { - int playerVersion = Via.getAPI().getPlayerVersion(player.getUniqueId()); - try { - ViaVersionHelper.skipTagViaVersion(friendlyByteBuf, playerVersion); - } catch (Exception e) { - throw new RuntimeException(e); - } - } else { - friendlyByteBuf.readNbt(); // Discard - } - } - - public static CompoundTag readTagUnknown(FriendlyByteBuf friendlyByteBuf, Player player) { - if (AxiomPaper.PLUGIN.isMismatchedDataVersion(player.getUniqueId())) { - int playerVersion = Via.getAPI().getPlayerVersion(player.getUniqueId()); - try { - return ViaVersionHelper.readTagViaVersion(friendlyByteBuf, playerVersion); - } catch (Exception e) { - throw new RuntimeException(e); - } - } else { - return friendlyByteBuf.readNbt(); - } + public static void skipTagViaVersion(FriendlyByteBuf friendlyByteBuf, Player player) throws Exception { + skipTagViaVersion(friendlyByteBuf, Via.getAPI().getPlayerVersion(player.getUniqueId())); } public static void skipTagViaVersion(FriendlyByteBuf friendlyByteBuf, int playerVersion) throws Exception { getTagType(playerVersion).read(friendlyByteBuf); } + public static CompoundTag readTagViaVersion(FriendlyByteBuf friendlyByteBuf, Player player) throws Exception { + return readTagViaVersion(friendlyByteBuf, Via.getAPI().getPlayerVersion(player.getUniqueId())); + } + public static CompoundTag readTagViaVersion(FriendlyByteBuf friendlyByteBuf, int playerVersion) throws Exception { Type from = getTagType(playerVersion); Type to = getTagType(SharedConstants.getProtocolVersion()); @@ -150,9 +130,9 @@ public class ViaVersionHelper { } com.viaversion.viaversion.libs.opennbt.tag.builtin.CompoundTag tag = from.read(friendlyByteBuf); - ByteBuf buffer = Unpooled.buffer(); + FriendlyByteBuf buffer = new FriendlyByteBuf(Unpooled.buffer()); to.write(buffer, tag); - return new FriendlyByteBuf(buffer).readNbt(); + return buffer.readNbt(); } } From 37788e270385f8c39a880215931eec604250c07e Mon Sep 17 00:00:00 2001 From: Moulberry Date: Wed, 8 May 2024 18:59:20 +0800 Subject: [PATCH 12/22] Bump version to 11 --- build.gradle.kts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.gradle.kts b/build.gradle.kts index 4ca6b26..41c1833 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -8,7 +8,7 @@ plugins { } group = "com.moulberry.axiom" -version = "1.5.10" +version = "1.5.11" description = "Serverside component for Axiom on Paper" java { From cd8b5c534607cc59fd93425795741d106fde398f Mon Sep 17 00:00:00 2001 From: Moulberry Date: Fri, 10 May 2024 02:34:28 +0800 Subject: [PATCH 13/22] Attempt to support ViaVersion on the proxy by looking up player version from the data version --- .../java/com/moulberry/axiom/AxiomPaper.java | 16 ++++---- .../axiom/packet/HelloPacketListener.java | 39 ++++++++++++------- .../axiom/viaversion/ViaVersionHelper.java | 4 +- 3 files changed, 36 insertions(+), 23 deletions(-) diff --git a/src/main/java/com/moulberry/axiom/AxiomPaper.java b/src/main/java/com/moulberry/axiom/AxiomPaper.java index 6c782c6..ad423ed 100644 --- a/src/main/java/com/moulberry/axiom/AxiomPaper.java +++ b/src/main/java/com/moulberry/axiom/AxiomPaper.java @@ -9,7 +9,6 @@ import com.moulberry.axiom.event.AxiomModifyWorldEvent; import com.moulberry.axiom.integration.plotsquared.PlotSquaredIntegration; import com.moulberry.axiom.packet.*; import com.moulberry.axiom.world_properties.server.ServerWorldPropertiesRegistry; -import io.netty.buffer.ByteBuf; import io.netty.buffer.Unpooled; import io.netty.channel.Channel; import io.papermc.paper.event.player.PlayerFailMoveEvent; @@ -17,13 +16,11 @@ import io.papermc.paper.event.world.WorldGameRuleChangeEvent; import io.papermc.paper.network.ChannelInitializeListener; import io.papermc.paper.network.ChannelInitializeListenerHolder; import net.kyori.adventure.key.Key; +import net.minecraft.SharedConstants; import net.minecraft.core.BlockPos; import net.minecraft.core.IdMapper; import net.minecraft.network.*; -import net.minecraft.network.protocol.Packet; -import net.minecraft.network.protocol.PacketFlow; import net.minecraft.network.protocol.common.ServerboundCustomPayloadPacket; -import net.minecraft.network.protocol.common.custom.CustomPacketPayload; import net.minecraft.network.protocol.common.custom.DiscardedPayload; import net.minecraft.network.protocol.game.GameProtocols; import net.minecraft.network.protocol.game.ServerGamePacketListener; @@ -45,7 +42,6 @@ import org.incendo.cloud.execution.ExecutionCoordinator; import org.incendo.cloud.paper.PaperCommandManager; import org.jetbrains.annotations.Nullable; -import java.io.FileReader; import java.io.IOException; import java.nio.file.Files; import java.nio.file.Path; @@ -60,7 +56,7 @@ public class AxiomPaper extends JavaPlugin implements Listener { public final Map playerBlockBufferRateLimiters = new ConcurrentHashMap<>(); public final Map playerRestrictions = new ConcurrentHashMap<>(); public final Map> playerBlockRegistry = new ConcurrentHashMap<>(); - public final Set mismatchedDataVersionUsingViaVersion = Collections.newSetFromMap(new ConcurrentHashMap<>()); + public final Map playerProtocolVersion = new ConcurrentHashMap<>(); public Configuration configuration; public IdMapper allowedBlockRegistry = null; @@ -273,7 +269,7 @@ public class AxiomPaper extends JavaPlugin implements Listener { playerBlockBufferRateLimiters.keySet().retainAll(stillActiveAxiomPlayers); playerRestrictions.keySet().retainAll(stillActiveAxiomPlayers); playerBlockRegistry.keySet().retainAll(stillActiveAxiomPlayers); - mismatchedDataVersionUsingViaVersion.retainAll(stillActiveAxiomPlayers); + playerProtocolVersion.keySet().retainAll(stillActiveAxiomPlayers); }, 20, 20); boolean sendMarkers = configuration.getBoolean("send-markers"); @@ -317,7 +313,11 @@ public class AxiomPaper extends JavaPlugin implements Listener { } public boolean isMismatchedDataVersion(UUID uuid) { - return this.mismatchedDataVersionUsingViaVersion.contains(uuid); + return this.playerProtocolVersion.containsKey(uuid); + } + + public int getProtocolVersionFor(UUID uuid) { + return this.playerProtocolVersion.getOrDefault(uuid, SharedConstants.getProtocolVersion()); } public IdMapper getBlockRegistry(UUID uuid) { diff --git a/src/main/java/com/moulberry/axiom/packet/HelloPacketListener.java b/src/main/java/com/moulberry/axiom/packet/HelloPacketListener.java index 0bdfcac..9d52748 100644 --- a/src/main/java/com/moulberry/axiom/packet/HelloPacketListener.java +++ b/src/main/java/com/moulberry/axiom/packet/HelloPacketListener.java @@ -9,18 +9,12 @@ import com.moulberry.axiom.persistence.UUIDDataType; import com.moulberry.axiom.viaversion.ViaVersionHelper; import com.moulberry.axiom.world_properties.server.ServerWorldPropertiesRegistry; import com.viaversion.viaversion.api.Via; -import com.viaversion.viaversion.api.data.*; -import com.viaversion.viaversion.api.protocol.ProtocolPathEntry; import com.viaversion.viaversion.api.protocol.version.ProtocolVersion; -import com.viaversion.viaversion.api.type.ByteBufReader; -import com.viaversion.viaversion.api.type.Type; -import com.viaversion.viaversion.libs.opennbt.tag.builtin.CompoundTag; import io.netty.buffer.Unpooled; import net.kyori.adventure.text.Component; import net.kyori.adventure.text.format.NamedTextColor; import net.minecraft.SharedConstants; import net.minecraft.core.IdMapper; -import net.minecraft.nbt.NbtIo; import net.minecraft.network.FriendlyByteBuf; import net.minecraft.network.RegistryFriendlyByteBuf; import net.minecraft.server.MinecraftServer; @@ -38,7 +32,6 @@ import org.bukkit.plugin.messaging.PluginMessageListener; import org.jetbrains.annotations.NotNull; import java.util.List; -import java.util.Set; import java.util.UUID; public class HelloPacketListener implements PluginMessageListener { @@ -73,19 +66,39 @@ public class HelloPacketListener implements PluginMessageListener { String incompatibleDataVersion = plugin.configuration.getString("incompatible-data-version"); if (incompatibleDataVersion == null) incompatibleDataVersion = "warn"; - if (!Bukkit.getPluginManager().isPluginEnabled("ViaVersion")) { - Component text = Component.text("Axiom: Incompatible data version detected (client " + dataVersion + - ", server " + serverDataVersion + ")"); + Component incompatibleWarning = Component.text("Axiom: Incompatible data version detected (client " + dataVersion + + ", server " + serverDataVersion + ")"); + if (!Bukkit.getPluginManager().isPluginEnabled("ViaVersion")) { if (incompatibleDataVersion.equals("warn")) { - player.sendMessage(text.color(NamedTextColor.RED)); + player.sendMessage(incompatibleWarning.color(NamedTextColor.RED)); return; } else if (!incompatibleDataVersion.equals("ignore")) { - player.kick(text); + player.kick(incompatibleWarning); return; } } else { int playerVersion = Via.getAPI().getPlayerVersion(player.getUniqueId()); + if (playerVersion == SharedConstants.getProtocolVersion()) { + // Likely using via on the proxy, try to get protocol version from data version + if (dataVersion < 3337) { + player.sendMessage(incompatibleWarning.color(NamedTextColor.RED)); + return; + } else if (dataVersion == 3337) { + playerVersion = 762; // 1.19.4 + } else if (dataVersion <= 3465) { + playerVersion = 763; // 1.20.1 + } else if (dataVersion <= 3578) { + playerVersion = 764; // 1.20.2 + } else if (dataVersion <= 3700) { + playerVersion = 765; // 1.20.3 / 1.20.4 + } else if (dataVersion <= 3837) { + playerVersion = 766; // 1.20.3 / 1.20.4 + } else { + player.sendMessage(incompatibleWarning.color(NamedTextColor.RED)); + return; + } + } IdMapper mapper; try { @@ -105,7 +118,7 @@ public class HelloPacketListener implements PluginMessageListener { } this.plugin.playerBlockRegistry.put(player.getUniqueId(), mapper); - this.plugin.mismatchedDataVersionUsingViaVersion.add(player.getUniqueId()); + this.plugin.playerProtocolVersion.put(player.getUniqueId(), playerVersion); Component text = Component.text("Axiom: Warning, client and server versions don't match. " + "Axiom will try to use ViaVersion conversions, but this process may cause problems"); diff --git a/src/main/java/com/moulberry/axiom/viaversion/ViaVersionHelper.java b/src/main/java/com/moulberry/axiom/viaversion/ViaVersionHelper.java index cfd0685..896d313 100644 --- a/src/main/java/com/moulberry/axiom/viaversion/ViaVersionHelper.java +++ b/src/main/java/com/moulberry/axiom/viaversion/ViaVersionHelper.java @@ -96,7 +96,7 @@ public class ViaVersionHelper { private static final int UNNAMED_COMPOUND_TAG_CHANGE_VERSION = 764; // 1.20.2 public static void skipTagViaVersion(FriendlyByteBuf friendlyByteBuf, Player player) throws Exception { - skipTagViaVersion(friendlyByteBuf, Via.getAPI().getPlayerVersion(player.getUniqueId())); + skipTagViaVersion(friendlyByteBuf, AxiomPaper.PLUGIN.getProtocolVersionFor(player.getUniqueId())); } public static void skipTagViaVersion(FriendlyByteBuf friendlyByteBuf, int playerVersion) throws Exception { @@ -104,7 +104,7 @@ public class ViaVersionHelper { } public static CompoundTag readTagViaVersion(FriendlyByteBuf friendlyByteBuf, Player player) throws Exception { - return readTagViaVersion(friendlyByteBuf, Via.getAPI().getPlayerVersion(player.getUniqueId())); + return readTagViaVersion(friendlyByteBuf, AxiomPaper.PLUGIN.getProtocolVersionFor(player.getUniqueId())); } public static CompoundTag readTagViaVersion(FriendlyByteBuf friendlyByteBuf, int playerVersion) throws Exception { From 85469fcf3d0ff6d8ce5ad9f5383a5ea2ff4c45e5 Mon Sep 17 00:00:00 2001 From: Joshua Castle <26531652+Kas-tle@users.noreply.github.com> Date: Sat, 18 May 2024 23:56:11 -0700 Subject: [PATCH 14/22] CoreProtect Integration Signed-off-by: Joshua Castle <26531652+Kas-tle@users.noreply.github.com> --- .gitignore | 3 + build.gradle.kts | 28 +++--- gradle/libs.versions.toml | 32 ++++++ .../java/com/moulberry/axiom/AxiomPaper.java | 9 +- .../coreprotect/CoreProtectIntegration.java | 60 +++++++++++ .../CoreProtectIntegrationImpl.java | 99 +++++++++++++++++++ .../packet/SetBlockBufferPacketListener.java | 4 + .../axiom/packet/SetBlockPacketListener.java | 7 ++ src/main/resources/plugin.yml | 1 + 9 files changed, 229 insertions(+), 14 deletions(-) create mode 100644 gradle/libs.versions.toml create mode 100644 src/main/java/com/moulberry/axiom/integration/coreprotect/CoreProtectIntegration.java create mode 100644 src/main/java/com/moulberry/axiom/integration/coreprotect/CoreProtectIntegrationImpl.java diff --git a/.gitignore b/.gitignore index 621429a..e0e1035 100644 --- a/.gitignore +++ b/.gitignore @@ -15,6 +15,9 @@ out/ plugin/bin/ api/bin/ +# VSCode +.vscode/ + # Compiled class file *.class diff --git a/build.gradle.kts b/build.gradle.kts index 41c1833..ad9212f 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -1,10 +1,10 @@ plugins { `java-library` - id("io.papermc.paperweight.userdev") version "1.6.3" - id("xyz.jpenilla.run-paper") version "2.2.4" // Adds runServer and runMojangMappedServer tasks for testing + alias(libs.plugins.paperweight.userdev) + alias(libs.plugins.run.paper) // Adds runServer and runMojangMappedServer tasks for testing // Shades and relocates dependencies into our plugin jar. See https://imperceptiblethoughts.com/shadow/introduction/ - id("io.github.goooler.shadow") version "8.1.7" + alias(libs.plugins.shadow) } group = "com.moulberry.axiom" @@ -23,26 +23,30 @@ repositories { maven("https://jitpack.io") maven("https://repo.papermc.io/repository/maven-public/") maven("https://maven.enginehub.org/repo/") + maven("https://maven.playpro.com") } dependencies { - paperweight.paperDevBundle("1.20.6-R0.1-SNAPSHOT") - implementation("xyz.jpenilla:reflection-remapper:0.1.0-SNAPSHOT") - implementation("org.incendo:cloud-paper:2.0.0-SNAPSHOT") + paperweight.paperDevBundle(libs.versions.paper) + implementation(libs.reflection.remapper) + implementation(libs.cloud.paper) // Zstd Compression Library - implementation("com.github.luben:zstd-jni:1.5.5-4") + implementation(libs.zstd.jni) // ViaVersion support - compileOnly("com.viaversion:viaversion-api:4.10.1-SNAPSHOT") + compileOnly(libs.viaversion.api) // WorldGuard support - compileOnly("com.sk89q.worldguard:worldguard-bukkit:7.1.0-SNAPSHOT") + compileOnly(libs.worldguard.bukkit) // PlotSquared support - implementation(platform("com.intellectualsites.bom:bom-newest:1.37")) - compileOnly("com.intellectualsites.plotsquared:plotsquared-core") - compileOnly("com.intellectualsites.plotsquared:plotsquared-bukkit") { isTransitive = false } + implementation(platform(libs.bom.newest)) + compileOnly(libs.plotsquared.core) + compileOnly(libs.plotsquared.bukkit) { isTransitive = false } + + // CoreProtect support + compileOnly(libs.coreprotect) } tasks { diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml new file mode 100644 index 0000000..3939ced --- /dev/null +++ b/gradle/libs.versions.toml @@ -0,0 +1,32 @@ +[versions] +# Dependencies +bom-newest = "1.37" +cloud-paper = "2.0.0-20240516.054251-69" +coreprotect = "22.4" +paper = "1.20.6-R0.1-SNAPSHOT" +plotsquared = "7.3.9-20240513.192211-13" +reflection-remapper = "0.1.2-20240315.033304-2" +viaversion-api = "4.10.1-20240505.124211-22" +worldguard-bukkit = "7.1.0-20240503.180049-12" +zstd-jni = "1.5.5-4" + +# Plugins +paperweight-userdev = "1.7.1" +run-paper = "2.2.4" +shadow = "8.1.7" + +[libraries] +bom-newest = { group = "com.intellectualsites.bom", name = "bom-newest", version.ref = "bom-newest" } +cloud-paper = { group = "org.incendo", name = "cloud-paper", version.ref = "cloud-paper" } +coreprotect = { group = "net.coreprotect", name = "coreprotect", version.ref = "coreprotect" } +plotsquared-bukkit = { group = "com.intellectualsites.plotsquared", name = "plotsquared-bukkit", version.ref = "plotsquared" } +plotsquared-core = { group = "com.intellectualsites.plotsquared", name = "plotsquared-core", version.ref = "plotsquared" } +reflection-remapper = { group = "xyz.jpenilla", name = "reflection-remapper", version.ref = "reflection-remapper" } +viaversion-api = { group = "com.viaversion", name = "viaversion-api", version.ref = "viaversion-api" } +worldguard-bukkit = { group = "com.sk89q.worldguard", name = "worldguard-bukkit", version.ref = "worldguard-bukkit" } +zstd-jni = { group = "com.github.luben", name = "zstd-jni", version = "1.5.5-4" } + +[plugins] +paperweight-userdev = { id = "io.papermc.paperweight.userdev", version.ref = "paperweight-userdev" } +run-paper = { id = "xyz.jpenilla.run-paper", version.ref = "run-paper" } +shadow = { id = "io.github.goooler.shadow", version.ref = "shadow" } \ No newline at end of file diff --git a/src/main/java/com/moulberry/axiom/AxiomPaper.java b/src/main/java/com/moulberry/axiom/AxiomPaper.java index ad423ed..2b5c20c 100644 --- a/src/main/java/com/moulberry/axiom/AxiomPaper.java +++ b/src/main/java/com/moulberry/axiom/AxiomPaper.java @@ -6,6 +6,7 @@ import com.moulberry.axiom.buffer.CompressedBlockEntity; import com.moulberry.axiom.commands.AxiomDebugCommand; import com.moulberry.axiom.event.AxiomCreateWorldPropertiesEvent; import com.moulberry.axiom.event.AxiomModifyWorldEvent; +import com.moulberry.axiom.integration.coreprotect.CoreProtectIntegration; import com.moulberry.axiom.integration.plotsquared.PlotSquaredIntegration; import com.moulberry.axiom.packet.*; import com.moulberry.axiom.world_properties.server.ServerWorldPropertiesRegistry; @@ -39,7 +40,7 @@ import org.bukkit.plugin.messaging.Messenger; import org.checkerframework.checker.nullness.qual.NonNull; import org.incendo.cloud.bukkit.CloudBukkitCapabilities; import org.incendo.cloud.execution.ExecutionCoordinator; -import org.incendo.cloud.paper.PaperCommandManager; +import org.incendo.cloud.paper.LegacyPaperCommandManager; import org.jetbrains.annotations.Nullable; import java.io.IOException; @@ -281,7 +282,7 @@ public class AxiomPaper extends JavaPlugin implements Listener { }, 1, 1); try { - PaperCommandManager manager = PaperCommandManager.createNative( + LegacyPaperCommandManager manager = LegacyPaperCommandManager.createNative( this, ExecutionCoordinator.simpleCoordinator() ); @@ -294,6 +295,10 @@ public class AxiomPaper extends JavaPlugin implements Listener { } catch (Exception e) { e.printStackTrace(); } + + if (CoreProtectIntegration.isEnabled()) { + this.getLogger().info("CoreProtect integration enabled"); + } } public boolean logLargeBlockBufferChanges() { diff --git a/src/main/java/com/moulberry/axiom/integration/coreprotect/CoreProtectIntegration.java b/src/main/java/com/moulberry/axiom/integration/coreprotect/CoreProtectIntegration.java new file mode 100644 index 0000000..3bba2e7 --- /dev/null +++ b/src/main/java/com/moulberry/axiom/integration/coreprotect/CoreProtectIntegration.java @@ -0,0 +1,60 @@ +package com.moulberry.axiom.integration.coreprotect; + +import net.minecraft.core.BlockPos; +import net.minecraft.world.level.Level; +import net.minecraft.world.level.block.state.BlockState; +import org.bukkit.craftbukkit.CraftWorld; + +public class CoreProtectIntegration { + public static boolean isEnabled() { + return CoreProtectIntegrationImpl.isEnabled(); + } + + public static boolean logPlacement(String name, BlockState blockState, CraftWorld world, BlockPos pos) { + if (!CoreProtectIntegrationImpl.isEnabled()) { + return false; + } + + return CoreProtectIntegrationImpl.logPlacement(name, blockState, world, pos); + } + + public static boolean logPlacement(String name, BlockState blockState, CraftWorld world, int x, int y, int z) { + if (!CoreProtectIntegrationImpl.isEnabled()) { + return false; + } + + return CoreProtectIntegrationImpl.logPlacement(name, blockState, world, x, y, z); + } + + public static boolean logPlacement(String name, Level level, CraftWorld world, BlockPos pos) { + if (!CoreProtectIntegrationImpl.isEnabled()) { + return false; + } + + return CoreProtectIntegrationImpl.logPlacement(name, level, world, pos); + } + + public static boolean logRemoval(String name, BlockState blockState, CraftWorld world, BlockPos pos) { + if (!CoreProtectIntegrationImpl.isEnabled()) { + return false; + } + + return CoreProtectIntegrationImpl.logRemoval(name, blockState, world, pos); + } + + public static boolean logRemoval(String name, BlockState blockState, CraftWorld world, int x, int y, int z) { + if (!CoreProtectIntegrationImpl.isEnabled()) { + return false; + } + + return CoreProtectIntegrationImpl.logRemoval(name, blockState, world, x, y, z); + } + + public static boolean logRemoval(String name, Level level, CraftWorld world, BlockPos pos) { + if (!CoreProtectIntegrationImpl.isEnabled()) { + return false; + } + + return CoreProtectIntegrationImpl.logRemoval(name, level, world, pos); + } +} \ No newline at end of file diff --git a/src/main/java/com/moulberry/axiom/integration/coreprotect/CoreProtectIntegrationImpl.java b/src/main/java/com/moulberry/axiom/integration/coreprotect/CoreProtectIntegrationImpl.java new file mode 100644 index 0000000..571d90b --- /dev/null +++ b/src/main/java/com/moulberry/axiom/integration/coreprotect/CoreProtectIntegrationImpl.java @@ -0,0 +1,99 @@ +package com.moulberry.axiom.integration.coreprotect; + +import com.moulberry.axiom.AxiomPaper; +import net.coreprotect.CoreProtect; +import net.coreprotect.CoreProtectAPI; +import net.minecraft.core.BlockPos; +import net.minecraft.world.level.Level; +import net.minecraft.world.level.block.state.BlockState; +import org.bukkit.Bukkit; +import org.bukkit.World; +import org.bukkit.craftbukkit.CraftWorld; +import org.bukkit.craftbukkit.block.CraftBlockState; +import org.bukkit.plugin.Plugin; + +import java.lang.reflect.Constructor; +import java.lang.reflect.InvocationTargetException; + +public class CoreProtectIntegrationImpl { + private static final CoreProtectAPI COREPROTECT_API; + private static final boolean COREPROTECT_ENABLED; + private static final Constructor CRAFT_BLOCK_STATE_CONSTRUCTOR; + + static { + COREPROTECT_API = getCoreProtect(); + Constructor constructor = null; + + if (COREPROTECT_API != null) { + try { + constructor = CraftBlockState.class.getDeclaredConstructor(World.class, BlockPos.class, BlockState.class); + constructor.setAccessible(true); + } catch (NoSuchMethodException | SecurityException e) { + AxiomPaper.PLUGIN.getLogger().warning("Failed to get CraftBlockState constructor for CoreProtect: " + e); + } + } + + CRAFT_BLOCK_STATE_CONSTRUCTOR = constructor; + COREPROTECT_ENABLED = COREPROTECT_API != null && CRAFT_BLOCK_STATE_CONSTRUCTOR != null; + } + + private static CoreProtectAPI getCoreProtect() { + Plugin plugin = Bukkit.getPluginManager().getPlugin("CoreProtect"); + + if (plugin == null || !(plugin instanceof CoreProtect)) { + return null; + } + + CoreProtectAPI coreProtect = ((CoreProtect) plugin).getAPI(); + if (coreProtect.isEnabled() == false) { + return null; + } + + if (coreProtect.APIVersion() < 10) { + return null; + } + + return coreProtect; + } + + private static CraftBlockState createCraftBlockState(World world, BlockPos pos, BlockState blockState) { + try { + return (CraftBlockState) CRAFT_BLOCK_STATE_CONSTRUCTOR.newInstance(world, pos, blockState); + } catch (InstantiationException | IllegalAccessException | IllegalArgumentException | InvocationTargetException e) { + AxiomPaper.PLUGIN.getLogger().warning("Failed to create CraftBlockState for CoreProtect: " + e); + return null; + } + } + + static boolean isEnabled() { + return COREPROTECT_ENABLED; + } + + static boolean logPlacement(String name, BlockState blockState, CraftWorld world, BlockPos pos) { + if (blockState.isAir()) { + return false; + } + + return COREPROTECT_API.logPlacement(name, createCraftBlockState(world, pos, blockState)); + } + + static boolean logPlacement(String name, BlockState blockState, CraftWorld world, int x, int y, int z) { + return logPlacement(name, blockState, world, new BlockPos(x, y, z)); + } + + static boolean logPlacement(String name, Level level, CraftWorld world, BlockPos pos) { + return logPlacement(name, level.getBlockState(pos), world, pos); + } + + static boolean logRemoval(String name, BlockState blockState, CraftWorld world, BlockPos pos) { + return COREPROTECT_API.logRemoval(name, createCraftBlockState(world, pos, blockState)); + } + + static boolean logRemoval(String name, BlockState blockState, CraftWorld world, int x, int y, int z) { + return logRemoval(name, blockState, world, new BlockPos(x, y, z)); + } + + static boolean logRemoval(String name, Level level, CraftWorld world, BlockPos pos) { + return logRemoval(name, level.getBlockState(pos), world, pos); + } +} \ No newline at end of file diff --git a/src/main/java/com/moulberry/axiom/packet/SetBlockBufferPacketListener.java b/src/main/java/com/moulberry/axiom/packet/SetBlockBufferPacketListener.java index 4e45325..844fe9d 100644 --- a/src/main/java/com/moulberry/axiom/packet/SetBlockBufferPacketListener.java +++ b/src/main/java/com/moulberry/axiom/packet/SetBlockBufferPacketListener.java @@ -8,6 +8,7 @@ import com.moulberry.axiom.buffer.BlockBuffer; import com.moulberry.axiom.buffer.CompressedBlockEntity; import com.moulberry.axiom.integration.Integration; import com.moulberry.axiom.integration.SectionPermissionChecker; +import com.moulberry.axiom.integration.coreprotect.CoreProtectIntegration; import com.moulberry.axiom.viaversion.UnknownVersionHelper; import it.unimi.dsi.fastutil.longs.Long2ObjectMap; import it.unimi.dsi.fastutil.shorts.Short2ObjectMap; @@ -220,6 +221,9 @@ public class SetBlockBufferPacketListener { BlockState old = section.setBlockState(x, y, z, blockState, true); if (blockState != old) { + CoreProtectIntegration.logRemoval(player.getBukkitEntity().getName(), old, world.getWorld(), bx, by, bz); + CoreProtectIntegration.logPlacement(player.getBukkitEntity().getName(), blockState, world.getWorld(), bx, by, bz); + sectionChanged = true; blockPos.set(bx, by, bz); diff --git a/src/main/java/com/moulberry/axiom/packet/SetBlockPacketListener.java b/src/main/java/com/moulberry/axiom/packet/SetBlockPacketListener.java index 98b289e..8305e01 100644 --- a/src/main/java/com/moulberry/axiom/packet/SetBlockPacketListener.java +++ b/src/main/java/com/moulberry/axiom/packet/SetBlockPacketListener.java @@ -3,6 +3,7 @@ package com.moulberry.axiom.packet; import com.google.common.collect.Maps; import com.moulberry.axiom.AxiomPaper; import com.moulberry.axiom.integration.Integration; +import com.moulberry.axiom.integration.coreprotect.CoreProtectIntegration; import com.moulberry.axiom.integration.plotsquared.PlotSquaredIntegration; import io.netty.buffer.Unpooled; import net.kyori.adventure.text.Component; @@ -158,8 +159,11 @@ public class SetBlockPacketListener implements PluginMessageListener { continue; } + CoreProtectIntegration.logRemoval(bukkitPlayer.getName(), player.level(), world, blockPos); + // Place block player.level().setBlock(blockPos, blockState, 3); + CoreProtectIntegration.logPlacement(bukkitPlayer.getName(), blockState, world, blockPos); } } else { int count = 0; @@ -221,6 +225,9 @@ public class SetBlockPacketListener implements PluginMessageListener { BlockState old = section.setBlockState(x, y, z, blockState, true); if (blockState != old) { + CoreProtectIntegration.logRemoval(bukkitPlayer.getName(), old, world, blockPos); + CoreProtectIntegration.logPlacement(bukkitPlayer.getName(), blockState, world, blockPos); + Block block = blockState.getBlock(); motionBlocking.update(x, by, z, blockState); motionBlockingNoLeaves.update(x, by, z, blockState); diff --git a/src/main/resources/plugin.yml b/src/main/resources/plugin.yml index 2531c61..8e00fc0 100644 --- a/src/main/resources/plugin.yml +++ b/src/main/resources/plugin.yml @@ -5,6 +5,7 @@ description: $description authors: - Moulberry api-version: "$apiVersion" +softdepend: ["CoreProtect"] permissions: axiom.*: description: Allows use of all default Axiom features From 632a17e1125939fdb44c6168159ab2f7790f6062 Mon Sep 17 00:00:00 2001 From: Moulberry Date: Sun, 19 May 2024 16:13:40 +0800 Subject: [PATCH 15/22] Clean up CoreProtect integration --- .../coreprotect/CoreProtectIntegration.java | 47 ++++--------------- .../CoreProtectIntegrationImpl.java | 34 ++++---------- .../packet/SetBlockBufferPacketListener.java | 11 +++-- .../axiom/packet/SetBlockPacketListener.java | 16 +++++-- 4 files changed, 37 insertions(+), 71 deletions(-) diff --git a/src/main/java/com/moulberry/axiom/integration/coreprotect/CoreProtectIntegration.java b/src/main/java/com/moulberry/axiom/integration/coreprotect/CoreProtectIntegration.java index 3bba2e7..60d43ec 100644 --- a/src/main/java/com/moulberry/axiom/integration/coreprotect/CoreProtectIntegration.java +++ b/src/main/java/com/moulberry/axiom/integration/coreprotect/CoreProtectIntegration.java @@ -9,52 +9,21 @@ public class CoreProtectIntegration { public static boolean isEnabled() { return CoreProtectIntegrationImpl.isEnabled(); } - - public static boolean logPlacement(String name, BlockState blockState, CraftWorld world, BlockPos pos) { + + public static void logPlacement(String name, BlockState blockState, CraftWorld world, BlockPos pos) { if (!CoreProtectIntegrationImpl.isEnabled()) { - return false; + return; } - return CoreProtectIntegrationImpl.logPlacement(name, blockState, world, pos); + CoreProtectIntegrationImpl.logPlacement(name, blockState, world, pos); } - public static boolean logPlacement(String name, BlockState blockState, CraftWorld world, int x, int y, int z) { + public static void logRemoval(String name, BlockState blockState, CraftWorld world, BlockPos pos) { if (!CoreProtectIntegrationImpl.isEnabled()) { - return false; - } - - return CoreProtectIntegrationImpl.logPlacement(name, blockState, world, x, y, z); - } - - public static boolean logPlacement(String name, Level level, CraftWorld world, BlockPos pos) { - if (!CoreProtectIntegrationImpl.isEnabled()) { - return false; + return; } - return CoreProtectIntegrationImpl.logPlacement(name, level, world, pos); + CoreProtectIntegrationImpl.logRemoval(name, blockState, world, pos); } - public static boolean logRemoval(String name, BlockState blockState, CraftWorld world, BlockPos pos) { - if (!CoreProtectIntegrationImpl.isEnabled()) { - return false; - } - - return CoreProtectIntegrationImpl.logRemoval(name, blockState, world, pos); - } - - public static boolean logRemoval(String name, BlockState blockState, CraftWorld world, int x, int y, int z) { - if (!CoreProtectIntegrationImpl.isEnabled()) { - return false; - } - - return CoreProtectIntegrationImpl.logRemoval(name, blockState, world, x, y, z); - } - - public static boolean logRemoval(String name, Level level, CraftWorld world, BlockPos pos) { - if (!CoreProtectIntegrationImpl.isEnabled()) { - return false; - } - - return CoreProtectIntegrationImpl.logRemoval(name, level, world, pos); - } -} \ No newline at end of file +} diff --git a/src/main/java/com/moulberry/axiom/integration/coreprotect/CoreProtectIntegrationImpl.java b/src/main/java/com/moulberry/axiom/integration/coreprotect/CoreProtectIntegrationImpl.java index 571d90b..65fc3ec 100644 --- a/src/main/java/com/moulberry/axiom/integration/coreprotect/CoreProtectIntegrationImpl.java +++ b/src/main/java/com/moulberry/axiom/integration/coreprotect/CoreProtectIntegrationImpl.java @@ -4,7 +4,6 @@ import com.moulberry.axiom.AxiomPaper; import net.coreprotect.CoreProtect; import net.coreprotect.CoreProtectAPI; import net.minecraft.core.BlockPos; -import net.minecraft.world.level.Level; import net.minecraft.world.level.block.state.BlockState; import org.bukkit.Bukkit; import org.bukkit.World; @@ -40,12 +39,12 @@ public class CoreProtectIntegrationImpl { private static CoreProtectAPI getCoreProtect() { Plugin plugin = Bukkit.getPluginManager().getPlugin("CoreProtect"); - if (plugin == null || !(plugin instanceof CoreProtect)) { + if (!(plugin instanceof CoreProtect)) { return null; } CoreProtectAPI coreProtect = ((CoreProtect) plugin).getAPI(); - if (coreProtect.isEnabled() == false) { + if (!coreProtect.isEnabled()) { return null; } @@ -58,7 +57,7 @@ public class CoreProtectIntegrationImpl { private static CraftBlockState createCraftBlockState(World world, BlockPos pos, BlockState blockState) { try { - return (CraftBlockState) CRAFT_BLOCK_STATE_CONSTRUCTOR.newInstance(world, pos, blockState); + return CRAFT_BLOCK_STATE_CONSTRUCTOR.newInstance(world, pos, blockState); } catch (InstantiationException | IllegalAccessException | IllegalArgumentException | InvocationTargetException e) { AxiomPaper.PLUGIN.getLogger().warning("Failed to create CraftBlockState for CoreProtect: " + e); return null; @@ -69,31 +68,16 @@ public class CoreProtectIntegrationImpl { return COREPROTECT_ENABLED; } - static boolean logPlacement(String name, BlockState blockState, CraftWorld world, BlockPos pos) { + static void logPlacement(String name, BlockState blockState, CraftWorld world, BlockPos pos) { if (blockState.isAir()) { - return false; + return; } - return COREPROTECT_API.logPlacement(name, createCraftBlockState(world, pos, blockState)); + COREPROTECT_API.logPlacement(name, createCraftBlockState(world, pos, blockState)); } - static boolean logPlacement(String name, BlockState blockState, CraftWorld world, int x, int y, int z) { - return logPlacement(name, blockState, world, new BlockPos(x, y, z)); + static void logRemoval(String name, BlockState blockState, CraftWorld world, BlockPos pos) { + COREPROTECT_API.logRemoval(name, createCraftBlockState(world, pos, blockState)); } - static boolean logPlacement(String name, Level level, CraftWorld world, BlockPos pos) { - return logPlacement(name, level.getBlockState(pos), world, pos); - } - - static boolean logRemoval(String name, BlockState blockState, CraftWorld world, BlockPos pos) { - return COREPROTECT_API.logRemoval(name, createCraftBlockState(world, pos, blockState)); - } - - static boolean logRemoval(String name, BlockState blockState, CraftWorld world, int x, int y, int z) { - return logRemoval(name, blockState, world, new BlockPos(x, y, z)); - } - - static boolean logRemoval(String name, Level level, CraftWorld world, BlockPos pos) { - return logRemoval(name, level.getBlockState(pos), world, pos); - } -} \ No newline at end of file +} diff --git a/src/main/java/com/moulberry/axiom/packet/SetBlockBufferPacketListener.java b/src/main/java/com/moulberry/axiom/packet/SetBlockBufferPacketListener.java index 844fe9d..e2c8d27 100644 --- a/src/main/java/com/moulberry/axiom/packet/SetBlockBufferPacketListener.java +++ b/src/main/java/com/moulberry/axiom/packet/SetBlockBufferPacketListener.java @@ -221,9 +221,6 @@ public class SetBlockBufferPacketListener { BlockState old = section.setBlockState(x, y, z, blockState, true); if (blockState != old) { - CoreProtectIntegration.logRemoval(player.getBukkitEntity().getName(), old, world.getWorld(), bx, by, bz); - CoreProtectIntegration.logPlacement(player.getBukkitEntity().getName(), blockState, world.getWorld(), bx, by, bz); - sectionChanged = true; blockPos.set(bx, by, bz); @@ -291,6 +288,14 @@ public class SetBlockBufferPacketListener { } else if (old.hasBlockEntity()) { chunk.removeBlockEntity(blockPos); } + + if (CoreProtectIntegration.isEnabled() && old != blockState) { + String changedBy = player.getBukkitEntity().getName(); + BlockPos changedPos = new BlockPos(bx, by, bz); + + CoreProtectIntegration.logRemoval(changedBy, old, world.getWorld(), changedPos); + CoreProtectIntegration.logPlacement(changedBy, blockState, world.getWorld(), changedPos); + } } } } diff --git a/src/main/java/com/moulberry/axiom/packet/SetBlockPacketListener.java b/src/main/java/com/moulberry/axiom/packet/SetBlockPacketListener.java index 8305e01..860cb65 100644 --- a/src/main/java/com/moulberry/axiom/packet/SetBlockPacketListener.java +++ b/src/main/java/com/moulberry/axiom/packet/SetBlockPacketListener.java @@ -159,7 +159,10 @@ public class SetBlockPacketListener implements PluginMessageListener { continue; } - CoreProtectIntegration.logRemoval(bukkitPlayer.getName(), player.level(), world, blockPos); + if (CoreProtectIntegration.isEnabled()) { + BlockState old = player.level().getBlockState(blockPos); + CoreProtectIntegration.logRemoval(bukkitPlayer.getName(), old, world, blockPos); + } // Place block player.level().setBlock(blockPos, blockState, 3); @@ -225,9 +228,6 @@ public class SetBlockPacketListener implements PluginMessageListener { BlockState old = section.setBlockState(x, y, z, blockState, true); if (blockState != old) { - CoreProtectIntegration.logRemoval(bukkitPlayer.getName(), old, world, blockPos); - CoreProtectIntegration.logPlacement(bukkitPlayer.getName(), blockState, world, blockPos); - Block block = blockState.getBlock(); motionBlocking.update(x, by, z, blockState); motionBlockingNoLeaves.update(x, by, z, blockState); @@ -284,6 +284,14 @@ public class SetBlockPacketListener implements PluginMessageListener { if (oldPoi.isPresent()) level.getPoiManager().remove(blockPos); if (newPoi.isPresent()) level.getPoiManager().add(blockPos, newPoi.get()); } + + if (CoreProtectIntegration.isEnabled()) { + String changedBy = player.getBukkitEntity().getName(); + BlockPos changedPos = new BlockPos(bx, by, bz); + + CoreProtectIntegration.logRemoval(changedBy, old, world, changedPos); + CoreProtectIntegration.logPlacement(changedBy, blockState, world, changedPos); + } } boolean nowHasOnlyAir = section.hasOnlyAir(); From 26eb24f2084528a1b9dbd8daeea193cf2d2ec161 Mon Sep 17 00:00:00 2001 From: Moulberry Date: Sun, 26 May 2024 22:37:06 +0800 Subject: [PATCH 16/22] Use WeakReference in ServerWorldPropertiesRegistry --- src/main/java/com/moulberry/axiom/AxiomPaper.java | 3 ++- .../server/ServerWorldPropertiesRegistry.java | 12 +++++++++--- 2 files changed, 11 insertions(+), 4 deletions(-) diff --git a/src/main/java/com/moulberry/axiom/AxiomPaper.java b/src/main/java/com/moulberry/axiom/AxiomPaper.java index 2b5c20c..cccef8c 100644 --- a/src/main/java/com/moulberry/axiom/AxiomPaper.java +++ b/src/main/java/com/moulberry/axiom/AxiomPaper.java @@ -44,6 +44,7 @@ import org.incendo.cloud.paper.LegacyPaperCommandManager; import org.jetbrains.annotations.Nullable; import java.io.IOException; +import java.lang.ref.WeakReference; import java.nio.file.Files; import java.nio.file.Path; import java.util.*; @@ -400,7 +401,7 @@ public class AxiomPaper extends JavaPlugin implements Listener { } private ServerWorldPropertiesRegistry createWorldProperties(World world) { - ServerWorldPropertiesRegistry registry = new ServerWorldPropertiesRegistry(world); + ServerWorldPropertiesRegistry registry = new ServerWorldPropertiesRegistry(new WeakReference<>(world)); AxiomCreateWorldPropertiesEvent createEvent = new AxiomCreateWorldPropertiesEvent(world, registry); Bukkit.getPluginManager().callEvent(createEvent); diff --git a/src/main/java/com/moulberry/axiom/world_properties/server/ServerWorldPropertiesRegistry.java b/src/main/java/com/moulberry/axiom/world_properties/server/ServerWorldPropertiesRegistry.java index f8fa272..f26aaee 100644 --- a/src/main/java/com/moulberry/axiom/world_properties/server/ServerWorldPropertiesRegistry.java +++ b/src/main/java/com/moulberry/axiom/world_properties/server/ServerWorldPropertiesRegistry.java @@ -13,15 +13,16 @@ import org.bukkit.craftbukkit.CraftWorld; import org.bukkit.entity.Player; import org.bukkit.plugin.Plugin; +import java.lang.ref.Reference; import java.util.*; public class ServerWorldPropertiesRegistry { private final LinkedHashMap>> propertyList = new LinkedHashMap<>(); private final Map> propertyMap = new HashMap<>(); - private final World world; + private final Reference world; - public ServerWorldPropertiesRegistry(World world) { + public ServerWorldPropertiesRegistry(Reference world) { this.world = world; this.registerDefault(); } @@ -32,9 +33,14 @@ public class ServerWorldPropertiesRegistry { @SuppressWarnings("unchecked") public void addCategory(WorldPropertyCategory category, List> properties) { + World world = this.world.get(); + if (world == null) { + return; + } + List> holders = new ArrayList<>(); for (ServerWorldPropertyBase property : properties) { - Object defaultValue = property.getDefaultValue(this.world); + Object defaultValue = property.getDefaultValue(world); holders.add(new ServerWorldPropertyHolder<>(defaultValue, (ServerWorldPropertyBase) property)); } From 2e3f3a1ae63de28b88d9a79d4d943a2c53f72e64 Mon Sep 17 00:00:00 2001 From: Moulberry Date: Sun, 26 May 2024 23:03:58 +0800 Subject: [PATCH 17/22] Fix command erroneously casting to Player --- .../axiom/commands/AxiomDebugCommand.java | 52 ++++++++++++------- 1 file changed, 34 insertions(+), 18 deletions(-) diff --git a/src/main/java/com/moulberry/axiom/commands/AxiomDebugCommand.java b/src/main/java/com/moulberry/axiom/commands/AxiomDebugCommand.java index 5172953..fe6b2c5 100644 --- a/src/main/java/com/moulberry/axiom/commands/AxiomDebugCommand.java +++ b/src/main/java/com/moulberry/axiom/commands/AxiomDebugCommand.java @@ -31,32 +31,37 @@ public class AxiomDebugCommand { public static void register(AxiomPaper axiomPaper, BukkitCommandManager manager) { manager.command( base(manager, "hasAxiomPermission").handler(context -> { - boolean hasAxiomPermission = axiomPaper.hasAxiomPermission(context.sender()); + if (!(context.sender() instanceof Player player)) return; + boolean hasAxiomPermission = axiomPaper.hasAxiomPermission(player); context.sender().sendMessage(Component.text("hasAxiomPermission: " + hasAxiomPermission)); }) ); manager.command( base(manager, "canUseAxiom").handler(context -> { - boolean canUseAxiom = axiomPaper.canUseAxiom(context.sender()); + if (!(context.sender() instanceof Player player)) return; + boolean canUseAxiom = axiomPaper.canUseAxiom(player); context.sender().sendMessage(Component.text("canUseAxiom: " + canUseAxiom)); }) ); manager.command( base(manager, "isMismatchedDataVersion").handler(context -> { - boolean isMismatchedDataVersion = axiomPaper.isMismatchedDataVersion(context.sender().getUniqueId()); + if (!(context.sender() instanceof Player player)) return; + boolean isMismatchedDataVersion = axiomPaper.isMismatchedDataVersion(player.getUniqueId()); context.sender().sendMessage(Component.text("isMismatchedDataVersion: " + isMismatchedDataVersion)); }) ); manager.command( base(manager, "canModifyWorld").handler(context -> { - boolean canModifyWorld = axiomPaper.canModifyWorld(context.sender(), context.sender().getWorld()); + if (!(context.sender() instanceof Player player)) return; + boolean canModifyWorld = axiomPaper.canModifyWorld(player, player.getWorld()); context.sender().sendMessage(Component.text("canModifyWorld: " + canModifyWorld)); }) ); manager.command( base(manager, "isClientListening").required("channel", StringParser.greedyStringParser()).handler(context -> { + if (!(context.sender() instanceof Player player)) return; String channel = context.get("channel"); - boolean isClientListening = context.sender().getListeningPluginChannels().contains(channel); + boolean isClientListening = player.getListeningPluginChannels().contains(channel); context.sender().sendMessage(Component.text("listening to " + channel +": " + isClientListening)); }) ); @@ -69,7 +74,8 @@ public class AxiomDebugCommand { ); manager.command( base(manager, "getRestrictions").handler(context -> { - Restrictions restrictions = axiomPaper.playerRestrictions.get(context.sender().getUniqueId()); + if (!(context.sender() instanceof Player player)) return; + Restrictions restrictions = axiomPaper.playerRestrictions.get(player.getUniqueId()); if (restrictions == null) { context.sender().sendMessage(Component.text("no restrictions")); } else { @@ -83,55 +89,65 @@ public class AxiomDebugCommand { } manager.command( base(manager, "canBreakBlockAtCurrentPosition").optional("type", EnumParser.enumParser(IntegrationType.class)).handler(context -> { + if (!(context.sender() instanceof Player player)) return; IntegrationType integrationType = (IntegrationType) context.optional("type").orElse(null); - Block block = context.sender().getWorld().getBlockAt(context.sender().getLocation()); + Block block = player.getWorld().getBlockAt(player.getLocation()); boolean canBreakBlock; if (integrationType == IntegrationType.PLOT_SQUARED) { - canBreakBlock = PlotSquaredIntegration.canBreakBlock(context.sender(), block); + canBreakBlock = PlotSquaredIntegration.canBreakBlock(player, block); } else if (integrationType == IntegrationType.WORLD_GUARD) { - canBreakBlock = WorldGuardIntegration.canBreakBlock(context.sender(), block.getLocation()); + canBreakBlock = WorldGuardIntegration.canBreakBlock(player, block.getLocation()); } else { - canBreakBlock = Integration.canBreakBlock(context.sender(), block); + canBreakBlock = Integration.canBreakBlock(player, block); } context.sender().sendMessage(Component.text("canBreakBlock: " + canBreakBlock)); }) ); manager.command( base(manager, "canPlaceBlockAtCurrentPosition").optional("type", EnumParser.enumParser(IntegrationType.class)).handler(context -> { + if (!(context.sender() instanceof Player player)) return; IntegrationType integrationType = (IntegrationType) context.optional("type").orElse(null); boolean canPlaceBlock; if (integrationType == IntegrationType.PLOT_SQUARED) { - canPlaceBlock = PlotSquaredIntegration.canPlaceBlock(context.sender(), context.sender().getLocation()); + canPlaceBlock = PlotSquaredIntegration.canPlaceBlock(player, player.getLocation()); } else if (integrationType == IntegrationType.WORLD_GUARD) { - canPlaceBlock = WorldGuardIntegration.canPlaceBlock(context.sender(), context.sender().getLocation()); + canPlaceBlock = WorldGuardIntegration.canPlaceBlock(player, player.getLocation()); } else { - canPlaceBlock = Integration.canPlaceBlock(context.sender(), context.sender().getLocation()); + canPlaceBlock = Integration.canPlaceBlock(player, player.getLocation()); } context.sender().sendMessage(Component.text("canPlaceBlock: " + canPlaceBlock)); }) ); manager.command( base(manager, "isPlotWorld").handler(context -> { - boolean isPlotWorld = PlotSquaredIntegration.isPlotWorld(context.sender().getWorld()); + if (!(context.sender() instanceof Player player)) return; + boolean isPlotWorld = PlotSquaredIntegration.isPlotWorld(player.getWorld()); context.sender().sendMessage(Component.text("isPlotWorld: " + isPlotWorld)); }) ); manager.command( base(manager, "getCurrentEditablePlot").handler(context -> { - PlotSquaredIntegration.PlotBounds plotBounds = PlotSquaredIntegration.getCurrentEditablePlot(context.sender()); + if (!(context.sender() instanceof Player player)) return; + PlotSquaredIntegration.PlotBounds plotBounds = PlotSquaredIntegration.getCurrentEditablePlot(player); context.sender().sendMessage(Component.text("plotBounds: " + plotBounds)); }) ); } - private static Command.Builder base(BukkitCommandManager manager, String subcommand) { + private static Command.Builder base(BukkitCommandManager manager, String subcommand) { return manager.commandBuilder("axiompaperdebug") .literal(subcommand) - .senderType(Player.class) - .permission(PredicatePermission.of(sender -> sender.hasPermission("axiom.debug") || sender.getUniqueId().equals(MOULBERRY_UUID))); + .senderType(CommandSender.class) + .permission(PredicatePermission.of(sender -> { + if (sender instanceof Player player) { + return player.hasPermission("axiom.debug") || player.getUniqueId().equals(MOULBERRY_UUID); + } else { + return false; + } + })); } From 38ed66d0830af20750f50a54a8b34b6aa9552d83 Mon Sep 17 00:00:00 2001 From: Moulberry Date: Tue, 28 May 2024 22:28:26 +0800 Subject: [PATCH 18/22] Improve plot bounds handling to support arbitrarily sized non-cuboid plots --- .../java/com/moulberry/axiom/AxiomPaper.java | 35 +++++++++---------- .../com/moulberry/axiom/Restrictions.java | 33 +++++++++-------- .../plotsquared/PlotSquaredIntegration.java | 21 +++-------- .../PlotSquaredIntegrationImpl.java | 33 ++++++++++++----- 4 files changed, 64 insertions(+), 58 deletions(-) diff --git a/src/main/java/com/moulberry/axiom/AxiomPaper.java b/src/main/java/com/moulberry/axiom/AxiomPaper.java index cccef8c..8da16c2 100644 --- a/src/main/java/com/moulberry/axiom/AxiomPaper.java +++ b/src/main/java/com/moulberry/axiom/AxiomPaper.java @@ -218,32 +218,31 @@ public class AxiomPaper extends JavaPlugin implements Listener { send = true; } - BlockPos boundsMin = null; - BlockPos boundsMax = null; + Set bounds = Set.of(); if (!player.hasPermission("axiom.allow_copying_other_plots")) { if (PlotSquaredIntegration.isPlotWorld(player.getWorld())) { PlotSquaredIntegration.PlotBounds editable = PlotSquaredIntegration.getCurrentEditablePlot(player); if (editable != null) { restrictions.lastPlotBounds = editable; - boundsMin = editable.min(); - boundsMax = editable.max(); + bounds = editable.boxes(); } else if (restrictions.lastPlotBounds != null && restrictions.lastPlotBounds.worldName().equals(player.getWorld().getName())) { - boundsMin = restrictions.lastPlotBounds.min(); - boundsMax = restrictions.lastPlotBounds.max(); + bounds = restrictions.lastPlotBounds.boxes(); } else { - boundsMin = BlockPos.ZERO; - boundsMax = BlockPos.ZERO; + bounds = Set.of(new PlotSquaredIntegration.PlotBox(BlockPos.ZERO, BlockPos.ZERO)); } } - int min = Integer.MIN_VALUE; - int max = Integer.MAX_VALUE; - if (boundsMin != null && boundsMax != null && - boundsMin.getX() == min && boundsMin.getY() == min && boundsMin.getZ() == min && - boundsMax.getX() == max && boundsMax.getY() == max && boundsMax.getZ() == max) { - boundsMin = null; - boundsMax = null; + if (bounds.size() == 1) { + PlotSquaredIntegration.PlotBox plotBounds = bounds.iterator().next(); + + int min = Integer.MIN_VALUE; + int max = Integer.MAX_VALUE; + + if (plotBounds.min().getX() == min && plotBounds.min().getY() == min && plotBounds.min().getZ() == min && + plotBounds.max().getX() == max && plotBounds.max().getY() == max && plotBounds.max().getZ() == max) { + bounds = Set.of(); + } } } @@ -251,12 +250,10 @@ public class AxiomPaper extends JavaPlugin implements Listener { if (restrictions.maxSectionsPerSecond != rateLimit || restrictions.canImportBlocks != allowImportingBlocks || - !Objects.equals(restrictions.boundsMin, boundsMin) || - !Objects.equals(restrictions.boundsMax, boundsMax)) { + !Objects.equals(restrictions.bounds, bounds)) { restrictions.maxSectionsPerSecond = rateLimit; restrictions.canImportBlocks = allowImportingBlocks; - restrictions.boundsMin = boundsMin; - restrictions.boundsMax = boundsMax; + restrictions.bounds = bounds; send = true; } diff --git a/src/main/java/com/moulberry/axiom/Restrictions.java b/src/main/java/com/moulberry/axiom/Restrictions.java index 4b6c25c..c36329c 100644 --- a/src/main/java/com/moulberry/axiom/Restrictions.java +++ b/src/main/java/com/moulberry/axiom/Restrictions.java @@ -6,14 +6,15 @@ import net.minecraft.core.BlockPos; import net.minecraft.network.FriendlyByteBuf; import org.bukkit.entity.Player; +import java.util.Set; + public class Restrictions { public boolean canImportBlocks = true; public boolean canUseEditor = true; public boolean canEditDisplayEntities = true; public int maxSectionsPerSecond = 0; - public BlockPos boundsMin = null; - public BlockPos boundsMax = null; + public Set bounds = Set.of(); public PlotSquaredIntegration.PlotBounds lastPlotBounds = null; @@ -26,16 +27,21 @@ public class Restrictions { buf.writeVarInt(this.maxSectionsPerSecond); - if (this.boundsMin == null || this.boundsMax == null) { - buf.writeBoolean(false); - } else { - buf.writeBoolean(true); - int minX = this.boundsMin.getX(); - int minY = this.boundsMin.getY(); - int minZ = this.boundsMin.getZ(); - int maxX = this.boundsMax.getX(); - int maxY = this.boundsMax.getY(); - int maxZ = this.boundsMax.getZ(); + int count = Math.min(64, bounds.size()); + buf.writeVarInt(count); + for (PlotSquaredIntegration.PlotBox bound : this.bounds) { + if (count > 0) { + count -= 1; + } else { + break; + } + + int minX = bound.min().getX(); + int minY = bound.min().getY(); + int minZ = bound.min().getZ(); + int maxX = bound.max().getX(); + int maxY = bound.max().getY(); + int maxZ = bound.max().getZ(); if (minX < -33554431) minX = -33554431; if (minX > 33554431) minX = 33554431; @@ -68,8 +74,7 @@ public class Restrictions { ", canUseEditor=" + canUseEditor + ", canEditDisplayEntities=" + canEditDisplayEntities + ", maxSectionsPerSecond=" + maxSectionsPerSecond + - ", boundsMin=" + boundsMin + - ", boundsMax=" + boundsMax + + ", bounds=" + bounds + ", lastPlotBounds=" + lastPlotBounds + '}'; } diff --git a/src/main/java/com/moulberry/axiom/integration/plotsquared/PlotSquaredIntegration.java b/src/main/java/com/moulberry/axiom/integration/plotsquared/PlotSquaredIntegration.java index deab2cf..586930c 100644 --- a/src/main/java/com/moulberry/axiom/integration/plotsquared/PlotSquaredIntegration.java +++ b/src/main/java/com/moulberry/axiom/integration/plotsquared/PlotSquaredIntegration.java @@ -10,26 +10,13 @@ import org.bukkit.World; import org.bukkit.block.Block; import org.bukkit.entity.Player; +import java.util.Set; + public class PlotSquaredIntegration { - public record PlotBounds(BlockPos min, BlockPos max, String worldName) { - public PlotBounds(CuboidRegion cuboidRegion, String worldName) { - this( - new BlockPos( - cuboidRegion.getMinimumPoint().getBlockX(), - cuboidRegion.getMinimumPoint().getBlockY(), - cuboidRegion.getMinimumPoint().getBlockZ() - ), - new BlockPos( - cuboidRegion.getMaximumPoint().getBlockX(), - cuboidRegion.getMaximumPoint().getBlockY(), - cuboidRegion.getMaximumPoint().getBlockZ() - ), - worldName - ); - } - } + public record PlotBox(BlockPos min, BlockPos max) {} + public record PlotBounds(Set boxes, String worldName) {} public static boolean canBreakBlock(Player player, Block block) { if (!Bukkit.getPluginManager().isPluginEnabled("PlotSquared")) { diff --git a/src/main/java/com/moulberry/axiom/integration/plotsquared/PlotSquaredIntegrationImpl.java b/src/main/java/com/moulberry/axiom/integration/plotsquared/PlotSquaredIntegrationImpl.java index d9ea465..b6b71d7 100644 --- a/src/main/java/com/moulberry/axiom/integration/plotsquared/PlotSquaredIntegrationImpl.java +++ b/src/main/java/com/moulberry/axiom/integration/plotsquared/PlotSquaredIntegrationImpl.java @@ -18,6 +18,7 @@ import com.sk89q.worldedit.bukkit.BukkitAdapter; import com.sk89q.worldedit.math.BlockVector3; import com.sk89q.worldedit.regions.CuboidRegion; import com.sk89q.worldedit.world.block.BlockType; +import net.minecraft.core.BlockPos; import org.bukkit.World; import org.bukkit.block.Block; import org.bukkit.entity.Player; @@ -147,16 +148,12 @@ public class PlotSquaredIntegrationImpl { BukkitPlayer pp = BukkitUtil.adapt(player); Plot plot = area.getPlot(location); if (plot != null) { - Location bottom = plot.getExtendedBottomAbs(); - Location top = plot.getExtendedTopAbs(); - CuboidRegion cuboidRegion = new CuboidRegion(bottom.getBlockVector3(), top.getBlockVector3()); - // check unowned plots if (!plot.hasOwner()) { if (!pp.hasPermission(Permission.PERMISSION_ADMIN_BUILD_UNOWNED, false)) { return null; } else { - return new PlotSquaredIntegration.PlotBounds(cuboidRegion, player.getWorld().getName()); + return createBounds(plot, player.getWorld().getName()); } } // player is breaking another player's plot @@ -164,7 +161,7 @@ public class PlotSquaredIntegrationImpl { if (!pp.hasPermission(Permission.PERMISSION_ADMIN_BUILD_OTHER, false)) { return null; } else { - return new PlotSquaredIntegration.PlotBounds(cuboidRegion, player.getWorld().getName()); + return createBounds(plot, player.getWorld().getName()); } } // plot is 'done' @@ -172,15 +169,35 @@ public class PlotSquaredIntegrationImpl { if (!pp.hasPermission(Permission.PERMISSION_ADMIN_BUILD_OTHER, false)) { return null; } else { - return new PlotSquaredIntegration.PlotBounds(cuboidRegion, player.getWorld().getName()); + return createBounds(plot, player.getWorld().getName()); } } - return new PlotSquaredIntegration.PlotBounds(cuboidRegion, player.getWorld().getName()); + return createBounds(plot, player.getWorld().getName()); } return null; } + private static PlotSquaredIntegration.PlotBounds createBounds(Plot plot, String worldName) { + Set boxes = new HashSet<>(); + + for (CuboidRegion region : plot.getRegions()) { + BlockPos min = new BlockPos( + region.getMinimumPoint().getBlockX(), + region.getMinimumPoint().getBlockY(), + region.getMinimumPoint().getBlockZ() + ); + BlockPos max = new BlockPos( + region.getMaximumPoint().getBlockX(), + region.getMaximumPoint().getBlockY(), + region.getMaximumPoint().getBlockZ() + ); + boxes.add(new PlotSquaredIntegration.PlotBox(min, max)); + } + + return new PlotSquaredIntegration.PlotBounds(boxes, worldName); + } + static SectionPermissionChecker checkSection(Player player, World world, int sectionX, int sectionY, int sectionZ) { int minX = sectionX * 16; int minY = sectionY * 16; From 38d5ee334d1e142c3f894a4937024b0dfc021956 Mon Sep 17 00:00:00 2001 From: Rubenicos <44579213+Rubenicos@users.noreply.github.com> Date: Sat, 11 May 2024 14:44:48 -0600 Subject: [PATCH 19/22] Add individual permissions --- .../java/com/moulberry/axiom/AxiomPaper.java | 17 +++++- .../BlueprintRequestPacketListener.java | 2 +- .../packet/DeleteEntityPacketListener.java | 6 +- .../ManipulateEntityPacketListener.java | 6 +- .../MarkerNbtRequestPacketListener.java | 6 +- .../RequestChunkDataPacketListener.java | 2 +- .../packet/SetBlockBufferPacketListener.java | 4 +- .../axiom/packet/SetBlockPacketListener.java | 2 +- .../packet/SetEditorViewsPacketListener.java | 2 +- .../packet/SetFlySpeedPacketListener.java | 2 +- .../packet/SetGamemodePacketListener.java | 2 +- .../packet/SetHotbarSlotPacketListener.java | 2 +- .../axiom/packet/SetTimePacketListener.java | 2 +- .../packet/SetWorldPropertyListener.java | 2 +- .../packet/SpawnEntityPacketListener.java | 6 +- .../SwitchActiveHotbarPacketListener.java | 2 +- .../axiom/packet/TeleportPacketListener.java | 2 +- .../packet/UploadBlueprintPacketListener.java | 2 +- src/main/resources/plugin.yml | 55 ++++++++++++++++--- 19 files changed, 81 insertions(+), 43 deletions(-) diff --git a/src/main/java/com/moulberry/axiom/AxiomPaper.java b/src/main/java/com/moulberry/axiom/AxiomPaper.java index 8da16c2..82b22cd 100644 --- a/src/main/java/com/moulberry/axiom/AxiomPaper.java +++ b/src/main/java/com/moulberry/axiom/AxiomPaper.java @@ -304,11 +304,24 @@ public class AxiomPaper extends JavaPlugin implements Listener { } public boolean hasAxiomPermission(Player player) { - return player.hasPermission("axiom.*") || player.isOp(); + return hasAxiomPermission(player, null); + } + + public boolean hasAxiomPermission(Player player, String permission) { + if (player.hasPermission("axiom.*") || player.isOp()) { + return true; + } else if (permission != null && !player.hasPermission(permission)) { + return false; + } + return player.hasPermission("axiom.use"); } public boolean canUseAxiom(Player player) { - return hasAxiomPermission(player) && activeAxiomPlayers.contains(player.getUniqueId()); + return canUseAxiom(player, null); + } + + public boolean canUseAxiom(Player player, String permission) { + return activeAxiomPlayers.contains(player.getUniqueId()) && hasAxiomPermission(player, permission); } public @Nullable RateLimiter getBlockBufferRateLimiter(UUID uuid) { diff --git a/src/main/java/com/moulberry/axiom/packet/BlueprintRequestPacketListener.java b/src/main/java/com/moulberry/axiom/packet/BlueprintRequestPacketListener.java index 6d3741e..8b920e0 100644 --- a/src/main/java/com/moulberry/axiom/packet/BlueprintRequestPacketListener.java +++ b/src/main/java/com/moulberry/axiom/packet/BlueprintRequestPacketListener.java @@ -36,7 +36,7 @@ public class BlueprintRequestPacketListener implements PluginMessageListener { } private void process(Player player, byte[] message) { - if (!this.plugin.canUseAxiom(player)) { + if (!this.plugin.canUseAxiom(player, "axiom.blueprint.request")) { return; } diff --git a/src/main/java/com/moulberry/axiom/packet/DeleteEntityPacketListener.java b/src/main/java/com/moulberry/axiom/packet/DeleteEntityPacketListener.java index bfddcb0..3e4d413 100644 --- a/src/main/java/com/moulberry/axiom/packet/DeleteEntityPacketListener.java +++ b/src/main/java/com/moulberry/axiom/packet/DeleteEntityPacketListener.java @@ -35,11 +35,7 @@ public class DeleteEntityPacketListener implements PluginMessageListener { } private void process(Player player, byte[] message) { - if (!this.plugin.canUseAxiom(player)) { - return; - } - - if (!player.hasPermission("axiom.entity.*") && !player.hasPermission("axiom.entity.delete")) { + if (!this.plugin.canUseAxiom(player, "axiom.entity.delete")) { return; } diff --git a/src/main/java/com/moulberry/axiom/packet/ManipulateEntityPacketListener.java b/src/main/java/com/moulberry/axiom/packet/ManipulateEntityPacketListener.java index af926a5..2323a7e 100644 --- a/src/main/java/com/moulberry/axiom/packet/ManipulateEntityPacketListener.java +++ b/src/main/java/com/moulberry/axiom/packet/ManipulateEntityPacketListener.java @@ -90,11 +90,7 @@ public class ManipulateEntityPacketListener implements PluginMessageListener { } private void process(Player player, byte[] message) { - if (!this.plugin.canUseAxiom(player)) { - return; - } - - if (!player.hasPermission("axiom.entity.*") && !player.hasPermission("axiom.entity.manipulate")) { + if (!this.plugin.canUseAxiom(player, "axiom.entity.manipulate")) { return; } diff --git a/src/main/java/com/moulberry/axiom/packet/MarkerNbtRequestPacketListener.java b/src/main/java/com/moulberry/axiom/packet/MarkerNbtRequestPacketListener.java index 1856c13..516dfa5 100644 --- a/src/main/java/com/moulberry/axiom/packet/MarkerNbtRequestPacketListener.java +++ b/src/main/java/com/moulberry/axiom/packet/MarkerNbtRequestPacketListener.java @@ -33,11 +33,7 @@ public class MarkerNbtRequestPacketListener implements PluginMessageListener { } private void process(Player player, byte[] message) { - if (!this.plugin.canUseAxiom(player)) { - return; - } - - if (!player.hasPermission("axiom.entity.*") && !player.hasPermission("axiom.entity.manipulate")) { + if (!this.plugin.canUseAxiom(player, "axiom.entity.manipulate")) { return; } diff --git a/src/main/java/com/moulberry/axiom/packet/RequestChunkDataPacketListener.java b/src/main/java/com/moulberry/axiom/packet/RequestChunkDataPacketListener.java index 0aae6cd..b538c44 100644 --- a/src/main/java/com/moulberry/axiom/packet/RequestChunkDataPacketListener.java +++ b/src/main/java/com/moulberry/axiom/packet/RequestChunkDataPacketListener.java @@ -56,7 +56,7 @@ public class RequestChunkDataPacketListener implements PluginMessageListener { FriendlyByteBuf friendlyByteBuf = new FriendlyByteBuf(Unpooled.wrappedBuffer(message)); long id = friendlyByteBuf.readLong(); - if (!this.plugin.canUseAxiom(bukkitPlayer) || this.plugin.isMismatchedDataVersion(bukkitPlayer.getUniqueId())) { + if (!this.plugin.canUseAxiom(bukkitPlayer, "axiom.chunk.request") || this.plugin.isMismatchedDataVersion(bukkitPlayer.getUniqueId())) { // We always send an 'empty' response in order to make the client happy sendEmptyResponse(player, id); return; diff --git a/src/main/java/com/moulberry/axiom/packet/SetBlockBufferPacketListener.java b/src/main/java/com/moulberry/axiom/packet/SetBlockBufferPacketListener.java index e2c8d27..5c54b10 100644 --- a/src/main/java/com/moulberry/axiom/packet/SetBlockBufferPacketListener.java +++ b/src/main/java/com/moulberry/axiom/packet/SetBlockBufferPacketListener.java @@ -125,7 +125,7 @@ public class SetBlockBufferPacketListener { ServerLevel world = player.serverLevel(); if (!world.dimension().equals(worldKey)) return; - if (!this.plugin.canUseAxiom(player.getBukkitEntity())) { + if (!this.plugin.canUseAxiom(player.getBukkitEntity(), "axiom.build.section")) { return; } @@ -325,7 +325,7 @@ public class SetBlockBufferPacketListener { ServerLevel world = player.serverLevel(); if (!world.dimension().equals(worldKey)) return; - if (!this.plugin.canUseAxiom(player.getBukkitEntity())) { + if (!this.plugin.canUseAxiom(player.getBukkitEntity(), "axiom.build.section")) { return; } diff --git a/src/main/java/com/moulberry/axiom/packet/SetBlockPacketListener.java b/src/main/java/com/moulberry/axiom/packet/SetBlockPacketListener.java index 860cb65..0bf6d59 100644 --- a/src/main/java/com/moulberry/axiom/packet/SetBlockPacketListener.java +++ b/src/main/java/com/moulberry/axiom/packet/SetBlockPacketListener.java @@ -79,7 +79,7 @@ public class SetBlockPacketListener implements PluginMessageListener { } private void process(Player bukkitPlayer, byte[] message) { - if (!this.plugin.canUseAxiom(bukkitPlayer)) { + if (!this.plugin.canUseAxiom(bukkitPlayer, "axiom.build.place")) { return; } diff --git a/src/main/java/com/moulberry/axiom/packet/SetEditorViewsPacketListener.java b/src/main/java/com/moulberry/axiom/packet/SetEditorViewsPacketListener.java index 4bfc76f..e718080 100644 --- a/src/main/java/com/moulberry/axiom/packet/SetEditorViewsPacketListener.java +++ b/src/main/java/com/moulberry/axiom/packet/SetEditorViewsPacketListener.java @@ -35,7 +35,7 @@ public class SetEditorViewsPacketListener implements PluginMessageListener { } private void process(Player player, byte[] message) { - if (!this.plugin.canUseAxiom(player)) { + if (!this.plugin.canUseAxiom(player, "axiom.editor.views")) { return; } diff --git a/src/main/java/com/moulberry/axiom/packet/SetFlySpeedPacketListener.java b/src/main/java/com/moulberry/axiom/packet/SetFlySpeedPacketListener.java index e488f3b..421e745 100644 --- a/src/main/java/com/moulberry/axiom/packet/SetFlySpeedPacketListener.java +++ b/src/main/java/com/moulberry/axiom/packet/SetFlySpeedPacketListener.java @@ -28,7 +28,7 @@ public class SetFlySpeedPacketListener implements PluginMessageListener { } private void process(Player player, byte[] message) { - if (!this.plugin.canUseAxiom(player)) { + if (!this.plugin.canUseAxiom(player, "axiom.player.speed")) { return; } diff --git a/src/main/java/com/moulberry/axiom/packet/SetGamemodePacketListener.java b/src/main/java/com/moulberry/axiom/packet/SetGamemodePacketListener.java index be24422..de1c535 100644 --- a/src/main/java/com/moulberry/axiom/packet/SetGamemodePacketListener.java +++ b/src/main/java/com/moulberry/axiom/packet/SetGamemodePacketListener.java @@ -30,7 +30,7 @@ public class SetGamemodePacketListener implements PluginMessageListener { } private void process(Player player, byte[] message) { - if (!this.plugin.canUseAxiom(player)) { + if (!this.plugin.canUseAxiom(player, "axiom.player.gamemode")) { return; } diff --git a/src/main/java/com/moulberry/axiom/packet/SetHotbarSlotPacketListener.java b/src/main/java/com/moulberry/axiom/packet/SetHotbarSlotPacketListener.java index 685a7f0..f8a1a67 100644 --- a/src/main/java/com/moulberry/axiom/packet/SetHotbarSlotPacketListener.java +++ b/src/main/java/com/moulberry/axiom/packet/SetHotbarSlotPacketListener.java @@ -35,7 +35,7 @@ public class SetHotbarSlotPacketListener implements PluginMessageListener { } private void process(Player player, byte[] message) { - if (!this.plugin.canUseAxiom(player) || this.plugin.isMismatchedDataVersion(player.getUniqueId())) { + if (!this.plugin.canUseAxiom(player, "axiom.player.hotbar") || this.plugin.isMismatchedDataVersion(player.getUniqueId())) { return; } diff --git a/src/main/java/com/moulberry/axiom/packet/SetTimePacketListener.java b/src/main/java/com/moulberry/axiom/packet/SetTimePacketListener.java index a3b0c7b..f1bca47 100644 --- a/src/main/java/com/moulberry/axiom/packet/SetTimePacketListener.java +++ b/src/main/java/com/moulberry/axiom/packet/SetTimePacketListener.java @@ -34,7 +34,7 @@ public class SetTimePacketListener implements PluginMessageListener { } private void process(Player player, byte[] message) { - if (!this.plugin.canUseAxiom(player)) { + if (!this.plugin.canUseAxiom(player, "axiom.world.time")) { return; } diff --git a/src/main/java/com/moulberry/axiom/packet/SetWorldPropertyListener.java b/src/main/java/com/moulberry/axiom/packet/SetWorldPropertyListener.java index 5b23f3d..73bd459 100644 --- a/src/main/java/com/moulberry/axiom/packet/SetWorldPropertyListener.java +++ b/src/main/java/com/moulberry/axiom/packet/SetWorldPropertyListener.java @@ -29,7 +29,7 @@ public class SetWorldPropertyListener implements PluginMessageListener { } private void process(Player player, byte[] message) { - if (!this.plugin.canUseAxiom(player)) { + if (!this.plugin.canUseAxiom(player, "axiom.world.property")) { return; } diff --git a/src/main/java/com/moulberry/axiom/packet/SpawnEntityPacketListener.java b/src/main/java/com/moulberry/axiom/packet/SpawnEntityPacketListener.java index b643781..3714440 100644 --- a/src/main/java/com/moulberry/axiom/packet/SpawnEntityPacketListener.java +++ b/src/main/java/com/moulberry/axiom/packet/SpawnEntityPacketListener.java @@ -55,11 +55,7 @@ public class SpawnEntityPacketListener implements PluginMessageListener { } private void process(Player player, byte[] message) { - if (!this.plugin.canUseAxiom(player)) { - return; - } - - if (!player.hasPermission("axiom.entity.*") && !player.hasPermission("axiom.entity.spawn")) { + if (!this.plugin.canUseAxiom(player, "axiom.entity.spawn")) { return; } diff --git a/src/main/java/com/moulberry/axiom/packet/SwitchActiveHotbarPacketListener.java b/src/main/java/com/moulberry/axiom/packet/SwitchActiveHotbarPacketListener.java index 90a7338..f1056ef 100644 --- a/src/main/java/com/moulberry/axiom/packet/SwitchActiveHotbarPacketListener.java +++ b/src/main/java/com/moulberry/axiom/packet/SwitchActiveHotbarPacketListener.java @@ -36,7 +36,7 @@ public class SwitchActiveHotbarPacketListener implements PluginMessageListener { } private void process(Player player, byte[] message) { - if (!this.plugin.canUseAxiom(player) || this.plugin.isMismatchedDataVersion(player.getUniqueId())) { + if (!this.plugin.canUseAxiom(player, "axiom.player.hotbar") || this.plugin.isMismatchedDataVersion(player.getUniqueId())) { return; } diff --git a/src/main/java/com/moulberry/axiom/packet/TeleportPacketListener.java b/src/main/java/com/moulberry/axiom/packet/TeleportPacketListener.java index cdb93b5..dfbeb82 100644 --- a/src/main/java/com/moulberry/axiom/packet/TeleportPacketListener.java +++ b/src/main/java/com/moulberry/axiom/packet/TeleportPacketListener.java @@ -33,7 +33,7 @@ public class TeleportPacketListener implements PluginMessageListener { } private void process(Player player, byte[] message) { - if (!this.plugin.canUseAxiom(player)) { + if (!this.plugin.canUseAxiom(player, "axiom.world.teleport")) { return; } diff --git a/src/main/java/com/moulberry/axiom/packet/UploadBlueprintPacketListener.java b/src/main/java/com/moulberry/axiom/packet/UploadBlueprintPacketListener.java index 96b63b9..0a6d2eb 100644 --- a/src/main/java/com/moulberry/axiom/packet/UploadBlueprintPacketListener.java +++ b/src/main/java/com/moulberry/axiom/packet/UploadBlueprintPacketListener.java @@ -24,7 +24,7 @@ public class UploadBlueprintPacketListener { } public void onReceive(ServerPlayer serverPlayer, FriendlyByteBuf friendlyByteBuf) { - if (!this.plugin.canUseAxiom(serverPlayer.getBukkitEntity())) { + if (!this.plugin.canUseAxiom(serverPlayer.getBukkitEntity(), "axiom.blueprint.upload")) { return; } diff --git a/src/main/resources/plugin.yml b/src/main/resources/plugin.yml index 8e00fc0..0adda57 100644 --- a/src/main/resources/plugin.yml +++ b/src/main/resources/plugin.yml @@ -5,23 +5,64 @@ description: $description authors: - Moulberry api-version: "$apiVersion" -softdepend: ["CoreProtect"] +softdepend: + - ViaVersion + - WorldGuard + - PlotSquared permissions: axiom.*: description: Allows use of all default Axiom features default: op + axiom.use: + description: Allows basic use of axiom + default: op axiom.debug: description: Allows use of the /axiompaperdebug command default: op axiom.entity.*: description: Allows use of all entity-related features (spawning, manipulating, deleting) default: op - axiom.entity.spawn: - description: Allows entity spawning - axiom.entity.manipulate: - description: Allows entity manipulation - axiom.entity.delete: - description: Allows entity deletion + children: + axiom.entity.spawn: true + axiom.entity.manipulate: true + axiom.entity.delete: true + axiom.blueprint.*: + description: Allows use of all blueprint-related features + default: op + children: + axiom.blueprint.upload: true + axiom.blueprint.request: true + axiom.blueprint.manifest: true + axiom.chunk.*: + description: Allows use of all chunk-related features + default: op + children: + axiom.chunk.request: true + axiom.build.*: + description: Allows use of all build-related features + default: op + children: + axiom.build.place: true + axiom.build.section: true + axiom.editor.*: + description: Allows use of all editor-related features + default: op + children: + axiom.editor.views: true + axiom.player.*: + description: Allows use of all player-related features + default: op + children: + axiom.player.speed: true + axiom.player.gamemode: true + axiom.player.hotbar: true + axiom.world.*: + description: Allows use of all world-related features + default: op + children: + axiom.world.time: true + axiom.world.property: true + axiom.world.teleport: true axiom.allow_copying_other_plots: description: This permission allows users to copy other user's plots From 472c85652a3a00de4fba911e85877fb486739361 Mon Sep 17 00:00:00 2001 From: Rubenicos <44579213+Rubenicos@users.noreply.github.com> Date: Sun, 19 May 2024 11:40:47 -0600 Subject: [PATCH 20/22] Fix backwards compatibility --- src/main/java/com/moulberry/axiom/AxiomPaper.java | 14 +++++++++----- .../axiom/packet/DeleteEntityPacketListener.java | 2 +- .../packet/ManipulateEntityPacketListener.java | 2 +- .../packet/MarkerNbtRequestPacketListener.java | 2 +- .../axiom/packet/SpawnEntityPacketListener.java | 2 +- src/main/resources/plugin.yml | 4 +++- 6 files changed, 16 insertions(+), 10 deletions(-) diff --git a/src/main/java/com/moulberry/axiom/AxiomPaper.java b/src/main/java/com/moulberry/axiom/AxiomPaper.java index 82b22cd..feb4050 100644 --- a/src/main/java/com/moulberry/axiom/AxiomPaper.java +++ b/src/main/java/com/moulberry/axiom/AxiomPaper.java @@ -304,12 +304,12 @@ public class AxiomPaper extends JavaPlugin implements Listener { } public boolean hasAxiomPermission(Player player) { - return hasAxiomPermission(player, null); + return hasAxiomPermission(player, null, false); } - public boolean hasAxiomPermission(Player player, String permission) { + public boolean hasAxiomPermission(Player player, String permission, boolean strict) { if (player.hasPermission("axiom.*") || player.isOp()) { - return true; + return !strict || permission == null || player.hasPermission("axiom.all") || player.hasPermission(permission); } else if (permission != null && !player.hasPermission(permission)) { return false; } @@ -317,11 +317,15 @@ public class AxiomPaper extends JavaPlugin implements Listener { } public boolean canUseAxiom(Player player) { - return canUseAxiom(player, null); + return canUseAxiom(player, null, false); } public boolean canUseAxiom(Player player, String permission) { - return activeAxiomPlayers.contains(player.getUniqueId()) && hasAxiomPermission(player, permission); + return canUseAxiom(player, permission, false); + } + + public boolean canUseAxiom(Player player, String permission, boolean strict) { + return activeAxiomPlayers.contains(player.getUniqueId()) && hasAxiomPermission(player, permission, strict); } public @Nullable RateLimiter getBlockBufferRateLimiter(UUID uuid) { diff --git a/src/main/java/com/moulberry/axiom/packet/DeleteEntityPacketListener.java b/src/main/java/com/moulberry/axiom/packet/DeleteEntityPacketListener.java index 3e4d413..b74a0e4 100644 --- a/src/main/java/com/moulberry/axiom/packet/DeleteEntityPacketListener.java +++ b/src/main/java/com/moulberry/axiom/packet/DeleteEntityPacketListener.java @@ -35,7 +35,7 @@ public class DeleteEntityPacketListener implements PluginMessageListener { } private void process(Player player, byte[] message) { - if (!this.plugin.canUseAxiom(player, "axiom.entity.delete")) { + if (!this.plugin.canUseAxiom(player, "axiom.entity.delete", true)) { return; } diff --git a/src/main/java/com/moulberry/axiom/packet/ManipulateEntityPacketListener.java b/src/main/java/com/moulberry/axiom/packet/ManipulateEntityPacketListener.java index 2323a7e..b1d3a2c 100644 --- a/src/main/java/com/moulberry/axiom/packet/ManipulateEntityPacketListener.java +++ b/src/main/java/com/moulberry/axiom/packet/ManipulateEntityPacketListener.java @@ -90,7 +90,7 @@ public class ManipulateEntityPacketListener implements PluginMessageListener { } private void process(Player player, byte[] message) { - if (!this.plugin.canUseAxiom(player, "axiom.entity.manipulate")) { + if (!this.plugin.canUseAxiom(player, "axiom.entity.manipulate", true)) { return; } diff --git a/src/main/java/com/moulberry/axiom/packet/MarkerNbtRequestPacketListener.java b/src/main/java/com/moulberry/axiom/packet/MarkerNbtRequestPacketListener.java index 516dfa5..0902d2c 100644 --- a/src/main/java/com/moulberry/axiom/packet/MarkerNbtRequestPacketListener.java +++ b/src/main/java/com/moulberry/axiom/packet/MarkerNbtRequestPacketListener.java @@ -33,7 +33,7 @@ public class MarkerNbtRequestPacketListener implements PluginMessageListener { } private void process(Player player, byte[] message) { - if (!this.plugin.canUseAxiom(player, "axiom.entity.manipulate")) { + if (!this.plugin.canUseAxiom(player, "axiom.entity.manipulate", true)) { return; } diff --git a/src/main/java/com/moulberry/axiom/packet/SpawnEntityPacketListener.java b/src/main/java/com/moulberry/axiom/packet/SpawnEntityPacketListener.java index 3714440..90543ee 100644 --- a/src/main/java/com/moulberry/axiom/packet/SpawnEntityPacketListener.java +++ b/src/main/java/com/moulberry/axiom/packet/SpawnEntityPacketListener.java @@ -55,7 +55,7 @@ public class SpawnEntityPacketListener implements PluginMessageListener { } private void process(Player player, byte[] message) { - if (!this.plugin.canUseAxiom(player, "axiom.entity.spawn")) { + if (!this.plugin.canUseAxiom(player, "axiom.entity.spawn", true)) { return; } diff --git a/src/main/resources/plugin.yml b/src/main/resources/plugin.yml index 0adda57..1d567d9 100644 --- a/src/main/resources/plugin.yml +++ b/src/main/resources/plugin.yml @@ -10,9 +10,11 @@ softdepend: - WorldGuard - PlotSquared permissions: - axiom.*: + axiom.all: description: Allows use of all default Axiom features default: op + children: + axiom.*: true axiom.use: description: Allows basic use of axiom default: op From a248fc4d70e6710f9dcbc28001affebad469a484 Mon Sep 17 00:00:00 2001 From: Moulberry Date: Tue, 28 May 2024 22:46:37 +0800 Subject: [PATCH 21/22] Add CoreProtect to softdepend --- src/main/resources/plugin.yml | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/src/main/resources/plugin.yml b/src/main/resources/plugin.yml index 1d567d9..030c8eb 100644 --- a/src/main/resources/plugin.yml +++ b/src/main/resources/plugin.yml @@ -5,10 +5,7 @@ description: $description authors: - Moulberry api-version: "$apiVersion" -softdepend: - - ViaVersion - - WorldGuard - - PlotSquared +softdepend: ["CoreProtect", "ViaVersion", "WorldGuard", "PlotSquared"] permissions: axiom.all: description: Allows use of all default Axiom features From 199852308fa94ca57af205af50cd3c701d11cf1c Mon Sep 17 00:00:00 2001 From: Moulberry Date: Thu, 6 Jun 2024 04:35:19 +0800 Subject: [PATCH 22/22] Fix biome buffer checking wrong coordinates --- .../moulberry/axiom/packet/SetBlockBufferPacketListener.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/com/moulberry/axiom/packet/SetBlockBufferPacketListener.java b/src/main/java/com/moulberry/axiom/packet/SetBlockBufferPacketListener.java index 5c54b10..86b5e03 100644 --- a/src/main/java/com/moulberry/axiom/packet/SetBlockBufferPacketListener.java +++ b/src/main/java/com/moulberry/axiom/packet/SetBlockBufferPacketListener.java @@ -358,7 +358,7 @@ public class SetBlockBufferPacketListener { PalettedContainer> container = (PalettedContainer>) section.getBiomes(); if (!Integration.canPlaceBlock(player.getBukkitEntity(), - new Location(player.getBukkitEntity().getWorld(), x+1, y+1, z+1))) return; + new Location(player.getBukkitEntity().getWorld(), (x<<2)+1, (y<<2)+1, (z<<2)+1))) return; container.set(x & 3, y & 3, z & 3, holder.get()); changedChunks.add(chunk);