Skip to main content

Documentation Index

Fetch the complete documentation index at: https://mintlify.com/BG-Software-LLC/SuperiorSkyblock2/llms.txt

Use this file to discover all available pages before exploring further.

Player events track individual player actions and settings within the SuperiorSkyblock2 plugin, independent of specific island actions.

Role Management

PlayerChangeRoleEvent

Called when a player’s island role changes.
import com.bgsoftware.superiorskyblock.api.events.PlayerChangeRoleEvent;
import com.bgsoftware.superiorskyblock.api.island.PlayerRole;
import org.bukkit.event.EventHandler;
import org.bukkit.event.Listener;

public class RoleListener implements Listener {
    
    @EventHandler
    public void onRoleChange(PlayerChangeRoleEvent event) {
        SuperiorPlayer player = event.getPlayer();
        PlayerRole newRole = event.getNewRole();
        PlayerRole oldRole = player.getPlayerRole();
        
        // Prevent demoting from specific role
        if (oldRole.getWeight() > newRole.getWeight() && 
            oldRole.toString().equals("Moderator")) {
            event.setCancelled(true);
            return;
        }
        
        // Notify player of promotion
        if (newRole.getWeight() > oldRole.getWeight()) {
            player.asPlayer().sendMessage(
                "Congratulations! You've been promoted to " + newRole.toString()
            );
        }
        
        // Grant permissions based on role
        grantRolePermissions(player, newRole);
    }
}
Event Properties:
  • getPlayer() - The player whose role is changing
  • getNewRole() - The new role being assigned
  • isCancelled() / setCancelled(boolean) - Cancel the role change
The player’s current role can be obtained via player.getPlayerRole() before the event completes. Compare weights to determine if it’s a promotion or demotion.

Player Settings

PlayerChangeBorderColorEvent

Called when a player changes their world border color.
@EventHandler
public void onBorderColorChange(PlayerChangeBorderColorEvent event) {
    SuperiorPlayer player = event.getPlayer();
    BorderColor borderColor = event.getBorderColor();
    
    // Restrict certain colors to VIP
    if (borderColor == BorderColor.GOLD && 
        !player.asPlayer().hasPermission("vip.border.gold")) {
        event.setCancelled(true);
        player.asPlayer().sendMessage("Gold border color is VIP only!");
        return;
    }
    
    player.asPlayer().sendMessage(
        "Border color changed to " + borderColor.name()
    );
}

PlayerChangeLanguageEvent

Called when a player changes their language preference.
@EventHandler
public void onLanguageChange(PlayerChangeLanguageEvent event) {
    SuperiorPlayer player = event.getPlayer();
    Locale language = event.getLanguage();
    
    plugin.getLogger().info(
        player.getName() + " changed language to " + language.getDisplayName()
    );
    
    // Send confirmation in new language
    String message = getLocalizedMessage("language.changed", language);
    player.asPlayer().sendMessage(message);
}

PlayerChangeNameEvent

Called when a player’s display name changes (not Minecraft username).
@EventHandler
public void onNameChange(PlayerChangeNameEvent event) {
    SuperiorPlayer player = event.getPlayer();
    String newName = event.getNewName();
    
    // Validate name format
    if (!newName.matches("^[a-zA-Z0-9_]{3,16}$")) {
        event.setCancelled(true);
        player.asPlayer().sendMessage("Invalid name format!");
        return;
    }
    
    // Check for duplicate names
    if (isNameTaken(newName)) {
        event.setCancelled(true);
        player.asPlayer().sendMessage("That name is already taken!");
    }
}

Toggle Events

These events are triggered when players toggle various features on or off.

PlayerToggleBorderEvent

Called when a player toggles their world border visibility.
@EventHandler
public void onToggleBorder(PlayerToggleBorderEvent event) {
    SuperiorPlayer player = event.getPlayer();
    boolean enabled = event.isEnabled();
    
    if (enabled) {
        player.asPlayer().sendMessage("World border enabled");
    } else {
        player.asPlayer().sendMessage("World border disabled");
    }
}

PlayerToggleFlyEvent

