geforkt von Mirrors/AxiomPaperPlugin
backport1.20.1 #6
@ -19,7 +19,10 @@ import net.minecraft.network.protocol.Packet;
|
|||||||
import net.minecraft.network.protocol.PacketFlow;
|
import net.minecraft.network.protocol.PacketFlow;
|
||||||
import net.minecraft.network.protocol.common.ServerboundCustomPayloadPacket;
|
import net.minecraft.network.protocol.common.ServerboundCustomPayloadPacket;
|
||||||
import net.minecraft.resources.ResourceLocation;
|
import net.minecraft.resources.ResourceLocation;
|
||||||
|
import net.minecraft.server.MinecraftServer;
|
||||||
import org.bukkit.*;
|
import org.bukkit.*;
|
||||||
|
import org.bukkit.configuration.Configuration;
|
||||||
|
import org.bukkit.configuration.file.FileConfiguration;
|
||||||
import org.bukkit.entity.Player;
|
import org.bukkit.entity.Player;
|
||||||
import org.bukkit.event.EventHandler;
|
import org.bukkit.event.EventHandler;
|
||||||
import org.bukkit.event.Listener;
|
import org.bukkit.event.Listener;
|
||||||
@ -37,11 +40,23 @@ public class AxiomPaper extends JavaPlugin implements Listener {
|
|||||||
public static AxiomPaper PLUGIN; // tsk tsk tsk
|
public static AxiomPaper PLUGIN; // tsk tsk tsk
|
||||||
|
|
||||||
public final Set<UUID> activeAxiomPlayers = Collections.newSetFromMap(new ConcurrentHashMap<>());
|
public final Set<UUID> activeAxiomPlayers = Collections.newSetFromMap(new ConcurrentHashMap<>());
|
||||||
|
public Configuration configuration;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onEnable() {
|
public void onEnable() {
|
||||||
PLUGIN = this;
|
PLUGIN = this;
|
||||||
|
|
||||||
|
this.saveDefaultConfig();
|
||||||
|
configuration = this.getConfig();
|
||||||
|
|
||||||
|
Set<String> validResolutions = Set.of("kick", "warn", "ignore");
|
||||||
|
if (!validResolutions.contains(configuration.getString("incompatible-data-version"))) {
|
||||||
|
this.getLogger().warning("Invalid value for incompatible-data-version, expected 'kick', 'warn' or 'ignore'");
|
||||||
|
}
|
||||||
|
if (!validResolutions.contains(configuration.getString("unsupported-axiom-version"))) {
|
||||||
|
this.getLogger().warning("Invalid value for unsupported-axiom-version, expected 'kick', 'warn' or 'ignore'");
|
||||||
|
}
|
||||||
|
|
||||||
Bukkit.getPluginManager().registerEvents(this, this);
|
Bukkit.getPluginManager().registerEvents(this, this);
|
||||||
// Bukkit.getPluginManager().registerEvents(new WorldPropertiesExample(), this);
|
// Bukkit.getPluginManager().registerEvents(new WorldPropertiesExample(), this);
|
||||||
CompressedBlockEntity.initialize(this);
|
CompressedBlockEntity.initialize(this);
|
||||||
@ -56,40 +71,64 @@ 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.registerIncomingPluginChannel(this, "axiom:hello", new HelloPacketListener(this, activeAxiomPlayers));
|
if (configuration.getBoolean("packet-handlers.hello")) {
|
||||||
msg.registerIncomingPluginChannel(this, "axiom:set_gamemode", new SetGamemodePacketListener());
|
msg.registerIncomingPluginChannel(this, "axiom:hello", new HelloPacketListener(this, activeAxiomPlayers));
|
||||||
msg.registerIncomingPluginChannel(this, "axiom:set_fly_speed", new SetFlySpeedPacketListener());
|
}
|
||||||
msg.registerIncomingPluginChannel(this, "axiom:set_world_time", new SetTimePacketListener());
|
if (configuration.getBoolean("packet-handlers.set-gamemode")) {
|
||||||
msg.registerIncomingPluginChannel(this, "axiom:set_world_property", new SetWorldPropertyListener());
|
msg.registerIncomingPluginChannel(this, "axiom:set_gamemode", new SetGamemodePacketListener(this));
|
||||||
msg.registerIncomingPluginChannel(this, "axiom:set_block", new SetBlockPacketListener(this));
|
}
|
||||||
msg.registerIncomingPluginChannel(this, "axiom:set_hotbar_slot", new SetHotbarSlotPacketListener());
|
if (configuration.getBoolean("packet-handlers.set-fly-speed")) {
|
||||||
msg.registerIncomingPluginChannel(this, "axiom:switch_active_hotbar", new SwitchActiveHotbarPacketListener());
|
msg.registerIncomingPluginChannel(this, "axiom:set_fly_speed", new SetFlySpeedPacketListener(this));
|
||||||
msg.registerIncomingPluginChannel(this, "axiom:teleport", new TeleportPacketListener());
|
}
|
||||||
msg.registerIncomingPluginChannel(this, "axiom:set_editor_views", new SetEditorViewsPacketListener());
|
if (configuration.getBoolean("packet-handlers.set-world-time")) {
|
||||||
msg.registerIncomingPluginChannel(this, "axiom:request_chunk_data", new RequestChunkDataPacketListener(this));
|
msg.registerIncomingPluginChannel(this, "axiom:set_world_time", new SetTimePacketListener(this));
|
||||||
|
}
|
||||||
|
if (configuration.getBoolean("packet-handlers.set-world-property")) {
|
||||||
|
msg.registerIncomingPluginChannel(this, "axiom:set_world_property", new SetWorldPropertyListener(this));
|
||||||
|
}
|
||||||
|
if (configuration.getBoolean("packet-handlers.set-single-block")) {
|
||||||
|
msg.registerIncomingPluginChannel(this, "axiom:set_block", new SetBlockPacketListener(this));
|
||||||
|
}
|
||||||
|
if (configuration.getBoolean("packet-handlers.set-hotbar-slot")) {
|
||||||
|
msg.registerIncomingPluginChannel(this, "axiom:set_hotbar_slot", new SetHotbarSlotPacketListener(this));
|
||||||
|
}
|
||||||
|
if (configuration.getBoolean("packet-handlers.switch-active-hotbar")) {
|
||||||
|
msg.registerIncomingPluginChannel(this, "axiom:switch_active_hotbar", new SwitchActiveHotbarPacketListener(this));
|
||||||
|
}
|
||||||
|
if (configuration.getBoolean("packet-handlers.teleport")) {
|
||||||
|
msg.registerIncomingPluginChannel(this, "axiom:teleport", new TeleportPacketListener(this));
|
||||||
|
}
|
||||||
|
if (configuration.getBoolean("packet-handlers.set-editor-views")) {
|
||||||
|
msg.registerIncomingPluginChannel(this, "axiom:set_editor_views", new SetEditorViewsPacketListener(this));
|
||||||
|
}
|
||||||
|
if (configuration.getBoolean("packet-handlers.request-chunk-data")) {
|
||||||
|
msg.registerIncomingPluginChannel(this, "axiom:request_chunk_data", new RequestChunkDataPacketListener(this));
|
||||||
|
}
|
||||||
|
|
||||||
SetBlockBufferPacketListener setBlockBufferPacketListener = new SetBlockBufferPacketListener(this);
|
if (configuration.getBoolean("packet-handlers.set-buffer")) {
|
||||||
|
SetBlockBufferPacketListener setBlockBufferPacketListener = new SetBlockBufferPacketListener(this);
|
||||||
|
|
||||||
ChannelInitializeListenerHolder.addListener(Key.key("axiom:handle_big_payload"), new ChannelInitializeListener() {
|
ChannelInitializeListenerHolder.addListener(Key.key("axiom:handle_big_payload"), new ChannelInitializeListener() {
|
||||||
@Override
|
@Override
|
||||||
public void afterInitChannel(@NonNull Channel channel) {
|
public void afterInitChannel(@NonNull Channel channel) {
|
||||||
var packets = ConnectionProtocol.PLAY.getPacketsByIds(PacketFlow.SERVERBOUND);
|
var packets = ConnectionProtocol.PLAY.getPacketsByIds(PacketFlow.SERVERBOUND);
|
||||||
int payloadId = -1;
|
int payloadId = -1;
|
||||||
for (Map.Entry<Integer, Class<? extends Packet<?>>> entry : packets.entrySet()) {
|
for (Map.Entry<Integer, Class<? extends Packet<?>>> entry : packets.entrySet()) {
|
||||||
if (entry.getValue() == ServerboundCustomPayloadPacket.class) {
|
if (entry.getValue() == ServerboundCustomPayloadPacket.class) {
|
||||||
payloadId = entry.getKey();
|
payloadId = entry.getKey();
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (payloadId < 0) {
|
||||||
|
throw new RuntimeException("Failed to find ServerboundCustomPayloadPacket id");
|
||||||
}
|
}
|
||||||
}
|
|
||||||
if (payloadId < 0) {
|
|
||||||
throw new RuntimeException("Failed to find ServerboundCustomPayloadPacket id");
|
|
||||||
}
|
|
||||||
|
|
||||||
Connection connection = (Connection) channel.pipeline().get("packet_handler");
|
Connection connection = (Connection) channel.pipeline().get("packet_handler");
|
||||||
channel.pipeline().addBefore("decoder", "axiom-big-payload-handler",
|
channel.pipeline().addBefore("decoder", "axiom-big-payload-handler",
|
||||||
new AxiomBigPayloadHandler(payloadId, connection, setBlockBufferPacketListener));
|
new AxiomBigPayloadHandler(payloadId, connection, setBlockBufferPacketListener));
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
}
|
||||||
|
|
||||||
Bukkit.getScheduler().scheduleSyncRepeatingTask(this, () -> {
|
Bukkit.getScheduler().scheduleSyncRepeatingTask(this, () -> {
|
||||||
HashSet<UUID> newActiveAxiomPlayers = new HashSet<>();
|
HashSet<UUID> newActiveAxiomPlayers = new HashSet<>();
|
||||||
@ -111,6 +150,17 @@ public class AxiomPaper extends JavaPlugin implements Listener {
|
|||||||
activeAxiomPlayers.clear();
|
activeAxiomPlayers.clear();
|
||||||
activeAxiomPlayers.addAll(newActiveAxiomPlayers);
|
activeAxiomPlayers.addAll(newActiveAxiomPlayers);
|
||||||
}, 20, 20);
|
}, 20, 20);
|
||||||
|
|
||||||
|
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);
|
||||||
|
}, 1, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean canUseAxiom(Player player) {
|
||||||
|
return player.hasPermission("axiom.*") && activeAxiomPlayers.contains(player.getUniqueId());
|
||||||
}
|
}
|
||||||
|
|
||||||
private final WeakHashMap<World, ServerWorldPropertiesRegistry> worldProperties = new WeakHashMap<>();
|
private final WeakHashMap<World, ServerWorldPropertiesRegistry> worldProperties = new WeakHashMap<>();
|
||||||
|
105
src/main/java/com/moulberry/axiom/WorldExtension.java
Normale Datei
105
src/main/java/com/moulberry/axiom/WorldExtension.java
Normale Datei
@ -0,0 +1,105 @@
|
|||||||
|
package com.moulberry.axiom;
|
||||||
|
|
||||||
|
import it.unimi.dsi.fastutil.longs.*;
|
||||||
|
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.level.ChunkPos;
|
||||||
|
import net.minecraft.world.level.Level;
|
||||||
|
import net.minecraft.world.level.chunk.LevelChunk;
|
||||||
|
|
||||||
|
import java.util.*;
|
||||||
|
|
||||||
|
public class WorldExtension {
|
||||||
|
|
||||||
|
private static final Map<ResourceKey<Level>, WorldExtension> extensions = new HashMap<>();
|
||||||
|
|
||||||
|
public static WorldExtension get(ServerLevel serverLevel) {
|
||||||
|
WorldExtension extension = extensions.computeIfAbsent(serverLevel.dimension(), k -> new WorldExtension());
|
||||||
|
extension.level = serverLevel;
|
||||||
|
return extension;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void tick(MinecraftServer server, 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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private ServerLevel level;
|
||||||
|
|
||||||
|
private final LongSet pendingChunksToSend = new LongOpenHashSet();
|
||||||
|
private final LongSet pendingChunksToLight = new LongOpenHashSet();
|
||||||
|
|
||||||
|
public void sendChunk(int cx, int cz) {
|
||||||
|
this.pendingChunksToSend.add(ChunkPos.asLong(cx, cz));
|
||||||
|
}
|
||||||
|
|
||||||
|
public void lightChunk(int cx, int cz) {
|
||||||
|
this.pendingChunksToLight.add(ChunkPos.asLong(cx, cz));
|
||||||
|
}
|
||||||
|
|
||||||
|
public void tick(int maxChunkRelightsPerTick, int maxChunkSendsPerTick) {
|
||||||
|
ChunkMap chunkMap = this.level.getChunkSource().chunkMap;
|
||||||
|
|
||||||
|
boolean sendAll = maxChunkSendsPerTick <= 0;
|
||||||
|
|
||||||
|
// Send chunks
|
||||||
|
LongIterator longIterator = this.pendingChunksToSend.longIterator();
|
||||||
|
while (longIterator.hasNext()) {
|
||||||
|
ChunkPos chunkPos = new ChunkPos(longIterator.nextLong());
|
||||||
|
List<ServerPlayer> players = chunkMap.getPlayers(chunkPos, false);
|
||||||
|
if (players.isEmpty()) continue;
|
||||||
|
|
||||||
|
LevelChunk chunk = this.level.getChunk(chunkPos.x, chunkPos.z);
|
||||||
|
var packet = new ClientboundLevelChunkWithLightPacket(chunk, this.level.getLightEngine(), null, null, false);
|
||||||
|
for (ServerPlayer player : players) {
|
||||||
|
player.connection.send(packet);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!sendAll) {
|
||||||
|
longIterator.remove();
|
||||||
|
|
||||||
|
maxChunkSendsPerTick -= 1;
|
||||||
|
if (maxChunkSendsPerTick <= 0) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (sendAll) {
|
||||||
|
this.pendingChunksToSend.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Relight chunks
|
||||||
|
Set<ChunkPos> chunkSet = new HashSet<>();
|
||||||
|
longIterator = this.pendingChunksToLight.longIterator();
|
||||||
|
if (maxChunkRelightsPerTick <= 0) {
|
||||||
|
while (longIterator.hasNext()) {
|
||||||
|
chunkSet.add(new ChunkPos(longIterator.nextLong()));
|
||||||
|
}
|
||||||
|
this.pendingChunksToLight.clear();
|
||||||
|
} else {
|
||||||
|
while (longIterator.hasNext()) {
|
||||||
|
chunkSet.add(new ChunkPos(longIterator.nextLong()));
|
||||||
|
longIterator.remove();
|
||||||
|
|
||||||
|
maxChunkRelightsPerTick -= 1;
|
||||||
|
if (maxChunkRelightsPerTick <= 0) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
this.level.getChunkSource().getLightEngine().relight(chunkSet, pos -> {}, count -> {});
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -12,10 +12,11 @@ public class AxiomHandshakeEvent extends Event implements Cancellable {
|
|||||||
|
|
||||||
private final Player player;
|
private final Player player;
|
||||||
private boolean cancelled = false;
|
private boolean cancelled = false;
|
||||||
private int maxBufferSize = 0x100000;
|
private int maxBufferSize;
|
||||||
|
|
||||||
public AxiomHandshakeEvent(Player player) {
|
public AxiomHandshakeEvent(Player player, int maxBufferSize) {
|
||||||
this.player = player;
|
this.player = player;
|
||||||
|
this.maxBufferSize = maxBufferSize;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Player getPlayer() {
|
public Player getPlayer() {
|
||||||
|
@ -1,39 +0,0 @@
|
|||||||
package com.moulberry.axiom.integration;
|
|
||||||
|
|
||||||
import org.bukkit.Bukkit;
|
|
||||||
import org.bukkit.World;
|
|
||||||
import org.bukkit.entity.Player;
|
|
||||||
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
public class RegionProtection {
|
|
||||||
|
|
||||||
private final RegionProtectionWorldGuard worldGuard;
|
|
||||||
|
|
||||||
public RegionProtection(Player player, World world) {
|
|
||||||
if (Bukkit.getPluginManager().isPluginEnabled("WorldGuard")) {
|
|
||||||
this.worldGuard = RegionProtectionWorldGuard.tryCreate(player, world);
|
|
||||||
} else {
|
|
||||||
this.worldGuard = null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public SectionProtection getSection(int cx, int cy, int cz) {
|
|
||||||
List<SectionProtection> protections = new ArrayList<>();
|
|
||||||
if (this.worldGuard != null) {
|
|
||||||
return this.worldGuard.getSection(cx, cy, cz);
|
|
||||||
}
|
|
||||||
// todo: PlotSquared
|
|
||||||
return SectionProtection.ALLOW;
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean canBuild(int x, int y, int z) {
|
|
||||||
if (this.worldGuard != null && !this.worldGuard.canBuild(x, y, z)) return false;
|
|
||||||
// todo: PlotSquared
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
@ -1,183 +0,0 @@
|
|||||||
package com.moulberry.axiom.integration;
|
|
||||||
|
|
||||||
import com.google.common.collect.ImmutableList;
|
|
||||||
import com.google.common.collect.Sets;
|
|
||||||
import com.sk89q.worldedit.bukkit.BukkitAdapter;
|
|
||||||
import com.sk89q.worldedit.math.BlockVector3;
|
|
||||||
import com.sk89q.worldguard.LocalPlayer;
|
|
||||||
import com.sk89q.worldguard.WorldGuard;
|
|
||||||
import com.sk89q.worldguard.bukkit.WorldGuardPlugin;
|
|
||||||
import com.sk89q.worldguard.internal.platform.WorldGuardPlatform;
|
|
||||||
import com.sk89q.worldguard.protection.ApplicableRegionSet;
|
|
||||||
import com.sk89q.worldguard.protection.FlagValueCalculator;
|
|
||||||
import com.sk89q.worldguard.protection.association.RegionAssociable;
|
|
||||||
import com.sk89q.worldguard.protection.flags.Flags;
|
|
||||||
import com.sk89q.worldguard.protection.flags.RegionGroup;
|
|
||||||
import com.sk89q.worldguard.protection.flags.StateFlag;
|
|
||||||
import com.sk89q.worldguard.protection.managers.RegionManager;
|
|
||||||
import com.sk89q.worldguard.protection.regions.*;
|
|
||||||
import org.bukkit.World;
|
|
||||||
import org.bukkit.entity.Player;
|
|
||||||
import org.jetbrains.annotations.Nullable;
|
|
||||||
|
|
||||||
import java.util.*;
|
|
||||||
|
|
||||||
import static com.google.common.base.Preconditions.checkNotNull;
|
|
||||||
|
|
||||||
public class RegionProtectionWorldGuard {
|
|
||||||
|
|
||||||
private final LocalPlayer player;
|
|
||||||
private final RegionManager regionManager;
|
|
||||||
|
|
||||||
public RegionProtectionWorldGuard(LocalPlayer player, RegionManager regionManager) {
|
|
||||||
this.player = player;
|
|
||||||
this.regionManager = regionManager;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Nullable
|
|
||||||
public static RegionProtectionWorldGuard tryCreate(Player player, World world) {
|
|
||||||
WorldGuardPlatform platform = WorldGuard.getInstance().getPlatform();
|
|
||||||
|
|
||||||
RegionContainer regionContainer = platform.getRegionContainer();
|
|
||||||
if (regionContainer == null) return null;
|
|
||||||
|
|
||||||
com.sk89q.worldedit.world.World worldEditWorld = BukkitAdapter.adapt(world);
|
|
||||||
LocalPlayer worldGuardPlayer = WorldGuardPlugin.inst().wrapPlayer(player);
|
|
||||||
|
|
||||||
// Don't do any protection if player has bypass
|
|
||||||
if (platform.getSessionManager().hasBypass(worldGuardPlayer, worldEditWorld)) {
|
|
||||||
// todo: enable bypass
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
RegionManager regionManager = regionContainer.get(worldEditWorld);
|
|
||||||
if (regionManager == null) return null;
|
|
||||||
|
|
||||||
return new RegionProtectionWorldGuard(worldGuardPlayer, regionManager);
|
|
||||||
}
|
|
||||||
|
|
||||||
public SectionProtection getSection(int cx, int cy, int cz) {
|
|
||||||
BlockVector3 min = BlockVector3.at(cx*16, cy*16, cz*16);
|
|
||||||
BlockVector3 max = BlockVector3.at(cx*16+15, cy*16+15, cz*16+15);
|
|
||||||
ProtectedRegion test = new ProtectedCuboidRegion("dummy", min, max);
|
|
||||||
ApplicableRegionSet regions = this.regionManager.getApplicableRegions(test, RegionQuery.QueryOption.COMPUTE_PARENTS);
|
|
||||||
|
|
||||||
int minimumPriority = Integer.MIN_VALUE;
|
|
||||||
|
|
||||||
Map<ProtectedRegion, StateFlag.State> consideredValues = new HashMap<>();
|
|
||||||
Set<ProtectedRegion> ignoredParents = new HashSet<>();
|
|
||||||
|
|
||||||
for (ProtectedRegion region : regions) {
|
|
||||||
int priority = FlagValueCalculator.getPriorityOf(region);
|
|
||||||
|
|
||||||
// todo: this logic doesn't work for us in determining ALLOW, DENY, CHECK
|
|
||||||
if (priority < minimumPriority) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
// todo: have to keep track of 2 booleans: partialAllow & partialDeny
|
|
||||||
|
|
||||||
if (ignoredParents.contains(region)) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
StateFlag.State value = FlagValueCalculator.getEffectiveFlagOf(region, Flags.BUILD, this.player);
|
|
||||||
if (value != null) {
|
|
||||||
minimumPriority = priority;
|
|
||||||
consideredValues.put(region, value);
|
|
||||||
}
|
|
||||||
|
|
||||||
addParents(ignoredParents, region);
|
|
||||||
|
|
||||||
// The BUILD flag is implicitly set on every region where
|
|
||||||
// PASSTHROUGH is not set to ALLOW
|
|
||||||
if (minimumPriority != priority && Flags.BUILD.implicitlySetWithMembership() &&
|
|
||||||
FlagValueCalculator.getEffectiveFlagOf(region, Flags.PASSTHROUGH, this.player) != StateFlag.State.ALLOW) {
|
|
||||||
minimumPriority = priority;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (consideredValues.isEmpty()) {
|
|
||||||
if (Flags.BUILD.usesMembershipAsDefault()) {
|
|
||||||
// todo
|
|
||||||
// switch (getMembership(subject)) {
|
|
||||||
// case FAIL:
|
|
||||||
// return ImmutableList.of();
|
|
||||||
// case SUCCESS:
|
|
||||||
// return (Collection<V>) ImmutableList.of(StateFlag.State.ALLOW);
|
|
||||||
// }
|
|
||||||
}
|
|
||||||
|
|
||||||
// System.out.println("returning default");
|
|
||||||
StateFlag.State fallback = Flags.BUILD.getDefault();
|
|
||||||
return fallback == StateFlag.State.DENY ? SectionProtection.DENY : SectionProtection.ALLOW;
|
|
||||||
}
|
|
||||||
|
|
||||||
boolean hasPartialDeny = false;
|
|
||||||
for (Map.Entry<ProtectedRegion, StateFlag.State> entry : consideredValues.entrySet()) {
|
|
||||||
ProtectedRegion region = entry.getKey();
|
|
||||||
if (entry.getValue() == StateFlag.State.DENY) {
|
|
||||||
// System.out.println("found region with deny!");
|
|
||||||
if (region instanceof GlobalProtectedRegion) {
|
|
||||||
return SectionProtection.DENY;
|
|
||||||
} else if (region instanceof ProtectedCuboidRegion && doesRegionCompletelyContainSection(region, cx, cy, cz)) {
|
|
||||||
return SectionProtection.DENY;
|
|
||||||
}
|
|
||||||
hasPartialDeny = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (hasPartialDeny) {
|
|
||||||
// System.out.println("returning check!");
|
|
||||||
return new SectionProtection() {
|
|
||||||
@Override
|
|
||||||
public SectionState getSectionState() {
|
|
||||||
return SectionState.CHECK;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean check(int wx, int wy, int wz) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
// return complex thing
|
|
||||||
}
|
|
||||||
|
|
||||||
// System.out.println("returning allow!");
|
|
||||||
return SectionProtection.ALLOW;
|
|
||||||
}
|
|
||||||
|
|
||||||
private boolean doesRegionCompletelyContainSection(ProtectedRegion region, int cx, int cy, int cz) {
|
|
||||||
BlockVector3 regionMin = region.getMinimumPoint();
|
|
||||||
|
|
||||||
if (regionMin.getBlockX() > cx*16) return false;
|
|
||||||
if (regionMin.getBlockY() > cy*16) return false;
|
|
||||||
if (regionMin.getBlockZ() > cz*16) return false;
|
|
||||||
|
|
||||||
BlockVector3 regionMax = region.getMaximumPoint();
|
|
||||||
|
|
||||||
if (regionMax.getBlockX() < cx*16+15) return false;
|
|
||||||
if (regionMax.getBlockY() < cy*16+15) return false;
|
|
||||||
if (regionMax.getBlockZ() < cz*16+15) return false;
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
private void addParents(Set<ProtectedRegion> ignored, ProtectedRegion region) {
|
|
||||||
ProtectedRegion parent = region.getParent();
|
|
||||||
|
|
||||||
while (parent != null) {
|
|
||||||
ignored.add(parent);
|
|
||||||
parent = parent.getParent();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean canBuild(int x, int y, int z) {
|
|
||||||
return this.regionManager.getApplicableRegions(BlockVector3.at(x, y, z)).testState(this.player, Flags.BUILD);
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean isAllowed(LocalPlayer player, ProtectedRegion protectedRegion) {
|
|
||||||
return protectedRegion.isOwner(player) || protectedRegion.isMember(player);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
@ -1,38 +0,0 @@
|
|||||||
package com.moulberry.axiom.integration;
|
|
||||||
|
|
||||||
public interface SectionProtection {
|
|
||||||
|
|
||||||
SectionProtection ALLOW = new SectionProtection() {
|
|
||||||
@Override
|
|
||||||
public SectionState getSectionState() {
|
|
||||||
return SectionState.ALLOW;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean check(int wx, int wy, int wz) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
SectionProtection DENY = new SectionProtection() {
|
|
||||||
@Override
|
|
||||||
public SectionState getSectionState() {
|
|
||||||
return SectionState.DENY;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean check(int wx, int wy, int wz) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
enum SectionState {
|
|
||||||
ALLOW,
|
|
||||||
DENY,
|
|
||||||
CHECK
|
|
||||||
}
|
|
||||||
|
|
||||||
SectionState getSectionState();
|
|
||||||
boolean check(int wx, int wy, int wz);
|
|
||||||
|
|
||||||
}
|
|
@ -9,6 +9,7 @@ import com.moulberry.axiom.persistence.UUIDDataType;
|
|||||||
import com.moulberry.axiom.world_properties.server.ServerWorldPropertiesRegistry;
|
import com.moulberry.axiom.world_properties.server.ServerWorldPropertiesRegistry;
|
||||||
import io.netty.buffer.Unpooled;
|
import io.netty.buffer.Unpooled;
|
||||||
import net.kyori.adventure.text.Component;
|
import net.kyori.adventure.text.Component;
|
||||||
|
import net.kyori.adventure.text.format.NamedTextColor;
|
||||||
import net.minecraft.SharedConstants;
|
import net.minecraft.SharedConstants;
|
||||||
import net.minecraft.network.FriendlyByteBuf;
|
import net.minecraft.network.FriendlyByteBuf;
|
||||||
import org.bukkit.Bukkit;
|
import org.bukkit.Bukkit;
|
||||||
@ -48,19 +49,38 @@ public class HelloPacketListener implements PluginMessageListener {
|
|||||||
|
|
||||||
int serverDataVersion = SharedConstants.getCurrentVersion().getDataVersion().getVersion();
|
int serverDataVersion = SharedConstants.getCurrentVersion().getDataVersion().getVersion();
|
||||||
if (dataVersion != serverDataVersion) {
|
if (dataVersion != serverDataVersion) {
|
||||||
player.kick(Component.text("Axiom: Incompatible data version detected (client " + dataVersion +
|
Component text = Component.text("Axiom: Incompatible data version detected (client " + dataVersion +
|
||||||
", server " + serverDataVersion + "), are you using ViaVersion?"));
|
", server " + serverDataVersion + "), are you using ViaVersion?");
|
||||||
return;
|
|
||||||
|
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;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (apiVersion != AxiomConstants.API_VERSION) {
|
if (apiVersion != AxiomConstants.API_VERSION) {
|
||||||
player.kick(Component.text("Unsupported Axiom API Version. Server supports " + AxiomConstants.API_VERSION +
|
Component text = Component.text("Unsupported Axiom API Version. Server supports " + AxiomConstants.API_VERSION +
|
||||||
", while client is " + apiVersion));
|
", while client is " + apiVersion);
|
||||||
return;
|
|
||||||
|
String unsupportedAxiomVersion = plugin.configuration.getString("unsupported-axiom-version");
|
||||||
|
if (unsupportedAxiomVersion == null) unsupportedAxiomVersion = "kick";
|
||||||
|
if (unsupportedAxiomVersion.equals("warn")) {
|
||||||
|
player.sendMessage(text.color(NamedTextColor.RED));
|
||||||
|
return;
|
||||||
|
} else if (!unsupportedAxiomVersion.equals("ignore")) {
|
||||||
|
player.kick(text);
|
||||||
|
return;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Call handshake event
|
// Call handshake event
|
||||||
AxiomHandshakeEvent handshakeEvent = new AxiomHandshakeEvent(player);
|
int maxBufferSize = plugin.configuration.getInt("max-block-buffer-packet-size");
|
||||||
|
AxiomHandshakeEvent handshakeEvent = new AxiomHandshakeEvent(player, maxBufferSize);
|
||||||
Bukkit.getPluginManager().callEvent(handshakeEvent);
|
Bukkit.getPluginManager().callEvent(handshakeEvent);
|
||||||
if (handshakeEvent.isCancelled()) {
|
if (handshakeEvent.isCancelled()) {
|
||||||
return;
|
return;
|
||||||
|
@ -3,6 +3,7 @@ package com.moulberry.axiom.packet;
|
|||||||
import com.moulberry.axiom.AxiomConstants;
|
import com.moulberry.axiom.AxiomConstants;
|
||||||
import com.moulberry.axiom.AxiomPaper;
|
import com.moulberry.axiom.AxiomPaper;
|
||||||
import com.moulberry.axiom.buffer.CompressedBlockEntity;
|
import com.moulberry.axiom.buffer.CompressedBlockEntity;
|
||||||
|
import com.moulberry.axiom.event.AxiomModifyWorldEvent;
|
||||||
import io.netty.buffer.Unpooled;
|
import io.netty.buffer.Unpooled;
|
||||||
import it.unimi.dsi.fastutil.longs.*;
|
import it.unimi.dsi.fastutil.longs.*;
|
||||||
import net.minecraft.core.BlockPos;
|
import net.minecraft.core.BlockPos;
|
||||||
@ -21,6 +22,7 @@ import net.minecraft.world.level.block.state.BlockState;
|
|||||||
import net.minecraft.world.level.chunk.LevelChunk;
|
import net.minecraft.world.level.chunk.LevelChunk;
|
||||||
import net.minecraft.world.level.chunk.LevelChunkSection;
|
import net.minecraft.world.level.chunk.LevelChunkSection;
|
||||||
import net.minecraft.world.level.chunk.PalettedContainer;
|
import net.minecraft.world.level.chunk.PalettedContainer;
|
||||||
|
import org.bukkit.Bukkit;
|
||||||
import org.bukkit.craftbukkit.v1_20_R2.entity.CraftPlayer;
|
import org.bukkit.craftbukkit.v1_20_R2.entity.CraftPlayer;
|
||||||
import org.bukkit.entity.Player;
|
import org.bukkit.entity.Player;
|
||||||
import org.bukkit.plugin.messaging.PluginMessageListener;
|
import org.bukkit.plugin.messaging.PluginMessageListener;
|
||||||
@ -33,7 +35,6 @@ public class RequestChunkDataPacketListener implements PluginMessageListener {
|
|||||||
private static final ResourceLocation RESPONSE_ID = new ResourceLocation("axiom:response_chunk_data");
|
private static final ResourceLocation RESPONSE_ID = new ResourceLocation("axiom:response_chunk_data");
|
||||||
|
|
||||||
private final AxiomPaper plugin;
|
private final AxiomPaper plugin;
|
||||||
|
|
||||||
public RequestChunkDataPacketListener(AxiomPaper plugin) {
|
public RequestChunkDataPacketListener(AxiomPaper plugin) {
|
||||||
this.plugin = plugin;
|
this.plugin = plugin;
|
||||||
}
|
}
|
||||||
@ -44,12 +45,20 @@ public class RequestChunkDataPacketListener implements PluginMessageListener {
|
|||||||
FriendlyByteBuf friendlyByteBuf = new FriendlyByteBuf(Unpooled.wrappedBuffer(message));
|
FriendlyByteBuf friendlyByteBuf = new FriendlyByteBuf(Unpooled.wrappedBuffer(message));
|
||||||
long id = friendlyByteBuf.readLong();
|
long id = friendlyByteBuf.readLong();
|
||||||
|
|
||||||
if (!bukkitPlayer.hasPermission("axiom.*")) {
|
if (!this.plugin.canUseAxiom(bukkitPlayer)) {
|
||||||
// We always send an 'empty' response in order to make the client happy
|
// We always send an 'empty' response in order to make the client happy
|
||||||
sendEmptyResponse(player, id);
|
sendEmptyResponse(player, id);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Call AxiomModifyWorldEvent event
|
||||||
|
AxiomModifyWorldEvent modifyWorldEvent = new AxiomModifyWorldEvent(bukkitPlayer, bukkitPlayer.getWorld());
|
||||||
|
Bukkit.getPluginManager().callEvent(modifyWorldEvent);
|
||||||
|
if (modifyWorldEvent.isCancelled()) {
|
||||||
|
sendEmptyResponse(player, id);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
MinecraftServer server = player.getServer();
|
MinecraftServer server = player.getServer();
|
||||||
if (server == null) {
|
if (server == null) {
|
||||||
sendEmptyResponse(player, id);
|
sendEmptyResponse(player, id);
|
||||||
|
@ -1,27 +1,11 @@
|
|||||||
package com.moulberry.axiom.packet;
|
package com.moulberry.axiom.packet;
|
||||||
|
|
||||||
import com.moulberry.axiom.AxiomPaper;
|
import com.moulberry.axiom.AxiomPaper;
|
||||||
|
import com.moulberry.axiom.WorldExtension;
|
||||||
import com.moulberry.axiom.buffer.BiomeBuffer;
|
import com.moulberry.axiom.buffer.BiomeBuffer;
|
||||||
import com.moulberry.axiom.buffer.BlockBuffer;
|
import com.moulberry.axiom.buffer.BlockBuffer;
|
||||||
import com.moulberry.axiom.buffer.CompressedBlockEntity;
|
import com.moulberry.axiom.buffer.CompressedBlockEntity;
|
||||||
import com.moulberry.axiom.event.AxiomModifyWorldEvent;
|
import com.moulberry.axiom.event.AxiomModifyWorldEvent;
|
||||||
import com.moulberry.axiom.integration.RegionProtection;
|
|
||||||
import com.moulberry.axiom.integration.SectionProtection;
|
|
||||||
import com.sk89q.worldedit.bukkit.BukkitAdapter;
|
|
||||||
import com.sk89q.worldedit.math.BlockVector3;
|
|
||||||
import com.sk89q.worldedit.world.World;
|
|
||||||
import com.sk89q.worldguard.LocalPlayer;
|
|
||||||
import com.sk89q.worldguard.WorldGuard;
|
|
||||||
import com.sk89q.worldguard.bukkit.WorldGuardPlugin;
|
|
||||||
import com.sk89q.worldguard.protection.ApplicableRegionSet;
|
|
||||||
import com.sk89q.worldguard.protection.flags.Flags;
|
|
||||||
import com.sk89q.worldguard.protection.flags.StateFlag;
|
|
||||||
import com.sk89q.worldguard.protection.managers.RegionManager;
|
|
||||||
import com.sk89q.worldguard.protection.regions.ProtectedCuboidRegion;
|
|
||||||
import com.sk89q.worldguard.protection.regions.ProtectedRegion;
|
|
||||||
import com.sk89q.worldguard.protection.regions.RegionContainer;
|
|
||||||
import com.sk89q.worldguard.protection.regions.RegionQuery;
|
|
||||||
import io.netty.buffer.Unpooled;
|
|
||||||
import it.unimi.dsi.fastutil.longs.Long2ObjectMap;
|
import it.unimi.dsi.fastutil.longs.Long2ObjectMap;
|
||||||
import it.unimi.dsi.fastutil.shorts.Short2ObjectMap;
|
import it.unimi.dsi.fastutil.shorts.Short2ObjectMap;
|
||||||
import net.minecraft.core.BlockPos;
|
import net.minecraft.core.BlockPos;
|
||||||
@ -41,7 +25,6 @@ import net.minecraft.world.level.ChunkPos;
|
|||||||
import net.minecraft.world.level.Level;
|
import net.minecraft.world.level.Level;
|
||||||
import net.minecraft.world.level.biome.Biome;
|
import net.minecraft.world.level.biome.Biome;
|
||||||
import net.minecraft.world.level.block.Block;
|
import net.minecraft.world.level.block.Block;
|
||||||
import net.minecraft.world.level.block.Blocks;
|
|
||||||
import net.minecraft.world.level.block.EntityBlock;
|
import net.minecraft.world.level.block.EntityBlock;
|
||||||
import net.minecraft.world.level.block.entity.BlockEntity;
|
import net.minecraft.world.level.block.entity.BlockEntity;
|
||||||
import net.minecraft.world.level.block.state.BlockState;
|
import net.minecraft.world.level.block.state.BlockState;
|
||||||
@ -96,7 +79,7 @@ public class SetBlockBufferPacketListener {
|
|||||||
applyBlockBuffer(player, server, buffer, worldKey);
|
applyBlockBuffer(player, server, buffer, worldKey);
|
||||||
} else if (type == 1) {
|
} else if (type == 1) {
|
||||||
BiomeBuffer buffer = BiomeBuffer.load(friendlyByteBuf);
|
BiomeBuffer buffer = BiomeBuffer.load(friendlyByteBuf);
|
||||||
applyBiomeBuffer(server, buffer, worldKey);
|
applyBiomeBuffer(player, server, buffer, worldKey);
|
||||||
} else {
|
} else {
|
||||||
throw new RuntimeException("Unknown buffer type: " + type);
|
throw new RuntimeException("Unknown buffer type: " + type);
|
||||||
}
|
}
|
||||||
@ -109,17 +92,18 @@ public class SetBlockBufferPacketListener {
|
|||||||
ServerLevel world = server.getLevel(worldKey);
|
ServerLevel world = server.getLevel(worldKey);
|
||||||
if (world == null) return;
|
if (world == null) return;
|
||||||
|
|
||||||
|
if (!this.plugin.canUseAxiom(player.getBukkitEntity())) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
// Call AxiomModifyWorldEvent event
|
// Call AxiomModifyWorldEvent event
|
||||||
AxiomModifyWorldEvent modifyWorldEvent = new AxiomModifyWorldEvent(player.getBukkitEntity(), world.getWorld());
|
AxiomModifyWorldEvent modifyWorldEvent = new AxiomModifyWorldEvent(player.getBukkitEntity(), world.getWorld());
|
||||||
Bukkit.getPluginManager().callEvent(modifyWorldEvent);
|
Bukkit.getPluginManager().callEvent(modifyWorldEvent);
|
||||||
if (modifyWorldEvent.isCancelled()) return;
|
if (modifyWorldEvent.isCancelled()) return;
|
||||||
|
|
||||||
// RegionProtection regionProtection = new RegionProtection(player.getBukkitEntity(), world.getWorld());
|
|
||||||
|
|
||||||
// Allowed, apply buffer
|
// Allowed, apply buffer
|
||||||
BlockPos.MutableBlockPos blockPos = new BlockPos.MutableBlockPos();
|
BlockPos.MutableBlockPos blockPos = new BlockPos.MutableBlockPos();
|
||||||
|
WorldExtension extension = WorldExtension.get(world);
|
||||||
var lightEngine = world.getChunkSource().getLightEngine();
|
|
||||||
|
|
||||||
BlockState emptyState = BlockBuffer.EMPTY_STATE;
|
BlockState emptyState = BlockBuffer.EMPTY_STATE;
|
||||||
|
|
||||||
@ -133,17 +117,7 @@ public class SetBlockBufferPacketListener {
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
// SectionProtection sectionProtection = regionProtection.getSection(cx, cy, cz);
|
|
||||||
// switch (sectionProtection.getSectionState()) {
|
|
||||||
// case ALLOW -> sectionProtection = null;
|
|
||||||
// case DENY -> {
|
|
||||||
// continue;
|
|
||||||
// }
|
|
||||||
// case CHECK -> {}
|
|
||||||
// }
|
|
||||||
|
|
||||||
LevelChunk chunk = world.getChunk(cx, cz);
|
LevelChunk chunk = world.getChunk(cx, cz);
|
||||||
chunk.setUnsaved(true);
|
|
||||||
|
|
||||||
LevelChunkSection section = chunk.getSection(world.getSectionIndexFromSectionY(cy));
|
LevelChunkSection section = chunk.getSection(world.getSectionIndexFromSectionY(cy));
|
||||||
PalettedContainer<BlockState> sectionStates = section.getStates();
|
PalettedContainer<BlockState> sectionStates = section.getStates();
|
||||||
@ -163,6 +137,12 @@ public class SetBlockBufferPacketListener {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
boolean sectionChanged = false;
|
||||||
|
boolean sectionLightChanged = false;
|
||||||
|
|
||||||
|
boolean containerMaybeHasPoi = container.maybeHas(PoiTypes::hasPoi);
|
||||||
|
boolean sectionMaybeHasPoi = section.maybeHas(PoiTypes::hasPoi);
|
||||||
|
|
||||||
Short2ObjectMap<CompressedBlockEntity> blockEntityChunkMap = buffer.getBlockEntityChunkMap(entry.getLongKey());
|
Short2ObjectMap<CompressedBlockEntity> blockEntityChunkMap = buffer.getBlockEntityChunkMap(entry.getLongKey());
|
||||||
|
|
||||||
for (int x = 0; x < 16; x++) {
|
for (int x = 0; x < 16; x++) {
|
||||||
@ -171,28 +151,19 @@ public class SetBlockBufferPacketListener {
|
|||||||
BlockState blockState = container.get(x, y, z);
|
BlockState blockState = container.get(x, y, z);
|
||||||
if (blockState == emptyState) continue;
|
if (blockState == emptyState) continue;
|
||||||
|
|
||||||
// switch (sectionProtection.getSectionState()) {
|
|
||||||
// case ALLOW -> {}
|
|
||||||
// case DENY -> blockState = Blocks.REDSTONE_BLOCK.defaultBlockState();
|
|
||||||
// case CHECK -> blockState = Blocks.DIAMOND_BLOCK.defaultBlockState();
|
|
||||||
// }
|
|
||||||
|
|
||||||
int bx = cx*16 + x;
|
int bx = cx*16 + x;
|
||||||
int by = cy*16 + y;
|
int by = cy*16 + y;
|
||||||
int bz = cz*16 + z;
|
int bz = cz*16 + z;
|
||||||
|
|
||||||
// if (!regionProtection.canBuild(bx, by, bz)) {
|
|
||||||
// continue;
|
|
||||||
// }
|
|
||||||
|
|
||||||
blockPos.set(bx, by, bz);
|
|
||||||
|
|
||||||
if (hasOnlyAir && blockState.isAir()) {
|
if (hasOnlyAir && blockState.isAir()) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
BlockState old = section.setBlockState(x, y, z, blockState, true);
|
BlockState old = section.setBlockState(x, y, z, blockState, true);
|
||||||
if (blockState != old) {
|
if (blockState != old) {
|
||||||
|
sectionChanged = true;
|
||||||
|
blockPos.set(bx, by, bz);
|
||||||
|
|
||||||
Block block = blockState.getBlock();
|
Block block = blockState.getBlock();
|
||||||
motionBlocking.update(x, by, z, blockState);
|
motionBlocking.update(x, by, z, blockState);
|
||||||
motionBlockingNoLeaves.update(x, by, z, blockState);
|
motionBlockingNoLeaves.update(x, by, z, blockState);
|
||||||
@ -245,18 +216,12 @@ public class SetBlockBufferPacketListener {
|
|||||||
chunk.removeBlockEntity(blockPos);
|
chunk.removeBlockEntity(blockPos);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Mark block changed
|
|
||||||
world.getChunkSource().blockChanged(blockPos); // todo: maybe simply resend chunk instead of this?
|
|
||||||
|
|
||||||
// Update Light
|
// Update Light
|
||||||
if (LightEngine.hasDifferentLightProperties(chunk, blockPos, old, blockState)) {
|
sectionLightChanged |= LightEngine.hasDifferentLightProperties(chunk, blockPos, old, blockState);
|
||||||
chunk.getSkyLightSources().update(chunk, x, by, z);
|
|
||||||
lightEngine.checkBlock(blockPos);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Update Poi
|
// Update Poi
|
||||||
Optional<Holder<PoiType>> newPoi = PoiTypes.forState(blockState);
|
Optional<Holder<PoiType>> newPoi = containerMaybeHasPoi ? PoiTypes.forState(blockState) : Optional.empty();
|
||||||
Optional<Holder<PoiType>> oldPoi = PoiTypes.forState(old);
|
Optional<Holder<PoiType>> oldPoi = sectionMaybeHasPoi ? PoiTypes.forState(old) : Optional.empty();
|
||||||
if (!Objects.equals(oldPoi, newPoi)) {
|
if (!Objects.equals(oldPoi, newPoi)) {
|
||||||
if (oldPoi.isPresent()) world.getPoiManager().remove(blockPos);
|
if (oldPoi.isPresent()) world.getPoiManager().remove(blockPos);
|
||||||
if (newPoi.isPresent()) world.getPoiManager().add(blockPos, newPoi.get());
|
if (newPoi.isPresent()) world.getPoiManager().add(blockPos, newPoi.get());
|
||||||
@ -270,16 +235,33 @@ public class SetBlockBufferPacketListener {
|
|||||||
if (hasOnlyAir != nowHasOnlyAir) {
|
if (hasOnlyAir != nowHasOnlyAir) {
|
||||||
world.getChunkSource().getLightEngine().updateSectionStatus(SectionPos.of(cx, cy, cz), nowHasOnlyAir);
|
world.getChunkSource().getLightEngine().updateSectionStatus(SectionPos.of(cx, cy, cz), nowHasOnlyAir);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (sectionChanged) {
|
||||||
|
extension.sendChunk(cx, cz);
|
||||||
|
chunk.setUnsaved(true);
|
||||||
|
}
|
||||||
|
if (sectionLightChanged) {
|
||||||
|
extension.lightChunk(cx, cz);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
private void applyBiomeBuffer(MinecraftServer server, BiomeBuffer biomeBuffer, ResourceKey<Level> worldKey) {
|
private void applyBiomeBuffer(ServerPlayer player, MinecraftServer server, BiomeBuffer biomeBuffer, ResourceKey<Level> worldKey) {
|
||||||
server.execute(() -> {
|
server.execute(() -> {
|
||||||
ServerLevel world = server.getLevel(worldKey);
|
ServerLevel world = server.getLevel(worldKey);
|
||||||
if (world == null) return;
|
if (world == null) return;
|
||||||
|
|
||||||
|
if (!this.plugin.canUseAxiom(player.getBukkitEntity())) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Call AxiomModifyWorldEvent event
|
||||||
|
AxiomModifyWorldEvent modifyWorldEvent = new AxiomModifyWorldEvent(player.getBukkitEntity(), world.getWorld());
|
||||||
|
Bukkit.getPluginManager().callEvent(modifyWorldEvent);
|
||||||
|
if (modifyWorldEvent.isCancelled()) return;
|
||||||
|
|
||||||
Set<LevelChunk> changedChunks = new HashSet<>();
|
Set<LevelChunk> changedChunks = new HashSet<>();
|
||||||
|
|
||||||
int minSection = world.getMinSection();
|
int minSection = world.getMinSection();
|
||||||
|
@ -62,7 +62,7 @@ public class SetBlockPacketListener implements PluginMessageListener {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onPluginMessageReceived(@NotNull String channel, @NotNull Player bukkitPlayer, @NotNull byte[] message) {
|
public void onPluginMessageReceived(@NotNull String channel, @NotNull Player bukkitPlayer, @NotNull byte[] message) {
|
||||||
if (!bukkitPlayer.hasPermission("axiom.*")) {
|
if (!this.plugin.canUseAxiom(bukkitPlayer)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
package com.moulberry.axiom.packet;
|
package com.moulberry.axiom.packet;
|
||||||
|
|
||||||
import com.moulberry.axiom.AxiomConstants;
|
import com.moulberry.axiom.AxiomConstants;
|
||||||
|
import com.moulberry.axiom.AxiomPaper;
|
||||||
import com.moulberry.axiom.View;
|
import com.moulberry.axiom.View;
|
||||||
import com.moulberry.axiom.persistence.UUIDDataType;
|
import com.moulberry.axiom.persistence.UUIDDataType;
|
||||||
import io.netty.buffer.Unpooled;
|
import io.netty.buffer.Unpooled;
|
||||||
@ -16,9 +17,14 @@ import java.util.UUID;
|
|||||||
|
|
||||||
public class SetEditorViewsPacketListener implements PluginMessageListener {
|
public class SetEditorViewsPacketListener implements PluginMessageListener {
|
||||||
|
|
||||||
|
private final AxiomPaper plugin;
|
||||||
|
public SetEditorViewsPacketListener(AxiomPaper plugin) {
|
||||||
|
this.plugin = plugin;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onPluginMessageReceived(@NotNull String channel, @NotNull Player player, @NotNull byte[] message) {
|
public void onPluginMessageReceived(@NotNull String channel, @NotNull Player player, @NotNull byte[] message) {
|
||||||
if (!player.hasPermission("axiom.*")) {
|
if (!this.plugin.canUseAxiom(player)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
package com.moulberry.axiom.packet;
|
package com.moulberry.axiom.packet;
|
||||||
|
|
||||||
|
import com.moulberry.axiom.AxiomPaper;
|
||||||
import com.moulberry.axiom.event.AxiomFlySpeedChangeEvent;
|
import com.moulberry.axiom.event.AxiomFlySpeedChangeEvent;
|
||||||
import io.netty.buffer.Unpooled;
|
import io.netty.buffer.Unpooled;
|
||||||
import net.minecraft.network.FriendlyByteBuf;
|
import net.minecraft.network.FriendlyByteBuf;
|
||||||
@ -11,9 +12,14 @@ import org.jetbrains.annotations.NotNull;
|
|||||||
|
|
||||||
public class SetFlySpeedPacketListener implements PluginMessageListener {
|
public class SetFlySpeedPacketListener implements PluginMessageListener {
|
||||||
|
|
||||||
|
private final AxiomPaper plugin;
|
||||||
|
public SetFlySpeedPacketListener(AxiomPaper plugin) {
|
||||||
|
this.plugin = plugin;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onPluginMessageReceived(@NotNull String channel, @NotNull Player player, @NotNull byte[] message) {
|
public void onPluginMessageReceived(@NotNull String channel, @NotNull Player player, @NotNull byte[] message) {
|
||||||
if (!player.hasPermission("axiom.*")) {
|
if (!this.plugin.canUseAxiom(player)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
package com.moulberry.axiom.packet;
|
package com.moulberry.axiom.packet;
|
||||||
|
|
||||||
|
import com.moulberry.axiom.AxiomPaper;
|
||||||
import com.moulberry.axiom.event.AxiomGameModeChangeEvent;
|
import com.moulberry.axiom.event.AxiomGameModeChangeEvent;
|
||||||
import io.netty.buffer.Unpooled;
|
import io.netty.buffer.Unpooled;
|
||||||
import net.minecraft.network.FriendlyByteBuf;
|
import net.minecraft.network.FriendlyByteBuf;
|
||||||
@ -13,9 +14,14 @@ import org.jetbrains.annotations.NotNull;
|
|||||||
|
|
||||||
public class SetGamemodePacketListener implements PluginMessageListener {
|
public class SetGamemodePacketListener implements PluginMessageListener {
|
||||||
|
|
||||||
|
private final AxiomPaper plugin;
|
||||||
|
public SetGamemodePacketListener(AxiomPaper plugin) {
|
||||||
|
this.plugin = plugin;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onPluginMessageReceived(@NotNull String channel, @NotNull Player player, @NotNull byte[] message) {
|
public void onPluginMessageReceived(@NotNull String channel, @NotNull Player player, @NotNull byte[] message) {
|
||||||
if (!player.hasPermission("axiom.*")) {
|
if (!this.plugin.canUseAxiom(player)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
package com.moulberry.axiom.packet;
|
package com.moulberry.axiom.packet;
|
||||||
|
|
||||||
import com.moulberry.axiom.AxiomConstants;
|
import com.moulberry.axiom.AxiomConstants;
|
||||||
|
import com.moulberry.axiom.AxiomPaper;
|
||||||
import com.moulberry.axiom.persistence.ItemStackDataType;
|
import com.moulberry.axiom.persistence.ItemStackDataType;
|
||||||
import io.netty.buffer.Unpooled;
|
import io.netty.buffer.Unpooled;
|
||||||
import net.minecraft.network.FriendlyByteBuf;
|
import net.minecraft.network.FriendlyByteBuf;
|
||||||
@ -15,9 +16,14 @@ import org.jetbrains.annotations.NotNull;
|
|||||||
|
|
||||||
public class SetHotbarSlotPacketListener implements PluginMessageListener {
|
public class SetHotbarSlotPacketListener implements PluginMessageListener {
|
||||||
|
|
||||||
|
private final AxiomPaper plugin;
|
||||||
|
public SetHotbarSlotPacketListener(AxiomPaper plugin) {
|
||||||
|
this.plugin = plugin;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onPluginMessageReceived(@NotNull String channel, @NotNull Player player, @NotNull byte[] message) {
|
public void onPluginMessageReceived(@NotNull String channel, @NotNull Player player, @NotNull byte[] message) {
|
||||||
if (!player.hasPermission("axiom.*")) {
|
if (!this.plugin.canUseAxiom(player)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,5 +1,7 @@
|
|||||||
package com.moulberry.axiom.packet;
|
package com.moulberry.axiom.packet;
|
||||||
|
|
||||||
|
import com.moulberry.axiom.AxiomPaper;
|
||||||
|
import com.moulberry.axiom.event.AxiomModifyWorldEvent;
|
||||||
import com.moulberry.axiom.event.AxiomTimeChangeEvent;
|
import com.moulberry.axiom.event.AxiomTimeChangeEvent;
|
||||||
import io.netty.buffer.Unpooled;
|
import io.netty.buffer.Unpooled;
|
||||||
import net.minecraft.core.registries.Registries;
|
import net.minecraft.core.registries.Registries;
|
||||||
@ -16,9 +18,14 @@ import org.jetbrains.annotations.NotNull;
|
|||||||
|
|
||||||
public class SetTimePacketListener implements PluginMessageListener {
|
public class SetTimePacketListener implements PluginMessageListener {
|
||||||
|
|
||||||
|
private final AxiomPaper plugin;
|
||||||
|
public SetTimePacketListener(AxiomPaper plugin) {
|
||||||
|
this.plugin = plugin;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onPluginMessageReceived(@NotNull String channel, @NotNull Player player, @NotNull byte[] message) {
|
public void onPluginMessageReceived(@NotNull String channel, @NotNull Player player, @NotNull byte[] message) {
|
||||||
if (!player.hasPermission("axiom.*")) {
|
if (!this.plugin.canUseAxiom(player)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -32,7 +39,12 @@ public class SetTimePacketListener implements PluginMessageListener {
|
|||||||
ServerLevel level = ((CraftWorld)player.getWorld()).getHandle();
|
ServerLevel level = ((CraftWorld)player.getWorld()).getHandle();
|
||||||
if (!level.dimension().equals(key)) return;
|
if (!level.dimension().equals(key)) return;
|
||||||
|
|
||||||
// Call event
|
// Call modify world
|
||||||
|
AxiomModifyWorldEvent modifyWorldEvent = new AxiomModifyWorldEvent(player, player.getWorld());
|
||||||
|
Bukkit.getPluginManager().callEvent(modifyWorldEvent);
|
||||||
|
if (modifyWorldEvent.isCancelled()) return;
|
||||||
|
|
||||||
|
// Call time change event
|
||||||
AxiomTimeChangeEvent timeChangeEvent = new AxiomTimeChangeEvent(player, time, freezeTime);
|
AxiomTimeChangeEvent timeChangeEvent = new AxiomTimeChangeEvent(player, time, freezeTime);
|
||||||
Bukkit.getPluginManager().callEvent(timeChangeEvent);
|
Bukkit.getPluginManager().callEvent(timeChangeEvent);
|
||||||
if (timeChangeEvent.isCancelled()) return;
|
if (timeChangeEvent.isCancelled()) return;
|
||||||
|
@ -12,9 +12,14 @@ import org.jetbrains.annotations.NotNull;
|
|||||||
|
|
||||||
public class SetWorldPropertyListener implements PluginMessageListener {
|
public class SetWorldPropertyListener implements PluginMessageListener {
|
||||||
|
|
||||||
|
private final AxiomPaper plugin;
|
||||||
|
public SetWorldPropertyListener(AxiomPaper plugin) {
|
||||||
|
this.plugin = plugin;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onPluginMessageReceived(@NotNull String channel, @NotNull Player player, @NotNull byte[] message) {
|
public void onPluginMessageReceived(@NotNull String channel, @NotNull Player player, @NotNull byte[] message) {
|
||||||
if (!player.hasPermission("axiom.*")) {
|
if (!this.plugin.canUseAxiom(player)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
package com.moulberry.axiom.packet;
|
package com.moulberry.axiom.packet;
|
||||||
|
|
||||||
import com.moulberry.axiom.AxiomConstants;
|
import com.moulberry.axiom.AxiomConstants;
|
||||||
|
import com.moulberry.axiom.AxiomPaper;
|
||||||
import com.moulberry.axiom.persistence.ItemStackDataType;
|
import com.moulberry.axiom.persistence.ItemStackDataType;
|
||||||
import io.netty.buffer.Unpooled;
|
import io.netty.buffer.Unpooled;
|
||||||
import net.minecraft.network.FriendlyByteBuf;
|
import net.minecraft.network.FriendlyByteBuf;
|
||||||
@ -17,9 +18,14 @@ import org.jetbrains.annotations.NotNull;
|
|||||||
|
|
||||||
public class SwitchActiveHotbarPacketListener implements PluginMessageListener {
|
public class SwitchActiveHotbarPacketListener implements PluginMessageListener {
|
||||||
|
|
||||||
|
private final AxiomPaper plugin;
|
||||||
|
public SwitchActiveHotbarPacketListener(AxiomPaper plugin) {
|
||||||
|
this.plugin = plugin;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onPluginMessageReceived(@NotNull String channel, @NotNull Player player, @NotNull byte[] message) {
|
public void onPluginMessageReceived(@NotNull String channel, @NotNull Player player, @NotNull byte[] message) {
|
||||||
if (!player.hasPermission("axiom.*")) {
|
if (!this.plugin.canUseAxiom(player)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
package com.moulberry.axiom.packet;
|
package com.moulberry.axiom.packet;
|
||||||
|
|
||||||
|
import com.moulberry.axiom.AxiomPaper;
|
||||||
import com.moulberry.axiom.event.AxiomGameModeChangeEvent;
|
import com.moulberry.axiom.event.AxiomGameModeChangeEvent;
|
||||||
import com.moulberry.axiom.event.AxiomTeleportEvent;
|
import com.moulberry.axiom.event.AxiomTeleportEvent;
|
||||||
import io.netty.buffer.Unpooled;
|
import io.netty.buffer.Unpooled;
|
||||||
@ -14,9 +15,14 @@ import org.jetbrains.annotations.NotNull;
|
|||||||
|
|
||||||
public class TeleportPacketListener implements PluginMessageListener {
|
public class TeleportPacketListener implements PluginMessageListener {
|
||||||
|
|
||||||
|
private final AxiomPaper plugin;
|
||||||
|
public TeleportPacketListener(AxiomPaper plugin) {
|
||||||
|
this.plugin = plugin;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onPluginMessageReceived(@NotNull String channel, @NotNull Player player, @NotNull byte[] message) {
|
public void onPluginMessageReceived(@NotNull String channel, @NotNull Player player, @NotNull byte[] message) {
|
||||||
if (!player.hasPermission("axiom.*")) {
|
if (!this.plugin.canUseAxiom(player)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
29
src/main/resources/config.yml
Normale Datei
29
src/main/resources/config.yml
Normale Datei
@ -0,0 +1,29 @@
|
|||||||
|
# Max chunk sends per tick (per-world), 0 = no limit
|
||||||
|
max-chunk-sends-per-tick: 0
|
||||||
|
|
||||||
|
# Max chunk relights per tick (per-world), 0 = no limit
|
||||||
|
max-chunk-relights-per-tick: 0
|
||||||
|
|
||||||
|
# Action to take when a user with an incompatible Minecraft version or Axiom version joins
|
||||||
|
# Valid actions are 'kick', 'warn' and 'ignore'
|
||||||
|
# Using 'ignore' may result in corruption and is only provided for debugging purposes
|
||||||
|
incompatible-data-version: "kick"
|
||||||
|
unsupported-axiom-version: "kick"
|
||||||
|
|
||||||
|
# Maximum packet size. Must not be less than 32767
|
||||||
|
max-block-buffer-packet-size: 0x100000
|
||||||
|
|
||||||
|
# Toggles for individual packet handlers. May break certain features
|
||||||
|
packet-handlers:
|
||||||
|
hello: true
|
||||||
|
set-gamemode: true
|
||||||
|
set-fly-speed: true
|
||||||
|
set-world-time: true
|
||||||
|
set-world-property: true
|
||||||
|
set-single-block: true
|
||||||
|
set-hotbar-slot: true
|
||||||
|
switch-active-hotbar: true
|
||||||
|
teleport: true
|
||||||
|
set-editor-views: true
|
||||||
|
request-chunk-data: true
|
||||||
|
set-buffer: true
|
Laden…
In neuem Issue referenzieren
Einen Benutzer sperren