geforkt von Mirrors/AxiomPaperPlugin
backport1.20.1 #6
@ -84,6 +84,8 @@ public class AxiomPaper extends JavaPlugin implements Listener {
|
||||
msg.registerOutgoingPluginChannel(this, "axiom:set_world_property");
|
||||
msg.registerOutgoingPluginChannel(this, "axiom:ack_world_properties");
|
||||
msg.registerOutgoingPluginChannel(this, "axiom:restrictions");
|
||||
msg.registerOutgoingPluginChannel(this, "axiom:marker_data");
|
||||
msg.registerOutgoingPluginChannel(this, "axiom:marker_nbt_response");
|
||||
|
||||
if (configuration.getBoolean("packet-handlers.hello")) {
|
||||
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")) {
|
||||
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")) {
|
||||
SetBlockBufferPacketListener setBlockBufferPacketListener = new SetBlockBufferPacketListener(this);
|
||||
@ -238,11 +243,12 @@ public class AxiomPaper extends JavaPlugin implements Listener {
|
||||
playerRestrictions.keySet().retainAll(stillActiveAxiomPlayers);
|
||||
}, 20, 20);
|
||||
|
||||
boolean sendMarkers = configuration.getBoolean("send-markers");
|
||||
int maxChunkRelightsPerTick = configuration.getInt("max-chunk-relights-per-tick");
|
||||
int maxChunkSendsPerTick = configuration.getInt("max-chunk-sends-per-tick");
|
||||
|
||||
Bukkit.getScheduler().scheduleSyncRepeatingTask(this, () -> {
|
||||
WorldExtension.tick(MinecraftServer.getServer(), maxChunkRelightsPerTick, maxChunkSendsPerTick);
|
||||
WorldExtension.tick(MinecraftServer.getServer(), sendMarkers, maxChunkRelightsPerTick, maxChunkSendsPerTick);
|
||||
}, 1, 1);
|
||||
}
|
||||
|
||||
@ -292,17 +298,22 @@ public class AxiomPaper extends JavaPlugin implements Listener {
|
||||
|
||||
@EventHandler
|
||||
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) {
|
||||
event.setAllowed(true); // Support for arcball camera
|
||||
} else if (event.getPlayer().isFlying()) {
|
||||
event.setAllowed(true); // Support for noclip
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
public void onChangedWorld(PlayerChangedWorldEvent event) {
|
||||
if (!this.activeAxiomPlayers.contains(event.getPlayer().getUniqueId())) {
|
||||
return;
|
||||
}
|
||||
|
||||
World world = event.getPlayer().getWorld();
|
||||
|
||||
ServerWorldPropertiesRegistry properties = getOrCreateWorldProperties(world);
|
||||
@ -312,6 +323,8 @@ public class AxiomPaper extends JavaPlugin implements Listener {
|
||||
} else {
|
||||
properties.registerFor(this, event.getPlayer());
|
||||
}
|
||||
|
||||
WorldExtension.onPlayerJoin(world, event.getPlayer());
|
||||
}
|
||||
|
||||
@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;
|
||||
|
||||
import com.moulberry.axiom.marker.MarkerData;
|
||||
import io.netty.buffer.Unpooled;
|
||||
import it.unimi.dsi.fastutil.longs.*;
|
||||
import net.minecraft.network.FriendlyByteBuf;
|
||||
import net.minecraft.network.protocol.game.ClientboundLevelChunkWithLightPacket;
|
||||
import net.minecraft.resources.ResourceKey;
|
||||
import net.minecraft.server.MinecraftServer;
|
||||
import net.minecraft.server.level.ChunkMap;
|
||||
import net.minecraft.server.level.ServerLevel;
|
||||
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.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.entity.Player;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
@ -23,15 +32,16 @@ public class WorldExtension {
|
||||
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());
|
||||
|
||||
for (ServerLevel level : server.getAllLevels()) {
|
||||
WorldExtension extension = extensions.get(level.dimension());
|
||||
if (extension != null) {
|
||||
extension.level = level;
|
||||
extension.tick(maxChunkRelightsPerTick, maxChunkSendsPerTick);
|
||||
}
|
||||
get(level).tick(sendMarkers, maxChunkRelightsPerTick, maxChunkSendsPerTick);
|
||||
}
|
||||
}
|
||||
|
||||
@ -39,6 +49,7 @@ public class WorldExtension {
|
||||
|
||||
private final LongSet pendingChunksToSend = new LongOpenHashSet();
|
||||
private final LongSet pendingChunksToLight = new LongOpenHashSet();
|
||||
private final Map<UUID, MarkerData> previousMarkerData = new HashMap<>();
|
||||
|
||||
public void sendChunk(int cx, int cz) {
|
||||
this.pendingChunksToSend.add(ChunkPos.asLong(cx, cz));
|
||||
@ -48,7 +59,66 @@ public class WorldExtension {
|
||||
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;
|
||||
|
||||
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.AxiomPaper;
|
||||
import com.moulberry.axiom.View;
|
||||
import com.moulberry.axiom.WorldExtension;
|
||||
import com.moulberry.axiom.event.AxiomHandshakeEvent;
|
||||
import com.moulberry.axiom.persistence.ItemStackDataType;
|
||||
import com.moulberry.axiom.persistence.UUIDDataType;
|
||||
@ -167,6 +168,8 @@ public class HelloPacketListener implements PluginMessageListener {
|
||||
} else {
|
||||
properties.registerFor(plugin, player);
|
||||
}
|
||||
|
||||
WorldExtension.onPlayerJoin(world, player);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -1,6 +1,7 @@
|
||||
package com.moulberry.axiom.packet;
|
||||
|
||||
import com.moulberry.axiom.AxiomPaper;
|
||||
import com.moulberry.axiom.NbtSanitization;
|
||||
import io.netty.buffer.Unpooled;
|
||||
import net.minecraft.core.BlockPos;
|
||||
import net.minecraft.core.Direction;
|
||||
@ -104,6 +105,8 @@ public class ManipulateEntityPacketListener implements PluginMessageListener {
|
||||
if (blacklistedEntities.contains(type)) continue;
|
||||
|
||||
if (entry.merge != null && !entry.merge.isEmpty()) {
|
||||
NbtSanitization.sanitizeEntity(entry.merge);
|
||||
|
||||
CompoundTag compoundTag = entity.saveWithoutId(new CompoundTag());
|
||||
compoundTag = merge(compoundTag, entry.merge);
|
||||
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;
|
||||
|
||||
import com.moulberry.axiom.AxiomPaper;
|
||||
import com.moulberry.axiom.NbtSanitization;
|
||||
import com.moulberry.axiom.event.AxiomTeleportEvent;
|
||||
import com.moulberry.axiom.event.AxiomUnknownTeleportEvent;
|
||||
import io.netty.buffer.Unpooled;
|
||||
@ -81,9 +82,11 @@ public class SpawnEntityPacketListener implements PluginMessageListener {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (serverLevel.getEntity(entry.newUuid) != null) continue;
|
||||
|
||||
CompoundTag tag = entry.tag == null ? new CompoundTag() : entry.tag;
|
||||
|
||||
if (serverLevel.getEntity(entry.newUuid) != null) continue;
|
||||
NbtSanitization.sanitizeEntity(tag);
|
||||
|
||||
if (entry.copyFrom != null) {
|
||||
Entity entityCopyFrom = serverLevel.getEntity(entry.copyFrom);
|
||||
|
@ -19,7 +19,6 @@ incompatible-data-version: "warn"
|
||||
unsupported-axiom-version: "warn"
|
||||
client-doesnt-support-restrictions: "ignore"
|
||||
|
||||
|
||||
# Maximum packet size. Must not be less than 32767
|
||||
max-block-buffer-packet-size: 0x100000
|
||||
|
||||
@ -51,6 +50,9 @@ whitelist-entities:
|
||||
blacklist-entities:
|
||||
# - "minecraft:ender_dragon"
|
||||
|
||||
# True allows players to see/manipulate marker entities
|
||||
send-markers: false
|
||||
|
||||
# Disallowed blocks
|
||||
disallowed-blocks:
|
||||
# - "minecraft:wheat"
|
||||
@ -73,3 +75,4 @@ packet-handlers:
|
||||
spawn-entity: true
|
||||
manipulate-entity: true
|
||||
delete-entity: true
|
||||
marker-nbt-request: true
|
||||
|
Laden…
In neuem Issue referenzieren
Einen Benutzer sperren