Mirror von
https://github.com/Moulberry/AxiomPaperPlugin.git
synchronisiert 2024-11-14 20:20:07 +01:00
Add marker manipulation & nbt sanitization
Dieser Commit ist enthalten in:
Ursprung
ceefcf1bce
Commit
15161356f5
@ -84,6 +84,8 @@ public class AxiomPaper extends JavaPlugin implements Listener {
|
|||||||
msg.registerOutgoingPluginChannel(this, "axiom:set_world_property");
|
msg.registerOutgoingPluginChannel(this, "axiom:set_world_property");
|
||||||
msg.registerOutgoingPluginChannel(this, "axiom:ack_world_properties");
|
msg.registerOutgoingPluginChannel(this, "axiom:ack_world_properties");
|
||||||
msg.registerOutgoingPluginChannel(this, "axiom:restrictions");
|
msg.registerOutgoingPluginChannel(this, "axiom:restrictions");
|
||||||
|
msg.registerOutgoingPluginChannel(this, "axiom:marker_data");
|
||||||
|
msg.registerOutgoingPluginChannel(this, "axiom:marker_nbt_response");
|
||||||
|
|
||||||
if (configuration.getBoolean("packet-handlers.hello")) {
|
if (configuration.getBoolean("packet-handlers.hello")) {
|
||||||
msg.registerIncomingPluginChannel(this, "axiom:hello", new HelloPacketListener(this));
|
msg.registerIncomingPluginChannel(this, "axiom:hello", new HelloPacketListener(this));
|
||||||
@ -127,6 +129,9 @@ public class AxiomPaper extends JavaPlugin implements Listener {
|
|||||||
if (configuration.getBoolean("packet-handlers.delete-entity")) {
|
if (configuration.getBoolean("packet-handlers.delete-entity")) {
|
||||||
msg.registerIncomingPluginChannel(this, "axiom:delete_entity", new DeleteEntityPacketListener(this));
|
msg.registerIncomingPluginChannel(this, "axiom:delete_entity", new DeleteEntityPacketListener(this));
|
||||||
}
|
}
|
||||||
|
if (configuration.getBoolean("packet-handlers.marker-nbt-request")) {
|
||||||
|
msg.registerIncomingPluginChannel(this, "axiom:marker_nbt_request", new MarkerNbtRequestPacketListener(this));
|
||||||
|
}
|
||||||
|
|
||||||
if (configuration.getBoolean("packet-handlers.set-buffer")) {
|
if (configuration.getBoolean("packet-handlers.set-buffer")) {
|
||||||
SetBlockBufferPacketListener setBlockBufferPacketListener = new SetBlockBufferPacketListener(this);
|
SetBlockBufferPacketListener setBlockBufferPacketListener = new SetBlockBufferPacketListener(this);
|
||||||
@ -238,11 +243,12 @@ public class AxiomPaper extends JavaPlugin implements Listener {
|
|||||||
playerRestrictions.keySet().retainAll(stillActiveAxiomPlayers);
|
playerRestrictions.keySet().retainAll(stillActiveAxiomPlayers);
|
||||||
}, 20, 20);
|
}, 20, 20);
|
||||||
|
|
||||||
|
boolean sendMarkers = configuration.getBoolean("send-markers");
|
||||||
int maxChunkRelightsPerTick = configuration.getInt("max-chunk-relights-per-tick");
|
int maxChunkRelightsPerTick = configuration.getInt("max-chunk-relights-per-tick");
|
||||||
int maxChunkSendsPerTick = configuration.getInt("max-chunk-sends-per-tick");
|
int maxChunkSendsPerTick = configuration.getInt("max-chunk-sends-per-tick");
|
||||||
|
|
||||||
Bukkit.getScheduler().scheduleSyncRepeatingTask(this, () -> {
|
Bukkit.getScheduler().scheduleSyncRepeatingTask(this, () -> {
|
||||||
WorldExtension.tick(MinecraftServer.getServer(), maxChunkRelightsPerTick, maxChunkSendsPerTick);
|
WorldExtension.tick(MinecraftServer.getServer(), sendMarkers, maxChunkRelightsPerTick, maxChunkSendsPerTick);
|
||||||
}, 1, 1);
|
}, 1, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -292,17 +298,22 @@ public class AxiomPaper extends JavaPlugin implements Listener {
|
|||||||
|
|
||||||
@EventHandler
|
@EventHandler
|
||||||
public void onFailMove(PlayerFailMoveEvent event) {
|
public void onFailMove(PlayerFailMoveEvent event) {
|
||||||
if (event.getPlayer().hasPermission("axiom.*")) {
|
if (!this.activeAxiomPlayers.contains(event.getPlayer().getUniqueId())) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
if (event.getFailReason() == PlayerFailMoveEvent.FailReason.MOVED_TOO_QUICKLY) {
|
if (event.getFailReason() == PlayerFailMoveEvent.FailReason.MOVED_TOO_QUICKLY) {
|
||||||
event.setAllowed(true); // Support for arcball camera
|
event.setAllowed(true); // Support for arcball camera
|
||||||
} else if (event.getPlayer().isFlying()) {
|
} else if (event.getPlayer().isFlying()) {
|
||||||
event.setAllowed(true); // Support for noclip
|
event.setAllowed(true); // Support for noclip
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
@EventHandler
|
@EventHandler
|
||||||
public void onChangedWorld(PlayerChangedWorldEvent event) {
|
public void onChangedWorld(PlayerChangedWorldEvent event) {
|
||||||
|
if (!this.activeAxiomPlayers.contains(event.getPlayer().getUniqueId())) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
World world = event.getPlayer().getWorld();
|
World world = event.getPlayer().getWorld();
|
||||||
|
|
||||||
ServerWorldPropertiesRegistry properties = getOrCreateWorldProperties(world);
|
ServerWorldPropertiesRegistry properties = getOrCreateWorldProperties(world);
|
||||||
@ -312,6 +323,8 @@ public class AxiomPaper extends JavaPlugin implements Listener {
|
|||||||
} else {
|
} else {
|
||||||
properties.registerFor(this, event.getPlayer());
|
properties.registerFor(this, event.getPlayer());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
WorldExtension.onPlayerJoin(world, event.getPlayer());
|
||||||
}
|
}
|
||||||
|
|
||||||
@EventHandler
|
@EventHandler
|
||||||
|
63
src/main/java/com/moulberry/axiom/NbtSanitization.java
Normale Datei
63
src/main/java/com/moulberry/axiom/NbtSanitization.java
Normale Datei
@ -0,0 +1,63 @@
|
|||||||
|
package com.moulberry.axiom;
|
||||||
|
|
||||||
|
import net.minecraft.nbt.CompoundTag;
|
||||||
|
import net.minecraft.nbt.ListTag;
|
||||||
|
import net.minecraft.nbt.Tag;
|
||||||
|
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
|
public class NbtSanitization {
|
||||||
|
|
||||||
|
private static final Set<String> ALLOWED_KEYS = Set.of(
|
||||||
|
"id", // entity id
|
||||||
|
// generic
|
||||||
|
"Pos",
|
||||||
|
"Rotation",
|
||||||
|
"Invulnerable",
|
||||||
|
"CustomName",
|
||||||
|
"CustomNameVisible",
|
||||||
|
"Silent",
|
||||||
|
"NoGravity",
|
||||||
|
"Glowing",
|
||||||
|
"Tags",
|
||||||
|
"Passengers",
|
||||||
|
// marker
|
||||||
|
"data",
|
||||||
|
// display entity
|
||||||
|
"transformation",
|
||||||
|
"interpolation_duration",
|
||||||
|
"start_interpolation",
|
||||||
|
"teleport_duration",
|
||||||
|
"billboard",
|
||||||
|
"view_range",
|
||||||
|
"shadow_radius",
|
||||||
|
"shadow_strength",
|
||||||
|
"width",
|
||||||
|
"height",
|
||||||
|
"glow_color_override",
|
||||||
|
"brightness",
|
||||||
|
"line_width",
|
||||||
|
"text_opacity",
|
||||||
|
"background",
|
||||||
|
"shadow",
|
||||||
|
"see_through",
|
||||||
|
"default_background",
|
||||||
|
"alignment",
|
||||||
|
"text",
|
||||||
|
"block_state",
|
||||||
|
"item",
|
||||||
|
"item_display"
|
||||||
|
);
|
||||||
|
|
||||||
|
public static void sanitizeEntity(CompoundTag entityRoot) {
|
||||||
|
entityRoot.getAllKeys().retainAll(ALLOWED_KEYS);
|
||||||
|
|
||||||
|
if (entityRoot.contains("Passengers", Tag.TAG_LIST)) {
|
||||||
|
ListTag listTag = entityRoot.getList("Passengers", Tag.TAG_COMPOUND);
|
||||||
|
for (Tag tag : listTag) {
|
||||||
|
sanitizeEntity((CompoundTag) tag);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -1,15 +1,24 @@
|
|||||||
package com.moulberry.axiom;
|
package com.moulberry.axiom;
|
||||||
|
|
||||||
|
import com.moulberry.axiom.marker.MarkerData;
|
||||||
|
import io.netty.buffer.Unpooled;
|
||||||
import it.unimi.dsi.fastutil.longs.*;
|
import it.unimi.dsi.fastutil.longs.*;
|
||||||
|
import net.minecraft.network.FriendlyByteBuf;
|
||||||
import net.minecraft.network.protocol.game.ClientboundLevelChunkWithLightPacket;
|
import net.minecraft.network.protocol.game.ClientboundLevelChunkWithLightPacket;
|
||||||
import net.minecraft.resources.ResourceKey;
|
import net.minecraft.resources.ResourceKey;
|
||||||
import net.minecraft.server.MinecraftServer;
|
import net.minecraft.server.MinecraftServer;
|
||||||
import net.minecraft.server.level.ChunkMap;
|
import net.minecraft.server.level.ChunkMap;
|
||||||
import net.minecraft.server.level.ServerLevel;
|
import net.minecraft.server.level.ServerLevel;
|
||||||
import net.minecraft.server.level.ServerPlayer;
|
import net.minecraft.server.level.ServerPlayer;
|
||||||
|
import net.minecraft.world.entity.Entity;
|
||||||
|
import net.minecraft.world.entity.Marker;
|
||||||
import net.minecraft.world.level.ChunkPos;
|
import net.minecraft.world.level.ChunkPos;
|
||||||
import net.minecraft.world.level.Level;
|
import net.minecraft.world.level.Level;
|
||||||
import net.minecraft.world.level.chunk.LevelChunk;
|
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.entity.Player;
|
||||||
|
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
|
|
||||||
@ -23,15 +32,16 @@ public class WorldExtension {
|
|||||||
return extension;
|
return extension;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void tick(MinecraftServer server, int maxChunkRelightsPerTick, int maxChunkSendsPerTick) {
|
public static void onPlayerJoin(World world, Player player) {
|
||||||
|
ServerLevel level = ((CraftWorld)world).getHandle();
|
||||||
|
get(level).onPlayerJoin(player);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void tick(MinecraftServer server, boolean sendMarkers, int maxChunkRelightsPerTick, int maxChunkSendsPerTick) {
|
||||||
extensions.keySet().retainAll(server.levelKeys());
|
extensions.keySet().retainAll(server.levelKeys());
|
||||||
|
|
||||||
for (ServerLevel level : server.getAllLevels()) {
|
for (ServerLevel level : server.getAllLevels()) {
|
||||||
WorldExtension extension = extensions.get(level.dimension());
|
get(level).tick(sendMarkers, maxChunkRelightsPerTick, maxChunkSendsPerTick);
|
||||||
if (extension != null) {
|
|
||||||
extension.level = level;
|
|
||||||
extension.tick(maxChunkRelightsPerTick, maxChunkSendsPerTick);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -39,6 +49,7 @@ public class WorldExtension {
|
|||||||
|
|
||||||
private final LongSet pendingChunksToSend = new LongOpenHashSet();
|
private final LongSet pendingChunksToSend = new LongOpenHashSet();
|
||||||
private final LongSet pendingChunksToLight = new LongOpenHashSet();
|
private final LongSet pendingChunksToLight = new LongOpenHashSet();
|
||||||
|
private final Map<UUID, MarkerData> previousMarkerData = new HashMap<>();
|
||||||
|
|
||||||
public void sendChunk(int cx, int cz) {
|
public void sendChunk(int cx, int cz) {
|
||||||
this.pendingChunksToSend.add(ChunkPos.asLong(cx, cz));
|
this.pendingChunksToSend.add(ChunkPos.asLong(cx, cz));
|
||||||
@ -48,7 +59,66 @@ public class WorldExtension {
|
|||||||
this.pendingChunksToLight.add(ChunkPos.asLong(cx, cz));
|
this.pendingChunksToLight.add(ChunkPos.asLong(cx, cz));
|
||||||
}
|
}
|
||||||
|
|
||||||
public void tick(int maxChunkRelightsPerTick, int maxChunkSendsPerTick) {
|
public void onPlayerJoin(Player player) {
|
||||||
|
if (!this.previousMarkerData.isEmpty()) {
|
||||||
|
List<MarkerData> markerData = new ArrayList<>(this.previousMarkerData.values());
|
||||||
|
|
||||||
|
FriendlyByteBuf buf = new FriendlyByteBuf(Unpooled.buffer());
|
||||||
|
buf.writeCollection(markerData, MarkerData::write);
|
||||||
|
buf.writeCollection(Set.of(), FriendlyByteBuf::writeUUID);
|
||||||
|
byte[] bytes = new byte[buf.writerIndex()];
|
||||||
|
buf.getBytes(0, bytes);
|
||||||
|
|
||||||
|
player.sendPluginMessage(AxiomPaper.PLUGIN, "axiom:marker_data", bytes);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void tick(boolean sendMarkers, int maxChunkRelightsPerTick, int maxChunkSendsPerTick) {
|
||||||
|
if (sendMarkers) {
|
||||||
|
this.tickMarkers();
|
||||||
|
}
|
||||||
|
this.tickChunkRelight(maxChunkRelightsPerTick, maxChunkSendsPerTick);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void tickMarkers() {
|
||||||
|
List<MarkerData> changedData = new ArrayList<>();
|
||||||
|
|
||||||
|
Set<UUID> allMarkers = new HashSet<>();
|
||||||
|
|
||||||
|
for (Entity entity : this.level.getEntities().getAll()) {
|
||||||
|
if (entity instanceof Marker marker) {
|
||||||
|
MarkerData currentData = MarkerData.createFrom(marker);
|
||||||
|
|
||||||
|
MarkerData previousData = this.previousMarkerData.get(marker.getUUID());
|
||||||
|
if (!Objects.equals(currentData, previousData)) {
|
||||||
|
this.previousMarkerData.put(marker.getUUID(), currentData);
|
||||||
|
changedData.add(currentData);
|
||||||
|
}
|
||||||
|
|
||||||
|
allMarkers.add(marker.getUUID());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Set<UUID> oldUuids = new HashSet<>(this.previousMarkerData.keySet());
|
||||||
|
oldUuids.removeAll(allMarkers);
|
||||||
|
this.previousMarkerData.keySet().removeAll(oldUuids);
|
||||||
|
|
||||||
|
if (!changedData.isEmpty() || !oldUuids.isEmpty()) {
|
||||||
|
FriendlyByteBuf buf = new FriendlyByteBuf(Unpooled.buffer());
|
||||||
|
buf.writeCollection(changedData, MarkerData::write);
|
||||||
|
buf.writeCollection(oldUuids, FriendlyByteBuf::writeUUID);
|
||||||
|
byte[] bytes = new byte[buf.writerIndex()];
|
||||||
|
buf.getBytes(0, bytes);
|
||||||
|
|
||||||
|
for (ServerPlayer player : this.level.players()) {
|
||||||
|
if (AxiomPaper.PLUGIN.activeAxiomPlayers.contains(player.getUUID())) {
|
||||||
|
player.getBukkitEntity().sendPluginMessage(AxiomPaper.PLUGIN, "axiom:marker_data", bytes);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void tickChunkRelight(int maxChunkRelightsPerTick, int maxChunkSendsPerTick) {
|
||||||
ChunkMap chunkMap = this.level.getChunkSource().chunkMap;
|
ChunkMap chunkMap = this.level.getChunkSource().chunkMap;
|
||||||
|
|
||||||
boolean sendAll = maxChunkSendsPerTick <= 0;
|
boolean sendAll = maxChunkSendsPerTick <= 0;
|
||||||
|
105
src/main/java/com/moulberry/axiom/marker/MarkerData.java
Normale Datei
105
src/main/java/com/moulberry/axiom/marker/MarkerData.java
Normale Datei
@ -0,0 +1,105 @@
|
|||||||
|
package com.moulberry.axiom.marker;
|
||||||
|
|
||||||
|
import net.minecraft.nbt.CompoundTag;
|
||||||
|
import net.minecraft.nbt.ListTag;
|
||||||
|
import net.minecraft.nbt.Tag;
|
||||||
|
import net.minecraft.network.FriendlyByteBuf;
|
||||||
|
import net.minecraft.world.entity.Marker;
|
||||||
|
import net.minecraft.world.level.block.entity.BlockEntity;
|
||||||
|
import net.minecraft.world.level.chunk.LevelChunk;
|
||||||
|
import net.minecraft.world.phys.Vec3;
|
||||||
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
import xyz.jpenilla.reflectionremapper.ReflectionRemapper;
|
||||||
|
|
||||||
|
import java.lang.reflect.Field;
|
||||||
|
import java.lang.reflect.Method;
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
|
public record MarkerData(UUID uuid, Vec3 position, @Nullable String name, @Nullable Vec3 minRegion, @Nullable Vec3 maxRegion) {
|
||||||
|
public static MarkerData read(FriendlyByteBuf friendlyByteBuf) {
|
||||||
|
UUID uuid = friendlyByteBuf.readUUID();
|
||||||
|
Vec3 position = new Vec3(friendlyByteBuf.readDouble(), friendlyByteBuf.readDouble(), friendlyByteBuf.readDouble());
|
||||||
|
String name = friendlyByteBuf.readNullable(FriendlyByteBuf::readUtf);
|
||||||
|
|
||||||
|
Vec3 minRegion = null;
|
||||||
|
Vec3 maxRegion = null;
|
||||||
|
if (friendlyByteBuf.readBoolean()) {
|
||||||
|
minRegion = new Vec3(friendlyByteBuf.readDouble(), friendlyByteBuf.readDouble(), friendlyByteBuf.readDouble());
|
||||||
|
maxRegion = new Vec3(friendlyByteBuf.readDouble(), friendlyByteBuf.readDouble(), friendlyByteBuf.readDouble());
|
||||||
|
}
|
||||||
|
|
||||||
|
return new MarkerData(uuid, position, name, minRegion, maxRegion);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void write(FriendlyByteBuf friendlyByteBuf, MarkerData markerData) {
|
||||||
|
friendlyByteBuf.writeUUID(markerData.uuid);
|
||||||
|
friendlyByteBuf.writeDouble(markerData.position.x);
|
||||||
|
friendlyByteBuf.writeDouble(markerData.position.y);
|
||||||
|
friendlyByteBuf.writeDouble(markerData.position.z);
|
||||||
|
friendlyByteBuf.writeNullable(markerData.name, FriendlyByteBuf::writeUtf);
|
||||||
|
|
||||||
|
if (markerData.minRegion != null && markerData.maxRegion != null) {
|
||||||
|
friendlyByteBuf.writeBoolean(true);
|
||||||
|
friendlyByteBuf.writeDouble(markerData.minRegion.x);
|
||||||
|
friendlyByteBuf.writeDouble(markerData.minRegion.y);
|
||||||
|
friendlyByteBuf.writeDouble(markerData.minRegion.z);
|
||||||
|
friendlyByteBuf.writeDouble(markerData.maxRegion.x);
|
||||||
|
friendlyByteBuf.writeDouble(markerData.maxRegion.y);
|
||||||
|
friendlyByteBuf.writeDouble(markerData.maxRegion.z);
|
||||||
|
} else {
|
||||||
|
friendlyByteBuf.writeBoolean(false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static final Field dataField;
|
||||||
|
static {
|
||||||
|
ReflectionRemapper reflectionRemapper = ReflectionRemapper.forReobfMappingsInPaperJar();
|
||||||
|
String fieldName = reflectionRemapper.remapFieldName(Marker.class, "data");
|
||||||
|
|
||||||
|
try {
|
||||||
|
dataField = Marker.class.getDeclaredField(fieldName);
|
||||||
|
dataField.setAccessible(true);
|
||||||
|
} catch (Exception e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
throw new RuntimeException(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static CompoundTag getData(Marker marker) {
|
||||||
|
try {
|
||||||
|
return (CompoundTag) dataField.get(marker);
|
||||||
|
} catch (Exception e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
throw new RuntimeException(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static MarkerData createFrom(Marker marker) {
|
||||||
|
Vec3 position = marker.position();
|
||||||
|
CompoundTag data = getData(marker);
|
||||||
|
|
||||||
|
String name = data.getString("name").trim();
|
||||||
|
if (name.isEmpty()) name = null;
|
||||||
|
|
||||||
|
Vec3 minRegion = null;
|
||||||
|
Vec3 maxRegion = null;
|
||||||
|
if (data.contains("min", Tag.TAG_LIST) && data.contains("max", Tag.TAG_LIST)) {
|
||||||
|
ListTag min = data.getList("min", Tag.TAG_DOUBLE);
|
||||||
|
ListTag max = data.getList("max", Tag.TAG_DOUBLE);
|
||||||
|
|
||||||
|
if (min.size() == 3 && max.size() == 3) {
|
||||||
|
double minX = min.getDouble(0);
|
||||||
|
double minY = min.getDouble(1);
|
||||||
|
double minZ = min.getDouble(2);
|
||||||
|
double maxX = max.getDouble(0);
|
||||||
|
double maxY = max.getDouble(1);
|
||||||
|
double maxZ = max.getDouble(2);
|
||||||
|
minRegion = new Vec3(minX, minY, minZ);
|
||||||
|
maxRegion = new Vec3(maxX, maxY, maxZ);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
return new MarkerData(marker.getUUID(), position, name, minRegion, maxRegion);
|
||||||
|
}
|
||||||
|
}
|
@ -4,6 +4,7 @@ import com.google.common.util.concurrent.RateLimiter;
|
|||||||
import com.moulberry.axiom.AxiomConstants;
|
import com.moulberry.axiom.AxiomConstants;
|
||||||
import com.moulberry.axiom.AxiomPaper;
|
import com.moulberry.axiom.AxiomPaper;
|
||||||
import com.moulberry.axiom.View;
|
import com.moulberry.axiom.View;
|
||||||
|
import com.moulberry.axiom.WorldExtension;
|
||||||
import com.moulberry.axiom.event.AxiomHandshakeEvent;
|
import com.moulberry.axiom.event.AxiomHandshakeEvent;
|
||||||
import com.moulberry.axiom.persistence.ItemStackDataType;
|
import com.moulberry.axiom.persistence.ItemStackDataType;
|
||||||
import com.moulberry.axiom.persistence.UUIDDataType;
|
import com.moulberry.axiom.persistence.UUIDDataType;
|
||||||
@ -167,6 +168,8 @@ public class HelloPacketListener implements PluginMessageListener {
|
|||||||
} else {
|
} else {
|
||||||
properties.registerFor(plugin, player);
|
properties.registerFor(plugin, player);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
WorldExtension.onPlayerJoin(world, player);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
package com.moulberry.axiom.packet;
|
package com.moulberry.axiom.packet;
|
||||||
|
|
||||||
import com.moulberry.axiom.AxiomPaper;
|
import com.moulberry.axiom.AxiomPaper;
|
||||||
|
import com.moulberry.axiom.NbtSanitization;
|
||||||
import io.netty.buffer.Unpooled;
|
import io.netty.buffer.Unpooled;
|
||||||
import net.minecraft.core.BlockPos;
|
import net.minecraft.core.BlockPos;
|
||||||
import net.minecraft.core.Direction;
|
import net.minecraft.core.Direction;
|
||||||
@ -104,6 +105,8 @@ public class ManipulateEntityPacketListener implements PluginMessageListener {
|
|||||||
if (blacklistedEntities.contains(type)) continue;
|
if (blacklistedEntities.contains(type)) continue;
|
||||||
|
|
||||||
if (entry.merge != null && !entry.merge.isEmpty()) {
|
if (entry.merge != null && !entry.merge.isEmpty()) {
|
||||||
|
NbtSanitization.sanitizeEntity(entry.merge);
|
||||||
|
|
||||||
CompoundTag compoundTag = entity.saveWithoutId(new CompoundTag());
|
CompoundTag compoundTag = entity.saveWithoutId(new CompoundTag());
|
||||||
compoundTag = merge(compoundTag, entry.merge);
|
compoundTag = merge(compoundTag, entry.merge);
|
||||||
entity.load(compoundTag);
|
entity.load(compoundTag);
|
||||||
|
@ -0,0 +1,66 @@
|
|||||||
|
package com.moulberry.axiom.packet;
|
||||||
|
|
||||||
|
import com.moulberry.axiom.AxiomPaper;
|
||||||
|
import com.moulberry.axiom.event.AxiomTimeChangeEvent;
|
||||||
|
import com.moulberry.axiom.integration.plotsquared.PlotSquaredIntegration;
|
||||||
|
import com.moulberry.axiom.marker.MarkerData;
|
||||||
|
import io.netty.buffer.Unpooled;
|
||||||
|
import net.minecraft.core.registries.Registries;
|
||||||
|
import net.minecraft.nbt.CompoundTag;
|
||||||
|
import net.minecraft.network.FriendlyByteBuf;
|
||||||
|
import net.minecraft.resources.ResourceKey;
|
||||||
|
import net.minecraft.server.level.ServerLevel;
|
||||||
|
import net.minecraft.world.entity.Entity;
|
||||||
|
import net.minecraft.world.entity.Marker;
|
||||||
|
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.entity.Player;
|
||||||
|
import org.bukkit.plugin.messaging.PluginMessageListener;
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
|
||||||
|
import java.util.Set;
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
|
public class MarkerNbtRequestPacketListener implements PluginMessageListener {
|
||||||
|
|
||||||
|
private final AxiomPaper plugin;
|
||||||
|
public MarkerNbtRequestPacketListener(AxiomPaper plugin) {
|
||||||
|
this.plugin = plugin;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onPluginMessageReceived(@NotNull String channel, @NotNull Player player, @NotNull byte[] message) {
|
||||||
|
if (!this.plugin.canUseAxiom(player)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!player.hasPermission("axiom.entity.*") && !player.hasPermission("axiom.entity.manipulate")) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!this.plugin.canModifyWorld(player, player.getWorld())) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
FriendlyByteBuf friendlyByteBuf = new FriendlyByteBuf(Unpooled.wrappedBuffer(message));
|
||||||
|
UUID uuid = friendlyByteBuf.readUUID();
|
||||||
|
|
||||||
|
ServerLevel serverLevel = ((CraftWorld)player.getWorld()).getHandle();
|
||||||
|
|
||||||
|
Entity entity = serverLevel.getEntity(uuid);
|
||||||
|
if (entity instanceof Marker marker) {
|
||||||
|
CompoundTag data = MarkerData.getData(marker);
|
||||||
|
|
||||||
|
FriendlyByteBuf buf = new FriendlyByteBuf(Unpooled.buffer());
|
||||||
|
buf.writeUUID(uuid);
|
||||||
|
buf.writeNbt(data);
|
||||||
|
byte[] bytes = new byte[buf.writerIndex()];
|
||||||
|
buf.getBytes(0, bytes);
|
||||||
|
|
||||||
|
player.sendPluginMessage(AxiomPaper.PLUGIN, "axiom:marker_nbt_response", bytes);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -1,6 +1,7 @@
|
|||||||
package com.moulberry.axiom.packet;
|
package com.moulberry.axiom.packet;
|
||||||
|
|
||||||
import com.moulberry.axiom.AxiomPaper;
|
import com.moulberry.axiom.AxiomPaper;
|
||||||
|
import com.moulberry.axiom.NbtSanitization;
|
||||||
import com.moulberry.axiom.event.AxiomTeleportEvent;
|
import com.moulberry.axiom.event.AxiomTeleportEvent;
|
||||||
import com.moulberry.axiom.event.AxiomUnknownTeleportEvent;
|
import com.moulberry.axiom.event.AxiomUnknownTeleportEvent;
|
||||||
import io.netty.buffer.Unpooled;
|
import io.netty.buffer.Unpooled;
|
||||||
@ -81,9 +82,11 @@ public class SpawnEntityPacketListener implements PluginMessageListener {
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (serverLevel.getEntity(entry.newUuid) != null) continue;
|
||||||
|
|
||||||
CompoundTag tag = entry.tag == null ? new CompoundTag() : entry.tag;
|
CompoundTag tag = entry.tag == null ? new CompoundTag() : entry.tag;
|
||||||
|
|
||||||
if (serverLevel.getEntity(entry.newUuid) != null) continue;
|
NbtSanitization.sanitizeEntity(tag);
|
||||||
|
|
||||||
if (entry.copyFrom != null) {
|
if (entry.copyFrom != null) {
|
||||||
Entity entityCopyFrom = serverLevel.getEntity(entry.copyFrom);
|
Entity entityCopyFrom = serverLevel.getEntity(entry.copyFrom);
|
||||||
|
@ -19,7 +19,6 @@ incompatible-data-version: "warn"
|
|||||||
unsupported-axiom-version: "warn"
|
unsupported-axiom-version: "warn"
|
||||||
client-doesnt-support-restrictions: "ignore"
|
client-doesnt-support-restrictions: "ignore"
|
||||||
|
|
||||||
|
|
||||||
# Maximum packet size. Must not be less than 32767
|
# Maximum packet size. Must not be less than 32767
|
||||||
max-block-buffer-packet-size: 0x100000
|
max-block-buffer-packet-size: 0x100000
|
||||||
|
|
||||||
@ -51,6 +50,9 @@ whitelist-entities:
|
|||||||
blacklist-entities:
|
blacklist-entities:
|
||||||
# - "minecraft:ender_dragon"
|
# - "minecraft:ender_dragon"
|
||||||
|
|
||||||
|
# True allows players to see/manipulate marker entities
|
||||||
|
send-markers: false
|
||||||
|
|
||||||
# Disallowed blocks
|
# Disallowed blocks
|
||||||
disallowed-blocks:
|
disallowed-blocks:
|
||||||
# - "minecraft:wheat"
|
# - "minecraft:wheat"
|
||||||
@ -73,3 +75,4 @@ packet-handlers:
|
|||||||
spawn-entity: true
|
spawn-entity: true
|
||||||
manipulate-entity: true
|
manipulate-entity: true
|
||||||
delete-entity: true
|
delete-entity: true
|
||||||
|
marker-nbt-request: true
|
||||||
|
Laden…
In neuem Issue referenzieren
Einen Benutzer sperren