Called when a player toggles island fly mode.
@EventHandler
public void onToggleFly(PlayerToggleFlyEvent event) {
    SuperiorPlayer player = event.getPlayer();
    Island island = event.getIsland();
    boolean enabled = event.isEnabled();
    
    // Require permission for fly
    if (enabled && !player.hasPermission("island.fly")) {
        event.setCancelled(true);
        player.asPlayer().sendMessage("You don't have permission to fly!");
        return;
    }
    
    // Charge for fly activation
    if (enabled && !player.asPlayer().hasPermission("vip.fly.free")) {
        if (!chargeFlyFee(player, 100)) {
            event.setCancelled(true);
            player.asPlayer().sendMessage("Insufficient funds for fly mode!");
        }
    }
}
PlayerToggleFlyEvent is specific to island fly mode, not general Minecraft flight. It only affects flight within the player’s island boundaries.

PlayerToggleBypassEvent

Called when a player toggles island protection bypass mode.
@EventHandler
public void onToggleBypass(PlayerToggleBypassEvent event) {
    SuperiorPlayer player = event.getPlayer();
    boolean enabled = event.isEnabled();
    
    // Require admin permission
    if (!player.asPlayer().hasPermission("superiorskyblock.bypass")) {
        event.setCancelled(true);
        return;
    }
    
    // Log bypass usage
    plugin.getLogger().warning(
        player.getName() + (enabled ? " enabled" : " disabled") + " bypass mode"
    );
}

PlayerTogglePanelEvent

Called when a player toggles the top panel display.
@EventHandler
public void onTogglePanel(PlayerTogglePanelEvent event) {
    SuperiorPlayer player = event.getPlayer();
    boolean enabled = event.isEnabled();
    
    // Save preference
    playerData.setPanelEnabled(player.getUniqueId(), enabled);
}

PlayerToggleTeamChatEvent

Called when a player toggles island team chat.
@EventHandler
public void onToggleTeamChat(PlayerToggleTeamChatEvent event) {
    SuperiorPlayer player = event.getPlayer();
    boolean enabled = event.isEnabled();
    
    if (enabled) {
        player.asPlayer().sendMessage("Team chat enabled - messages will be sent to island members only");
    } else {
        player.asPlayer().sendMessage("Team chat disabled - messages will be sent globally");
    }
}

PlayerToggleSpyEvent

Called when a player toggles spy mode to see island team chats.
@EventHandler
public void onToggleSpy(PlayerToggleSpyEvent event) {
    SuperiorPlayer player = event.getPlayer();
    boolean enabled = event.isEnabled();
    
    // Require admin permission
    if (!player.asPlayer().hasPermission("superiorskyblock.spy")) {
        event.setCancelled(true);
        return;
    }
    
    // Log spy activation
    if (enabled) {
        plugin.getLogger().info(player.getName() + " enabled spy mode");
        spyModeUsers.add(player.getUniqueId());
    } else {
        spyModeUsers.remove(player.getUniqueId());
    }
}

PlayerToggleBlocksStackerEvent

Called when a player toggles the block stacker feature.
@EventHandler
public void onToggleBlocksStacker(PlayerToggleBlocksStackerEvent event) {
    SuperiorPlayer player = event.getPlayer();
    boolean enabled = event.isEnabled();
    
    if (enabled) {
        player.asPlayer().sendMessage("Block stacker enabled - blocks will stack automatically");
    } else {
        player.asPlayer().sendMessage("Block stacker disabled");
    }
}

PlayerOpenMenuEvent

Called when a player opens a SuperiorSkyblock2 menu.
@EventHandler
public void onMenuOpen(PlayerOpenMenuEvent event) {
    SuperiorPlayer player = event.getPlayer();
    MenuView menuView = event.getMenuView();
    String menuIdentifier = menuView.getIdentifier();
    
    // Track menu usage
    trackMenuOpen(player, menuIdentifier);
    
    // Prevent opening certain menus
    if (menuIdentifier.equals("top-islands") && !player.hasPermission("menu.top")) {
        event.setCancelled(true);
        player.asPlayer().sendMessage("You don't have permission to view this menu!");
    }
}

PlayerCloseMenuEvent

