Skip to content

Commit 4173c4a

Browse files
committed
support BlockCanBuildEvent using Reflection
1 parent ff6dbb4 commit 4173c4a

File tree

1 file changed

+72
-6
lines changed
  • AnarchyExploitFixesLegacy/src/main/java/me/xginko/aef/modules/chunklimits

1 file changed

+72
-6
lines changed

AnarchyExploitFixesLegacy/src/main/java/me/xginko/aef/modules/chunklimits/BlockLimit.java

Lines changed: 72 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,9 @@
88
import me.xginko.aef.modules.AEFModule;
99
import me.xginko.aef.utils.LocationUtil;
1010
import me.xginko.aef.utils.WorldUtil;
11+
import me.xginko.aef.utils.models.Lazy;
1112
import me.xginko.aef.utils.permissions.AEFPermission;
13+
import me.xginko.aef.utils.reflection.ReflectionUtil;
1214
import org.bukkit.Chunk;
1315
import org.bukkit.Location;
1416
import org.bukkit.Material;
@@ -18,10 +20,13 @@
1820
import org.bukkit.event.HandlerList;
1921
import org.bukkit.event.Listener;
2022
import org.bukkit.event.block.Action;
23+
import org.bukkit.event.block.BlockCanBuildEvent;
2124
import org.bukkit.event.block.BlockPlaceEvent;
2225
import org.bukkit.event.player.PlayerInteractEvent;
2326
import org.jetbrains.annotations.NotNull;
27+
import org.jetbrains.annotations.Nullable;
2428

29+
import java.lang.invoke.MethodHandle;
2530
import java.time.Duration;
2631
import java.util.EnumMap;
2732
import java.util.Map;
@@ -185,12 +190,45 @@ public void disable() {
185190
}
186191
}
187192

188-
private void sendPlayerNotification(Player player, Material block, int existing, int limit) {
189-
if (notifyPlayer) player.sendMessage(
190-
AnarchyExploitFixes.translation(player.getLocale()).chunklimits_block_limit_exceeded
191-
.replace("%block%", block.name())
192-
.replace("%existing%", Integer.toString(existing))
193-
.replace("%limit%", Integer.toString(limit)));
193+
@EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = true)
194+
private void onBlockCanBuild(BlockCanBuildEvent event) {
195+
if (!event.isBuildable() || !blockLimits.containsKey(event.getMaterial())) {
196+
return;
197+
}
198+
199+
Player player = getPlayer(event);
200+
if (player == null) return;
201+
202+
if (AnarchyExploitFixes.permissions().permissionValue(player, AEFPermission.BYPASS_CHUNK_LIMITS_BLOCK_LIMIT.node()).toBoolean()) {
203+
logger().debug("Ignoring {} for player '{}' because they have bypass permission: {}",
204+
event.getEventName(),
205+
player.getName(),
206+
AEFPermission.BYPASS_CHUNK_LIMITS_BLOCK_LIMIT.node());
207+
return;
208+
}
209+
210+
int materialCount = getMaterialCountForChunk(event.getBlock().getType(), event.getBlock().getChunk());
211+
int limit = blockLimits.get(event.getMaterial());
212+
213+
if (materialCount <= limit) {
214+
logger().debug("Allowing player '{}' to place {} at location {} => count={} limit={}",
215+
player.getName(),
216+
event.getMaterial(),
217+
LocationUtil.toString(event.getBlock().getLocation()),
218+
materialCount,
219+
limit);
220+
return;
221+
}
222+
223+
event.setBuildable(false);
224+
225+
sendPlayerNotification(player, event.getMaterial(), materialCount, limit);
226+
logger().info("Preventing player '{}' from placing {} at location {} => count={} limit={}",
227+
player.getName(),
228+
event.getBlock().getType(),
229+
LocationUtil.toString(event.getBlock().getLocation()),
230+
materialCount,
231+
limit);
194232
}
195233

196234
@EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = true)
@@ -302,4 +340,32 @@ private int getMaterialCountForChunk(Material blockType, Chunk chunk) {
302340

303341
return cachedMaterialCount;
304342
}
343+
344+
private void sendPlayerNotification(Player player, Material block, int existing, int limit) {
345+
if (notifyPlayer) player.sendMessage(
346+
AnarchyExploitFixes.translation(player.getLocale()).chunklimits_block_limit_exceeded
347+
.replace("%block%", block.name())
348+
.replace("%existing%", Integer.toString(existing))
349+
.replace("%limit%", Integer.toString(limit)));
350+
}
351+
352+
private @Nullable Player getPlayer(@NotNull BlockCanBuildEvent event) {
353+
if (BLOCK_CAN_BUILD_PLAYER_FIELD.get() == null) {
354+
return null;
355+
}
356+
357+
try {
358+
return (Player) BLOCK_CAN_BUILD_PLAYER_FIELD.get().invoke(event);
359+
} catch (Throwable t) {
360+
return null;
361+
}
362+
}
363+
364+
private static final Lazy<@Nullable MethodHandle> BLOCK_CAN_BUILD_PLAYER_FIELD = Lazy.of(() -> {
365+
try {
366+
return ReflectionUtil.findMethod(BlockCanBuildEvent.class, "getPlayer", Player.class);
367+
} catch (Throwable t) {
368+
return null;
369+
}
370+
});
305371
}

0 commit comments

Comments
 (0)