Skip to content

Commit

Permalink
Support 4.2.0 changes
Browse files Browse the repository at this point in the history
  • Loading branch information
Moulberry committed Oct 11, 2024
1 parent f44449c commit 21fef04
Show file tree
Hide file tree
Showing 15 changed files with 280 additions and 140 deletions.
2 changes: 1 addition & 1 deletion gradle/libs.versions.toml
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ bom-newest = "1.37"
cloud-paper = "2.0.0-20240516.054251-69"
coreprotect = "22.4"
paper = "1.20.1-R0.1-SNAPSHOT"
plotsquared = "7.3.9-20240513.192211-13"
plotsquared = "7.3.8"
reflection-remapper = "0.1.2-20240315.033304-2"
viaversion-api = "5.0.1"
worldguard-bukkit = "7.0.9-SNAPSHOT"
Expand Down
127 changes: 73 additions & 54 deletions src/main/java/com/moulberry/axiom/AxiomPaper.java
Original file line number Diff line number Diff line change
Expand Up @@ -9,25 +9,7 @@
import com.moulberry.axiom.integration.coreprotect.CoreProtectIntegration;
import com.moulberry.axiom.integration.plotsquared.PlotSquaredIntegration;
import com.moulberry.axiom.packet.*;
import com.moulberry.axiom.packet.impl.BlueprintRequestPacketListener;
import com.moulberry.axiom.packet.impl.DeleteEntityPacketListener;
import com.moulberry.axiom.packet.impl.HelloPacketListener;
import com.moulberry.axiom.packet.impl.ManipulateEntityPacketListener;
import com.moulberry.axiom.packet.impl.MarkerNbtRequestPacketListener;
import com.moulberry.axiom.packet.impl.RequestChunkDataPacketListener;
import com.moulberry.axiom.packet.impl.SetBlockBufferPacketListener;
import com.moulberry.axiom.packet.impl.SetBlockPacketListener;
import com.moulberry.axiom.packet.impl.SetEditorViewsPacketListener;
import com.moulberry.axiom.packet.impl.SetFlySpeedPacketListener;
import com.moulberry.axiom.packet.impl.SetGamemodePacketListener;
import com.moulberry.axiom.packet.impl.SetHotbarSlotPacketListener;
import com.moulberry.axiom.packet.impl.SetTimePacketListener;
import com.moulberry.axiom.packet.impl.SetWorldPropertyListener;
import com.moulberry.axiom.packet.impl.SpawnEntityPacketListener;
import com.moulberry.axiom.packet.impl.SwitchActiveHotbarPacketListener;
import com.moulberry.axiom.packet.impl.TeleportPacketListener;
import com.moulberry.axiom.packet.impl.UpdateAnnotationPacketListener;
import com.moulberry.axiom.packet.impl.UploadBlueprintPacketListener;
import com.moulberry.axiom.packet.impl.*;
import com.moulberry.axiom.world_properties.server.ServerWorldPropertiesRegistry;
import io.netty.buffer.Unpooled;
import io.netty.channel.Channel;
Expand All @@ -46,6 +28,7 @@
import net.minecraft.network.protocol.PacketFlow;
import net.minecraft.network.protocol.game.ServerboundCustomPayloadPacket;
import net.minecraft.server.MinecraftServer;
import net.minecraft.world.entity.EntityType;
import net.minecraft.world.level.block.state.BlockState;
import org.bukkit.*;
import org.bukkit.command.CommandSender;
Expand All @@ -68,6 +51,7 @@
import java.nio.file.Path;
import java.util.*;
import java.util.concurrent.ConcurrentHashMap;
import java.util.function.IntFunction;