Called when a player closes a SuperiorSkyblock2 menu.
@EventHandler
public void onMenuClose(PlayerCloseMenuEvent event) {
    SuperiorPlayer player = event.getPlayer();
    MenuView menuView = event.getMenuView();
    
    // Save any pending changes
    if (menuView.getIdentifier().equals("island-settings")) {
        savePendingSettings(player);
    }
}
Menu events allow you to track player navigation through the plugin’s GUI system and implement custom validation or side effects.

Player Replacement

PlayerReplaceEvent

Called when a player object is being replaced (usually due to a nickname change or data refresh).
@EventHandler
public void onPlayerReplace(PlayerReplaceEvent event) {
    SuperiorPlayer oldPlayer = event.getOldPlayer();
    SuperiorPlayer newPlayer = event.getNewPlayer();
    
    // Transfer custom data
    transferCustomData(oldPlayer, newPlayer);
    
    // Update references
    updatePlayerReferences(oldPlayer.getUniqueId(), newPlayer);
}
This is an advanced event typically used by other plugins that maintain player data. Most developers won’t need to handle this event.

Message Events

AttemptPlayerSendMessageEvent

Called before a message is sent to a player by the plugin.
@EventHandler
public void onAttemptSendMessage(AttemptPlayerSendMessageEvent event) {
    SuperiorPlayer player = event.getPlayer();
    String message = event.getMessage();
    
    // Filter messages for muted players
    if (isMuted(player)) {
        event.setCancelled(true);
        return;
    }
    
    // Custom message formatting
    String formatted = applyCustomFormatting(message, player);
    event.setMessage(formatted);
}

SendMessageEvent

Called when a message is being sent to a player.
@EventHandler
public void onSendMessage(SendMessageEvent event) {
    String message = event.getMessage();
    
    // Log important messages
    if (message.contains("island") || message.contains("upgrade")) {
        plugin.getLogger().info("Message sent: " + message);
    }
}

Complete Event Examples

VIP Features Manager

public class VIPFeaturesListener implements Listener {
    
    @EventHandler
    public void onToggleFly(PlayerToggleFlyEvent event) {
        SuperiorPlayer player = event.getPlayer();
        
        if (!event.isEnabled()) return;
        
        // VIPs fly for free, others pay
        if (player.asPlayer().hasPermission("vip.fly")) {
            player.asPlayer().sendMessage("VIP fly activated!");
        } else if (withdraw(player, 100)) {
            player.asPlayer().sendMessage("Fly activated for $100");
        } else {
            event.setCancelled(true);
            player.asPlayer().sendMessage("Insufficient funds! Fly costs $100");
        }
    }
    
    @EventHandler
    public void onBorderColorChange(PlayerChangeBorderColorEvent event) {
        SuperiorPlayer player = event.getPlayer();
        BorderColor color = event.getBorderColor();
        
        // Premium colors for VIP
        List<BorderColor> vipColors = Arrays.asList(
            BorderColor.GOLD, BorderColor.AQUA, BorderColor.LIGHT_PURPLE
        );
        
        if (vipColors.contains(color) && !player.asPlayer().hasPermission("vip.border")) {
            event.setCancelled(true);
            player.asPlayer().sendMessage("This border color is VIP only!");
        }
    }
}

Role Promotion System

public class RolePromotionListener implements Listener {
    
    @EventHandler
    public void onRoleChange(PlayerChangeRoleEvent event) {
        SuperiorPlayer player = event.getPlayer();
        PlayerRole newRole = event.getNewRole();
        PlayerRole oldRole = player.getPlayerRole();
        Island island = player.getIsland();
        
        if (island == null) return;
        
        // Promotion
        if (newRole.getWeight() > oldRole.getWeight()) {
            // Celebrate promotion
            island.sendMessage(
                "§6" + player.getName() + " has been promoted to " + 
                newRole.toString() + "!"
            );
            
            // Grant promotion rewards
            givePromotionReward(player, newRole);
            
            // Achievement tracking
            incrementAchievement(player, "promotions_received");
        }
        
        // Demotion
        else if (newRole.getWeight() < oldRole.getWeight()) {
            // Prevent demoting the last admin
            if (oldRole.toString().equals("Admin") && 
                getAdminCount(island) <= 1) {
                event.setCancelled(true);
                player.asPlayer().sendMessage(
                    "Cannot demote the last admin!"
                );
            }
        }
    }
    
