|
20 | 20 | import org.bukkit.permissions.PermissionAttachmentInfo; |
21 | 21 | import org.eclipse.jdt.annotation.NonNull; |
22 | 22 |
|
| 23 | +import world.bentobox.bentobox.api.addons.GameModeAddon; |
23 | 24 | import world.bentobox.bentobox.api.events.island.IslandEvent; |
24 | 25 | import world.bentobox.bentobox.api.events.island.IslandEvent.Reason; |
25 | 26 | import world.bentobox.bentobox.api.events.team.TeamSetownerEvent; |
|
34 | 35 | /** |
35 | 36 | * Applies permission-based block, entity, and entity-group limits to islands. |
36 | 37 | * |
| 38 | + * <p>By default only the island owner's permissions count. When |
| 39 | + * {@code apply-member-limit-perms} is enabled in the config, team members' permissions |
| 40 | + * are merged in as well: a member's login merges their limits on top (highest value |
| 41 | + * wins), and the owner's login recalculates from scratch and then merges the |
| 42 | + * permissions of all online members. |
| 43 | + * |
37 | 44 | * <p>Permission format: |
38 | 45 | * <ul> |
39 | 46 | * <li>5-segment: {@code <gm>.island.limit.<KEY>.<N>} — same limit applied independently |
@@ -64,6 +71,16 @@ public void checkPerms(Player player, String permissionPrefix, String islandId, |
64 | 71 | islandBlockCount.clearAllEntityGroupLimits(); |
65 | 72 | islandBlockCount.clearAllBlockLimits(); |
66 | 73 | } |
| 74 | + mergePerms(player, permissionPrefix, islandId, gameMode); |
| 75 | + } |
| 76 | + |
| 77 | + /** |
| 78 | + * Reads every limit-shaped permission the player has and merges it into the island's |
| 79 | + * existing permission-based limits — the highest value wins. Unlike |
| 80 | + * {@link #checkPerms}, nothing is cleared first. |
| 81 | + */ |
| 82 | + public void mergePerms(Player player, String permissionPrefix, String islandId, String gameMode) { |
| 83 | + IslandBlockCount islandBlockCount = addon.getBlockLimitListener().getIsland(islandId); |
67 | 84 | for (PermissionAttachmentInfo permissionInfo : player.getEffectivePermissions()) { |
68 | 85 | if (!permissionInfo.getValue() || !permissionInfo.getPermission().startsWith(permissionPrefix)) { |
69 | 86 | continue; |
@@ -251,16 +268,47 @@ public void onOwnerChange(TeamSetownerEvent event) { |
251 | 268 |
|
252 | 269 | @EventHandler(priority = EventPriority.NORMAL, ignoreCancelled = true) |
253 | 270 | public void onPlayerJoin(PlayerJoinEvent event) { |
| 271 | + UUID playerUUID = event.getPlayer().getUniqueId(); |
254 | 272 | addon.getGameModes().forEach(gameMode -> addon.getIslands() |
255 | | - .getIslands(gameMode.getOverWorld(), event.getPlayer().getUniqueId()).stream() |
256 | | - .filter(island -> event.getPlayer().getUniqueId().equals(island.getOwner())) |
257 | | - .map(Island::getUniqueId).forEach(islandId -> { |
258 | | - IslandBlockCount islandBlockCount = addon.getBlockLimitListener().getIsland(islandId); |
259 | | - if (!joinEventCheck(event.getPlayer(), islandId, islandBlockCount)) { |
260 | | - checkPerms(event.getPlayer(), gameMode.getPermissionPrefix() + "island.limit.", islandId, |
261 | | - gameMode.getDescription().getName()); |
262 | | - } |
263 | | - })); |
| 273 | + .getIslands(gameMode.getOverWorld(), playerUUID).stream() |
| 274 | + .filter(island -> playerUUID.equals(island.getOwner()) |
| 275 | + || (addon.getSettings().isApplyMemberLimitPerms() |
| 276 | + && island.getMemberSet().contains(playerUUID))) |
| 277 | + .forEach(island -> processJoin(event.getPlayer(), island, gameMode))); |
| 278 | + } |
| 279 | + |
| 280 | + private void processJoin(Player player, Island island, GameModeAddon gameMode) { |
| 281 | + String islandId = island.getUniqueId(); |
| 282 | + IslandBlockCount islandBlockCount = addon.getBlockLimitListener().getIsland(islandId); |
| 283 | + if (joinEventCheck(player, islandId, islandBlockCount)) { |
| 284 | + return; |
| 285 | + } |
| 286 | + String permissionPrefix = gameMode.getPermissionPrefix() + "island.limit."; |
| 287 | + String gameModeName = gameMode.getDescription().getName(); |
| 288 | + if (player.getUniqueId().equals(island.getOwner())) { |
| 289 | + // Owner login recalculates the limits from scratch... |
| 290 | + checkPerms(player, permissionPrefix, islandId, gameModeName); |
| 291 | + // ...then merges in the perms of any online team members |
| 292 | + mergeOnlineMemberPerms(island, permissionPrefix, gameModeName); |
| 293 | + } else { |
| 294 | + // Member login merges their perms on top of whatever is set — highest wins |
| 295 | + mergePerms(player, permissionPrefix, islandId, gameModeName); |
| 296 | + } |
| 297 | + } |
| 298 | + |
| 299 | + /** |
| 300 | + * Merges the limit permissions of every online team member (excluding the owner) |
| 301 | + * into the island's limits. No-op unless {@code apply-member-limit-perms} is enabled. |
| 302 | + */ |
| 303 | + private void mergeOnlineMemberPerms(Island island, String permissionPrefix, String gameModeName) { |
| 304 | + if (!addon.getSettings().isApplyMemberLimitPerms()) { |
| 305 | + return; |
| 306 | + } |
| 307 | + island.getMemberSet().stream() |
| 308 | + .filter(memberUUID -> !memberUUID.equals(island.getOwner())) |
| 309 | + .map(Bukkit::getPlayer) |
| 310 | + .filter(Objects::nonNull) |
| 311 | + .forEach(member -> mergePerms(member, permissionPrefix, island.getUniqueId(), gameModeName)); |
264 | 312 | } |
265 | 313 |
|
266 | 314 | private boolean joinEventCheck(Player player, String islandId, IslandBlockCount islandBlockCount) { |
@@ -303,6 +351,7 @@ private void setOwnerPerms(Island island, UUID ownerUUID) { |
303 | 351 | if (!permissionPrefix.isEmpty() && !gameModeName.isEmpty() && owner.getPlayer() != null) { |
304 | 352 | checkPerms(Objects.requireNonNull(owner.getPlayer()), permissionPrefix + "island.limit.", |
305 | 353 | island.getUniqueId(), gameModeName); |
| 354 | + mergeOnlineMemberPerms(island, permissionPrefix + "island.limit.", gameModeName); |
306 | 355 | } |
307 | 356 | } |
308 | 357 | } |
|
0 commit comments