Skip to content

Commit b32d1ea

Browse files
committed
# Conflicts: # build.gradle.kts
2 parents ce4948a + 8cd2930 commit b32d1ea

File tree

11 files changed

+670
-16
lines changed

11 files changed

+670
-16
lines changed

build.gradle.kts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ plugins {
88
}
99

1010
group = "com.moulberry.axiom"
11-
version = "1.5.7.1"
11+
version = "1.5.8"
1212
description = "Serverside component for Axiom on Paper"
1313

1414
java {

src/main/java/com/moulberry/axiom/AxiomPaper.java

Lines changed: 78 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,10 @@
11
package com.moulberry.axiom;
22

33
import com.google.common.util.concurrent.RateLimiter;
4-
import com.mojang.brigadier.StringReader;
5-
import com.moulberry.axiom.buffer.BlockBuffer;
64
import com.moulberry.axiom.buffer.CompressedBlockEntity;
75
import com.moulberry.axiom.event.AxiomCreateWorldPropertiesEvent;
86
import com.moulberry.axiom.event.AxiomModifyWorldEvent;
7+
import com.moulberry.axiom.integration.plotsquared.PlotSquaredIntegration;
98
import com.moulberry.axiom.packet.*;
109
import com.moulberry.axiom.world_properties.server.ServerWorldPropertiesRegistry;
1110
import io.netty.buffer.Unpooled;
@@ -15,20 +14,15 @@
1514
import io.papermc.paper.network.ChannelInitializeListener;
1615
import io.papermc.paper.network.ChannelInitializeListenerHolder;
1716
import net.kyori.adventure.key.Key;
18-
import net.minecraft.commands.arguments.blocks.BlockPredicateArgument;
19-
import net.minecraft.commands.arguments.blocks.BlockStateArgument;
20-
import net.minecraft.commands.arguments.blocks.BlockStateParser;
17+
import net.minecraft.core.BlockPos;
2118
import net.minecraft.core.IdMapper;
22-
import net.minecraft.core.registries.BuiltInRegistries;
2319
import net.minecraft.network.Connection;
2420
import net.minecraft.network.ConnectionProtocol;
2521
import net.minecraft.network.FriendlyByteBuf;
2622
import net.minecraft.network.protocol.Packet;
2723
import net.minecraft.network.protocol.PacketFlow;
2824
import net.minecraft.network.protocol.common.ServerboundCustomPayloadPacket;
2925
import net.minecraft.server.MinecraftServer;
30-
import net.minecraft.world.level.block.Block;
31-
import net.minecraft.world.level.block.Blocks;
3226
import net.minecraft.world.level.block.state.BlockState;
3327
import org.bukkit.*;
3428
import org.bukkit.configuration.Configuration;
@@ -43,15 +37,14 @@
4337

4438
import java.util.*;
4539
import java.util.concurrent.ConcurrentHashMap;
46-
import java.util.concurrent.TimeUnit;
47-
import java.util.logging.Level;
4840

4941
public class AxiomPaper extends JavaPlugin implements Listener {
5042

5143
public static AxiomPaper PLUGIN; // tsk tsk tsk
5244

5345
public final Set<UUID> activeAxiomPlayers = Collections.newSetFromMap(new ConcurrentHashMap<>());
5446
public final Map<UUID, RateLimiter> playerBlockBufferRateLimiters = new ConcurrentHashMap<>();
47+
public final Map<UUID, Restrictions> playerRestrictions = new ConcurrentHashMap<>();
5548
public Configuration configuration;
5649

5750
public IdMapper<BlockState> allowedBlockRegistry = null;
@@ -90,6 +83,7 @@ public void onEnable() {
9083
msg.registerOutgoingPluginChannel(this, "axiom:register_world_properties");
9184
msg.registerOutgoingPluginChannel(this, "axiom:set_world_property");
9285
msg.registerOutgoingPluginChannel(this, "axiom:ack_world_properties");
86+
msg.registerOutgoingPluginChannel(this, "axiom:restrictions");
9387

9488
if (configuration.getBoolean("packet-handlers.hello")) {
9589
msg.registerIncomingPluginChannel(this, "axiom:hello", new HelloPacketListener(this));
@@ -124,6 +118,15 @@ public void onEnable() {
124118
if (configuration.getBoolean("packet-handlers.request-chunk-data")) {
125119
msg.registerIncomingPluginChannel(this, "axiom:request_chunk_data", new RequestChunkDataPacketListener(this));
126120
}
121+
if (configuration.getBoolean("packet-handlers.spawn-entity")) {
122+
msg.registerIncomingPluginChannel(this, "axiom:spawn_entity", new SpawnEntityPacketListener(this));
123+
}
124+
if (configuration.getBoolean("packet-handlers.manipulate-entity")) {
125+
msg.registerIncomingPluginChannel(this, "axiom:manipulate_entity", new ManipulateEntityPacketListener(this));
126+
}
127+
if (configuration.getBoolean("packet-handlers.delete-entity")) {
128+
msg.registerIncomingPluginChannel(this, "axiom:delete_entity", new DeleteEntityPacketListener(this));
129+
}
127130

128131
if (configuration.getBoolean("packet-handlers.set-buffer")) {
129132
SetBlockBufferPacketListener setBlockBufferPacketListener = new SetBlockBufferPacketListener(this);
@@ -153,6 +156,13 @@ public void afterInitChannel(@NonNull Channel channel) {
153156
Bukkit.getScheduler().scheduleSyncRepeatingTask(this, () -> {
154157
HashSet<UUID> stillActiveAxiomPlayers = new HashSet<>();
155158

159+
int rateLimit = this.configuration.getInt("block-buffer-rate-limit");
160+
if (rateLimit > 0) {
161+
// Reduce by 20% just to prevent synchronization/timing issues
162+
rateLimit = rateLimit * 8/10;
163+
if (rateLimit <= 0) rateLimit = 1;
164+
}
165+
156166
for (Player player : Bukkit.getServer().getOnlinePlayers()) {
157167
if (activeAxiomPlayers.contains(player.getUniqueId())) {
158168
if (!player.hasPermission("axiom.*")) {
@@ -162,13 +172,70 @@ public void afterInitChannel(@NonNull Channel channel) {
162172
buf.getBytes(0, bytes);
163173
player.sendPluginMessage(this, "axiom:enable", bytes);
164174
} else {
165-
stillActiveAxiomPlayers.add(player.getUniqueId());
175+
UUID uuid = player.getUniqueId();
176+
stillActiveAxiomPlayers.add(uuid);
177+
178+
boolean send = false;
179+
180+
Restrictions restrictions = playerRestrictions.get(uuid);
181+
if (restrictions == null) {
182+
restrictions = new Restrictions();
183+
playerRestrictions.put(uuid, restrictions);
184+
send = true;
185+
}
186+
187+
BlockPos boundsMin = null;
188+
BlockPos boundsMax = null;
189+
190+
if (!player.hasPermission("axiom.allow_copying_other_plots")) {
191+
if (PlotSquaredIntegration.isPlotWorld(player.getWorld())) {
192+
PlotSquaredIntegration.PlotBounds editable = PlotSquaredIntegration.getCurrentEditablePlot(player);
193+
if (editable != null) {
194+
restrictions.lastPlotBounds = editable;
195+
boundsMin = editable.min();
196+
boundsMax = editable.max();
197+
} else if (restrictions.lastPlotBounds != null && restrictions.lastPlotBounds.worldName().equals(player.getWorld().getName())) {
198+
boundsMin = restrictions.lastPlotBounds.min();
199+
boundsMax = restrictions.lastPlotBounds.max();
200+
} else {
201+
boundsMin = BlockPos.ZERO;
202+
boundsMax = BlockPos.ZERO;
203+
}
204+
}
205+
206+
int min = Integer.MIN_VALUE;
207+
int max = Integer.MAX_VALUE;
208+
if (boundsMin != null && boundsMax != null &&
209+
boundsMin.getX() == min && boundsMin.getY() == min && boundsMin.getZ() == min &&
210+
boundsMax.getX() == max && boundsMax.getY() == max && boundsMax.getZ() == max) {
211+
boundsMin = null;
212+
boundsMax = null;
213+
}
214+
}
215+
216+
boolean allowImportingBlocks = player.hasPermission("axiom.can_import_blocks");
217+
218+
if (restrictions.maxSectionsPerSecond != rateLimit ||
219+
restrictions.canImportBlocks != allowImportingBlocks ||
220+
!Objects.equals(restrictions.boundsMin, boundsMin) ||
221+
!Objects.equals(restrictions.boundsMax, boundsMax)) {
222+
restrictions.maxSectionsPerSecond = rateLimit;
223+
restrictions.canImportBlocks = allowImportingBlocks;
224+
restrictions.boundsMin = boundsMin;
225+
restrictions.boundsMax = boundsMax;
226+
send = true;
227+
}
228+
229+
if (send) {
230+
restrictions.send(this, player);
231+
}
166232
}
167233
}
168234
}
169235

170236
activeAxiomPlayers.retainAll(stillActiveAxiomPlayers);
171237
playerBlockBufferRateLimiters.keySet().retainAll(stillActiveAxiomPlayers);
238+
playerRestrictions.keySet().retainAll(stillActiveAxiomPlayers);
172239
}, 20, 20);
173240

174241
int maxChunkRelightsPerTick = configuration.getInt("max-chunk-relights-per-tick");
Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
package com.moulberry.axiom;
2+
3+
import com.moulberry.axiom.integration.plotsquared.PlotSquaredIntegration;
4+
import io.netty.buffer.Unpooled;
5+
import net.minecraft.core.BlockPos;
6+
import net.minecraft.network.FriendlyByteBuf;
7+
import org.bukkit.entity.Player;
8+
9+
public class Restrictions {
10+
11+
public boolean canImportBlocks = true;
12+
public boolean canUseEditor = true;
13+
public boolean canEditDisplayEntities = true;
14+
public int maxSectionsPerSecond = 0;
15+
public BlockPos boundsMin = null;
16+
public BlockPos boundsMax = null;
17+
18+
public PlotSquaredIntegration.PlotBounds lastPlotBounds = null;
19+
20+
public void send(AxiomPaper plugin, Player player) {
21+
if (player.getListeningPluginChannels().contains("axiom:restrictions")) {
22+
FriendlyByteBuf buf = new FriendlyByteBuf(Unpooled.buffer());
23+
buf.writeBoolean(this.canImportBlocks);
24+
buf.writeBoolean(this.canUseEditor);
25+
buf.writeBoolean(this.canEditDisplayEntities);
26+
27+
buf.writeVarInt(this.maxSectionsPerSecond);
28+
29+
if (this.boundsMin == null || this.boundsMax == null) {
30+
buf.writeBoolean(false);
31+
} else {
32+
buf.writeBoolean(true);
33+
int minX = this.boundsMin.getX();
34+
int minY = this.boundsMin.getY();
35+
int minZ = this.boundsMin.getZ();
36+
int maxX = this.boundsMax.getX();
37+
int maxY = this.boundsMax.getY();
38+
int maxZ = this.boundsMax.getZ();
39+
40+
if (minX < -33554431) minX = -33554431;
41+
if (minX > 33554431) minX = 33554431;
42+
if (minY < -2047) minY = -2047;
43+
if (minY > 2047) minY = 2047;
44+
if (minZ < -33554431) minZ = -33554431;
45+
if (minZ > 33554431) minZ = 33554431;
46+
47+
if (maxX < -33554431) maxX = -33554431;
48+
if (maxX > 33554431) maxX = 33554431;
49+
if (maxY < -2047) maxY = -2047;
50+
if (maxY > 2047) maxY = 2047;
51+
if (maxZ < -33554431) maxZ = -33554431;
52+
if (maxZ > 33554431) maxZ = 33554431;
53+
54+
buf.writeBlockPos(new BlockPos(minX, minY, minZ));
55+
buf.writeBlockPos(new BlockPos(maxX, maxY, maxZ));
56+
}
57+
58+
byte[] bytes = new byte[buf.writerIndex()];
59+
buf.getBytes(0, bytes);
60+
player.sendPluginMessage(plugin, "axiom:restrictions", bytes);
61+
}
62+
}
63+
64+
}

src/main/java/com/moulberry/axiom/integration/plotsquared/PlotSquaredIntegration.java

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,14 +2,35 @@
22

33

44
import com.moulberry.axiom.integration.SectionPermissionChecker;
5+
import com.sk89q.worldedit.regions.CuboidRegion;
6+
import net.minecraft.core.BlockPos;
57
import org.bukkit.Bukkit;
8+
import org.bukkit.Location;
69
import org.bukkit.World;
710
import org.bukkit.block.Block;
811
import org.bukkit.entity.Player;
912

1013

1114
public class PlotSquaredIntegration {
1215

16+
public record PlotBounds(BlockPos min, BlockPos max, String worldName) {
17+
public PlotBounds(CuboidRegion cuboidRegion, String worldName) {
18+
this(
19+
new BlockPos(
20+
cuboidRegion.getMinimumPoint().getBlockX(),
21+
cuboidRegion.getMinimumPoint().getBlockY(),
22+
cuboidRegion.getMinimumPoint().getBlockZ()
23+
),
24+
new BlockPos(
25+
cuboidRegion.getMaximumPoint().getBlockX(),
26+
cuboidRegion.getMaximumPoint().getBlockY(),
27+
cuboidRegion.getMaximumPoint().getBlockZ()
28+
),
29+
worldName
30+
);
31+
}
32+
}
33+
1334
public static boolean canBreakBlock(Player player, Block block) {
1435
if (!Bukkit.getPluginManager().isPluginEnabled("PlotSquared")) {
1536
return true;
@@ -31,6 +52,13 @@ public static boolean isPlotWorld(World world) {
3152
return PlotSquaredIntegrationImpl.isPlotWorld(world);
3253
}
3354

55+
public static PlotSquaredIntegration.PlotBounds getCurrentEditablePlot(Player player) {
56+
if (!Bukkit.getPluginManager().isPluginEnabled("PlotSquared")) {
57+
return null;
58+
}
59+
return PlotSquaredIntegrationImpl.getCurrentEditablePlot(player);
60+
}
61+
3462
public static SectionPermissionChecker checkSection(Player player, World world, int sectionX, int sectionY, int sectionZ) {
3563
if (!Bukkit.getPluginManager().isPluginEnabled("PlotSquared")) {
3664
return SectionPermissionChecker.ALL_ALLOWED;

src/main/java/com/moulberry/axiom/integration/plotsquared/PlotSquaredIntegrationImpl.java

Lines changed: 47 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -135,6 +135,52 @@ static boolean isPlotWorld(World world) {
135135
return isPlotWorld;
136136
}
137137

138+
static PlotSquaredIntegration.PlotBounds getCurrentEditablePlot(Player player) {
139+
org.bukkit.Location loc = player.getLocation();
140+
141+
Location location = BukkitUtil.adapt(loc);
142+
PlotArea area = location.getPlotArea();
143+
if (area == null) {
144+
return null;
145+
}
146+
147+
BukkitPlayer pp = BukkitUtil.adapt(player);
148+
Plot plot = area.getPlot(location);
149+
if (plot != null) {
150+
Location bottom = plot.getExtendedBottomAbs();
151+
Location top = plot.getExtendedTopAbs();
152+
CuboidRegion cuboidRegion = new CuboidRegion(bottom.getBlockVector3(), top.getBlockVector3());
153+
154+
// check unowned plots
155+
if (!plot.hasOwner()) {
156+
if (!pp.hasPermission(Permission.PERMISSION_ADMIN_BUILD_UNOWNED, false)) {
157+
return null;
158+
} else {
159+
return new PlotSquaredIntegration.PlotBounds(cuboidRegion, player.getWorld().getName());
160+
}
161+
}
162+
// player is breaking another player's plot
163+
if (!plot.isAdded(pp.getUUID())) {
164+
if (!pp.hasPermission(Permission.PERMISSION_ADMIN_BUILD_OTHER, false)) {
165+
return null;
166+
} else {
167+
return new PlotSquaredIntegration.PlotBounds(cuboidRegion, player.getWorld().getName());
168+
}
169+
}
170+
// plot is 'done'
171+
if (Settings.Done.RESTRICT_BUILDING && DoneFlag.isDone(plot)) {
172+
if (!pp.hasPermission(Permission.PERMISSION_ADMIN_BUILD_OTHER, false)) {
173+
return null;
174+
} else {
175+
return new PlotSquaredIntegration.PlotBounds(cuboidRegion, player.getWorld().getName());
176+
}
177+
}
178+
return new PlotSquaredIntegration.PlotBounds(cuboidRegion, player.getWorld().getName());
179+
}
180+
181+
return null;
182+
}
183+
138184
static SectionPermissionChecker checkSection(Player player, World world, int sectionX, int sectionY, int sectionZ) {
139185
int minX = sectionX * 16;
140186
int minY = sectionY * 16;
@@ -220,4 +266,4 @@ static SectionPermissionChecker checkSection(Player player, World world, int sec
220266

221267
return SectionPermissionChecker.fromAllowedBoxes(allowed);
222268
}
223-
}
269+
}

0 commit comments

Comments
 (0)