    private int getAdminCount(Island island) {
        return (int) island.getIslandMembers(false).stream()
            .filter(member -> member.getPlayerRole().toString().equals("Admin"))
            .count();
    }
}

Player Preferences Manager

public class PreferencesListener implements Listener {
    
    @EventHandler
    public void onLanguageChange(PlayerChangeLanguageEvent event) {
        SuperiorPlayer player = event.getPlayer();
        Locale language = event.getLanguage();
        
        // Save to database
        database.saveLanguage(player.getUniqueId(), language);
        
        // Update scoreboard in new language
        updateScoreboard(player, language);
        
        // Send confirmation
        player.asPlayer().sendMessage(
            translate("language.changed", language)
        );
    }
    
    @EventHandler
    public void onTogglePanel(PlayerTogglePanelEvent event) {
        SuperiorPlayer player = event.getPlayer();
        boolean enabled = event.isEnabled();
        
        // Save preference
        database.savePanelPreference(player.getUniqueId(), enabled);
        
        // Apply immediately
        if (enabled) {
            showPanel(player);
        } else {
            hidePanel(player);
        }
    }
    
    @EventHandler
    public void onToggleBorder(PlayerToggleBorderEvent event) {
        SuperiorPlayer player = event.getPlayer();
        boolean enabled = event.isEnabled();
        
        database.saveBorderPreference(player.getUniqueId(), enabled);
        
        if (enabled) {
            showBorder(player);
        } else {
            hideBorder(player);
        }
    }
}

Admin Tools Manager

public class AdminToolsListener implements Listener {
    
    @EventHandler
    public void onToggleBypass(PlayerToggleBypassEvent event) {
        SuperiorPlayer player = event.getPlayer();
        boolean enabled = event.isEnabled();
        
        if (!player.asPlayer().hasPermission("superiorskyblock.bypass")) {
            event.setCancelled(true);
            return;
        }
        
        // Log bypass usage
        String action = enabled ? "enabled" : "disabled";
        plugin.getLogger().warning(
            "[ADMIN] " + player.getName() + " " + action + " bypass mode"
        );
        
        // Notify other admins
        notifyAdmins(player.getName() + " " + action + " bypass mode");
    }
    
    @EventHandler
    public void onToggleSpy(PlayerToggleSpyEvent event) {
        SuperiorPlayer player = event.getPlayer();
        boolean enabled = event.isEnabled();
        
        if (!player.asPlayer().hasPermission("superiorskyblock.spy")) {
            event.setCancelled(true);
            return;
        }
        
        if (enabled) {
            spyUsers.add(player.getUniqueId());
            player.asPlayer().sendMessage("§cSpy mode enabled - you will see all island chats");
        } else {
            spyUsers.remove(player.getUniqueId());
            player.asPlayer().sendMessage("§cSpy mode disabled");
        }
    }
}

Complete Event List

All player-specific events:

Role & Status

  • PlayerChangeRoleEvent - Player role changes
  • PlayerReplaceEvent - Player object replacement

Settings

  • PlayerChangeBorderColorEvent - Border color change
  • PlayerChangeLanguageEvent - Language preference change
  • PlayerChangeNameEvent - Display name change

Toggles

  • PlayerToggleBorderEvent - World border visibility toggle
  • PlayerToggleFlyEvent - Island fly mode toggle
  • PlayerToggleBypassEvent - Protection bypass toggle
  • PlayerTogglePanelEvent - Top panel toggle
  • PlayerToggleTeamChatEvent - Team chat toggle
  • PlayerToggleSpyEvent - Spy mode toggle
  • PlayerToggleBlocksStackerEvent - Block stacker toggle
  • PlayerOpenMenuEvent - Menu opened
  • PlayerCloseMenuEvent - Menu closed

Messages

  • AttemptPlayerSendMessageEvent - Before message sent to player
  • SendMessageEvent - Message sent to player

Best Practices

Player Event Guidelines:
  • Always check permissions before allowing toggle features
  • Validate player input in change events (name, language, etc.)
  • Save player preferences to persistent storage
  • Log important admin actions (bypass, spy mode)
  • Consider economy costs for premium features
  • Handle null cases when players might not be online

Next Steps

Build docs developers (and LLMs) love