From 8104bd3928cb037218aeb95eb677be7abe482947 Mon Sep 17 00:00:00 2001 From: Mickey42302 <46900084+Mickey42302@users.noreply.github.com> Date: Sun, 16 Aug 2026 19:10:51 -0400 Subject: [PATCH 1/2] Add methods for player limit and operator level management --- .../main/java/org/bukkit/OfflinePlayer.java | 40 +++++++++++++++++++ 1 file changed, 40 insertions(+) diff --git a/paper-api/src/main/java/org/bukkit/OfflinePlayer.java b/paper-api/src/main/java/org/bukkit/OfflinePlayer.java index 13ec9ea1ee08..f1dba4998e4c 100644 --- a/paper-api/src/main/java/org/bukkit/OfflinePlayer.java +++ b/paper-api/src/main/java/org/bukkit/OfflinePlayer.java @@ -591,4 +591,44 @@ default Location getBedSpawnLocation() { default void applySkinToPlayerHeadContents(final PlayerHeadObjectContents.Builder builder) { builder.skin(this.getPlayerProfile()); } + + /** + * Checks if this player bypasses the server player limit when connecting. + *

+ * Note: A player must be an operator for this privilege to take effect. + *

+ * + * @return true if the player bypasses the player limit, false otherwise + */ + boolean bypassesPlayerLimit(); + + /** + * Sets whether this player bypasses the server player limit when connecting. + *

+ * Note: The player must already be an operator for this to update their entry in ops.json. + *

+ * + * @param bypass true if the player should bypass the player limit + * @return true if the status was successfully updated, false if the player is not an operator + */ + boolean setBypassesPlayerLimit(boolean bypass); + + /** + * Gets the operator permission level for this player (0 through 4). + * + * @return the permission level, or 0 if the player is not an operator or entry is missing + */ + int getOpLevel(); + + /** + * Sets the operator permission level for this player. + *

+ * If setting a level greater than 0, the player will be added to ops.json if not present. + * If set to 0, the player's level will be cleared (or removed from ops depending on server logic). + *

+ * + * @param level the level to set (must be between 0 and 4) + * @throws IllegalArgumentException if level is outside the 0–4 range + */ + void setOpLevel(int level); } From 5f8c36d35faba803cc4b0ef90b204055813f8e3c Mon Sep 17 00:00:00 2001 From: Mickey42302 <46900084+Mickey42302@users.noreply.github.com> Date: Sun, 16 Aug 2026 19:11:45 -0400 Subject: [PATCH 2/2] Add methods for player limit bypass and op level management --- .../craftbukkit/CraftOfflinePlayer.java | 75 +++++++++++++++++++ 1 file changed, 75 insertions(+) diff --git a/paper-server/src/main/java/org/bukkit/craftbukkit/CraftOfflinePlayer.java b/paper-server/src/main/java/org/bukkit/craftbukkit/CraftOfflinePlayer.java index 1aa8f1e0a309..e9f180ad08bf 100644 --- a/paper-server/src/main/java/org/bukkit/craftbukkit/CraftOfflinePlayer.java +++ b/paper-server/src/main/java/org/bukkit/craftbukkit/CraftOfflinePlayer.java @@ -579,4 +579,79 @@ public void setStatistic(Statistic statistic, EntityType entityType, int newValu manager.save(); } } + + @Override + public boolean bypassesPlayerLimit() { + ServerOpList opList = MinecraftServer.getServer().getPlayerList().getOps(); + NameAndId nameAndId = new NameAndId(this.getUniqueId(), this.getName() != null ? this.getName() : ""); + ServerOpListEntry entry = opList.get(nameAndId); + + return entry != null && entry.getBypassesPlayerLimit(); + } + + @Override + public boolean setBypassesPlayerLimit(boolean bypass) { + MinecraftServer server = MinecraftServer.getServer(); + ServerOpList opList = server.getPlayerList().getOps(); + + NameAndId nameAndId = new NameAndId(this.getUniqueId(), this.getName() != null ? this.getName() : ""); + ServerOpListEntry existingEntry = opList.get(nameAndId); + + if (existingEntry == null) { + return false; + } + + ServerOpListEntry newEntry = new ServerOpListEntry( + nameAndId, + existingEntry.permissions(), + bypass + ); + + opList.add(newEntry); + return true; + } + + @Override + public int getOpLevel() { + ServerOpList opList = MinecraftServer.getServer().getPlayerList().getOps(); + NameAndId nameAndId = new NameAndId(this.getUniqueId(), this.getName() != null ? this.getName() : ""); + ServerOpListEntry entry = opList.get(nameAndId); + + if (entry == null) { + return 0; + } + + LevelBasedPermissionSet levelSet = entry.permissions(); + return levelSet.level().id(); + + } + + @Override + public void setOpLevel(int level) { + if (level < 0 || level > 4) { + throw new IllegalArgumentException("Operator permission level must be between 0 and 4."); + } + + MinecraftServer server = MinecraftServer.getServer(); + ServerOpList opList = server.getPlayerList().getOps(); + + NameAndId nameAndId = new NameAndId(this.getUniqueId(), this.getName() != null ? this.getName() : ""); + ServerOpListEntry existingEntry = opList.get(nameAndId); + + boolean bypassesLimit = existingEntry != null && existingEntry.getBypassesPlayerLimit(); + + PermissionLevel permLevel = PermissionLevel.byId(level); + ServerOpListEntry newEntry = new ServerOpListEntry( + nameAndId, + LevelBasedPermissionSet.forLevel(permLevel), + bypassesLimit + ); + + opList.add(newEntry); + + ServerPlayer serverPlayer = server.getPlayerList().getPlayer(this.getUniqueId()); + if (serverPlayer != null) { + server.getPlayerList().sendPlayerPermissionLevel(serverPlayer); + } + } }