public class AxiomPaper extends JavaPlugin implements Listener {

Expand All @@ -82,6 +66,9 @@ public class AxiomPaper extends JavaPlugin implements Listener {

public IdMapper<BlockState> allowedBlockRegistry = null;
private boolean logLargeBlockBufferChanges = false;
private int packetCollectionReadLimit = 1024;
private Set<EntityType<?>> whitelistedEntities = new HashSet<>();
private Set<EntityType<?>> blacklistedEntities = new HashSet<>();

public Path blueprintFolder = null;
public boolean allowAnnotations = false;
Expand All @@ -101,9 +88,21 @@ public void onEnable() {
this.getLogger().warning("Invalid value for unsupported-axiom-version, expected 'kick', 'warn' or 'ignore'");
}

boolean allowLargeChunkDataRequest = this.configuration.getBoolean("allow-large-chunk-data-request");
this.logLargeBlockBufferChanges = this.configuration.getBoolean("log-large-block-buffer-changes");

if (this.configuration.getBoolean("allow-large-payload-for-all-packets")) {
packetCollectionReadLimit = Short.MAX_VALUE;
}

this.whitelistedEntities.clear();
this.blacklistedEntities.clear();
for (String whitelistedEntity : this.configuration.getStringList("whitelist-entities")) {
EntityType.byString(whitelistedEntity).ifPresent(this.whitelistedEntities::add);
}
for (String blacklistedEntity : this.configuration.getStringList("blacklist-entities")) {
EntityType.byString(blacklistedEntity).ifPresent(this.blacklistedEntities::add);
}

List<String> disallowedBlocks = this.configuration.getStringList("disallowed-blocks");
this.allowedBlockRegistry = DisallowedBlocks.createAllowedBlockRegistry(disallowedBlocks);

Expand Down Expand Up @@ -132,27 +131,29 @@ public void onEnable() {

Map<String, PacketHandler> largePayloadHandlers = new HashMap<>();

registerPacketHandler("hello", new HelloPacketListener(this), msg, largePayloadHandlers);
registerPacketHandler("set_gamemode", new SetGamemodePacketListener(this), msg, largePayloadHandlers);
registerPacketHandler("set_fly_speed", new SetFlySpeedPacketListener(this), msg, largePayloadHandlers);
registerPacketHandler("set_world_time", new SetTimePacketListener(this), msg, largePayloadHandlers);
registerPacketHandler("set_world_property", new SetWorldPropertyListener(this), msg, largePayloadHandlers);
registerPacketHandler("set_block", new SetBlockPacketListener(this), msg, largePayloadHandlers); // set-single-block
registerPacketHandler("set_hotbar_slot", new SetHotbarSlotPacketListener(this), msg, largePayloadHandlers);
registerPacketHandler("switch_active_hotbar", new SwitchActiveHotbarPacketListener(this), msg, largePayloadHandlers);
registerPacketHandler("teleport", new TeleportPacketListener(this), msg, largePayloadHandlers);
registerPacketHandler("set_editor_views", new SetEditorViewsPacketListener(this), msg, largePayloadHandlers);
registerPacketHandler("request_chunk_data", new RequestChunkDataPacketListener(this,
!configuration.getBoolean("packet-handlers.request-chunk-data")), msg, largePayloadHandlers);
registerPacketHandler("spawn_entity", new SpawnEntityPacketListener(this), msg, largePayloadHandlers);
registerPacketHandler("manipulate_entity", new ManipulateEntityPacketListener(this), msg, largePayloadHandlers);
registerPacketHandler("delete_entity", new DeleteEntityPacketListener(this), msg, largePayloadHandlers);
registerPacketHandler("marker_nbt_request", new MarkerNbtRequestPacketListener(this), msg, largePayloadHandlers);
registerPacketHandler("request_blueprint", new BlueprintRequestPacketListener(this), msg, largePayloadHandlers);

registerPacketHandler("set_buffer", new SetBlockBufferPacketListener(this), msg, largePayloadHandlers);
registerPacketHandler("upload_blueprint", new UploadBlueprintPacketListener(this), msg, largePayloadHandlers);
registerPacketHandler("annotation_update", new UpdateAnnotationPacketListener(this), msg, largePayloadHandlers);
registerPacketHandler("hello", new HelloPacketListener(this), msg, LargePayloadBehaviour.FORCE_SMALL, largePayloadHandlers);
registerPacketHandler("set_gamemode", new SetGamemodePacketListener(this), msg, LargePayloadBehaviour.DEFAULT, largePayloadHandlers);
registerPacketHandler("set_fly_speed", new SetFlySpeedPacketListener(this), msg, LargePayloadBehaviour.DEFAULT, largePayloadHandlers);
registerPacketHandler("set_world_time", new SetTimePacketListener(this), msg, LargePayloadBehaviour.DEFAULT, largePayloadHandlers);
registerPacketHandler("set_world_property", new SetWorldPropertyListener(this), msg, LargePayloadBehaviour.DEFAULT, largePayloadHandlers);
registerPacketHandler("set_block", new SetBlockPacketListener(this), msg, LargePayloadBehaviour.DEFAULT, largePayloadHandlers); // set-single-block
registerPacketHandler("set_hotbar_slot", new SetHotbarSlotPacketListener(this), msg, LargePayloadBehaviour.DEFAULT, largePayloadHandlers);
registerPacketHandler("switch_active_hotbar", new SwitchActiveHotbarPacketListener(this), msg, LargePayloadBehaviour.DEFAULT, largePayloadHandlers);
registerPacketHandler("teleport", new TeleportPacketListener(this), msg, LargePayloadBehaviour.DEFAULT, largePayloadHandlers);
registerPacketHandler("set_editor_views", new SetEditorViewsPacketListener(this), msg, LargePayloadBehaviour.DEFAULT, largePayloadHandlers);
registerPacketHandler("request_chunk_data", new RequestChunkDataPacketListener(this, !configuration.getBoolean("packet-handlers.request-chunk-data")), msg,
this.configuration.getBoolean("allow-large-chunk-data-request") ? LargePayloadBehaviour.FORCE_LARGE : LargePayloadBehaviour.DEFAULT, largePayloadHandlers);
registerPacketHandler("request_entity_data", new RequestEntityDataPacketListener(this, !configuration.getBoolean("packet-handlers.request-entity-data")), msg,
this.configuration.getBoolean("allow-large-chunk-data-request") ? LargePayloadBehaviour.FORCE_LARGE : LargePayloadBehaviour.DEFAULT, largePayloadHandlers);
registerPacketHandler("spawn_entity", new SpawnEntityPacketListener(this), msg, LargePayloadBehaviour.DEFAULT, largePayloadHandlers);
registerPacketHandler("manipulate_entity", new ManipulateEntityPacketListener(this), msg, LargePayloadBehaviour.DEFAULT, largePayloadHandlers);
registerPacketHandler("delete_entity", new DeleteEntityPacketListener(this), msg, LargePayloadBehaviour.DEFAULT, largePayloadHandlers);
registerPacketHandler("marker_nbt_request", new MarkerNbtRequestPacketListener(this), msg, LargePayloadBehaviour.DEFAULT, largePayloadHandlers);
registerPacketHandler("request_blueprint", new BlueprintRequestPacketListener(this), msg, LargePayloadBehaviour.DEFAULT, largePayloadHandlers);

registerPacketHandler("set_buffer", new SetBlockBufferPacketListener(this), msg, LargePayloadBehaviour.FORCE_LARGE, largePayloadHandlers);
registerPacketHandler("upload_blueprint", new UploadBlueprintPacketListener(this), msg, LargePayloadBehaviour.FORCE_LARGE, largePayloadHandlers);
registerPacketHandler("annotation_update", new UpdateAnnotationPacketListener(this), msg, LargePayloadBehaviour.FORCE_LARGE, largePayloadHandlers);

if (!largePayloadHandlers.isEmpty()) {
ChannelInitializeListenerHolder.addListener(Key.key("axiom:handle_big_payload"), new ChannelInitializeListener() {
Expand Down Expand Up @@ -302,25 +303,26 @@ public void afterInitChannel(@NonNull Channel channel) {
}
}

private void registerPacketHandler(String name, PacketHandler handler, Messenger messenger, Map<String, PacketHandler> largePayloadHandlers) {
private enum LargePayloadBehaviour {
DEFAULT,
FORCE_LARGE,
FORCE_SMALL
}

private void registerPacketHandler(String name, PacketHandler handler, Messenger messenger, LargePayloadBehaviour behaviour,
Map<String, PacketHandler> largePayloadHandlers) {
String configEntry = "packet-handlers." + name.replace("_", "-");
if (name.equals("set_block")) {
configEntry = "packet-handlers.set-single-block";
} else if (name.equals("request_blueprint")) {
configEntry = "packet-handlers.blueprint-request";
}
if (name.equals("request-chunk-data") || this.configuration.getBoolean(configEntry, true)) {
boolean isLargePayload = false;

if (name.equals("hello")) { // Hello must use normal system, as non-Axiom players can't send large payloads
isLargePayload = false;
} else if (this.configuration.getBoolean("allow-large-payload-for-all-packets")) {
isLargePayload = true;
} else if (name.equals("set_buffer") || name.equals("upload_blueprint") || name.equals("annotation_update")) {
isLargePayload = true;
} else if (name.equals("request_chunk_data") && this.configuration.getBoolean("allow-large-chunk-data-request")) {
isLargePayload = true;
}
if (name.equals("request_chunk_data") || name.equals("request_entity_data") || this.configuration.getBoolean(configEntry, true)) {
boolean isLargePayload = switch (behaviour) {
case DEFAULT -> this.configuration.getBoolean("allow-large-payload-for-all-packets");
case FORCE_LARGE -> true;
case FORCE_SMALL -> false;
};

if (isLargePayload) {
largePayloadHandlers.put("axiom:"+name, handler);
Expand Down Expand Up @@ -350,6 +352,10 @@ private int calculateAllowedCapabilities() {
return allowedCapabilities;
}

public <T> IntFunction<T> limitCollection(IntFunction<T> applier) {
return FriendlyByteBuf.limitValue(applier, this.packetCollectionReadLimit);
}

public boolean logLargeBlockBufferChanges() {
return this.logLargeBlockBufferChanges;
}
Expand Down Expand Up @@ -379,6 +385,19 @@ public boolean canUseAxiom(Player player, String permission, boolean strict) {
return activeAxiomPlayers.contains(player.getUniqueId()) && hasAxiomPermission(player, permission, strict);
}

public boolean canEntityBeManipulated(EntityType<?> entityType) {
if (entityType == EntityType.PLAYER) {
return false;
}
if (!this.whitelistedEntities.isEmpty() && !this.whitelistedEntities.contains(entityType)) {
return false;
}
if (this.blacklistedEntities.contains(entityType)) {
return false;
}
return true;
}

public @Nullable RateLimiter getBlockBufferRateLimiter(UUID uuid) {
return this.playerBlockBufferRateLimiters.get(uuid);
}
Expand Down
13 changes: 13 additions & 0 deletions src/main/java/com/moulberry/axiom/NbtSanitization.java
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,15 @@ public class NbtSanitization {
"Glowing",
"Tags",
"Passengers",
// armor stand
"ArmorItems",
"HandItems",
"Small",
"ShowArms",
"DisabledSlots",
"NoBasePlate",
"Marker",
"Pose",
// marker
"data",
// display entity
Expand Down Expand Up @@ -50,6 +59,10 @@ public class NbtSanitization {
);

public static void sanitizeEntity(CompoundTag entityRoot) {
if (AxiomPaper.PLUGIN.configuration.getBoolean("disable-entity-sanitization")) {
return;
}

entityRoot.getAllKeys().retainAll(ALLOWED_KEYS);

if (entityRoot.contains("Passengers", Tag.TAG_LIST)) {
Expand Down
15 changes: 9 additions & 6 deletions src/main/java/com/moulberry/axiom/blueprint/BlueprintHeader.java
Original file line number Diff line number Diff line change
Expand Up @@ -9,24 +9,25 @@
import java.util.ArrayList;
import java.util.List;

public record BlueprintHeader(String name, String author, List<String> tags, float thumbnailYaw, float thumbnailPitch, boolean lockedThumbnail, int blockCount) {
public record BlueprintHeader(String name, String author, List<String> tags, float thumbnailYaw, float thumbnailPitch, boolean lockedThumbnail, int blockCount, boolean containsAir) {

private static final int CURRENT_VERSION = 0;
private static final int CURRENT_VERSION = 1;

public void write(FriendlyByteBuf friendlyByteBuf) {
friendlyByteBuf.writeUtf(this.name);
friendlyByteBuf.writeUtf(this.author);
friendlyByteBuf.writeCollection(this.tags, FriendlyByteBuf::writeUtf);
friendlyByteBuf.writeInt(this.blockCount);
friendlyByteBuf.writeBoolean(this.containsAir);
}

public static BlueprintHeader read(FriendlyByteBuf friendlyByteBuf) {
String name = friendlyByteBuf.readUtf();
String author = friendlyByteBuf.readUtf();
List<String> tags = friendlyByteBuf.readCollection(FriendlyByteBuf.limitValue(ArrayList::new, 1000),
FriendlyByteBuf::readUtf);
List<String> tags = friendlyByteBuf.readList(FriendlyByteBuf::readUtf);
int blockCount = friendlyByteBuf.readInt();
return new BlueprintHeader(name, author, tags, 0, 0, true, blockCount);
boolean containsAir = friendlyByteBuf.readBoolean();
return new BlueprintHeader(name, author, tags, 0, 0, true, blockCount, containsAir);
}

public static BlueprintHeader load(CompoundTag tag) {
Expand All @@ -37,13 +38,14 @@ public static BlueprintHeader load(CompoundTag tag) {
float thumbnailPitch = tag.contains("ThumbnailPitch", Tag.TAG_FLOAT) ? tag.getFloat("ThumbnailPitch") : 30;
boolean lockedThumbnail = tag.getBoolean("LockedThumbnail");
int blockCount = tag.getInt("BlockCount");
boolean containsAir = tag.getBoolean("ContainsAir");

List<String> tags = new ArrayList<>();
for (Tag string : tag.getList("Tags", Tag.TAG_STRING)) {
tags.add(string.getAsString());
}

return new BlueprintHeader(name, author, tags, thumbnailYaw, thumbnailPitch, lockedThumbnail, blockCount);
return new BlueprintHeader(name, author, tags, thumbnailYaw, thumbnailPitch, lockedThumbnail, blockCount, containsAir);
}

public CompoundTag save(CompoundTag tag) {
Expand All @@ -60,6 +62,7 @@ public CompoundTag save(CompoundTag tag) {
tag.putFloat("ThumbnailPitch", this.thumbnailPitch);
tag.putBoolean("LockedThumbnail", this.lockedThumbnail);
tag.putInt("BlockCount", this.blockCount);
tag.putBoolean("ContainsAir", this.containsAir);
return tag;
}

Expand Down
Loading

0 comments on commit 21fef04

Please sign in to comment.