### Example Usage of CombatWorld Source: https://github.com/chancesd/pvpmanager/blob/master/_autodocs/types.md Demonstrates how to get a CombatWorld instance and check PvP status and forced settings. ```java CombatWorld world = playerManager.getPlugin().getWorldManager() .getWorld(player.getWorld()); if (world != null) { if (!world.isCombatAllowed()) { player.sendMessage("PvP is disabled in this world"); } if (world.isPvPForced() == WorldOptionState.ON) { player.sendMessage("PvP is forced in this world"); } } ``` -------------------------------- ### PvPManager Integration Example Source: https://github.com/chancesd/pvpmanager/blob/master/_autodocs/api-reference/pvpmanager.md Example of how to integrate a custom plugin with PvPManager. This involves getting instances of PvPManager and its managers, and registering event listeners. ```java public class PvPIntegrationPlugin extends JavaPlugin { @Override public void onEnable() { try { PvPManager pvpManager = PvPManager.getInstance(); if (pvpManager == null) { getLogger().severe("PvPManager not found!"); getServer().getPluginManager().disablePlugin(this); return; } PlayerManager playerMgr = pvpManager.getPlayerManager(); WorldManager worldMgr = pvpManager.getWorldManager(); // Register listeners getServer().getPluginManager().registerEvents( new CombatListener(playerMgr), this ); getLogger().info("Integrated with PvPManager"); } catch (Exception e) { getLogger().severe("Failed to integrate with PvPManager: " + e); getServer().getPluginManager().disablePlugin(this); } } } public class CombatListener implements Listener { private PlayerManager playerMgr; public CombatListener(PlayerManager playerMgr) { this.playerMgr = playerMgr; } @EventHandler public void onPlayerTag(PlayerTagEvent event) { // Handle tag event CombatPlayer player = event.getCombatPlayer(); Player enemy = event.getEnemy(); if (event.isAttacker()) { player.sendActionBar("Attacking " + enemy.getName()); } } @EventHandler public void onPlayerUntag(PlayerUntagEvent event) { // Handle untag event if (event.getReason() == UntagReason.DEATH) { event.getPlayer().sendMessage("You died"); } } } ``` -------------------------------- ### Example PVPManager Configuration Source: https://github.com/chancesd/pvpmanager/blob/master/_autodocs/configuration.md A comprehensive example of a PVPManager configuration file, illustrating various settings for combat, rewards, and protections. ```yaml # General Locale: EN Use Scoreboard Teams: true World Exclusions: [] # Combat Combat Tag: Enabled: true Time: 20 Glowing: true Close Inventory On Tag: true Duel Mode: false # Display Action Bar: Enabled: true Message: "&c⚔ Combat &c⚔" Symbol: "▊" Total Bars: 20 # Protections Newbie Protection: Enabled: true Time: 600 Allow Player Disable: true # Rewards Player Kills: Money Reward: 0.0 Money Penalty: 0.0 Exp Steal: 0.0 # Anti-Abuse Anti Kill Abuse: Enabled: true Max Kills: 5 Time Limit: 20 # Features Disable on Hit: Fly: true Restore Fly: true GameMode: true Disguise: true GodMode: true ``` -------------------------------- ### Complete Example Plugin Integration Source: https://github.com/chancesd/pvpmanager/blob/master/_autodocs/quickstart.md A full example of a Bukkit plugin hooking into PvPManager. This demonstrates enabling the plugin, registering events, and handling player tag/untag events. ```java import org.bukkit.plugin.java.JavaPlugin; import org.bukkit.event.EventHandler; import org.bukkit.event.Listener; import me.chancesd.pvpmanager.PvPManager; import me.chancesd.pvpmanager.manager.PlayerManager; import me.chancesd.pvpmanager.event.*; public class MyPvPPlugin extends JavaPlugin implements Listener { private PlayerManager playerManager; @Override public void onEnable() { // Hook into PvPManager PvPManager pvpManager = PvPManager.getInstance(); if (pvpManager == null) { getLogger().severe("PvPManager not found!"); getServer().getPluginManager().disablePlugin(this); return; } this.playerManager = pvpManager.getPlayerManager(); getServer().getPluginManager().registerEvents(this, this); getLogger().info("Hooked into PvPManager"); } @EventHandler public void onPlayerTag(PlayerTagEvent event) { event.getCombatPlayer().sendActionBar("Combat started!"); } @EventHandler public void onPlayerUntag(PlayerUntagEvent event) { if (event.getReason() == UntagReason.DEATH) { event.getPlayer().sendMessage("You were killed in combat!"); } } } ``` -------------------------------- ### World PvP Status Example Source: https://github.com/chancesd/pvpmanager/blob/master/_autodocs/api-reference/worldmanager.md This example scenario illustrates how PvP is handled when it's forced on. It shows that when isPvPForced() is not NONE, player settings are overridden. ```text World: "arena" - isCombatAllowed() = true - isPvPForced() = ON Result: PvP is allowed and cannot be disabled by players ``` -------------------------------- ### Get CombatPlayer Instance with Example Source: https://github.com/chancesd/pvpmanager/blob/master/_autodocs/api-reference/combatplayer.md Demonstrates how to retrieve a CombatPlayer instance for a Bukkit Player and use it to tag another player. Ensure the CombatPlayer instance is not null before proceeding. ```java Player bukkit = Bukkit.getPlayer("PlayerName"); CombatPlayer combatPlayer = CombatPlayer.get(bukkit); if (combatPlayer != null) { combatPlayer.tag(true, otherPlayer); } ``` -------------------------------- ### Example Usage of NewbieProtectionEvent Source: https://github.com/chancesd/pvpmanager/blob/master/_autodocs/api-reference/events.md Handles the NewbieProtectionEvent to send messages based on whether newbie protection is starting or expiring. ```java @EventHandler public void onNewbieProtection(NewbieProtectionEvent event) { if (event.isStarting()) { event.getPlayer().sendMessage("Newbie protection enabled"); } else { event.getPlayer().sendMessage("Newbie protection expired"); } } ``` -------------------------------- ### Placeholder API Example Source: https://github.com/chancesd/pvpmanager/blob/master/_autodocs/configuration.md An example of how to use placeholders within the Action Bar message configuration. ```yaml Action Bar.Message: "&c⚔ Combat: &6%time%s remaining" ``` -------------------------------- ### Check if Newbie Protection is Starting Source: https://github.com/chancesd/pvpmanager/blob/master/_autodocs/api-reference/events.md Determines if the newbie protection is starting or ending. ```java public final boolean isStarting() ``` -------------------------------- ### Get and Use CombatPlayer Instance Source: https://github.com/chancesd/pvpmanager/wiki/Developer-API Obtain a CombatPlayer instance using the static get() method or from the PvPManager plugin instance. Check player status like newbie protection or combat state. ```java PvPManager pvpmanager; // Check if PvPManager is enabled if (Bukkit.getPluginManager().isPluginEnabled("PvPManager")) pvpmanager = (PvPManager) Bukkit.getPluginManager().getPlugin("PvPManager"); if (pvpmanager == null) return; Player player = Bukkit.getPlayerExact("ChanceSD"); // You can get a CombatPlayer either through the playerManager or directly with the static get method CombatPlayer combatPlayer = CombatPlayer.get(player); CombatPlayer combatPlayer = pvpmanager.getPlayerManager().get(player); // Let's say we want to know if the player has newbie protection or is tagged if (combatPlayer.isNewbie()) combatPlayer.message("You are a newbie!"); if (combatPlayer.isInCombat()) combatPlayer.message("You are in combat!"); ``` -------------------------------- ### Accessing Configuration Values Example Source: https://github.com/chancesd/pvpmanager/blob/master/_autodocs/api-reference/pvpmanager.md Demonstrates how to access the ConfigManager and subsequently configuration values using the Conf enum. ```java PvPManager plugin = PvPManager.getInstance(); ConfigManager configMgr = plugin.getConfigM(); // Configuration values are accessed through Conf enum // See configuration.md for all available options ``` -------------------------------- ### ProtectionResult Example Usage Source: https://github.com/chancesd/pvpmanager/blob/master/_autodocs/types.md Demonstrates how to use the ProtectionResult to check if an attack is blocked and log the reason. ```java ProtectionResult result = playerManager.checkProtection(damager, defender); if (result.isProtected()) { System.out.println("Attack blocked: " + result.type()); if (result.type() == ProtectionType.NEWBIE) { damager.sendMessage("Cannot attack newbie players"); } } ``` -------------------------------- ### Typical PvP Listener Implementation Source: https://github.com/chancesd/pvpmanager/blob/master/_autodocs/api-reference/playermanager.md An example of how to implement a listener for combat events, using PlayerManager to check for protection and tag players involved in an attack. ```java public class MyPvPListener implements Listener { private PlayerManager playerManager; public MyPvPListener(PvPManager plugin) { this.playerManager = plugin.getPlayerManager(); } @EventHandler public void onEntityDamage(EntityDamageByEntityEvent event) { if (!(event.getDamager() instanceof Player) || !(event.getEntity() instanceof Player)) { return; } Player damager = (Player) event.getDamager(); Player defender = (Player) event.getEntity(); ProtectionResult result = playerManager.checkProtection(damager, defender); if (result.isProtected()) { event.setCancelled(true); return; } // Attack is allowed - tag both players CombatPlayer attacker = playerManager.get(damager); CombatPlayer attacked = playerManager.get(defender); if (attacker != null && attacked != null) { attacker.tag(true, attacked); attacked.tag(false, attacker); } } } ``` -------------------------------- ### Checking Multiple Hooks for PvP Eligibility Source: https://github.com/chancesd/pvpmanager/blob/master/_autodocs/permissions.md Example demonstrating how to check for the presence and integration of multiple hooks (Essentials, Vault, WorldGuard) to determine PvP eligibility. ```java public class PvPIntegration { private DependencyManager depMgr; public PvPIntegration(PvPManager pvpManager) { this.depMgr = pvpManager.getDependencyManager(); } public boolean canPvP(Player player) { // Check Essentials if (depMgr.isDependencyEnabled(Hook.ESSENTIALS)) { // Handle Essentials integration } // Check Vault if (depMgr.isDependencyEnabled(Hook.VAULT)) { // Handle economy } // Check WorldGuard if (depMgr.isDependencyEnabled(Hook.WORLDGUARD)) { // Handle regions } return true; } } ``` -------------------------------- ### Example Usage of PlayerTogglePvPEvent Source: https://github.com/chancesd/pvpmanager/blob/master/_autodocs/api-reference/events.md Handles the PlayerTogglePvPEvent to send messages based on the new PvP state. ```java @EventHandler(priority = EventPriority.HIGH) public void onPvPToggle(PlayerTogglePvPEvent event) { if (event.getPvPState()) { event.getPlayer().sendMessage("PvP enabled"); } else { event.getPlayer().sendMessage("PvP disabled"); } } ``` -------------------------------- ### Handling DependencyException Source: https://github.com/chancesd/pvpmanager/blob/master/_autodocs/errors.md Example of catching a DependencyException when setting up plugin hooks. This allows for graceful failure and logging of integration issues. ```java try { dependencyManager.setupHooks(Hook.WORLDGUARD); } catch (DependencyException e) { Log.warning("Failed to hook into WorldGuard: " + e.getMessage()); } ``` -------------------------------- ### NewbieProtectionEvent Source: https://github.com/chancesd/pvpmanager/blob/master/_autodocs/api-reference/events.md Fired when a player's newbie protection status changes (starts or expires). ```APIDOC ## NewbieProtectionEvent Fired when a player's newbie protection status changes (starts or expires). **Package:** `me.chancesd.pvpmanager.event` ### Signature ```java public final class NewbieProtectionEvent extends Event ``` ### Constructor ```java public NewbieProtectionEvent(Player player, CombatPlayer pvplayer, boolean starting) ``` | Parameter | Type | Description | |-----------|------|-------------| | player | Player | The player whose newbie status changed | | pvplayer | CombatPlayer | Utility reference to the CombatPlayer instance | | starting | boolean | true if protection is starting, false if ending | ### Methods #### getPlayer() ```java public final Player getPlayer() ``` Returns the player whose newbie protection status changed. **Returns:** Player whose protection status changed #### getPvPlayer() ```java public final CombatPlayer getPvPlayer() ``` Utility method to quickly get the CombatPlayer whose protection status changed. **Returns:** CombatPlayer instance of the player #### isStarting() ```java public final boolean isStarting() ``` Returns whether the newbie protection is starting or ending. **Returns:** true if protection is starting, false if protection is ending ### Example Usage ```java @EventHandler public void onNewbieProtection(NewbieProtectionEvent event) { if (event.isStarting()) { event.getPlayer().sendMessage("Newbie protection enabled"); } else { event.getPlayer().sendMessage("Newbie protection expired"); } } ``` ``` -------------------------------- ### Example Usage of PlayerCombatLogEvent Source: https://github.com/chancesd/pvpmanager/blob/master/_autodocs/api-reference/events.md Handles the PlayerCombatLogEvent to broadcast a message when a player combat logs. ```java @EventHandler public void onCombatLog(PlayerCombatLogEvent event) { Player player = event.getPlayer(); player.getServer().broadcastMessage(player.getName() + " combat logged!"); } ``` -------------------------------- ### Get PvP State from PlayerTogglePvPEvent Source: https://github.com/chancesd/pvpmanager/blob/master/_autodocs/api-reference/events.md Returns the upcoming PvP state for the player. ```java public final boolean getPvPState() ``` -------------------------------- ### UntagReason Usage Example Source: https://github.com/chancesd/pvpmanager/blob/master/_autodocs/types.md Shows how to handle PlayerUntagEvent by checking the UntagReason using a switch statement. ```java @EventHandler public void onPlayerUntag(PlayerUntagEvent event) { UntagReason reason = event.getReason(); switch(reason) { case DEATH: // Handle death untag break; case TIME_EXPIRED: // Handle timeout break; case LOGOUT: // Combat logged break; default: // Other reasons } } ``` -------------------------------- ### Checking Permissions in Code Source: https://github.com/chancesd/pvpmanager/blob/master/_autodocs/permissions.md Example of how to check if a player has a specific permission node in Java code. ```java CombatPlayer player = CombatPlayer.get(bukkit); if (player.hasPerm(Permissions.EXEMPT_COMBAT_TAG)) { // Player cannot be tagged } ``` -------------------------------- ### Get CombatPlayer from NewbieProtectionEvent Source: https://github.com/chancesd/pvpmanager/blob/master/_autodocs/api-reference/events.md Retrieves the CombatPlayer instance associated with the newbie protection event. ```java public final CombatPlayer getPvPlayer() ``` -------------------------------- ### Threading: Async Event Listener Example Source: https://github.com/chancesd/pvpmanager/blob/master/_autodocs/quickstart.md Demonstrates how to safely perform asynchronous operations, such as database calls, within an event listener. Wrap storage or I/O operations using Bukkit's scheduler. ```java @EventHandler public void onPlayerTag(PlayerTagEvent event) { // Safe to access player data CombatPlayer player = event.getCombatPlayer(); // If doing storage/database operations, run async: Bukkit.getScheduler().runTaskAsynchronously(plugin, () -> { // Database operations here }); } ``` -------------------------------- ### WorldManager Load/Save Flow Source: https://github.com/chancesd/pvpmanager/blob/master/_autodocs/architecture.md Illustrates the process of loading and saving world-specific PvP configurations. It covers querying the database on server start, creating and caching CombatWorld instances, and handling world changes. ```text Server Start → loadWorlds() → Query Database ↓ Create CombatWorld ↓ Cache in memory ↓ Player Change World → getWorld(world) → Return cached or load new ``` -------------------------------- ### WorldOptionState Conversion Methods Source: https://github.com/chancesd/pvpmanager/blob/master/_autodocs/types.md Provides static methods to convert booleans to WorldOptionState and get the opposite state. ```java public static WorldOptionState fromBoolean(boolean state) public static WorldOptionState getOpposite(WorldOptionState state) ``` -------------------------------- ### Get Newbie Task Instance Source: https://github.com/chancesd/pvpmanager/blob/master/_autodocs/api-reference/combatplayer.md Retrieves the NewbieTask instance that manages the newbie protection timer. Returns null if no protection is currently active. ```java public NewbieTask getNewbieTask() ``` -------------------------------- ### PvPManager Events Source: https://github.com/chancesd/pvpmanager/blob/master/_autodocs/DOCUMENTATION_MANIFEST.txt Documentation for the 5 custom events provided by PvPManager, including their triggers and handler examples. ```APIDOC ## Custom Events PvPManager emits 5 custom events to allow for integration and reaction to in-game events: 1. **PlayerTagEvent**: Triggered when a player enters combat. 2. **PlayerUntagEvent**: Triggered when a player exits combat. 3. **PlayerTogglePvPEvent**: Triggered when a player's PvP status is toggled. 4. **PlayerCombatLogEvent**: Triggered when combat logging is detected. 5. **NewbieProtectionEvent**: Triggered when a newbie's protection status changes. Each event is fully documented with its associated data and handler examples in `api-reference/events.md`. ``` -------------------------------- ### get(Player player) Source: https://github.com/chancesd/pvpmanager/blob/master/_autodocs/api-reference/playermanager.md Retrieves an existing CombatPlayer instance, creating one if needed for real players. It takes a Bukkit Player instance as input and returns the corresponding CombatPlayer, or null if the player is a non-real player and was not previously tracked. ```APIDOC ## get(Player player) ### Description Retrieves an existing CombatPlayer instance, creating one if needed for real players. ### Method public final CombatPlayer get(Player player) ### Parameters #### Path Parameters - **player** (Player) - Required - The Bukkit Player instance ### Response #### Success Response (200) - **CombatPlayer** - CombatPlayer instance, or null if the player is a non-real player (NPC) and was not previously tracked ### Request Example ```java Player bukkit = event.getDamager(); CombatPlayer damager = playerManager.get(bukkit); if (damager != null) { damager.tag(true, defender); } ``` ``` -------------------------------- ### Get Remaining Newbie Protection Time Source: https://github.com/chancesd/pvpmanager/blob/master/_autodocs/api-reference/combatplayer.md Retrieves the remaining duration in milliseconds for the player's newbie protection. Returns 0 if no protection is active. ```java public final long getNewbieTimeLeft() ``` -------------------------------- ### Get ConfigManager Instance Source: https://github.com/chancesd/pvpmanager/blob/master/_autodocs/api-reference/playermanager.md Retrieves the singleton instance of the ConfigManager, which provides access to all plugin configurations. ```java public ConfigManager getConfigManager() ``` -------------------------------- ### Get Player Balance Source: https://github.com/chancesd/pvpmanager/blob/master/_autodocs/api-reference/combatplayer.md Returns the player's current account balance. This functionality requires the Vault plugin to be installed and enabled. ```java public double getBalance() ``` -------------------------------- ### Handling Storage Save Errors Source: https://github.com/chancesd/pvpmanager/blob/master/_autodocs/errors.md Example of catching general exceptions during player data saving operations. Errors are logged, and data loss is noted, with a fallback to saving on plugin disable. ```java public void savePlayer(CombatPlayer player) { try { plugin.getStorageManager().getStorage().saveUserData(player); } catch (Exception e) { Log.severe("Failed to save player data for " + player.getName(), e); // Player data is lost for this session // Will be re-saved on plugin disable } } ``` -------------------------------- ### Get CombatPlayer Instance Source: https://github.com/chancesd/pvpmanager/blob/master/_autodocs/README.md Access the core CombatPlayer class representing a player's PvP state. This is the primary way to interact with player combat information. ```java CombatPlayer player = CombatPlayer.get(bukkitPlayer); ``` -------------------------------- ### Get CombatPlayer Instance Source: https://github.com/chancesd/pvpmanager/blob/master/_autodocs/api-reference/playermanager.md Retrieves an existing CombatPlayer instance for a Bukkit Player. Creates a new instance if one does not exist for real players. Use this to interact with player-specific PvP data. ```Java Player bukkit = event.getDamager(); CombatPlayer damager = playerManager.get(bukkit); if (damager != null) { damager.tag(true, defender); } ``` -------------------------------- ### applyFine Source: https://github.com/chancesd/pvpmanager/blob/master/_autodocs/api-reference/combatplayer.md Applies the configured fine to the player's account. ```APIDOC ## applyFine() ### Description Applies the configured fine to the player's account. ### Method POST ### Endpoint /CombatPlayer/applyFine ``` -------------------------------- ### Get World Name Source: https://github.com/chancesd/pvpmanager/blob/master/_autodocs/types.md Retrieves the name of the world. ```java public String getName() ``` -------------------------------- ### Configuration Loading Flow Source: https://github.com/chancesd/pvpmanager/blob/master/_autodocs/architecture.md Describes how the configuration file is loaded and parsed, and how values are accessed at runtime. ```text config.yml (YAML file) ↓ ConfigManager.load() ├─ Parse with Bukkit ConfigurationSection ├─ For each Conf enum value │ ├─ Get value from config │ ├─ Cast/convert to type │ └─ Apply custom function if defined └─ Store in enum field ↓ Runtime Access └─ Conf.SOME_OPTION.asBool() └─ Conf.SOME_OPTION.asInt() └─ Conf.SOME_OPTION.asDouble() ``` -------------------------------- ### PvPManager Key Methods Source: https://github.com/chancesd/pvpmanager/blob/master/_autodocs/architecture.md Provides a list of essential static access methods for interacting with core PvPManager functionalities. These methods allow access to managers for players, worlds, configuration, storage, and dependencies. ```text getInstance() getPlayerManager() getWorldManager() getConfigM() getStorageManager() getDependencyManager() ``` -------------------------------- ### Get Player Name Source: https://github.com/chancesd/pvpmanager/blob/master/_autodocs/api-reference/combatplayer.md Returns the player's name. ```java public final String getName() ``` -------------------------------- ### get Source: https://github.com/chancesd/pvpmanager/blob/master/_autodocs/api-reference/combatplayer.md Retrieves the CombatPlayer instance associated with a given Bukkit Player. ```APIDOC ## get(Player player) ### Description Retrieves the CombatPlayer instance for a given Bukkit Player. ### Method GET ### Endpoint /CombatPlayer/get ### Parameters #### Query Parameters - **player** (Player) - Required - The Bukkit Player instance. ### Returns - **CombatPlayer** or **null**: The CombatPlayer instance if found, otherwise null. ### Example ```java Player bukkit = Bukkit.getPlayer("PlayerName"); CombatPlayer combatPlayer = CombatPlayer.get(bukkit); if (combatPlayer != null) { combatPlayer.tag(true, otherPlayer); } ``` ``` -------------------------------- ### Get Player UUID Source: https://github.com/chancesd/pvpmanager/blob/master/_autodocs/api-reference/combatplayer.md Returns the unique identifier (UUID) for the player. ```java public final UUID getUUID() ``` -------------------------------- ### Newbie Protection Methods Source: https://github.com/chancesd/pvpmanager/blob/master/_autodocs/api-reference/combatplayer.md Methods for managing the player's newbie protection status. ```APIDOC ## isNewbie() ### Description Checks if the player has newbie protection enabled. ### Method GET ### Endpoint /player/{player_id}/newbie/status ### Response #### Success Response (200) - **isNewbie** (boolean) - true if the player is under newbie protection ### Response Example { "isNewbie": true } ``` ```APIDOC ## setNewbie(newbie) ### Description Enables or disables newbie protection indefinitely. ### Method POST ### Endpoint /player/{player_id}/newbie/set ### Parameters #### Request Body - **newbie** (boolean) - Required - true to enable protection, false to disable ### Request Example { "newbie": false } ### Response #### Success Response (200) - **message** (string) - Indicates the newbie protection state has been updated. ### Response Example { "message": "Newbie protection state updated successfully." } ``` -------------------------------- ### Get World UUID Source: https://github.com/chancesd/pvpmanager/blob/master/_autodocs/types.md Retrieves the unique identifier (UUID) of the world. ```java public UUID getUUID() ``` -------------------------------- ### Enable Newbie Protection Source: https://github.com/chancesd/pvpmanager/blob/master/_autodocs/api-reference/combatplayer.md Enables newbie protection for a player, with an optional time limit. Use this to prevent new players from being immediately attacked. ```java public final void setNewbie(boolean newbie, long time) ``` ```java // Enable newbie protection for 10 minutes (600 seconds = 600000 ms) combatPlayer.setNewbie(true, 600000); ``` -------------------------------- ### createPlayer(Player player, boolean save) Source: https://github.com/chancesd/pvpmanager/blob/master/_autodocs/api-reference/playermanager.md Creates a new CombatPlayer instance for the provided player. It takes a Bukkit Player instance and a boolean indicating whether to save player data. Returns the newly created CombatPlayer instance. ```APIDOC ## createPlayer(Player player, boolean save) ### Description Creates a new CombatPlayer instance for the provided player. ### Method @NotNull public final CombatPlayer createPlayer(Player player, boolean save) ### Parameters #### Path Parameters - **player** (Player) - Required - The Bukkit Player instance - **save** (boolean) - Required - If true, player data is persisted to storage ### Response #### Success Response (200) - **CombatPlayer** - New CombatPlayer instance ### Note Normally called internally on join events. Only call directly if needed for special cases. ``` -------------------------------- ### getEnemy Source: https://github.com/chancesd/pvpmanager/blob/master/_autodocs/api-reference/combatplayer.md Gets the primary enemy player that the current player is engaged in combat with. ```APIDOC ## getEnemy() ### Description Returns the primary enemy the player is fighting. ### Method `getEnemy` ### Returns - **CombatPlayer** - The enemy CombatPlayer or null if no primary enemy ``` -------------------------------- ### Get Player from PlayerTogglePvPEvent Source: https://github.com/chancesd/pvpmanager/blob/master/_autodocs/api-reference/events.md Retrieves the player associated with the PvP toggle event. ```java public final Player getPlayer() ``` -------------------------------- ### Check Newbie Protection Status Source: https://github.com/chancesd/pvpmanager/blob/master/_autodocs/api-reference/combatplayer.md Verifies if the player is currently under newbie protection. Returns true if protection is active. ```java public final boolean isNewbie() ``` -------------------------------- ### Get Total Combat Duration Source: https://github.com/chancesd/pvpmanager/blob/master/_autodocs/api-reference/combatplayer.md Retrieves the total configured duration for combat in milliseconds. ```java public final long getTotalTagTime() ``` -------------------------------- ### PvPManager Core Component Lifecycle Source: https://github.com/chancesd/pvpmanager/blob/master/_autodocs/architecture.md Illustrates the lifecycle of the main PvPManager component, from plugin loading to enabling and disabling. It outlines the initialization and cleanup steps. ```text onPluginLoad() → Initialize dependency system onPluginEnable() → Initialize all managers onPluginDisable() → Cleanup and persist data ``` -------------------------------- ### Version-Specific Feature Handling Source: https://github.com/chancesd/pvpmanager/blob/master/_autodocs/architecture.md Illustrates how the plugin adapts to different Minecraft versions by registering appropriate listeners and enabling/disabling features. ```text MCVersion enum ├─ V1_9 → Glowing, boss bars ├─ V1_11_2 → Player 1.11 listener ├─ V1_20_4 → Updated chat components └─ V1_21 → Wind charge support At runtime ├─ Check version ├─ Register appropriate listeners ├─ Enable version-specific features └─ Disable unsupported features ``` -------------------------------- ### Get CombatPlayer from PlayerTogglePvPEvent Source: https://github.com/chancesd/pvpmanager/blob/master/_autodocs/api-reference/events.md Retrieves the CombatPlayer instance associated with the PvP toggle event. ```java public final CombatPlayer getCombatPlayer() ``` -------------------------------- ### Build PlayerData with Default Data Option Source: https://github.com/chancesd/pvpmanager/blob/master/_autodocs/types.md Builds a PlayerData instance. Use defaultData to specify if it's for a new player. ```java public PlayerData build(boolean defaultData) ``` -------------------------------- ### Checking if WorldGuard Hook is Enabled Source: https://github.com/chancesd/pvpmanager/blob/master/_autodocs/permissions.md Example of how to check if the WorldGuard integration hook is active in PvPManager. ```java Hook worldguard = Hook.WORLDGUARD; if (worldguard.isEnabled()) { // WorldGuard integration is active } ``` -------------------------------- ### Player Data Loading Flow Source: https://github.com/chancesd/pvpmanager/blob/master/_autodocs/architecture.md Illustrates the asynchronous process of loading player data upon joining, including database queries and data application. ```text Player Join ↓ PlayerManager.createPlayer() ↓ loadPlayerDataAsync() ├─ Query database ├─ PlayerData.fromMap() ├─ applyPlayerData() │ ├─ Set pvp_enabled │ ├─ Set newbie if configured │ └─ Apply world overrides └─ notifyAll() to waiting threads ``` -------------------------------- ### CombatWorld Constructor Source: https://github.com/chancesd/pvpmanager/blob/master/_autodocs/types.md Initializes a CombatWorld instance with UUID, name, default PvP state, and forced PvP state. ```java public CombatWorld(UUID uuid, String name, boolean pvpState, WorldOptionState forcePVP) ``` -------------------------------- ### Get Combat World Source: https://github.com/chancesd/pvpmanager/blob/master/_autodocs/api-reference/combatplayer.md Returns the CombatWorld instance associated with the player's current world. ```java public CombatWorld getCombatWorld() ``` -------------------------------- ### Set Newbie Protection State Source: https://github.com/chancesd/pvpmanager/blob/master/_autodocs/api-reference/combatplayer.md Enables or disables newbie protection indefinitely for the player. Changes to this state fire a NewbieProtectionEvent. ```java public final void setNewbie(boolean newbie) ``` -------------------------------- ### Typical Plugin Development Pattern with PvPManager Source: https://github.com/chancesd/pvpmanager/blob/master/_autodocs/api-reference/pvpmanager.md Shows a standard pattern for integrating PvPManager into a custom Bukkit plugin. It covers accessing managers and registering custom listeners that utilize PvPManager's API. ```java public class MyPvPPlugin extends JavaPlugin { @Override public void onEnable() { // Access PvPManager PvPManager pvpManager = PvPManager.getInstance(); // Get managers PlayerManager playerManager = pvpManager.getPlayerManager(); WorldManager worldManager = pvpManager.getWorldManager(); // Register listeners getServer().getPluginManager().registerEvents( new MyPvPListener(playerManager), this ); } } public class MyPvPListener implements Listener { private PlayerManager playerManager; public MyPvPListener(PlayerManager playerManager) { this.playerManager = playerManager; } @EventHandler public void onEntityDamage(EntityDamageByEntityEvent event) { if (!(event.getDamager() instanceof Player) || !(event.getEntity() instanceof Player)) { return; } Player damager = (Player) event.getDamager(); Player defender = (Player) event.getEntity(); // Use PvPManager API if (!playerManager.canAttack(damager, defender)) { event.setCancelled(true); } } } ``` -------------------------------- ### PvPManager Player Lifecycle Source: https://github.com/chancesd/pvpmanager/blob/master/_autodocs/architecture.md Outlines the typical lifecycle of a player within the PvPManager system, from joining the server to leaving. It covers player creation, data loading, active state, and cleanup processes. ```text Join → createPlayer() → loadPlayerDataAsync() → applyPlayerData() ↓ Active → get() returns CombatPlayer ↓ Leave → removePlayer() → savePlayer() → cleanup() ``` -------------------------------- ### PlaceholderAPI Expansion Registration Source: https://github.com/chancesd/pvpmanager/blob/master/_autodocs/architecture.md Shows how to register placeholders with PlaceholderAPI and how they are resolved by returning formatted values. ```text Register Expansion ├─ Register %pvpmanager_pvp% ├─ Register %pvpmanager_in_combat% └─ Register %pvpmanager_tag_time_left% On Request └─ Get CombatPlayer └─ Return formatted value ``` -------------------------------- ### Get All Recent Enemies Source: https://github.com/chancesd/pvpmanager/blob/master/_autodocs/api-reference/combatplayer.md Retrieves a set of all players who have recently damaged this player. This is useful for tracking potential aggressors. ```java public Set getEnemies() ``` -------------------------------- ### Apply Fine Source: https://github.com/chancesd/pvpmanager/blob/master/_autodocs/api-reference/combatplayer.md Applies a configured fine to the player's account balance. ```java public final void applyFine() ``` -------------------------------- ### applyPenalty Source: https://github.com/chancesd/pvpmanager/blob/master/_autodocs/api-reference/combatplayer.md Applies the configured kill penalty to the player's account. ```APIDOC ## applyPenalty() ### Description Applies the configured kill penalty to the player's account. ### Method POST ### Endpoint /CombatPlayer/applyPenalty ``` -------------------------------- ### getPlayer Source: https://github.com/chancesd/pvpmanager/blob/master/_autodocs/api-reference/combatplayer.md Returns the underlying Bukkit Player instance. ```APIDOC ## getPlayer() ### Description Returns the underlying Bukkit Player instance. ### Method GET ### Endpoint /CombatPlayer/getPlayer ### Returns - **Player**: The Bukkit Player instance. ``` -------------------------------- ### Get PvP Toggle Timestamp Source: https://github.com/chancesd/pvpmanager/blob/master/_autodocs/api-reference/combatplayer.md Retrieves the system timestamp (in milliseconds since epoch) of the last PvP state toggle. ```java public final long getToggleTime() ``` -------------------------------- ### Get Remaining Combat Time Source: https://github.com/chancesd/pvpmanager/blob/master/_autodocs/api-reference/combatplayer.md Calculates and returns the time left in combat in milliseconds. Returns 0 if the player is not in combat. ```java public long getTagTimeLeft() ``` -------------------------------- ### CombatPlayer Constructor Source: https://github.com/chancesd/pvpmanager/blob/master/_autodocs/api-reference/combatplayer.md Initializes a new CombatPlayer instance. This is typically handled internally by the PlayerManager. ```java public CombatPlayer(Player player, PvPManager plugin) ``` -------------------------------- ### setNewbie Source: https://github.com/chancesd/pvpmanager/blob/master/_autodocs/api-reference/combatplayer.md Sets newbie protection for a player, with an optional time limit. This protection can be enabled or disabled. ```APIDOC ## setNewbie(boolean newbie, long time) ### Description Sets newbie protection with an optional time limit. This protection can be enabled or disabled. ### Method `setNewbie` ### Parameters #### Path Parameters - **newbie** (boolean) - Required - `true` to enable protection, `false` to disable - **time** (long) - Required - Duration in milliseconds (0 for no expiration) ### Example ```java // Enable newbie protection for 10 minutes (600 seconds = 600000 ms) combatPlayer.setNewbie(true, 600000); ``` ``` -------------------------------- ### Get PvPManager Instance Source: https://github.com/chancesd/pvpmanager/blob/master/_autodocs/quickstart.md Retrieve the PvPManager instance in your plugin's onEnable method. Disable the plugin if PvPManager is not found. ```java import me.chancesd.pvpmanager.PvPManager; public class MyPlugin extends JavaPlugin { @Override public void onEnable() { PvPManager pvpManager = PvPManager.getInstance(); if (pvpManager == null) { getLogger().severe("PvPManager not found!"); getServer().getPluginManager().disablePlugin(this); return; } getLogger().info("Successfully hooked into PvPManager"); } } ``` -------------------------------- ### WorldPvPManager Java Class Source: https://github.com/chancesd/pvpmanager/blob/master/_autodocs/api-reference/worldmanager.md This class demonstrates a typical usage pattern for managing world PvP settings. It includes methods for checking PvP status, enabling/disabling PvP, and forcing PvP in specific arenas. ```java public class WorldPvPManager { private WorldManager worldManager; public WorldPvPManager(PvPManager pvpManager) { this.worldManager = pvpManager.getWorldManager(); } // Get world PvP status public boolean isPvPEnabled(World world) { CombatWorld combatWorld = worldManager.getWorld(world); return combatWorld != null && combatWorld.isCombatAllowed(); } // Set world-wide PvP public void setPvPEnabled(String worldName, boolean enabled) { CombatWorld world = worldManager.getWorld(worldName); if (world != null) { world.setCombatAllowed(enabled); worldManager.saveWorldData(world); } } // Force PvP in arena public void forceArena(String worldName) { CombatWorld world = worldManager.getWorld(worldName); if (world != null) { world.setForcePVP(WorldOptionState.ON); world.setCombatAllowed(true); worldManager.saveWorldData(world); } } // Disable all worlds public void disableAllWorlds() { for (CombatWorld world : worldManager.getWorlds()) { world.setCombatAllowed(false); worldManager.saveWorldData(world); } } } ``` -------------------------------- ### Get PvPManager Instance Source: https://github.com/chancesd/pvpmanager/blob/master/_autodocs/api-reference/pvpmanager.md Access the singleton instance of the PvPManager. This is the primary way to interact with the plugin's core functionalities. ```java public static PvPManager getInstance() ``` -------------------------------- ### Accessing DependencyManager Source: https://github.com/chancesd/pvpmanager/blob/master/_autodocs/permissions.md Retrieve the DependencyManager instance to access plugin hooks. This is the starting point for integrating with PvPManager's dependency system. ```java DependencyManager depMgr = PvPManager.getInstance().getDependencyManager(); Dependency dependency = depMgr.getDependency(Hook.WORLDGUARD); ``` -------------------------------- ### WorldGuard Integration for Protection Checks Source: https://github.com/chancesd/pvpmanager/blob/master/_autodocs/architecture.md Explains how WorldGuard is queried to check region protection flags and apply overrides. ```text Check Protection ├─ If WORLDGUARD enabled │ └─ Query region │ ├─ Check pvp-manager flag │ ├─ Check other guards │ └─ Return override └─ Use result ``` -------------------------------- ### Prevent Attacks Example Source: https://github.com/chancesd/pvpmanager/blob/master/_autodocs/README.md Cancel an EntityDamageByEntityEvent if the protection system deems the attack invalid. This is a common pattern for enforcing PvP rules. ```java EntityDamageByEntityEvent event = ...; ProtectionResult result = playerManager.checkProtection( (Player) event.getDamager(), (Player) event.getEntity() ); if (result.isProtected()) { event.setCancelled(true); } ``` -------------------------------- ### Safe Event Handling with Try-Catch Source: https://github.com/chancesd/pvpmanager/blob/master/_autodocs/errors.md Demonstrates best practices for handling events by wrapping the logic in a try-catch block. This prevents unexpected exceptions from crashing the plugin and logs errors for debugging. ```java @EventHandler public void onTag(PlayerTagEvent event) { try { // Handle event CombatPlayer player = event.getCombatPlayer(); if (player != null) { // Safe to use } } catch (Exception e) { Log.severe("Error in tag handler", e); // Don't re-throw, let plugin continue } } ``` -------------------------------- ### PlaceholderAPI Placeholders for PvP Status Source: https://github.com/chancesd/pvpmanager/blob/master/_autodocs/permissions.md Example usage of PlaceholderAPI placeholders to display PvP status information in chat or other text elements. ```text &cPvP Status: %pvpmanager_pvp% &cIn Combat: %pvpmanager_in_combat% ``` -------------------------------- ### Get Primary Enemy Source: https://github.com/chancesd/pvpmanager/blob/master/_autodocs/api-reference/combatplayer.md Retrieves the main enemy the player is currently engaged in combat with. Returns null if the player is not fighting anyone. ```java @Nullable public CombatPlayer getEnemy() ``` -------------------------------- ### PlayerData Builder Pattern Source: https://github.com/chancesd/pvpmanager/blob/master/_autodocs/types.md Demonstrates the use of the Builder pattern to construct a PlayerData object with various player-specific attributes. ```java PlayerData data = PlayerData.builder() .uuid(player.getUniqueId()) .name(player.getName()) .displayName(player.getDisplayName()) .pvpEnabled(true) .toggleTime(System.currentTimeMillis()) .newbie(false) .newbieTimeLeft(0) .lastSeen(System.currentTimeMillis()) .build(false); // false = not default data ``` -------------------------------- ### Create Default PlayerData Source: https://github.com/chancesd/pvpmanager/blob/master/_autodocs/types.md Creates a PlayerData instance with default values for a new player. ```java public static PlayerData createDefault() ``` -------------------------------- ### Get Combat Timestamps Source: https://github.com/chancesd/pvpmanager/blob/master/_autodocs/api-reference/combatplayer.md Retrieve timestamps related to combat. getTaggedTime() returns when the player was tagged, and getUntagTime() returns when combat will end. ```java public final long getTaggedTime() ``` ```java public final long getUntagTime() ``` -------------------------------- ### Get All Tracked Players Source: https://github.com/chancesd/pvpmanager/blob/master/_autodocs/api-reference/playermanager.md Retrieves a map of all players currently being tracked by the PlayerManager, keyed by their UUID. Useful for iterating through all active players. ```java public final Map getPlayers() ``` ```java for (CombatPlayer player : playerManager.getPlayers().values()) { if (player.isInCombat()) { player.sendActionBar("Still fighting!"); } } ``` -------------------------------- ### Get CombatPlayer Instance Source: https://github.com/chancesd/pvpmanager/blob/master/_autodocs/api-reference/combatplayer.md Retrieves the CombatPlayer object associated with a given Bukkit Player. Returns null if no CombatPlayer instance is found for the player. ```java @Nullable public static CombatPlayer get(Player player) ``` -------------------------------- ### Get all loaded CombatWorld instances Source: https://github.com/chancesd/pvpmanager/blob/master/_autodocs/api-reference/worldmanager.md Returns a collection of all CombatWorld objects currently loaded by the WorldManager. This is useful for iterating through all worlds and their PvP states. ```java for (CombatWorld world : worldManager.getWorlds()) { System.out.println(world.getName() + ": " + (world.isCombatAllowed() ? "enabled" : "disabled")); } ``` -------------------------------- ### PvPManager Hook Methods Source: https://github.com/chancesd/pvpmanager/blob/master/_autodocs/permissions.md Provides methods to check if a specific hook is enabled, retrieve a dependency object, or get a collection of all enabled dependencies. ```java // Check if a hook is enabled public boolean isDependencyEnabled(Hook hook) // Get a specific dependency public Dependency getDependency(Hook hook) // Get all enabled dependencies public Collection getDependencies() ``` -------------------------------- ### Plugin Lifecycle: onPluginLoad Source: https://github.com/chancesd/pvpmanager/blob/master/_autodocs/api-reference/pvpmanager.md Internal method called when the plugin is first loaded. It initializes the dependency system. ```java @Override public void onPluginLoad() ``` -------------------------------- ### giveExp Source: https://github.com/chancesd/pvpmanager/blob/master/_autodocs/api-reference/combatplayer.md Steals experience from the victim and awards it to the player. ```APIDOC ## giveExp(EcoPlayer victim) ### Description Steals experience from the victim and gives it to the player. ### Method POST ### Endpoint /CombatPlayer/giveExp ### Parameters #### Request Body - **victim** (EcoPlayer) - Required - The victim player object. ### Returns - **int**: The amount of experience gained. ``` -------------------------------- ### getNewbieTask Source: https://github.com/chancesd/pvpmanager/blob/master/_autodocs/api-reference/combatplayer.md Retrieves the active NewbieTask instance that manages the newbie protection timer. ```APIDOC ## getNewbieTask() ### Description Returns the active NewbieTask managing the protection timer. ### Method `getNewbieTask` ### Returns - **NewbieTask** - NewbieTask instance or null if no active protection ``` -------------------------------- ### Get Players Currently in Combat Source: https://github.com/chancesd/pvpmanager/blob/master/_autodocs/api-reference/playermanager.md Retrieves a set of all players who are currently in combat. This is useful for broadcasting combat status or performing actions on all fighting players. ```java public final Set getPlayersInCombat() ``` ```java Set fighting = playerManager.getPlayersInCombat(); server.broadcastMessage(fighting.size() + " players are in combat"); ``` -------------------------------- ### Get Item Cooldown Expiration Time Source: https://github.com/chancesd/pvpmanager/blob/master/_autodocs/api-reference/combatplayer.md Retrieves the timestamp (in milliseconds) when an item's cooldown will expire. Returns 0 if no cooldown is currently active for the item. ```java public final Long getItemCooldown(ItemKey key) ``` -------------------------------- ### Create PlayerData Builder Source: https://github.com/chancesd/pvpmanager/blob/master/_autodocs/types.md Creates a new builder for PlayerData instances. ```java public static Builder builder() ``` -------------------------------- ### Get Detailed Protection Information Source: https://github.com/chancesd/pvpmanager/blob/master/_autodocs/quickstart.md Check for specific protection reasons between two players using PlayerManager. Provides detailed results including the protection type. ```java import me.chancesd.pvpmanager.player.ProtectionResult; import me.chancesd.pvpmanager.player.ProtectionType; ProtectionResult result = playerManager.checkProtection(attacker, defender); if (result.isProtected()) { String reason = switch(result.type()) { case NEWBIE -> "Target is a newbie"; case PVPDISABLED -> "Player has PvP disabled"; case RESPAWN_PROTECTION -> "Player has respawn protection"; case WORLD_PROTECTION -> "PvP is disabled in this world"; case AFK_PROTECTION -> "Player is AFK"; default -> "Unknown protection"; }; attacker.sendMessage(reason); } ``` -------------------------------- ### Implementing a Custom Hook Source: https://github.com/chancesd/pvpmanager/blob/master/_autodocs/permissions.md Create a custom hook by implementing the Dependency interface and registering it with the DependencyManager. Use this for integrating your own plugins. ```java public class MyCustomHook implements Dependency { @Override public void onHookEnable() { // Initialize hook } @Override public void onHookDisable() { // Cleanup } @Override public String getName() { return "MyCustom"; } } ``` -------------------------------- ### PvP Toggle Methods Source: https://github.com/chancesd/pvpmanager/blob/master/_autodocs/api-reference/combatplayer.md Methods for managing the player's PvP enablement status. ```APIDOC ## hasPvPEnabled() ### Description Checks if the player has PvP enabled. ### Method GET ### Endpoint /player/{player_id}/pvp/status ### Response #### Success Response (200) - **pvpEnabled** (boolean) - true if PvP is enabled ### Response Example { "pvpEnabled": true } ``` ```APIDOC ## setPvP(pvpState) ### Description Toggles the player's PvP state. ### Method POST ### Endpoint /player/{player_id}/pvp/toggle ### Parameters #### Request Body - **pvpState** (boolean) - Required - true to enable PvP, false to disable ### Request Example { "pvpState": false } ### Response #### Success Response (200) - **message** (string) - Indicates the PvP state has been updated. ### Response Example { "message": "PvP state updated successfully." } ``` ```APIDOC ## getToggleTime() ### Description Returns the timestamp when the player last toggled their PvP state. ### Method GET ### Endpoint /player/{player_id}/pvp/toggle-time ### Response #### Success Response (200) - **toggleTime** (long) - Milliseconds since epoch ### Response Example { "toggleTime": 1678886000000 } ``` -------------------------------- ### getNewbieTimeLeft Source: https://github.com/chancesd/pvpmanager/blob/master/_autodocs/api-reference/combatplayer.md Retrieves the remaining time in milliseconds until the player's newbie protection expires. ```APIDOC ## getNewbieTimeLeft() ### Description Returns the remaining time until newbie protection expires. ### Method `getNewbieTimeLeft` ### Returns - **long** - Milliseconds remaining, or 0 if no protection ``` -------------------------------- ### Get CombatWorld instance for a Bukkit World Source: https://github.com/chancesd/pvpmanager/blob/master/_autodocs/api-reference/worldmanager.md Retrieves or creates a CombatWorld instance for a given Bukkit World. This is useful for checking or modifying PvP settings for the world a player is currently in. ```java World bukkit = player.getWorld(); CombatWorld combatWorld = worldManager.getWorld(bukkit); if (!combatWorld.isCombatAllowed()) { player.sendMessage("PvP is disabled in this world"); } ``` -------------------------------- ### saveWorldData(CombatWorld combatWorld) Source: https://github.com/chancesd/pvpmanager/blob/master/_autodocs/api-reference/worldmanager.md Asynchronously saves the current settings of a CombatWorld to the database. Useful for immediate persistence. ```APIDOC ## saveWorldData(CombatWorld combatWorld) ### Description Asynchronously saves world settings to the database. Call explicitly for immediate persistence. ### Method POST ### Endpoint /worlds/{worldName}/save ### Parameters #### Path Parameters - **worldName** (String) - Required - The name of the world whose data needs to be saved. ### Response #### Success Response (200) - **message** (string) - Description: Confirmation message indicating the save operation was initiated. ### Response Example { "message": "World data save initiated for world 'world'." } ``` -------------------------------- ### Get Kill Abuse Count Source: https://github.com/chancesd/pvpmanager/blob/master/_autodocs/api-reference/combatplayer.md Retrieves the number of times the current player has killed a specific victim player within the defined time limit. This is used for kill abuse tracking. ```java public final int getKillAbuseCount(Player victimPlayer) ``` -------------------------------- ### Maven Repository Configuration Source: https://github.com/chancesd/pvpmanager/blob/master/README.md Add this repository to your project's pom.xml to access PvPManager artifacts. ```xml CodeMC https://repo.codemc.org/repository/maven-public/ ``` -------------------------------- ### Get CombatWorld instance by world name Source: https://github.com/chancesd/pvpmanager/blob/master/_autodocs/api-reference/worldmanager.md Retrieves a CombatWorld instance using its name. Use this when you need to access PvP settings for a world that is not necessarily the player's current world. ```java CombatWorld nether = worldManager.getWorld("world_nether"); if (nether != null) { nether.setCombatAllowed(false); } ``` -------------------------------- ### Listen to PlayerTagEvent Source: https://github.com/chancesd/pvpmanager/blob/master/_autodocs/quickstart.md Implement the Listener interface to handle PlayerTagEvent. This event fires when players enter combat. ```java import me.chancesd.pvpmanager.event.*; import org.bukkit.event.EventHandler; import org.bukkit.event.Listener; public class PvPListener implements Listener { @EventHandler public void onPlayerTag(PlayerTagEvent event) { if (event.isAttacker()) { event.getPlayer().sendMessage("You attacked " + event.getEnemy().getName()); } else { event.getPlayer().sendMessage("You were attacked by " + event.getEnemy().getName()); } } // ... other event handlers ```