Repository: SirBlobman/CombatLogX Branch: main Commit: dc68f1559e9b Files: 662 Total size: 1.8 MB Directory structure: gitextract_cpkbyraw/ ├── .github/ │ ├── ISSUE_TEMPLATE/ │ │ ├── bug-report.yml │ │ ├── config.yml │ │ ├── expansion-request.yml │ │ └── feature-requests.yml │ ├── PULL_REQUEST_TEMPLATE/ │ │ └── default.md │ ├── dependabot.yml │ └── funding.yml ├── .gitignore ├── CODE_OF_CONDUCT.md ├── CONTRIBUTING.MD ├── Jenkinsfile ├── LICENSE ├── README.MD ├── SECURITY.md ├── api/ │ ├── README.MD │ ├── build.gradle.kts │ ├── gradle.properties │ └── src/ │ └── main/ │ ├── java/ │ │ └── com/ │ │ └── github/ │ │ └── sirblobman/ │ │ └── combatlogx/ │ │ └── api/ │ │ ├── ICombatLogX.java │ │ ├── ICombatLogXNeeded.java │ │ ├── command/ │ │ │ ├── CombatLogCommand.java │ │ │ └── CombatLogPlayerCommand.java │ │ ├── configuration/ │ │ │ ├── CommandConfiguration.java │ │ │ ├── MainConfiguration.java │ │ │ └── PunishConfiguration.java │ │ ├── event/ │ │ │ ├── CustomPlayerEvent.java │ │ │ ├── CustomPlayerEventCancellable.java │ │ │ ├── NPCDropItemEvent.java │ │ │ ├── PlayerEnemyRemoveEvent.java │ │ │ ├── PlayerPreTagEvent.java │ │ │ ├── PlayerPunishEvent.java │ │ │ ├── PlayerReTagEvent.java │ │ │ ├── PlayerTagEvent.java │ │ │ └── PlayerUntagEvent.java │ │ ├── expansion/ │ │ │ ├── Expansion.java │ │ │ ├── ExpansionClassLoader.java │ │ │ ├── ExpansionComparator.java │ │ │ ├── ExpansionDescription.java │ │ │ ├── ExpansionDescriptionBuilder.java │ │ │ ├── ExpansionListener.java │ │ │ ├── ExpansionLogger.java │ │ │ ├── ExpansionManager.java │ │ │ ├── ExpansionWithDependencies.java │ │ │ ├── disguise/ │ │ │ │ ├── DisguiseExpansion.java │ │ │ │ ├── DisguiseExpansionListener.java │ │ │ │ ├── DisguiseHandler.java │ │ │ │ └── DisguiseListener.java │ │ │ ├── region/ │ │ │ │ ├── RegionExpansion.java │ │ │ │ ├── RegionHandler.java │ │ │ │ ├── configuration/ │ │ │ │ │ └── RegionExpansionConfiguration.java │ │ │ │ ├── listener/ │ │ │ │ │ ├── RegionExpansionListener.java │ │ │ │ │ ├── RegionMoveListener.java │ │ │ │ │ ├── RegionTeleportListener.java │ │ │ │ │ └── RegionVulnerableListener.java │ │ │ │ └── task/ │ │ │ │ └── KnockbackPlayerTask.java │ │ │ ├── skyblock/ │ │ │ │ ├── IslandWrapper.java │ │ │ │ ├── SkyBlockExpansion.java │ │ │ │ ├── SkyBlockExpansionListener.java │ │ │ │ ├── SkyBlockHandler.java │ │ │ │ └── SkyBlockListener.java │ │ │ └── vanish/ │ │ │ ├── VanishExpansion.java │ │ │ ├── VanishExpansionConfiguration.java │ │ │ ├── VanishExpansionListener.java │ │ │ ├── VanishHandler.java │ │ │ └── VanishListener.java │ │ ├── listener/ │ │ │ └── CombatListener.java │ │ ├── manager/ │ │ │ ├── ICombatManager.java │ │ │ ├── ICrystalManager.java │ │ │ ├── IDeathManager.java │ │ │ ├── IForgiveManager.java │ │ │ ├── IPlaceholderManager.java │ │ │ ├── IPunishManager.java │ │ │ └── ITimerManager.java │ │ ├── object/ │ │ │ ├── CitizensSlotType.java │ │ │ ├── CombatTag.java │ │ │ ├── KillTime.java │ │ │ ├── NoEntryMode.java │ │ │ ├── SpecialPunishCommand.java │ │ │ ├── TagInformation.java │ │ │ ├── TagReason.java │ │ │ ├── TagType.java │ │ │ ├── TimerType.java │ │ │ ├── TimerUpdater.java │ │ │ └── UntagReason.java │ │ ├── placeholder/ │ │ │ ├── IPlaceholderExpansion.java │ │ │ └── PlaceholderHelper.java │ │ └── utility/ │ │ ├── CommandHelper.java │ │ └── EntityHelper.java │ └── resources/ │ └── default-region-expansion-config.yml ├── build.gradle.kts ├── builder/ │ ├── build.gradle.kts │ └── src/ │ └── main/ │ └── resources/ │ └── README.TXT ├── crowdin.yml ├── expansion/ │ ├── action-bar/ │ │ ├── README.MD │ │ ├── gradle.properties │ │ └── src/ │ │ └── main/ │ │ ├── java/ │ │ │ └── combatlogx/ │ │ │ └── expansion/ │ │ │ └── action/ │ │ │ └── bar/ │ │ │ ├── ActionBarExpansion.java │ │ │ ├── ActionBarUpdater.java │ │ │ └── configuration/ │ │ │ └── ActionBarConfiguration.java │ │ └── resources/ │ │ ├── config.yml │ │ └── expansion.yml │ ├── boss-bar/ │ │ ├── README.MD │ │ ├── gradle.properties │ │ └── src/ │ │ └── main/ │ │ ├── java/ │ │ │ └── combatlogx/ │ │ │ └── expansion/ │ │ │ └── boss/ │ │ │ └── bar/ │ │ │ ├── BossBarConfiguration.java │ │ │ ├── BossBarExpansion.java │ │ │ └── BossBarUpdater.java │ │ └── resources/ │ │ ├── config.yml │ │ └── expansion.yml │ ├── build.gradle.kts │ ├── cheat-prevention/ │ │ ├── abstract/ │ │ │ └── src/ │ │ │ └── main/ │ │ │ └── java/ │ │ │ └── combatlogx/ │ │ │ └── expansion/ │ │ │ └── cheat/ │ │ │ └── prevention/ │ │ │ ├── ICheatPreventionExpansion.java │ │ │ ├── configuration/ │ │ │ │ ├── IBlockConfiguration.java │ │ │ │ ├── IBucketConfiguration.java │ │ │ │ ├── IChatConfiguration.java │ │ │ │ ├── ICommandConfiguration.java │ │ │ │ ├── IConfiguration.java │ │ │ │ ├── IEntityConfiguration.java │ │ │ │ ├── IFlightConfiguration.java │ │ │ │ ├── IGameModeConfiguration.java │ │ │ │ ├── IInventoryConfiguration.java │ │ │ │ ├── IItemConfiguration.java │ │ │ │ ├── IPotionConfiguration.java │ │ │ │ └── ITeleportConfiguration.java │ │ │ └── listener/ │ │ │ └── CheatPreventionListener.java │ │ ├── build.gradle.kts │ │ ├── gradle.properties │ │ ├── legacy/ │ │ │ ├── build.gradle.kts │ │ │ ├── gradle.properties │ │ │ └── src/ │ │ │ └── main/ │ │ │ └── java/ │ │ │ └── combatlogx/ │ │ │ └── expansion/ │ │ │ └── cheat/ │ │ │ └── prevention/ │ │ │ └── listener/ │ │ │ └── legacy/ │ │ │ ├── ListenerChat.java │ │ │ ├── ListenerLegacyItemPickup.java │ │ │ ├── ListenerLegacyPortalCreate.java │ │ │ └── ListenerLegacyPotions.java │ │ ├── modern/ │ │ │ ├── build.gradle.kts │ │ │ ├── gradle.properties │ │ │ └── src/ │ │ │ └── main/ │ │ │ └── java/ │ │ │ └── combatlogx/ │ │ │ └── expansion/ │ │ │ └── cheat/ │ │ │ └── prevention/ │ │ │ └── listener/ │ │ │ └── modern/ │ │ │ └── ListenerInventoriesModern.java │ │ ├── paper/ │ │ │ ├── build.gradle.kts │ │ │ ├── gradle.properties │ │ │ └── src/ │ │ │ └── main/ │ │ │ └── java/ │ │ │ └── combatlogx/ │ │ │ └── expansion/ │ │ │ └── cheat/ │ │ │ └── prevention/ │ │ │ └── listener/ │ │ │ └── paper/ │ │ │ ├── ListenerPaperChat.java │ │ │ └── ListenerPaperEntityInsideBlock.java │ │ └── src/ │ │ └── main/ │ │ ├── java/ │ │ │ └── combatlogx/ │ │ │ └── expansion/ │ │ │ └── cheat/ │ │ │ └── prevention/ │ │ │ ├── CheatPreventionExpansion.java │ │ │ ├── configuration/ │ │ │ │ ├── BlockConfiguration.java │ │ │ │ ├── BucketConfiguration.java │ │ │ │ ├── ChatConfiguration.java │ │ │ │ ├── CheatPreventionConfiguration.java │ │ │ │ ├── CommandConfiguration.java │ │ │ │ ├── EntityConfiguration.java │ │ │ │ ├── FlightConfiguration.java │ │ │ │ ├── GameModeConfiguration.java │ │ │ │ ├── InventoryConfiguration.java │ │ │ │ ├── ItemConfiguration.java │ │ │ │ ├── PotionConfiguration.java │ │ │ │ └── TeleportConfiguration.java │ │ │ ├── listener/ │ │ │ │ ├── ListenerBlocks.java │ │ │ │ ├── ListenerBuckets.java │ │ │ │ ├── ListenerCommands.java │ │ │ │ ├── ListenerDrop.java │ │ │ │ ├── ListenerElytra.java │ │ │ │ ├── ListenerEnderPearl.java │ │ │ │ ├── ListenerEntities.java │ │ │ │ ├── ListenerFlight.java │ │ │ │ ├── ListenerGameMode.java │ │ │ │ ├── ListenerInventories.java │ │ │ │ ├── ListenerRiptide.java │ │ │ │ ├── ListenerTeleport.java │ │ │ │ ├── ListenerTotem.java │ │ │ │ └── modern/ │ │ │ │ ├── ListenerModernItemPickup.java │ │ │ │ ├── ListenerModernPortalCreate.java │ │ │ │ └── ListenerModernPotions.java │ │ │ └── task/ │ │ │ ├── ElytraRetagTask.java │ │ │ └── FlightRetagTask.java │ │ └── resources/ │ │ ├── blocks.yml │ │ ├── buckets.yml │ │ ├── chat.yml │ │ ├── commands.yml │ │ ├── config.yml │ │ ├── entities.yml │ │ ├── expansion.yml │ │ ├── flight.yml │ │ ├── game-mode.yml │ │ ├── inventories.yml │ │ ├── items.yml │ │ ├── potions.yml │ │ └── teleportation.yml │ ├── compatibility/ │ │ ├── ASkyBlock/ │ │ │ ├── build.gradle.kts │ │ │ ├── gradle.properties │ │ │ └── src/ │ │ │ └── main/ │ │ │ ├── java/ │ │ │ │ └── combatlogx/ │ │ │ │ └── expansion/ │ │ │ │ └── compatibility/ │ │ │ │ └── askyblock/ │ │ │ │ ├── ASkyBlockExpansion.java │ │ │ │ └── listener/ │ │ │ │ └── ListenerASkyBlock.java │ │ │ └── resources/ │ │ │ └── expansion.yml │ │ ├── AngelChest/ │ │ │ ├── build.gradle.kts │ │ │ ├── gradle.properties │ │ │ └── src/ │ │ │ └── main/ │ │ │ ├── java/ │ │ │ │ └── combatlogx/ │ │ │ │ └── expansion/ │ │ │ │ └── compatibility/ │ │ │ │ └── angelchest/ │ │ │ │ ├── AngelChestConfiguration.java │ │ │ │ ├── AngelChestExpansion.java │ │ │ │ └── ListenerAngelChest.java │ │ │ └── resources/ │ │ │ ├── config.yml │ │ │ └── expansion.yml │ │ ├── BSkyBlock/ │ │ │ ├── build.gradle.kts │ │ │ ├── gradle.properties │ │ │ └── src/ │ │ │ └── main/ │ │ │ ├── java/ │ │ │ │ └── combatlogx/ │ │ │ │ └── expansion/ │ │ │ │ └── compatibility/ │ │ │ │ └── bskyblock/ │ │ │ │ ├── BSkyBlockExpansion.java │ │ │ │ ├── hook/ │ │ │ │ │ └── HookBentoBox.java │ │ │ │ └── listener/ │ │ │ │ └── ListenerBSkyBlock.java │ │ │ └── resources/ │ │ │ └── expansion.yml │ │ ├── CMI/ │ │ │ ├── build.gradle.kts │ │ │ ├── gradle.properties │ │ │ └── src/ │ │ │ └── main/ │ │ │ ├── java/ │ │ │ │ └── combatlogx/ │ │ │ │ └── expansion/ │ │ │ │ └── compatibility/ │ │ │ │ └── cmi/ │ │ │ │ ├── CMIExpansion.java │ │ │ │ └── VanishHandlerCMI.java │ │ │ └── resources/ │ │ │ ├── config.yml │ │ │ └── expansion.yml │ │ ├── Citizens/ │ │ │ ├── build.gradle.kts │ │ │ ├── gradle.properties │ │ │ └── src/ │ │ │ └── main/ │ │ │ ├── java/ │ │ │ │ └── combatlogx/ │ │ │ │ └── expansion/ │ │ │ │ └── compatibility/ │ │ │ │ └── citizens/ │ │ │ │ ├── CitizensExpansion.java │ │ │ │ ├── configuration/ │ │ │ │ │ ├── CitizensConfiguration.java │ │ │ │ │ ├── Configuration.java │ │ │ │ │ └── SentinelConfiguration.java │ │ │ │ ├── listener/ │ │ │ │ │ ├── CitizensExpansionListener.java │ │ │ │ │ ├── ListenerCombat.java │ │ │ │ │ ├── ListenerConvert.java │ │ │ │ │ ├── ListenerDeath.java │ │ │ │ │ ├── ListenerJoin.java │ │ │ │ │ ├── ListenerPunish.java │ │ │ │ │ ├── ListenerQuit.java │ │ │ │ │ └── ListenerResurrect.java │ │ │ │ ├── manager/ │ │ │ │ │ ├── CombatNpcManager.java │ │ │ │ │ └── InventoryManager.java │ │ │ │ ├── object/ │ │ │ │ │ ├── CombatNPC.java │ │ │ │ │ └── StoredInventory.java │ │ │ │ └── task/ │ │ │ │ └── PunishTask.java │ │ │ └── resources/ │ │ │ ├── citizens.yml │ │ │ ├── config.yml │ │ │ ├── expansion.yml │ │ │ └── sentinel.yml │ │ ├── CrackShot/ │ │ │ ├── build.gradle.kts │ │ │ ├── gradle.properties │ │ │ └── src/ │ │ │ └── main/ │ │ │ ├── java/ │ │ │ │ └── combatlogx/ │ │ │ │ └── expansion/ │ │ │ │ └── compatibility/ │ │ │ │ └── crackshot/ │ │ │ │ ├── CrackShotExpansion.java │ │ │ │ └── listener/ │ │ │ │ └── ListenerCrackShot.java │ │ │ └── resources/ │ │ │ └── expansion.yml │ │ ├── CrashClaim/ │ │ │ ├── build.gradle.kts │ │ │ ├── gradle.properties │ │ │ └── src/ │ │ │ └── main/ │ │ │ ├── java/ │ │ │ │ └── combatlogx/ │ │ │ │ └── expansion/ │ │ │ │ └── compatibility/ │ │ │ │ └── region/ │ │ │ │ └── crash/ │ │ │ │ └── claim/ │ │ │ │ ├── CrashClaimExpansion.java │ │ │ │ └── CrashClaimRegionHandler.java │ │ │ └── resources/ │ │ │ └── expansion.yml │ │ ├── EssentialsX/ │ │ │ ├── build.gradle.kts │ │ │ ├── gradle.properties │ │ │ └── src/ │ │ │ └── main/ │ │ │ ├── java/ │ │ │ │ └── combatlogx/ │ │ │ │ └── expansion/ │ │ │ │ └── compatibility/ │ │ │ │ └── essentials/ │ │ │ │ ├── EssentialsExpansion.java │ │ │ │ ├── EssentialsExpansionConfiguration.java │ │ │ │ ├── VanishHandlerEssentialsX.java │ │ │ │ └── listener/ │ │ │ │ └── ListenerEssentials.java │ │ │ └── resources/ │ │ │ ├── config.yml │ │ │ └── expansion.yml │ │ ├── FabledSkyBlock/ │ │ │ ├── build.gradle.kts │ │ │ ├── gradle.properties │ │ │ └── src/ │ │ │ └── main/ │ │ │ ├── java/ │ │ │ │ └── combatlogx/ │ │ │ │ └── expansion/ │ │ │ │ └── compatibility/ │ │ │ │ └── fabled/ │ │ │ │ └── skyblock/ │ │ │ │ ├── FabledSkyBlockExpansion.java │ │ │ │ ├── IslandWrapperFabled.java │ │ │ │ └── SkyBlockHandlerFabled.java │ │ │ └── resources/ │ │ │ └── expansion.yml │ │ ├── Factions/ │ │ │ ├── gradle.properties │ │ │ └── src/ │ │ │ └── main/ │ │ │ ├── java/ │ │ │ │ └── combatlogx/ │ │ │ │ └── expansion/ │ │ │ │ └── compatibility/ │ │ │ │ └── region/ │ │ │ │ └── factions/ │ │ │ │ ├── FactionsExpansion.java │ │ │ │ └── RegionHandlerFactions.java │ │ │ └── resources/ │ │ │ ├── config.yml │ │ │ └── expansion.yml │ │ ├── FeatherBoard/ │ │ │ ├── build.gradle.kts │ │ │ ├── gradle.properties │ │ │ └── src/ │ │ │ └── main/ │ │ │ ├── java/ │ │ │ │ └── combatlogx/ │ │ │ │ └── expansion/ │ │ │ │ └── compatibility/ │ │ │ │ └── featherboard/ │ │ │ │ ├── FeatherBoardConfiguration.java │ │ │ │ ├── FeatherBoardExpansion.java │ │ │ │ └── listener/ │ │ │ │ └── ListenerFeatherBoard.java │ │ │ └── resources/ │ │ │ ├── config.yml │ │ │ └── expansion.yml │ │ ├── GriefDefender/ │ │ │ ├── build.gradle.kts │ │ │ ├── gradle.properties │ │ │ └── src/ │ │ │ └── main/ │ │ │ ├── java/ │ │ │ │ └── combatlogx/ │ │ │ │ └── expansion/ │ │ │ │ └── compatibility/ │ │ │ │ └── region/ │ │ │ │ └── grief/ │ │ │ │ └── defender/ │ │ │ │ ├── GriefDefenderExpansion.java │ │ │ │ └── RegionHandlerGriefDefender.java │ │ │ └── resources/ │ │ │ └── expansion.yml │ │ ├── GriefPrevention/ │ │ │ ├── build.gradle.kts │ │ │ ├── gradle.properties │ │ │ └── src/ │ │ │ └── main/ │ │ │ ├── java/ │ │ │ │ └── combatlogx/ │ │ │ │ └── expansion/ │ │ │ │ └── compatibility/ │ │ │ │ └── region/ │ │ │ │ └── grief/ │ │ │ │ └── prevention/ │ │ │ │ ├── GriefPreventionExpansion.java │ │ │ │ └── RegionHandlerGriefPrevention.java │ │ │ └── resources/ │ │ │ └── expansion.yml │ │ ├── HuskHomes/ │ │ │ ├── build.gradle.kts │ │ │ ├── gradle.properties │ │ │ └── src/ │ │ │ └── main/ │ │ │ ├── java/ │ │ │ │ └── combatlogx/ │ │ │ │ └── expansion/ │ │ │ │ └── compatibility/ │ │ │ │ └── huskhomes/ │ │ │ │ ├── HuskHomesExpansion.java │ │ │ │ └── listener/ │ │ │ │ └── ListenerHuskHomes.java │ │ │ └── resources/ │ │ │ ├── config.yml │ │ │ └── expansion.yml │ │ ├── HuskSync/ │ │ │ ├── build.gradle.kts │ │ │ ├── gradle.properties │ │ │ └── src/ │ │ │ └── main/ │ │ │ ├── java/ │ │ │ │ └── combatlogx/ │ │ │ │ └── expansion/ │ │ │ │ └── compatibility/ │ │ │ │ └── husksync/ │ │ │ │ ├── DropItemsTask.java │ │ │ │ ├── HuskSyncExpansion.java │ │ │ │ ├── ListenerHuskSync.java │ │ │ │ └── PlayerData.java │ │ │ └── resources/ │ │ │ └── expansion.yml │ │ ├── HuskTowns/ │ │ │ ├── README.MD │ │ │ ├── build.gradle.kts │ │ │ ├── gradle.properties │ │ │ └── src/ │ │ │ └── main/ │ │ │ ├── java/ │ │ │ │ └── combatlogx/ │ │ │ │ └── expansion/ │ │ │ │ └── compatibility/ │ │ │ │ └── region/ │ │ │ │ └── husktowns/ │ │ │ │ ├── HuskTownsExpansion.java │ │ │ │ └── RegionHandlerHuskTowns.java │ │ │ └── resources/ │ │ │ ├── config.yml │ │ │ └── expansion.yml │ │ ├── IridiumSkyblock/ │ │ │ ├── build.gradle.kts │ │ │ ├── gradle.properties │ │ │ └── src/ │ │ │ └── main/ │ │ │ ├── java/ │ │ │ │ └── combatlogx/ │ │ │ │ └── expansion/ │ │ │ │ └── compatibility/ │ │ │ │ └── iridium/ │ │ │ │ └── skyblock/ │ │ │ │ ├── IridiumSkyblockExpansion.java │ │ │ │ ├── IslandWrapperIridium.java │ │ │ │ └── SkyBlockHandlerIridium.java │ │ │ └── resources/ │ │ │ └── expansion.yml │ │ ├── KingdomsX/ │ │ │ ├── build.gradle.kts │ │ │ ├── gradle.properties │ │ │ └── src/ │ │ │ └── main/ │ │ │ ├── java/ │ │ │ │ └── combatlogx/ │ │ │ │ └── expansion/ │ │ │ │ └── compatibility/ │ │ │ │ └── region/ │ │ │ │ └── kingdomsx/ │ │ │ │ ├── ExpansionKingdomsX.java │ │ │ │ └── RegionHandlerKingdomsX.java │ │ │ └── resources/ │ │ │ └── expansion.yml │ │ ├── Konquest/ │ │ │ ├── build.gradle.kts │ │ │ ├── gradle.properties │ │ │ └── src/ │ │ │ └── main/ │ │ │ ├── java/ │ │ │ │ └── combatlogx/ │ │ │ │ └── expansion/ │ │ │ │ └── compatibility/ │ │ │ │ └── region/ │ │ │ │ └── konquest/ │ │ │ │ ├── KonquestExpansion.java │ │ │ │ └── RegionHandlerKonquest.java │ │ │ └── resources/ │ │ │ └── expansion.yml │ │ ├── Lands/ │ │ │ ├── build.gradle.kts │ │ │ ├── gradle.properties │ │ │ └── src/ │ │ │ └── main/ │ │ │ ├── java/ │ │ │ │ └── combatlogx/ │ │ │ │ └── expansion/ │ │ │ │ └── compatibility/ │ │ │ │ └── region/ │ │ │ │ └── lands/ │ │ │ │ ├── LandsConfiguration.java │ │ │ │ ├── LandsExpansion.java │ │ │ │ ├── RegionHandlerLands.java │ │ │ │ └── listener/ │ │ │ │ └── ListenerLands.java │ │ │ └── resources/ │ │ │ ├── expansion.yml │ │ │ └── lands.yml │ │ ├── LibsDisguises/ │ │ │ ├── build.gradle.kts │ │ │ ├── gradle.properties │ │ │ └── src/ │ │ │ └── main/ │ │ │ ├── java/ │ │ │ │ └── combatlogx/ │ │ │ │ └── expansion/ │ │ │ │ └── compatibility/ │ │ │ │ └── libsdisguises/ │ │ │ │ ├── DisguiseHandlerLibsDisguises.java │ │ │ │ └── LibsDisguisesExpansion.java │ │ │ └── resources/ │ │ │ └── expansion.yml │ │ ├── LuckPerms/ │ │ │ ├── README.MD │ │ │ ├── build.gradle.kts │ │ │ ├── gradle.properties │ │ │ └── src/ │ │ │ └── main/ │ │ │ ├── java/ │ │ │ │ └── combatlogx/ │ │ │ │ └── expansion/ │ │ │ │ └── compatibility/ │ │ │ │ └── luckperms/ │ │ │ │ ├── LuckPermsExpansion.java │ │ │ │ ├── context/ │ │ │ │ │ ├── AbstractContext.java │ │ │ │ │ ├── ContextInCombat.java │ │ │ │ │ ├── ContextNewbieHelperProtected.java │ │ │ │ │ └── ContextNewbieHelperPvpStatus.java │ │ │ │ └── hook/ │ │ │ │ └── HookNewbieHelper.java │ │ │ └── resources/ │ │ │ └── expansion.yml │ │ ├── MCPets/ │ │ │ ├── README.md │ │ │ ├── build.gradle.kts │ │ │ ├── gradle.properties │ │ │ └── src/ │ │ │ └── main/ │ │ │ ├── java/ │ │ │ │ └── combatlogx/ │ │ │ │ └── expansion/ │ │ │ │ └── compatibility/ │ │ │ │ └── mcpets/ │ │ │ │ ├── ListenerMcPets.java │ │ │ │ └── McPetsExpansion.java │ │ │ └── resources/ │ │ │ └── expansion.yml │ │ ├── MarriageMaster/ │ │ │ ├── build.gradle.kts │ │ │ ├── gradle.properties │ │ │ └── src/ │ │ │ └── main/ │ │ │ ├── java/ │ │ │ │ └── combatlogx/ │ │ │ │ └── expansion/ │ │ │ │ └── compatibility/ │ │ │ │ └── marriagemaster/ │ │ │ │ ├── MarriageMasterExpansion.java │ │ │ │ └── listener/ │ │ │ │ └── ListenerMarriageMaster.java │ │ │ └── resources/ │ │ │ └── expansion.yml │ │ ├── MythicMobs/ │ │ │ ├── build.gradle.kts │ │ │ ├── gradle.properties │ │ │ └── src/ │ │ │ └── main/ │ │ │ ├── java/ │ │ │ │ └── combatlogx/ │ │ │ │ └── expansion/ │ │ │ │ └── compatibility/ │ │ │ │ └── mythicmobs/ │ │ │ │ ├── ListenerMythicMobs.java │ │ │ │ ├── MythicMobsConfiguration.java │ │ │ │ └── MythicMobsExpansion.java │ │ │ └── resources/ │ │ │ ├── config.yml │ │ │ └── expansion.yml │ │ ├── PlaceholderAPI/ │ │ │ ├── README.MD │ │ │ ├── build.gradle.kts │ │ │ ├── gradle.properties │ │ │ └── src/ │ │ │ └── main/ │ │ │ ├── java/ │ │ │ │ └── combatlogx/ │ │ │ │ └── expansion/ │ │ │ │ └── compatibility/ │ │ │ │ └── placeholderapi/ │ │ │ │ ├── HookPlaceholderAPI.java │ │ │ │ └── PlaceholderAPIExpansion.java │ │ │ └── resources/ │ │ │ └── expansion.yml │ │ ├── PlayerParticles/ │ │ │ ├── build.gradle.kts │ │ │ ├── gradle.properties │ │ │ └── src/ │ │ │ └── main/ │ │ │ ├── java/ │ │ │ │ └── combatlogx/ │ │ │ │ └── expansion/ │ │ │ │ └── compatibility/ │ │ │ │ └── player/ │ │ │ │ └── particles/ │ │ │ │ ├── ListenerPlayerParticles.java │ │ │ │ ├── PlayerParticlesConfiguration.java │ │ │ │ └── PlayerParticlesExpansion.java │ │ │ └── resources/ │ │ │ ├── config.yml │ │ │ └── expansion.yml │ │ ├── PreciousStones/ │ │ │ ├── build.gradle.kts │ │ │ ├── gradle.properties │ │ │ └── src/ │ │ │ └── main/ │ │ │ ├── java/ │ │ │ │ └── combatlogx/ │ │ │ │ └── expansion/ │ │ │ │ └── compatibility/ │ │ │ │ └── region/ │ │ │ │ └── preciousstones/ │ │ │ │ ├── ListenerPreciousStones.java │ │ │ │ ├── PreciousStonesConfiguration.java │ │ │ │ ├── PreciousStonesExpansion.java │ │ │ │ └── RegionHandlerPreciousStones.java │ │ │ └── resources/ │ │ │ └── expansion.yml │ │ ├── ProtectionStones/ │ │ │ ├── build.gradle.kts │ │ │ ├── gradle.properties │ │ │ └── src/ │ │ │ └── main/ │ │ │ ├── java/ │ │ │ │ └── combatlogx/ │ │ │ │ └── expansion/ │ │ │ │ └── compatibility/ │ │ │ │ └── region/ │ │ │ │ └── protectionstones/ │ │ │ │ ├── ProtectionStonesConfiguration.java │ │ │ │ ├── ProtectionStonesExpansion.java │ │ │ │ ├── ProtectionStonesListener.java │ │ │ │ └── RegionHandlerProtectionStones.java │ │ │ └── resources/ │ │ │ └── expansion.yml │ │ ├── README.MD │ │ ├── RedProtect/ │ │ │ ├── build.gradle.kts │ │ │ ├── gradle.properties │ │ │ └── src/ │ │ │ └── main/ │ │ │ ├── java/ │ │ │ │ └── combatlogx/ │ │ │ │ └── expansion/ │ │ │ │ └── compatibility/ │ │ │ │ └── region/ │ │ │ │ └── redprotect/ │ │ │ │ ├── RedProtectExpansion.java │ │ │ │ └── RegionHandlerRedProtect.java │ │ │ └── resources/ │ │ │ └── expansion.yml │ │ ├── Residence/ │ │ │ ├── build.gradle.kts │ │ │ ├── gradle.properties │ │ │ └── src/ │ │ │ └── main/ │ │ │ ├── java/ │ │ │ │ └── combatlogx/ │ │ │ │ └── expansion/ │ │ │ │ └── compatibility/ │ │ │ │ └── region/ │ │ │ │ └── residence/ │ │ │ │ ├── RegionHandlerResidence.java │ │ │ │ └── ResidenceExpansion.java │ │ │ └── resources/ │ │ │ └── expansion.yml │ │ ├── SuperVanish/ │ │ │ ├── build.gradle.kts │ │ │ ├── gradle.properties │ │ │ └── src/ │ │ │ └── main/ │ │ │ ├── java/ │ │ │ │ └── combatlogx/ │ │ │ │ └── expansion/ │ │ │ │ └── compatibility/ │ │ │ │ └── supervanish/ │ │ │ │ ├── SuperVanishExpansion.java │ │ │ │ └── VanishHandlerSuper.java │ │ │ └── resources/ │ │ │ ├── config.yml │ │ │ └── expansion.yml │ │ ├── SuperiorSkyblock/ │ │ │ ├── build.gradle.kts │ │ │ ├── gradle.properties │ │ │ └── src/ │ │ │ └── main/ │ │ │ ├── java/ │ │ │ │ └── combatlogx/ │ │ │ │ └── expansion/ │ │ │ │ └── compatibility/ │ │ │ │ └── superior/ │ │ │ │ └── skyblock/ │ │ │ │ ├── IslandWrapperSuperior.java │ │ │ │ ├── SkyBlockHandlerSuperior.java │ │ │ │ └── SuperiorSkyblockExpansion.java │ │ │ └── resources/ │ │ │ └── expansion.yml │ │ ├── Towny/ │ │ │ ├── build.gradle.kts │ │ │ ├── gradle.properties │ │ │ └── src/ │ │ │ └── main/ │ │ │ ├── java/ │ │ │ │ └── combatlogx/ │ │ │ │ └── expansion/ │ │ │ │ └── compatibility/ │ │ │ │ └── region/ │ │ │ │ └── towny/ │ │ │ │ ├── RegionHandlerTowny.java │ │ │ │ ├── TownyConfiguration.java │ │ │ │ ├── TownyExpansion.java │ │ │ │ └── listener/ │ │ │ │ └── ListenerPrison.java │ │ │ └── resources/ │ │ │ ├── expansion.yml │ │ │ └── towny.yml │ │ ├── UltimateClaims/ │ │ │ ├── build.gradle.kts │ │ │ ├── gradle.properties │ │ │ └── src/ │ │ │ └── main/ │ │ │ ├── java/ │ │ │ │ └── combatlogx/ │ │ │ │ └── expansion/ │ │ │ │ └── compatibility/ │ │ │ │ └── region/ │ │ │ │ └── ultimateclaims/ │ │ │ │ ├── RegionHandlerUltimateClaims.java │ │ │ │ └── UltimateClaimsExpansion.java │ │ │ └── resources/ │ │ │ └── expansion.yml │ │ ├── VanishNoPacket/ │ │ │ ├── build.gradle.kts │ │ │ ├── gradle.properties │ │ │ └── src/ │ │ │ └── main/ │ │ │ ├── java/ │ │ │ │ └── combatlogx/ │ │ │ │ └── expansion/ │ │ │ │ └── compatibility/ │ │ │ │ └── vnp/ │ │ │ │ ├── VanishHandlerNoPacket.java │ │ │ │ └── VanishNoPacketExpansion.java │ │ │ └── resources/ │ │ │ ├── config.yml │ │ │ └── expansion.yml │ │ ├── WorldGuard/ │ │ │ ├── build.gradle.kts │ │ │ ├── gradle.properties │ │ │ └── src/ │ │ │ └── main/ │ │ │ ├── java/ │ │ │ │ └── combatlogx/ │ │ │ │ └── expansion/ │ │ │ │ └── compatibility/ │ │ │ │ └── region/ │ │ │ │ └── world/ │ │ │ │ └── guard/ │ │ │ │ ├── WorldGuardConfiguration.java │ │ │ │ ├── WorldGuardExpansion.java │ │ │ │ ├── handler/ │ │ │ │ │ └── WorldGuardRegionHandler.java │ │ │ │ ├── hook/ │ │ │ │ │ └── HookWorldGuard.java │ │ │ │ └── listener/ │ │ │ │ ├── ListenerPreventLeaving.java │ │ │ │ └── ListenerWorldGuard.java │ │ │ └── resources/ │ │ │ ├── expansion.yml │ │ │ └── worldguard.yml │ │ ├── ZNPCsPlus/ │ │ │ ├── build.gradle.kts │ │ │ ├── gradle.properties │ │ │ └── src/ │ │ │ └── main/ │ │ │ ├── java/ │ │ │ │ └── combatlogx/ │ │ │ │ └── expansion/ │ │ │ │ └── compatibility/ │ │ │ │ └── znpc/ │ │ │ │ ├── CombatNpc.java │ │ │ │ ├── CombatNpcManager.java │ │ │ │ ├── ZNPCExpansion.java │ │ │ │ ├── configuration/ │ │ │ │ │ ├── Configuration.java │ │ │ │ │ └── NpcConfiguration.java │ │ │ │ ├── listener/ │ │ │ │ │ └── NpcExpansionListener.java │ │ │ │ └── task/ │ │ │ │ └── NpcRemoveTask.java │ │ │ └── resources/ │ │ │ ├── config.yml │ │ │ ├── expansion.yml │ │ │ └── npcs.yml │ │ ├── build.gradle.kts │ │ ├── iDisguise/ │ │ │ ├── build.gradle.kts │ │ │ ├── gradle.properties │ │ │ └── src/ │ │ │ └── main/ │ │ │ ├── java/ │ │ │ │ └── combatlogx/ │ │ │ │ └── expansion/ │ │ │ │ └── compatibility/ │ │ │ │ └── idisguise/ │ │ │ │ ├── DisguiseHandler_iDisguise.java │ │ │ │ └── Expansion_iDisguise.java │ │ │ └── resources/ │ │ │ └── expansion.yml │ │ └── uSkyBlock/ │ │ ├── build.gradle.kts │ │ ├── gradle.properties │ │ └── src/ │ │ └── main/ │ │ ├── java/ │ │ │ └── combatlogx/ │ │ │ └── expansion/ │ │ │ └── compatibility/ │ │ │ └── uskyblock/ │ │ │ ├── IslandWrapper_uSkyBlock.java │ │ │ ├── SkyBlockHandler_uSkyBlock.java │ │ │ └── uSkyBlockExpansion.java │ │ └── resources/ │ │ └── expansion.yml │ ├── damage-effects/ │ │ ├── README.MD │ │ ├── gradle.properties │ │ └── src/ │ │ └── main/ │ │ ├── java/ │ │ │ └── combatlogx/ │ │ │ └── expansion/ │ │ │ └── damage/ │ │ │ └── effects/ │ │ │ ├── DamageEffectsConfiguration.java │ │ │ ├── DamageEffectsExpansion.java │ │ │ ├── ListenerDamageEffects.java │ │ │ └── effect/ │ │ │ ├── Blood.java │ │ │ ├── DamageEffect.java │ │ │ └── Offset.java │ │ └── resources/ │ │ ├── effects.yml │ │ └── expansion.yml │ ├── damage-tagger/ │ │ ├── README.MD │ │ ├── gradle.properties │ │ └── src/ │ │ └── main/ │ │ ├── java/ │ │ │ └── combatlogx/ │ │ │ └── expansion/ │ │ │ └── damage/ │ │ │ └── tagger/ │ │ │ ├── DamageTaggerExpansion.java │ │ │ ├── configuration/ │ │ │ │ └── DamageTaggerConfiguration.java │ │ │ └── listener/ │ │ │ └── ListenerDamage.java │ │ └── resources/ │ │ ├── config.yml │ │ └── expansion.yml │ ├── death-effects/ │ │ ├── README.MD │ │ ├── gradle.properties │ │ └── src/ │ │ └── main/ │ │ ├── java/ │ │ │ └── combatlogx/ │ │ │ └── expansion/ │ │ │ └── death/ │ │ │ └── effects/ │ │ │ ├── DeathEffectsConfiguration.java │ │ │ ├── DeathEffectsExpansion.java │ │ │ ├── ListenerDeathEffects.java │ │ │ └── task/ │ │ │ └── ItemRemoveTask.java │ │ └── resources/ │ │ ├── config.yml │ │ └── expansion.yml │ ├── end-crystal/ │ │ ├── build.gradle.kts │ │ ├── gradle.properties │ │ ├── legacy/ │ │ │ ├── gradle.properties │ │ │ └── src/ │ │ │ └── main/ │ │ │ └── java/ │ │ │ └── combatlogx/ │ │ │ └── expansion/ │ │ │ └── endcrystals/ │ │ │ ├── CheckEndCrystalTask.java │ │ │ └── ListenerCrystals_Legacy.java │ │ ├── modern/ │ │ │ ├── gradle.properties │ │ │ └── src/ │ │ │ └── main/ │ │ │ └── java/ │ │ │ └── combatlogx/ │ │ │ └── expansion/ │ │ │ └── endcrystals/ │ │ │ └── ListenerCrystals_Modern.java │ │ └── src/ │ │ └── main/ │ │ ├── java/ │ │ │ └── combatlogx/ │ │ │ └── expansion/ │ │ │ └── endcrystals/ │ │ │ └── EndCrystalExpansion.java │ │ └── resources/ │ │ └── expansion.yml │ ├── force-field/ │ │ ├── README.MD │ │ ├── build.gradle.kts │ │ ├── gradle.properties │ │ └── src/ │ │ └── main/ │ │ ├── java/ │ │ │ └── combatlogx/ │ │ │ └── expansion/ │ │ │ └── force/ │ │ │ └── field/ │ │ │ ├── ForceFieldExpansion.java │ │ │ ├── configuration/ │ │ │ │ └── ForceFieldConfiguration.java │ │ │ └── task/ │ │ │ ├── ForceFieldAdapter.java │ │ │ └── ForceFieldTask.java │ │ └── resources/ │ │ ├── config.yml │ │ └── expansion.yml │ ├── glowing/ │ │ ├── README.MD │ │ ├── gradle.properties │ │ └── src/ │ │ └── main/ │ │ ├── java/ │ │ │ └── combatlogx/ │ │ │ └── expansion/ │ │ │ └── glowing/ │ │ │ ├── GlowingExpansion.java │ │ │ └── listener/ │ │ │ └── ListenerGlow.java │ │ └── resources/ │ │ └── expansion.yml │ ├── logger/ │ │ ├── README.MD │ │ ├── gradle.properties │ │ └── src/ │ │ └── main/ │ │ ├── java/ │ │ │ └── combatlogx/ │ │ │ └── expansion/ │ │ │ └── logger/ │ │ │ ├── LoggerExpansion.java │ │ │ ├── configuration/ │ │ │ │ ├── LogEntryOptions.java │ │ │ │ ├── LogFileInfo.java │ │ │ │ ├── LogOptions.java │ │ │ │ ├── LogType.java │ │ │ │ └── LoggerConfiguration.java │ │ │ └── listener/ │ │ │ └── ListenerLogger.java │ │ └── resources/ │ │ ├── config.yml │ │ └── expansion.yml │ ├── loot-protection/ │ │ ├── build.gradle.kts │ │ ├── gradle.properties │ │ └── src/ │ │ └── main/ │ │ ├── java/ │ │ │ └── combatlogx/ │ │ │ └── expansion/ │ │ │ └── loot/ │ │ │ └── protection/ │ │ │ ├── LootProtectionExpansion.java │ │ │ ├── configuration/ │ │ │ │ └── LootProtectionConfiguration.java │ │ │ ├── event/ │ │ │ │ └── QueryPickupEvent.java │ │ │ ├── listener/ │ │ │ │ └── ListenerLootProtection.java │ │ │ └── object/ │ │ │ └── ProtectedItem.java │ │ └── resources/ │ │ ├── config.yml │ │ └── expansion.yml │ ├── mob-tagger/ │ │ ├── README.MD │ │ ├── gradle.properties │ │ └── src/ │ │ └── main/ │ │ ├── java/ │ │ │ └── combatlogx/ │ │ │ └── expansion/ │ │ │ └── mob/ │ │ │ └── tagger/ │ │ │ ├── MobTaggerExpansion.java │ │ │ ├── configuration/ │ │ │ │ └── MobTaggerConfiguration.java │ │ │ ├── listener/ │ │ │ │ └── ListenerDamage.java │ │ │ └── manager/ │ │ │ ├── ISpawnReasonManager.java │ │ │ ├── SpawnReasonManager_Legacy.java │ │ │ └── SpawnReasonManager_New.java │ │ └── resources/ │ │ ├── config.yml │ │ └── expansion.yml │ ├── newbie-helper/ │ │ ├── README.MD │ │ ├── build.gradle.kts │ │ ├── gradle.properties │ │ └── src/ │ │ └── main/ │ │ ├── java/ │ │ │ └── combatlogx/ │ │ │ └── expansion/ │ │ │ └── newbie/ │ │ │ └── helper/ │ │ │ ├── NewbieHelperExpansion.java │ │ │ ├── command/ │ │ │ │ ├── CommandTogglePVP.java │ │ │ │ ├── SubCommandCheck.java │ │ │ │ ├── SubCommandOff.java │ │ │ │ ├── SubCommandOn.java │ │ │ │ └── admin/ │ │ │ │ ├── SubCommandAdmin.java │ │ │ │ ├── SubCommandAdminOff.java │ │ │ │ └── SubCommandAdminOn.java │ │ │ ├── configuration/ │ │ │ │ ├── NewbieHelperConfiguration.java │ │ │ │ └── WorldsConfiguration.java │ │ │ ├── listener/ │ │ │ │ ├── ListenerDamage.java │ │ │ │ ├── ListenerJoin.java │ │ │ │ └── ListenerLavaFire.java │ │ │ ├── manager/ │ │ │ │ ├── CooldownManager.java │ │ │ │ ├── PVPManager.java │ │ │ │ └── ProtectionManager.java │ │ │ └── placeholder/ │ │ │ └── NewbieHelperPlaceholderExpansion.java │ │ └── resources/ │ │ ├── config.yml │ │ ├── expansion.yml │ │ └── worlds.yml │ ├── rewards/ │ │ ├── README.MD │ │ ├── build.gradle.kts │ │ ├── gradle.properties │ │ └── src/ │ │ └── main/ │ │ ├── java/ │ │ │ └── combatlogx/ │ │ │ └── expansion/ │ │ │ └── rewards/ │ │ │ ├── RewardExpansion.java │ │ │ ├── configuration/ │ │ │ │ ├── Reward.java │ │ │ │ ├── RewardConfiguration.java │ │ │ │ └── requirement/ │ │ │ │ ├── EconomyRequirement.java │ │ │ │ ├── ExperienceRequirement.java │ │ │ │ └── Requirement.java │ │ │ ├── hook/ │ │ │ │ └── HookVault.java │ │ │ └── listener/ │ │ │ └── ListenerRewards.java │ │ └── resources/ │ │ ├── config.yml │ │ └── expansion.yml │ └── scoreboard/ │ ├── README.MD │ ├── build.gradle.kts │ ├── gradle.properties │ └── src/ │ └── main/ │ ├── java/ │ │ └── combatlogx/ │ │ └── expansion/ │ │ └── scoreboard/ │ │ ├── ScoreboardConfiguration.java │ │ ├── ScoreboardExpansion.java │ │ ├── ScoreboardUpdater.java │ │ ├── manager/ │ │ │ └── CustomScoreboardManager.java │ │ └── scoreboard/ │ │ ├── CustomLine.java │ │ ├── CustomScoreboard.java │ │ └── PaperScoreboard.java │ └── resources/ │ ├── config.yml │ └── expansion.yml ├── gradle/ │ └── wrapper/ │ ├── gradle-wrapper.jar │ └── gradle-wrapper.properties ├── gradle.properties ├── gradlew ├── gradlew.bat ├── plugin/ │ ├── README.MD │ ├── build.gradle.kts │ ├── gradle.properties │ └── src/ │ └── main/ │ ├── java/ │ │ └── com/ │ │ └── github/ │ │ └── sirblobman/ │ │ └── combatlogx/ │ │ ├── CombatPlugin.java │ │ ├── command/ │ │ │ ├── CommandCombatTimer.java │ │ │ ├── CommandTogglePVP.java │ │ │ └── combatlogx/ │ │ │ ├── CommandCombatLogX.java │ │ │ ├── SubCommandAbout.java │ │ │ ├── SubCommandHelp.java │ │ │ ├── SubCommandReload.java │ │ │ ├── SubCommandTag.java │ │ │ ├── SubCommandToggle.java │ │ │ ├── SubCommandUntag.java │ │ │ ├── SubCommandVersion.java │ │ │ └── forgive/ │ │ │ ├── SubCommandForgive.java │ │ │ ├── SubCommandForgiveAccept.java │ │ │ ├── SubCommandForgiveReject.java │ │ │ ├── SubCommandForgiveRequest.java │ │ │ └── SubCommandForgiveToggle.java │ │ ├── configuration/ │ │ │ └── ConfigurationChecker.java │ │ ├── listener/ │ │ │ ├── ListenerConfiguration.java │ │ │ ├── ListenerDamage.java │ │ │ ├── ListenerDeath.java │ │ │ ├── ListenerEndCrystal.java │ │ │ ├── ListenerInvulnerable.java │ │ │ ├── ListenerPunish.java │ │ │ └── ListenerUntag.java │ │ ├── manager/ │ │ │ ├── CombatManager.java │ │ │ ├── CrystalManager.java │ │ │ ├── DeathManager.java │ │ │ ├── ForgiveManager.java │ │ │ ├── Manager.java │ │ │ ├── PlaceholderManager.java │ │ │ └── PunishManager.java │ │ ├── placeholder/ │ │ │ └── BasePlaceholderExpansion.java │ │ └── task/ │ │ ├── PlayerVulnerableTask.java │ │ ├── TimerUpdateTask.java │ │ └── UntagTask.java │ └── resources/ │ ├── commands.yml │ ├── config.yml │ ├── language/ │ │ ├── ar_sa.lang.yml │ │ ├── cs_cz.lang.yml │ │ ├── da_dk.lang.yml │ │ ├── de_at.lang.yml │ │ ├── de_ch.lang.yml │ │ ├── de_de.lang.yml │ │ ├── el_gr.lang.yml │ │ ├── en_us.lang.yml │ │ ├── es_ar.lang.yml │ │ ├── es_cl.lang.yml │ │ ├── es_ec.lang.yml │ │ ├── es_es.lang.yml │ │ ├── es_mx.lang.yml │ │ ├── es_uy.lang.yml │ │ ├── es_ve.lang.yml │ │ ├── fi_fi.lang.yml │ │ ├── fr_ca.lang.yml │ │ ├── fr_fr.lang.yml │ │ ├── hu_hu.lang.yml │ │ ├── it_it.lang.yml │ │ ├── ka_ge.lang.yml │ │ ├── nl_be.yml │ │ ├── nl_nl.yml │ │ ├── nn_no.yml │ │ ├── no_no.yml │ │ ├── pl_pl.lang.yml │ │ ├── pt_br.lang.yml │ │ ├── pt_pt.lang.yml │ │ ├── ru_ru.lang.yml │ │ ├── sv_se.lang.yml │ │ ├── tr_tr.lang.yml │ │ ├── uk_ua.lang.yml │ │ └── zh_cn.lang.yml │ ├── language.yml │ └── punish.yml ├── settings.gradle.kts ├── spigot.documentation.bbcode └── spigot.overview.bbcode ================================================ FILE CONTENTS ================================================ ================================================ FILE: .github/ISSUE_TEMPLATE/bug-report.yml ================================================ name: Bug Report description: Create a report that will help us resolve an issue. labels: - Bug body: - type: markdown attributes: value: |- Please fill out the following form to the best of your ability. The better you fill this out, the faster we can resolve the problem. - type: dropdown attributes: label: Server Implementation description: >- Which server implementation are you using? If your server implementation is not listed, we do not provide support for it. multiple: false options: - Spigot - Paper - Folia validations: required: true - type: dropdown attributes: label: Server Version description: >- Which server version are you using? If your version is not listed, we do not provide support for it. multiple: false options: - 1.19.4 - 1.20.6 - 1.21 - other validations: required: true - type: textarea attributes: label: Describe the bug description: A clear and concise description of what the bug is. validations: required: true - type: textarea attributes: label: Reproduction Steps description: Steps to reproduce this behaviour placeholder: |- 1. Go to '...' 2. Click on '...' 3. Scroll down to '...' 4. See error validations: required: true - type: textarea attributes: label: Expected behaviour description: A clear and concise description of what you expected to happen. validations: required: true - type: textarea attributes: label: Screenshots / Videos description: 'If applicable, add screenshots to help explain your problem.' - type: input attributes: label: latest log file (if applicable) description: >- Please upload your '/logs/latest.log' file to a paste service and post the link here. - type: textarea attributes: label: CombatLogX Version description: >- Please run the command '/clx version' on your server and post the output here. validations: required: true - type: textarea attributes: label: Anything else? description: You can provide additional context below. ================================================ FILE: .github/ISSUE_TEMPLATE/config.yml ================================================ blank_issues_enabled: false contact_links: - name: "Discord Server" url: "https://discord.gg/XMq2agT" about: "Get help through Discord." - name: "E-Mail Support" url: "mailto:support@sirblobman.xyz" about: "Contact SirBlobman through e-mail. Response will be more delayed than GitHub/Discord." ================================================ FILE: .github/ISSUE_TEMPLATE/expansion-request.yml ================================================ name: Expansion Request description: Make a suggestion for a new plugin compatibility expansion. labels: - Feature Request body: - type: markdown attributes: value: |- Please fill out the following form to the best of your ability. The better you fill this out, the faster we can resolve the problem. - type: dropdown attributes: label: Server Implementation description: >- Which server implementation are you using? If your server implementation is not listed, we do not provide support for it. multiple: false options: - Spigot - Paper - Folia validations: required: true - type: dropdown attributes: label: Server Version description: >- Which server version are you using? If your version is not listed, we do not provide support for it. multiple: false options: - 1.19.4 - 1.20.6 - 1.21 - other validations: required: true - type: textarea attributes: label: CombatLogX Version description: >- Please run the command '/clx version' on your server and post the output here. validations: required: true - type: textarea attributes: label: Plugin description: >- Which plugin needs a compatibility expansion? Please provide a link to the plugin. We also need access to source or an API jar. validations: required: true - type: textarea attributes: label: Explanation description: >- Please explain why this plugin needs support or how we can improve the support for this plugin. validations: required: true - type: textarea attributes: label: Extra Information description: What other information (if any) do you need us to know? ================================================ FILE: .github/ISSUE_TEMPLATE/feature-requests.yml ================================================ name: Feature Request description: Make a suggestion or submit a feature you already coded labels: - Feature Request body: - type: markdown attributes: value: |- Please fill out the following form to the best of your ability. The better you fill this out, the faster we can resolve the problem. - type: dropdown attributes: label: Server Implementation description: >- Which server implementation are you using? If your server implementation is not listed, we do not provide support for it. multiple: false options: - Spigot - Paper - Folia validations: required: true - type: dropdown attributes: label: Server Version description: >- Which server version are you using? If your version is not listed, we do not provide support for it. multiple: false options: - 1.19.4 - 1.20.6 - 1.21 - other validations: required: true - type: textarea attributes: label: CombatLogX Version description: >- Please run the command '/clx version' on your server and post the output here. validations: required: true - type: textarea attributes: label: Feature Request description: What is your request? What do you think we should add to CombatLogX? validations: required: true ================================================ FILE: .github/PULL_REQUEST_TEMPLATE/default.md ================================================ ## Description ### Testing done ### Submitter checklist - [ ] Make sure you are opening from a **topic/feature/bugfix branch** (right side) and not your main branch! - [ ] Please describe what you did - [ ] Link to relevant issues in GitHub. - [ ] Link to relevant pull requests. - [ ] Ensure you have provided tests - that demonstrates feature works or fixes the issue. ================================================ FILE: .github/dependabot.yml ================================================ version: 2 updates: - package-ecosystem: gradle directory: "/" schedule: interval: daily open-pull-requests-limit: 20 ================================================ FILE: .github/funding.yml ================================================ github: - "SirBlobman" custom: - "https://bit.ly/SirBlobmanDonate" ================================================ FILE: .gitignore ================================================ ############################## ## Java ############################## .mtj.tmp/ *.class *.jar *.war *.ear *.nar hs_err_pid* ############################## ## Maven ############################## target/ pom.xml.tag pom.xml.releaseBackup pom.xml.versionsBackup pom.xml.next pom.xml.bak release.properties dependency-reduced-pom.xml buildNumber.properties .mvn/timing.properties .mvn/wrapper/maven-wrapper.jar ############################## ## Gradle ############################## bin/ build/ .gradle .gradletasknamecache gradle-app.setting !gradle-wrapper.jar ############################## ## IntelliJ ############################## out/ .idea/ .idea_modules/ *.iml *.ipr *.iws ############################## ## Eclipse ############################## .settings/ bin/ tmp/ .metadata .classpath .project *.tmp *.bak *.swp *~.nib local.properties .loadpath .factorypath ############################## ## NetBeans ############################## nbproject/private/ build/ nbbuild/ dist/ nbdist/ nbactions.xml nb-configuration.xml ############################## ## Visual Studio Code ############################## .vscode/ .code-workspace ############################## ## OS X ############################## .DS_Store ._* ############################## ## Windows ############################## ~$* *.tmp ================================================ FILE: CODE_OF_CONDUCT.md ================================================ # Contributor Covenant Code of Conduct ## Our Pledge We as members, contributors, and leaders pledge to make participation in our community a harassment-free experience for everyone, regardless of age, body size, visible or invisible disability, ethnicity, sex characteristics, gender identity and expression, level of experience, education, socio-economic status, nationality, personal appearance, race, religion, or sexual identity and orientation. We pledge to act and interact in ways that contribute to an open, welcoming, diverse, inclusive, and healthy community. ## Our Standards Examples of behavior that contributes to a positive environment for our community include: * Demonstrating empathy and kindness toward other people * Being respectful of differing opinions, viewpoints, and experiences * Giving and gracefully accepting constructive feedback * Accepting responsibility and apologizing to those affected by our mistakes, and learning from the experience * Focusing on what is best not just for us as individuals, but for the overall community Examples of unacceptable behavior include: * The use of sexualized language or imagery, and sexual attention or advances of any kind * Trolling, insulting or derogatory comments, and personal or political attacks * Public or private harassment * Publishing others' private information, such as a physical or email address, without their explicit permission * Other conduct which could reasonably be considered inappropriate in a professional setting ## Enforcement Responsibilities Community leaders are responsible for clarifying and enforcing our standards of acceptable behavior and will take appropriate and fair corrective action in response to any behavior that they deem inappropriate, threatening, offensive, or harmful. Community leaders have the right and responsibility to remove, edit, or reject comments, commits, code, wiki edits, issues, and other contributions that are not aligned to this Code of Conduct, and will communicate reasons for moderation decisions when appropriate. ## Scope This Code of Conduct applies within all community spaces, and also applies when an individual is officially representing the community in public spaces. Examples of representing our community include using an official e-mail address, posting via an official social media account, or acting as an appointed representative at an online or offline event. ## Enforcement Instances of abusive, harassing, or otherwise unacceptable behavior may be reported to the community leaders responsible for enforcement at github@sirblobman.xyz. All complaints will be reviewed and investigated promptly and fairly. All community leaders are obligated to respect the privacy and security of the reporter of any incident. ## Enforcement Guidelines Community leaders will follow these Community Impact Guidelines in determining the consequences for any action they deem in violation of this Code of Conduct: ### 1. Correction **Community Impact**: Use of inappropriate language or other behavior deemed unprofessional or unwelcome in the community. **Consequence**: A private, written warning from community leaders, providing clarity around the nature of the violation and an explanation of why the behavior was inappropriate. A public apology may be requested. ### 2. Warning **Community Impact**: A violation through a single incident or series of actions. **Consequence**: A warning with consequences for continued behavior. No interaction with the people involved, including unsolicited interaction with those enforcing the Code of Conduct, for a specified period of time. This includes avoiding interactions in community spaces as well as external channels like social media. Violating these terms may lead to a temporary or permanent ban. ### 3. Temporary Ban **Community Impact**: A serious violation of community standards, including sustained inappropriate behavior. **Consequence**: A temporary ban from any sort of interaction or public communication with the community for a specified period of time. No public or private interaction with the people involved, including unsolicited interaction with those enforcing the Code of Conduct, is allowed during this period. Violating these terms may lead to a permanent ban. ### 4. Permanent Ban **Community Impact**: Demonstrating a pattern of violation of community standards, including sustained inappropriate behavior, harassment of an individual, or aggression toward or disparagement of classes of individuals. **Consequence**: A permanent ban from any sort of public interaction within the community. ## Attribution This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 2.0, available at https://www.contributor-covenant.org/version/2/0/code_of_conduct.html. Community Impact Guidelines were inspired by [Mozilla's code of conduct enforcement ladder](https://github.com/mozilla/diversity). [homepage]: https://www.contributor-covenant.org For answers to common questions about this code of conduct, see the FAQ at https://www.contributor-covenant.org/faq. Translations are available at https://www.contributor-covenant.org/translations. ================================================ FILE: CONTRIBUTING.MD ================================================ # CombatLogX Contribution Guide 1) Try to keep the code style the same. Do not change the import order if possible. 2) If your feature requires a separate plugin, you may want to create an expansion instead. 3) Please give full details for any changes you make. 4) Follow the GitHub rules, project license, and all guidelines. 5) Good Luck and have fun! ================================================ FILE: Jenkinsfile ================================================ pipeline { agent any options { githubProjectProperty(projectUrlStr: "https://github.com/SirBlobman/CombatLogX") } environment { DISCORD_URL = credentials('PUBLIC_DISCORD_WEBHOOK') MAVEN_DEPLOY = credentials('MAVEN_DEPLOY') } triggers { githubPush() } tools { jdk "JDK 25" } stages { stage("Gradle: Build") { steps { withGradle { script { sh("./gradlew --refresh-dependencies --no-daemon clean build") if (env.BRANCH_NAME == "main") { sh("./gradlew publish --no-daemon") } } } } } } post { success { archiveArtifacts artifacts: 'builder/build/distributions/CombatLogX-*.zip', fingerprint: true } always { script { discordSend webhookURL: DISCORD_URL, title: "CombatLogX", link: "${env.BUILD_URL}", result: currentBuild.currentResult, description: """\ **Branch:** ${env.GIT_BRANCH} **Build:** ${env.BUILD_NUMBER} **Status:** ${currentBuild.currentResult}""".stripIndent(), enableArtifactsList: false, showChangeset: true } } } } ================================================ FILE: LICENSE ================================================ GNU GENERAL PUBLIC LICENSE Version 3, 29 June 2007 Copyright (C) 2007 Free Software Foundation, Inc. Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. Preamble The GNU General Public License is a free, copyleft license for software and other kinds of works. The licenses for most software and other practical works are designed to take away your freedom to share and change the works. By contrast, the GNU General Public License is intended to guarantee your freedom to share and change all versions of a program--to make sure it remains free software for all its users. We, the Free Software Foundation, use the GNU General Public License for most of our software; it applies also to any other work released this way by its authors. You can apply it to your programs, too. When we speak of free software, we are referring to freedom, not price. Our General Public Licenses are designed to make sure that you have the freedom to distribute copies of free software (and charge for them if you wish), that you receive source code or can get it if you want it, that you can change the software or use pieces of it in new free programs, and that you know you can do these things. To protect your rights, we need to prevent others from denying you these rights or asking you to surrender the rights. Therefore, you have certain responsibilities if you distribute copies of the software, or if you modify it: responsibilities to respect the freedom of others. For example, if you distribute copies of such a program, whether gratis or for a fee, you must pass on to the recipients the same freedoms that you received. You must make sure that they, too, receive or can get the source code. And you must show them these terms so they know their rights. Developers that use the GNU GPL protect your rights with two steps: (1) assert copyright on the software, and (2) offer you this License giving you legal permission to copy, distribute and/or modify it. For the developers' and authors' protection, the GPL clearly explains that there is no warranty for this free software. For both users' and authors' sake, the GPL requires that modified versions be marked as changed, so that their problems will not be attributed erroneously to authors of previous versions. Some devices are designed to deny users access to install or run modified versions of the software inside them, although the manufacturer can do so. This is fundamentally incompatible with the aim of protecting users' freedom to change the software. The systematic pattern of such abuse occurs in the area of products for individuals to use, which is precisely where it is most unacceptable. Therefore, we have designed this version of the GPL to prohibit the practice for those products. If such problems arise substantially in other domains, we stand ready to extend this provision to those domains in future versions of the GPL, as needed to protect the freedom of users. Finally, every program is threatened constantly by software patents. States should not allow patents to restrict development and use of software on general-purpose computers, but in those that do, we wish to avoid the special danger that patents applied to a free program could make it effectively proprietary. To prevent this, the GPL assures that patents cannot be used to render the program non-free. The precise terms and conditions for copying, distribution and modification follow. TERMS AND CONDITIONS 0. Definitions. "This License" refers to version 3 of the GNU General Public License. "Copyright" also means copyright-like laws that apply to other kinds of works, such as semiconductor masks. "The Program" refers to any copyrightable work licensed under this License. Each licensee is addressed as "you". "Licensees" and "recipients" may be individuals or organizations. To "modify" a work means to copy from or adapt all or part of the work in a fashion requiring copyright permission, other than the making of an exact copy. The resulting work is called a "modified version" of the earlier work or a work "based on" the earlier work. A "covered work" means either the unmodified Program or a work based on the Program. To "propagate" a work means to do anything with it that, without permission, would make you directly or secondarily liable for infringement under applicable copyright law, except executing it on a computer or modifying a private copy. Propagation includes copying, distribution (with or without modification), making available to the public, and in some countries other activities as well. To "convey" a work means any kind of propagation that enables other parties to make or receive copies. Mere interaction with a user through a computer network, with no transfer of a copy, is not conveying. An interactive user interface displays "Appropriate Legal Notices" to the extent that it includes a convenient and prominently visible feature that (1) displays an appropriate copyright notice, and (2) tells the user that there is no warranty for the work (except to the extent that warranties are provided), that licensees may convey the work under this License, and how to view a copy of this License. If the interface presents a list of user commands or options, such as a menu, a prominent item in the list meets this criterion. 1. Source Code. The "source code" for a work means the preferred form of the work for making modifications to it. "Object code" means any non-source form of a work. A "Standard Interface" means an interface that either is an official standard defined by a recognized standards body, or, in the case of interfaces specified for a particular programming language, one that is widely used among developers working in that language. The "System Libraries" of an executable work include anything, other than the work as a whole, that (a) is included in the normal form of packaging a Major Component, but which is not part of that Major Component, and (b) serves only to enable use of the work with that Major Component, or to implement a Standard Interface for which an implementation is available to the public in source code form. A "Major Component", in this context, means a major essential component (kernel, window system, and so on) of the specific operating system (if any) on which the executable work runs, or a compiler used to produce the work, or an object code interpreter used to run it. The "Corresponding Source" for a work in object code form means all the source code needed to generate, install, and (for an executable work) run the object code and to modify the work, including scripts to control those activities. However, it does not include the work's System Libraries, or general-purpose tools or generally available free programs which are used unmodified in performing those activities but which are not part of the work. For example, Corresponding Source includes interface definition files associated with source files for the work, and the source code for shared libraries and dynamically linked subprograms that the work is specifically designed to require, such as by intimate data communication or control flow between those subprograms and other parts of the work. The Corresponding Source need not include anything that users can regenerate automatically from other parts of the Corresponding Source. The Corresponding Source for a work in source code form is that same work. 2. Basic Permissions. All rights granted under this License are granted for the term of copyright on the Program, and are irrevocable provided the stated conditions are met. This License explicitly affirms your unlimited permission to run the unmodified Program. The output from running a covered work is covered by this License only if the output, given its content, constitutes a covered work. This License acknowledges your rights of fair use or other equivalent, as provided by copyright law. You may make, run and propagate covered works that you do not convey, without conditions so long as your license otherwise remains in force. You may convey covered works to others for the sole purpose of having them make modifications exclusively for you, or provide you with facilities for running those works, provided that you comply with the terms of this License in conveying all material for which you do not control copyright. Those thus making or running the covered works for you must do so exclusively on your behalf, under your direction and control, on terms that prohibit them from making any copies of your copyrighted material outside their relationship with you. Conveying under any other circumstances is permitted solely under the conditions stated below. Sublicensing is not allowed; section 10 makes it unnecessary. 3. Protecting Users' Legal Rights From Anti-Circumvention Law. No covered work shall be deemed part of an effective technological measure under any applicable law fulfilling obligations under article 11 of the WIPO copyright treaty adopted on 20 December 1996, or similar laws prohibiting or restricting circumvention of such measures. When you convey a covered work, you waive any legal power to forbid circumvention of technological measures to the extent such circumvention is effected by exercising rights under this License with respect to the covered work, and you disclaim any intention to limit operation or modification of the work as a means of enforcing, against the work's users, your or third parties' legal rights to forbid circumvention of technological measures. 4. Conveying Verbatim Copies. You may convey verbatim copies of the Program's source code as you receive it, in any medium, provided that you conspicuously and appropriately publish on each copy an appropriate copyright notice; keep intact all notices stating that this License and any non-permissive terms added in accord with section 7 apply to the code; keep intact all notices of the absence of any warranty; and give all recipients a copy of this License along with the Program. You may charge any price or no price for each copy that you convey, and you may offer support or warranty protection for a fee. 5. Conveying Modified Source Versions. You may convey a work based on the Program, or the modifications to produce it from the Program, in the form of source code under the terms of section 4, provided that you also meet all of these conditions: a) The work must carry prominent notices stating that you modified it, and giving a relevant date. b) The work must carry prominent notices stating that it is released under this License and any conditions added under section 7. This requirement modifies the requirement in section 4 to "keep intact all notices". c) You must license the entire work, as a whole, under this License to anyone who comes into possession of a copy. This License will therefore apply, along with any applicable section 7 additional terms, to the whole of the work, and all its parts, regardless of how they are packaged. This License gives no permission to license the work in any other way, but it does not invalidate such permission if you have separately received it. d) If the work has interactive user interfaces, each must display Appropriate Legal Notices; however, if the Program has interactive interfaces that do not display Appropriate Legal Notices, your work need not make them do so. A compilation of a covered work with other separate and independent works, which are not by their nature extensions of the covered work, and which are not combined with it such as to form a larger program, in or on a volume of a storage or distribution medium, is called an "aggregate" if the compilation and its resulting copyright are not used to limit the access or legal rights of the compilation's users beyond what the individual works permit. Inclusion of a covered work in an aggregate does not cause this License to apply to the other parts of the aggregate. 6. Conveying Non-Source Forms. You may convey a covered work in object code form under the terms of sections 4 and 5, provided that you also convey the machine-readable Corresponding Source under the terms of this License, in one of these ways: a) Convey the object code in, or embodied in, a physical product (including a physical distribution medium), accompanied by the Corresponding Source fixed on a durable physical medium customarily used for software interchange. b) Convey the object code in, or embodied in, a physical product (including a physical distribution medium), accompanied by a written offer, valid for at least three years and valid for as long as you offer spare parts or customer support for that product model, to give anyone who possesses the object code either (1) a copy of the Corresponding Source for all the software in the product that is covered by this License, on a durable physical medium customarily used for software interchange, for a price no more than your reasonable cost of physically performing this conveying of source, or (2) access to copy the Corresponding Source from a network server at no charge. c) Convey individual copies of the object code with a copy of the written offer to provide the Corresponding Source. This alternative is allowed only occasionally and noncommercially, and only if you received the object code with such an offer, in accord with subsection 6b. d) Convey the object code by offering access from a designated place (gratis or for a charge), and offer equivalent access to the Corresponding Source in the same way through the same place at no further charge. You need not require recipients to copy the Corresponding Source along with the object code. If the place to copy the object code is a network server, the Corresponding Source may be on a different server (operated by you or a third party) that supports equivalent copying facilities, provided you maintain clear directions next to the object code saying where to find the Corresponding Source. Regardless of what server hosts the Corresponding Source, you remain obligated to ensure that it is available for as long as needed to satisfy these requirements. e) Convey the object code using peer-to-peer transmission, provided you inform other peers where the object code and Corresponding Source of the work are being offered to the general public at no charge under subsection 6d. A separable portion of the object code, whose source code is excluded from the Corresponding Source as a System Library, need not be included in conveying the object code work. A "User Product" is either (1) a "consumer product", which means any tangible personal property which is normally used for personal, family, or household purposes, or (2) anything designed or sold for incorporation into a dwelling. In determining whether a product is a consumer product, doubtful cases shall be resolved in favor of coverage. For a particular product received by a particular user, "normally used" refers to a typical or common use of that class of product, regardless of the status of the particular user or of the way in which the particular user actually uses, or expects or is expected to use, the product. A product is a consumer product regardless of whether the product has substantial commercial, industrial or non-consumer uses, unless such uses represent the only significant mode of use of the product. "Installation Information" for a User Product means any methods, procedures, authorization keys, or other information required to install and execute modified versions of a covered work in that User Product from a modified version of its Corresponding Source. The information must suffice to ensure that the continued functioning of the modified object code is in no case prevented or interfered with solely because modification has been made. If you convey an object code work under this section in, or with, or specifically for use in, a User Product, and the conveying occurs as part of a transaction in which the right of possession and use of the User Product is transferred to the recipient in perpetuity or for a fixed term (regardless of how the transaction is characterized), the Corresponding Source conveyed under this section must be accompanied by the Installation Information. But this requirement does not apply if neither you nor any third party retains the ability to install modified object code on the User Product (for example, the work has been installed in ROM). The requirement to provide Installation Information does not include a requirement to continue to provide support service, warranty, or updates for a work that has been modified or installed by the recipient, or for the User Product in which it has been modified or installed. Access to a network may be denied when the modification itself materially and adversely affects the operation of the network or violates the rules and protocols for communication across the network. Corresponding Source conveyed, and Installation Information provided, in accord with this section must be in a format that is publicly documented (and with an implementation available to the public in source code form), and must require no special password or key for unpacking, reading or copying. 7. Additional Terms. "Additional permissions" are terms that supplement the terms of this License by making exceptions from one or more of its conditions. Additional permissions that are applicable to the entire Program shall be treated as though they were included in this License, to the extent that they are valid under applicable law. If additional permissions apply only to part of the Program, that part may be used separately under those permissions, but the entire Program remains governed by this License without regard to the additional permissions. When you convey a copy of a covered work, you may at your option remove any additional permissions from that copy, or from any part of it. (Additional permissions may be written to require their own removal in certain cases when you modify the work.) You may place additional permissions on material, added by you to a covered work, for which you have or can give appropriate copyright permission. Notwithstanding any other provision of this License, for material you add to a covered work, you may (if authorized by the copyright holders of that material) supplement the terms of this License with terms: a) Disclaiming warranty or limiting liability differently from the terms of sections 15 and 16 of this License; or b) Requiring preservation of specified reasonable legal notices or author attributions in that material or in the Appropriate Legal Notices displayed by works containing it; or c) Prohibiting misrepresentation of the origin of that material, or requiring that modified versions of such material be marked in reasonable ways as different from the original version; or d) Limiting the use for publicity purposes of names of licensors or authors of the material; or e) Declining to grant rights under trademark law for use of some trade names, trademarks, or service marks; or f) Requiring indemnification of licensors and authors of that material by anyone who conveys the material (or modified versions of it) with contractual assumptions of liability to the recipient, for any liability that these contractual assumptions directly impose on those licensors and authors. All other non-permissive additional terms are considered "further restrictions" within the meaning of section 10. If the Program as you received it, or any part of it, contains a notice stating that it is governed by this License along with a term that is a further restriction, you may remove that term. If a license document contains a further restriction but permits relicensing or conveying under this License, you may add to a covered work material governed by the terms of that license document, provided that the further restriction does not survive such relicensing or conveying. If you add terms to a covered work in accord with this section, you must place, in the relevant source files, a statement of the additional terms that apply to those files, or a notice indicating where to find the applicable terms. Additional terms, permissive or non-permissive, may be stated in the form of a separately written license, or stated as exceptions; the above requirements apply either way. 8. Termination. You may not propagate or modify a covered work except as expressly provided under this License. Any attempt otherwise to propagate or modify it is void, and will automatically terminate your rights under this License (including any patent licenses granted under the third paragraph of section 11). However, if you cease all violation of this License, then your license from a particular copyright holder is reinstated (a) provisionally, unless and until the copyright holder explicitly and finally terminates your license, and (b) permanently, if the copyright holder fails to notify you of the violation by some reasonable means prior to 60 days after the cessation. Moreover, your license from a particular copyright holder is reinstated permanently if the copyright holder notifies you of the violation by some reasonable means, this is the first time you have received notice of violation of this License (for any work) from that copyright holder, and you cure the violation prior to 30 days after your receipt of the notice. Termination of your rights under this section does not terminate the licenses of parties who have received copies or rights from you under this License. If your rights have been terminated and not permanently reinstated, you do not qualify to receive new licenses for the same material under section 10. 9. Acceptance Not Required for Having Copies. You are not required to accept this License in order to receive or run a copy of the Program. Ancillary propagation of a covered work occurring solely as a consequence of using peer-to-peer transmission to receive a copy likewise does not require acceptance. However, nothing other than this License grants you permission to propagate or modify any covered work. These actions infringe copyright if you do not accept this License. Therefore, by modifying or propagating a covered work, you indicate your acceptance of this License to do so. 10. Automatic Licensing of Downstream Recipients. Each time you convey a covered work, the recipient automatically receives a license from the original licensors, to run, modify and propagate that work, subject to this License. You are not responsible for enforcing compliance by third parties with this License. An "entity transaction" is a transaction transferring control of an organization, or substantially all assets of one, or subdividing an organization, or merging organizations. If propagation of a covered work results from an entity transaction, each party to that transaction who receives a copy of the work also receives whatever licenses to the work the party's predecessor in interest had or could give under the previous paragraph, plus a right to possession of the Corresponding Source of the work from the predecessor in interest, if the predecessor has it or can get it with reasonable efforts. You may not impose any further restrictions on the exercise of the rights granted or affirmed under this License. For example, you may not impose a license fee, royalty, or other charge for exercise of rights granted under this License, and you may not initiate litigation (including a cross-claim or counterclaim in a lawsuit) alleging that any patent claim is infringed by making, using, selling, offering for sale, or importing the Program or any portion of it. 11. Patents. A "contributor" is a copyright holder who authorizes use under this License of the Program or a work on which the Program is based. The work thus licensed is called the contributor's "contributor version". A contributor's "essential patent claims" are all patent claims owned or controlled by the contributor, whether already acquired or hereafter acquired, that would be infringed by some manner, permitted by this License, of making, using, or selling its contributor version, but do not include claims that would be infringed only as a consequence of further modification of the contributor version. For purposes of this definition, "control" includes the right to grant patent sublicenses in a manner consistent with the requirements of this License. Each contributor grants you a non-exclusive, worldwide, royalty-free patent license under the contributor's essential patent claims, to make, use, sell, offer for sale, import and otherwise run, modify and propagate the contents of its contributor version. In the following three paragraphs, a "patent license" is any express agreement or commitment, however denominated, not to enforce a patent (such as an express permission to practice a patent or covenant not to sue for patent infringement). To "grant" such a patent license to a party means to make such an agreement or commitment not to enforce a patent against the party. If you convey a covered work, knowingly relying on a patent license, and the Corresponding Source of the work is not available for anyone to copy, free of charge and under the terms of this License, through a publicly available network server or other readily accessible means, then you must either (1) cause the Corresponding Source to be so available, or (2) arrange to deprive yourself of the benefit of the patent license for this particular work, or (3) arrange, in a manner consistent with the requirements of this License, to extend the patent license to downstream recipients. "Knowingly relying" means you have actual knowledge that, but for the patent license, your conveying the covered work in a country, or your recipient's use of the covered work in a country, would infringe one or more identifiable patents in that country that you have reason to believe are valid. If, pursuant to or in connection with a single transaction or arrangement, you convey, or propagate by procuring conveyance of, a covered work, and grant a patent license to some of the parties receiving the covered work authorizing them to use, propagate, modify or convey a specific copy of the covered work, then the patent license you grant is automatically extended to all recipients of the covered work and works based on it. A patent license is "discriminatory" if it does not include within the scope of its coverage, prohibits the exercise of, or is conditioned on the non-exercise of one or more of the rights that are specifically granted under this License. You may not convey a covered work if you are a party to an arrangement with a third party that is in the business of distributing software, under which you make payment to the third party based on the extent of your activity of conveying the work, and under which the third party grants, to any of the parties who would receive the covered work from you, a discriminatory patent license (a) in connection with copies of the covered work conveyed by you (or copies made from those copies), or (b) primarily for and in connection with specific products or compilations that contain the covered work, unless you entered into that arrangement, or that patent license was granted, prior to 28 March 2007. Nothing in this License shall be construed as excluding or limiting any implied license or other defenses to infringement that may otherwise be available to you under applicable patent law. 12. No Surrender of Others' Freedom. If conditions are imposed on you (whether by court order, agreement or otherwise) that contradict the conditions of this License, they do not excuse you from the conditions of this License. If you cannot convey a covered work so as to satisfy simultaneously your obligations under this License and any other pertinent obligations, then as a consequence you may not convey it at all. For example, if you agree to terms that obligate you to collect a royalty for further conveying from those to whom you convey the Program, the only way you could satisfy both those terms and this License would be to refrain entirely from conveying the Program. 13. Use with the GNU Affero General Public License. Notwithstanding any other provision of this License, you have permission to link or combine any covered work with a work licensed under version 3 of the GNU Affero General Public License into a single combined work, and to convey the resulting work. The terms of this License will continue to apply to the part which is the covered work, but the special requirements of the GNU Affero General Public License, section 13, concerning interaction through a network will apply to the combination as such. 14. Revised Versions of this License. The Free Software Foundation may publish revised and/or new versions of the GNU General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns. Each version is given a distinguishing version number. If the Program specifies that a certain numbered version of the GNU General Public License "or any later version" applies to it, you have the option of following the terms and conditions either of that numbered version or of any later version published by the Free Software Foundation. If the Program does not specify a version number of the GNU General Public License, you may choose any version ever published by the Free Software Foundation. If the Program specifies that a proxy can decide which future versions of the GNU General Public License can be used, that proxy's public statement of acceptance of a version permanently authorizes you to choose that version for the Program. Later license versions may give you additional or different permissions. However, no additional obligations are imposed on any author or copyright holder as a result of your choosing to follow a later version. 15. Disclaimer of Warranty. THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. 16. Limitation of Liability. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. 17. Interpretation of Sections 15 and 16. If the disclaimer of warranty and limitation of liability provided above cannot be given local legal effect according to their terms, reviewing courts shall apply local law that most closely approximates an absolute waiver of all civil liability in connection with the Program, unless a warranty or assumption of liability accompanies a copy of the Program in return for a fee. END OF TERMS AND CONDITIONS How to Apply These Terms to Your New Programs If you develop a new program, and you want it to be of the greatest possible use to the public, the best way to achieve this is to make it free software which everyone can redistribute and change under these terms. To do so, attach the following notices to the program. It is safest to attach them to the start of each source file to most effectively state the exclusion of warranty; and each file should have at least the "copyright" line and a pointer to where the full notice is found. Copyright (C) This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . Also add information on how to contact you by electronic and paper mail. If the program does terminal interaction, make it output a short notice like this when it starts in an interactive mode: Copyright (C) This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'. This is free software, and you are welcome to redistribute it under certain conditions; type `show c' for details. The hypothetical commands `show w' and `show c' should show the appropriate parts of the General Public License. Of course, your program's commands might be different; for a GUI interface, you would use an "about box". You should also get your employer (if you work as a programmer) or school, if any, to sign a "copyright disclaimer" for the program, if necessary. For more information on this, and how to apply and follow the GNU GPL, see . The GNU General Public License does not permit incorporating your program into proprietary programs. If your program is a subroutine library, you may consider it more useful to permit linking proprietary applications with the library. If this is what you want to do, use the GNU Lesser General Public License instead of this License. But first, please read . ================================================ FILE: README.MD ================================================ # CombatLogX [![Code Size](https://img.shields.io/github/languages/code-size/SirBlobman/CombatLogX)](https://github.com/SirBlobman/CombatLogX/) [![Build Status](https://jenkins.sirblobman.xyz/job/SirBlobman/job/CombatLogX/job/main/badge/icon)](https://jenkins.sirblobman.xyz/job/SirBlobman/job/CombatLogX/) [![Crowdin Localization](https://badges.crowdin.net/combatlogx-spigot-plugin/localized.svg)](https://crowdin.com/project/combatlogx-spigot-plugin) ## Description CombatLogX is a plugin made for the Spigot server software. It has many combat-related features to add to your server. One of the main features of this plugin are the Expansions, which are like modules that allow you to add different things and change how the plugin works. ## Requirements - Java 25 - [Spigot](https://spigotmc.org/), [Paper](https://papermc.io/download/paper), or [Folia](https://papermc.io/software/folia) 1.19.4-26.1.2 - [BlueSlimeCore](https://hangar.papermc.io/SirBlobman/BlueSlimeCore) 2.9.9 or higher. ## Main Features - Custom expansions that change how the plugin works - Tag players when they attack other players - Punish players that log out during combat ## Installation Guide 1. Download the CombatLogX.zip file from Jenkins or SpigotMC. 2. Extract the contents of the CombatLogX.zip to your PC. 3. Click the stop button on the panel. If your server doesn't use a panel, type `stop` into the console. 4. Upload `CombatLogX.jar` and `BlueSlimeCore.jar` to your server `/plugins/` folder. 5. Upload the contents of `CombatLogX/expansions` to your server `/plugins/CombatLogX/expansions` folder. 6. If the files were uploaded and extracted correctly, your server should have the following files: - File: /plugins/CombatLogX.jar - File /plugins/BlueSlimeCore.jar - Folder: /plugins/CombatLogX/ - Folder: /plugins/CombatLogX/expansions/ - Multiple Files: /plugins/CombatLogX/expansions/*.jar 7. Delete the `CombatLogX.zip` file. 8. Restart your server using the panel or your startup script. 9. Edit the configuration files for the main plugin, languages, and expansions. 10. Type the command `/clx reload` to reload the configuration files. 11. If you want to remove an expansion, delete the jar file from `/plugins/CombatLogX/expansions`. ## Downloads - [SpigotMC](https://www.spigotmc.org/resources/31689/) - [Jenkins Beta Builds](https://jenkins.sirblobman.xyz/job/SirBlobman/job/CombatLogX/job/main/) ## Expansions If you want to find out more about the expansions, please visit this page: [CombatLogX Documentation](https://www.spigotmc.org/resources/combatlogx.31689/field?field=documentation) You can also open the README files in each expansion folder. ## Developer API If you want to create expansions or learn how to use the CombatLogX API for V11/Beta, please visit this page: [API README](api/README.MD) ## Sponsors The people or organizations listed below were kind enough to fund my open-source projects! - Privately sponsored by [Alien Host](https://alienhost.net). - Sponsored on GitHub by [feather64.net](https://feather64.net) owned by Derek Larson. ## Localization A community translation project for CombatLogX is open. If you want to help with translations, please visit our Crowdin page. ### Localization Credits You can view a list of contributions made to CombatLogX on our Crowdin page. ## Support Support is provided by creating a new issue, or by chatting with the Support Team on my discord. **Discord Link:** ================================================ FILE: SECURITY.md ================================================ # Security Policy ## Supported Versions | Version | Supported | |-------------------|--------------------| | 11.6-SNAPSHOT | :white_check_mark: | | 11.5-SNAPSHOT | :x: | | 11.4-SNAPSHOT | :x: | | 11.3-SNAPSHOT | :x: | | 11.2-SNAPSHOT | :x: | | 11.0.0.0-SNAPSHOT | :x: | | < 11.0 | :x: | ## Expansions You must update all expansions when updating CombatLogX ## Reporting a Vulnerability Please report any security vulnerabilities to my [e-mail](mailto:combatlogx@sirblobman.xyz) ================================================ FILE: api/README.MD ================================================ # CombatLogX API This is the API module for CombatLogX. You can use it to create new expansions or to check stuff with your own plugin. ## Maven Repository A lot of developers use maven to build projects more easily. **Repository: SirBlobman Public** Maven: ```xml sirblobman-public https://nexus.sirblobman.xyz/public/ ``` Gradle Groovy: ```groovy repositories { maven { name = 'sirblobman-public' url = 'https://nexus.sirblobman.xyz/public/' } } ``` Gradle Kotlin: ```kotlin repositories { maven("https://nexus.sirblobman.xyz/public/") } ``` **Dependency: CombatLogX API** Maven: ```xml com.github.sirblobman.api core 2.9-SNAPSHOT provided com.github.sirblobman.combatlogx api 11.6-SNAPSHOT provided ``` Gradle Groovy: ```groovy dependencies { compileOnly 'com.github.sirblobman.api:core:2.9-SNAPSHOT' compileOnly 'com.github.sirblobman.combatlogx:api:11.6-SNAPSHOT' } ``` Gradle Kotlin: ```kotlin dependencies { compileOnly("com.github.sirblobman.api:core:2.9-SNAPSHOT") compileOnly("com.github.sirblobman.combatlogx:api:11.6-SNAPSHOT") } ``` ## Events A list of events and their uses can be found in the `com.github.sirblobman.combatlogx.api.event` package. You can see more information about them below: - **PlayerPreTagEvent:** Triggered before a player gets tagged. (cancellable) - **PlayerTagEvent:** Triggered when a player gets tagged into combat (not cancellable). - **PlayerReTagEvent:** Triggered when a player already has a timer, but they are tagged again. (cancellable) - **PlayerUntagEvent:** Triggered when a player gets out of combat. - **PlayerPunishEvent:** Triggered when a player is going to be punished for logging out (cancellable). ## Other API Uses CombatLogX has many uses, but some common examples are provided below. Good luck with your coding! **Example 01: Check if CombatLogX is enabled and get an instance of it.** ```java public boolean isEnabled() { PluginManager pluginManager = Bukkit.getPluginManager(); return pluginManager.isPluginEnabled("CombatLogX"); } public ICombatLogX getAPI() { PluginManager pluginManager = Bukkit.getPluginManager(); Plugin plugin = pluginManager.getPlugin("CombatLogX"); return (ICombatLogX) plugin; } ``` **Example 02: Check if a player is in combat.** ```java public boolean isInCombat(Player player) { ICombatLogX plugin = getAPI(); ICombatManager combatManager = plugin.getCombatManager(); return combatManager.isInCombat(player); } ``` **Example 03: Check if a player was killed by CombatLogX.** ```java @EventHandler(priority = EventPriority.NORMAL, ignoreCancelled = true) public void onDeath(PlayerDeathEvent e) { Player player = e.getEntity(); ICombatLogX plugin = getAPI(); IDeathManager deathManager = plugin.getDeathManager(); if(deathManager.wasPunishKilled(player)) { // Player was killed by CombatLogX e.setDeathMessage(player.getName() + " was killed for logging out during combat."); } } ``` ================================================ FILE: api/build.gradle.kts ================================================ fun getEnvOrProp(variableName: String, propertyName: String): String { val environmentProvider = providers.environmentVariable(variableName) val propertyProvider = providers.gradleProperty(propertyName) return environmentProvider.orElse(propertyProvider).orElse("").get() } fun getProp(propertyName: String): String { val propertyProvider = providers.gradleProperty(propertyName) return propertyProvider.get() } plugins { id("maven-publish") } java { withSourcesJar() withJavadocJar() } repositories { maven("https://repo.helpch.at/releases/") } dependencies { compileOnly("me.clip:placeholderapi:2.11.6") } publishing { repositories { maven("https://nexus.sirblobman.xyz/public") { credentials { username = getEnvOrProp("MAVEN_DEPLOY_USR", "maven.username.sirblobman") password = getEnvOrProp("MAVEN_DEPLOY_PSW", "maven.password.sirblobman") } } } publications { create("maven") { groupId = "com.github.sirblobman.combatlogx" artifactId = "api" version = getProp("version.api") from(components["java"]) } } } tasks.withType { val standardOptions = (options as StandardJavadocDocletOptions) standardOptions.addStringOption("Xdoclint:none", "-quiet") } ================================================ FILE: api/gradle.properties ================================================ version.spigot=1.11.2-R0.1-SNAPSHOT ================================================ FILE: api/src/main/java/com/github/sirblobman/combatlogx/api/ICombatLogX.java ================================================ package com.github.sirblobman.combatlogx.api; import org.jetbrains.annotations.NotNull; import com.github.sirblobman.api.configuration.IResourceHolder; import com.github.sirblobman.api.configuration.PlayerDataManager; import com.github.sirblobman.api.language.LanguageManager; import com.github.sirblobman.api.plugin.ConfigurablePlugin; import com.github.sirblobman.api.plugin.IMultiVersionPlugin; import com.github.sirblobman.combatlogx.api.configuration.CommandConfiguration; import com.github.sirblobman.combatlogx.api.configuration.MainConfiguration; import com.github.sirblobman.combatlogx.api.configuration.PunishConfiguration; import com.github.sirblobman.combatlogx.api.expansion.ExpansionManager; import com.github.sirblobman.combatlogx.api.manager.ICombatManager; import com.github.sirblobman.combatlogx.api.manager.ICrystalManager; import com.github.sirblobman.combatlogx.api.manager.IDeathManager; import com.github.sirblobman.combatlogx.api.manager.IForgiveManager; import com.github.sirblobman.combatlogx.api.manager.IPlaceholderManager; import com.github.sirblobman.combatlogx.api.manager.IPunishManager; import com.github.sirblobman.combatlogx.api.manager.ITimerManager; public interface ICombatLogX extends IResourceHolder, IMultiVersionPlugin { /** * @return The JavaPlugin instance for this object. */ @NotNull ConfigurablePlugin getPlugin(); /** * Called when the configuration files should be reloaded. */ void onReload(); /** * @return The player data file manager for this plugin. */ @NotNull PlayerDataManager getPlayerDataManager(); /** * @return The language configuration manager for this plugin. */ @NotNull LanguageManager getLanguageManager(); /** * @return The expansion manager for this plugin. */ @NotNull ExpansionManager getExpansionManager(); /** * @return The combat manager for this plugin. */ @NotNull ICombatManager getCombatManager(); /** * @return The timer and notification manager for this plugin. */ @NotNull ITimerManager getTimerManager(); /** * @return The punishment manager for this plugin. */ @NotNull IPunishManager getPunishManager(); /** * @return The death manager for this plugin. */ @NotNull IDeathManager getDeathManager(); /** * @return The placeholder hook manager for this plugin. */ @NotNull IPlaceholderManager getPlaceholderManager(); /** * @return The combat forgiveness manager for this plugin. */ @NotNull IForgiveManager getForgiveManager(); /** * @return {@code true} if the debug mode feature is disabled, otherwise {@code false}. */ boolean isDebugModeDisabled(); /** * Print some messages to the server logs. * If debug-mode is not enabled, the messages should not be sent. * * @param messageArray An array of messages to print * @see #isDebugModeDisabled() */ void printDebug(String @NotNull ... messageArray); /** * Print a thrown exception to the server logs. * If debug-mode is not enabled, the error should not be sent. * * @param ex The error that was thrown. * @see #printDebug(String...) * @see #isDebugModeDisabled() */ void printDebug(@NotNull Throwable ex); /** * @return The configuration reader for 'config.yml'. */ @NotNull MainConfiguration getConfiguration(); /** * @return The configuration reader for 'commands.yml' */ @NotNull CommandConfiguration getCommandConfiguration(); /** * @return The configuration reader for 'punish.yml' */ @NotNull PunishConfiguration getPunishConfiguration(); @NotNull ICrystalManager getCrystalManager(); } ================================================ FILE: api/src/main/java/com/github/sirblobman/combatlogx/api/ICombatLogXNeeded.java ================================================ package com.github.sirblobman.combatlogx.api; import java.util.logging.Logger; import org.jetbrains.annotations.NotNull; public interface ICombatLogXNeeded { @NotNull ICombatLogX getCombatLogX(); default @NotNull Logger getLogger() { ICombatLogX combatLogX = getCombatLogX(); return combatLogX.getLogger(); } } ================================================ FILE: api/src/main/java/com/github/sirblobman/combatlogx/api/command/CombatLogCommand.java ================================================ package com.github.sirblobman.combatlogx.api.command; import java.util.Collections; import java.util.List; import org.jetbrains.annotations.NotNull; import org.bukkit.World; import org.bukkit.command.CommandSender; import com.github.sirblobman.api.command.Command; import com.github.sirblobman.api.language.LanguageManager; import com.github.sirblobman.combatlogx.api.ICombatLogX; import com.github.sirblobman.combatlogx.api.configuration.MainConfiguration; import com.github.sirblobman.combatlogx.api.expansion.ExpansionManager; public abstract class CombatLogCommand extends Command { private final ICombatLogX plugin; public CombatLogCommand(@NotNull ICombatLogX plugin, @NotNull String commandName) { super(plugin.getPlugin(), commandName); this.plugin = plugin; } protected final @NotNull ICombatLogX getCombatLogX() { return this.plugin; } @Override protected final @NotNull LanguageManager getLanguageManager() { ICombatLogX plugin = getCombatLogX(); return plugin.getLanguageManager(); } @Override protected @NotNull List onTabComplete(@NotNull CommandSender sender, String @NotNull [] args) { return Collections.emptyList(); } @Override protected boolean execute(@NotNull CommandSender sender, String @NotNull [] args) { return false; } protected final @NotNull ExpansionManager getExpansionManager() { ICombatLogX plugin = getCombatLogX(); return plugin.getExpansionManager(); } protected final boolean isWorldDisabled(World world) { ICombatLogX plugin = getCombatLogX(); MainConfiguration configuration = plugin.getConfiguration(); return configuration.isDisabled(world); } } ================================================ FILE: api/src/main/java/com/github/sirblobman/combatlogx/api/command/CombatLogPlayerCommand.java ================================================ package com.github.sirblobman.combatlogx.api.command; import java.util.Collections; import java.util.List; import org.jetbrains.annotations.NotNull; import org.bukkit.World; import org.bukkit.entity.Player; import com.github.sirblobman.api.command.PlayerCommand; import com.github.sirblobman.api.language.LanguageManager; import com.github.sirblobman.combatlogx.api.ICombatLogX; import com.github.sirblobman.combatlogx.api.configuration.MainConfiguration; import com.github.sirblobman.combatlogx.api.expansion.ExpansionManager; public abstract class CombatLogPlayerCommand extends PlayerCommand { private final ICombatLogX plugin; public CombatLogPlayerCommand(ICombatLogX plugin, String commandName) { super(plugin.getPlugin(), commandName); this.plugin = plugin; } protected final @NotNull ICombatLogX getCombatLogX() { return this.plugin; } @Override protected final @NotNull LanguageManager getLanguageManager() { ICombatLogX plugin = getCombatLogX(); return plugin.getLanguageManager(); } @Override protected @NotNull List onTabComplete(@NotNull Player player, String @NotNull [] args) { return Collections.emptyList(); } @Override protected boolean execute(@NotNull Player player, String @NotNull [] args) { return false; } protected final @NotNull ExpansionManager getExpansionManager() { ICombatLogX plugin = getCombatLogX(); return plugin.getExpansionManager(); } protected final boolean isWorldDisabled(World world) { ICombatLogX plugin = getCombatLogX(); MainConfiguration configuration = plugin.getConfiguration(); return configuration.isDisabled(world); } } ================================================ FILE: api/src/main/java/com/github/sirblobman/combatlogx/api/configuration/CommandConfiguration.java ================================================ package com.github.sirblobman.combatlogx.api.configuration; import java.util.ArrayList; import java.util.Collection; import java.util.Collections; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.Set; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import org.bukkit.configuration.ConfigurationSection; import com.github.sirblobman.api.configuration.IConfigurable; import com.github.sirblobman.combatlogx.api.object.SpecialPunishCommand; public final class CommandConfiguration implements IConfigurable { private final List tagCommandList; private final List untagCommandList; private final List punishCommandList; private final Map specialPunishCommandMap; private boolean specialPunishCommandsEnabled; public CommandConfiguration() { this.tagCommandList = new ArrayList<>(); this.untagCommandList = new ArrayList<>(); this.punishCommandList = new ArrayList<>(); this.specialPunishCommandsEnabled = false; this.specialPunishCommandMap = new HashMap<>(); } @Override public void load(ConfigurationSection config) { setTagCommands(config.getStringList("tag-command-list")); setUntagCommands(config.getStringList("untag-command-list")); setPunishCommands(config.getStringList("punish-command-list")); setSpecialPunishCommandsEnabled(config.getBoolean("special-punish-commands-enabled")); removeSpecialPunishCommands(); ConfigurationSection sectionSpecials = getOrCreateSection(config, "special-punish-commands"); Set specialIdSet = sectionSpecials.getKeys(false); for (String specialId : specialIdSet) { ConfigurationSection section = sectionSpecials.getConfigurationSection(specialId); if (section == null) { continue; } SpecialPunishCommand command = new SpecialPunishCommand(specialId); command.load(section); addSpecialPunishCommand(command); } } public @NotNull List getTagCommands() { return Collections.unmodifiableList(this.tagCommandList); } public void setTagCommands(@NotNull Collection commands) { this.tagCommandList.clear(); this.tagCommandList.addAll(commands); } public @NotNull List getUntagCommands() { return Collections.unmodifiableList(this.untagCommandList); } public void setUntagCommands(@NotNull Collection commands) { this.untagCommandList.clear(); this.untagCommandList.addAll(commands); } public @NotNull List getPunishCommands() { return Collections.unmodifiableList(this.punishCommandList); } public void setPunishCommands(@NotNull Collection commands) { this.punishCommandList.clear(); this.punishCommandList.addAll(commands); } public @NotNull Map getSpecialPunishCommands() { return Collections.unmodifiableMap(this.specialPunishCommandMap); } public @NotNull List getSpecialPunishCommandList() { Collection valueCollection = this.specialPunishCommandMap.values(); return Collections.unmodifiableList(new ArrayList<>(valueCollection)); } public @Nullable SpecialPunishCommand getSpecialPunishCommand(String id) { return this.specialPunishCommandMap.get(id); } public void addSpecialPunishCommand(SpecialPunishCommand command) { String id = command.getId(); this.specialPunishCommandMap.put(id, command); } public void removeSpecialPunishCommands() { this.specialPunishCommandMap.clear(); } public boolean isSpecialPunishCommandsEnabled() { return specialPunishCommandsEnabled; } public void setSpecialPunishCommandsEnabled(boolean specialPunishCommandsEnabled) { this.specialPunishCommandsEnabled = specialPunishCommandsEnabled; } } ================================================ FILE: api/src/main/java/com/github/sirblobman/combatlogx/api/configuration/MainConfiguration.java ================================================ package com.github.sirblobman.combatlogx.api.configuration; import java.util.Collection; import java.util.Collections; import java.util.EnumSet; import java.util.HashSet; import java.util.List; import java.util.Set; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import org.bukkit.World; import org.bukkit.configuration.ConfigurationSection; import org.bukkit.entity.EntityType; import org.bukkit.permissions.Permission; import org.bukkit.permissions.PermissionDefault; import com.github.sirblobman.api.configuration.IConfigurable; import com.github.sirblobman.combatlogx.api.ICombatLogX; import com.github.sirblobman.combatlogx.api.object.TagReason; import com.github.sirblobman.combatlogx.api.object.TimerType; import static com.github.sirblobman.api.utility.ConfigurationHelper.parseEnum; import static com.github.sirblobman.api.utility.ConfigurationHelper.parseEnums; public final class MainConfiguration implements IConfigurable { private final ICombatLogX plugin; private final Set worldSet; private final Set ignoredProjectileSet; private String generatedByVersion; private boolean debugMode; private boolean broadcastOnLoad; private boolean broadcastOnEnable; private boolean broadcastOnDisable; private boolean worldListInverted; private boolean linkPets; private boolean linkProjectiles; private boolean linkFishingRod; private boolean linkTnt; private boolean linkEndCrystals; private TimerType timerType; private int defaultTimer; private String bypassPermissionName; private transient Permission bypassPermission; private boolean selfCombat; private boolean untagOnSelfDeath; private boolean untagOnEnemyDeath; private boolean removeNoDamageCooldown; private int forgiveRequestCooldown; private int forgiveRequestExpire; private double minimumTps; private Set enabledTagReasons; public MainConfiguration(@NotNull ICombatLogX plugin) { this.plugin = plugin; this.generatedByVersion = plugin.getPlugin().getDescription().getVersion(); this.debugMode = false; this.broadcastOnLoad = true; this.broadcastOnEnable = true; this.broadcastOnDisable = true; this.worldSet = new HashSet<>(); this.worldListInverted = false; this.linkPets = true; this.linkProjectiles = true; this.linkFishingRod = true; this.linkTnt = true; this.linkEndCrystals = true; this.ignoredProjectileSet = EnumSet.noneOf(EntityType.class); this.timerType = TimerType.GLOBAL; this.defaultTimer = 10; this.bypassPermissionName = null; this.bypassPermission = null; this.selfCombat = false; this.untagOnSelfDeath = true; this.untagOnEnemyDeath = true; this.removeNoDamageCooldown = true; this.forgiveRequestCooldown = 30; this.forgiveRequestExpire = 10; this.minimumTps = 15.0D; this.enabledTagReasons = EnumSet.allOf(TagReason.class); } @Override public void load(ConfigurationSection config) { String pluginVersion = this.plugin.getPlugin().getDescription().getVersion(); setGeneratedByVersion(config.getString("generated-by-version", pluginVersion)); setDebugMode(config.getBoolean("debug-mode", false)); ConfigurationSection broadcastSection = getOrCreateSection(config, "broadcast"); setBroadcastOnLoad(broadcastSection.getBoolean("on-load", true)); setBroadcastOnEnable(broadcastSection.getBoolean("on-enable", true)); setBroadcastOnDisable(broadcastSection.getBoolean("on-disable", true)); List worldNameList = config.getStringList("disabled-world-list"); setWorlds(worldNameList); setWorldListInverted(config.getBoolean("disabled-world-list-inverted")); setLinkPets(config.getBoolean("link-pets", true)); setLinkProjectiles(config.getBoolean("link-projectiles", true)); setLinkFishingRod(config.getBoolean("link-fishing-rod", true)); setLinkTnt(config.getBoolean("link-tnt", true)); setLinkEndCrystals(config.getBoolean("link-end-crystal", true)); List projectileNameList = config.getStringList("ignored-projectiles"); Set ignoredProjectileSet = parseEnums(projectileNameList, EntityType.class); setIgnoredProjectiles(ignoredProjectileSet); ConfigurationSection timerSection = getOrCreateSection(config, "timer"); String timerTypeName = timerSection.getString("type", "GLOBAL"); setTimerType(parseEnum(TimerType.class, timerTypeName, TimerType.GLOBAL)); setDefaultTimer(timerSection.getInt("default-timer", 10)); setBypassPermissionName(config.getString("bypass-permission")); setSelfCombat(config.getBoolean("self-combat", false)); setUntagOnSelfDeath(config.getBoolean("untag-on-death", true)); setUntagOnEnemyDeath(config.getBoolean("untag-on-enemy-death", true)); setRemoveNoDamageCooldown(config.getBoolean("remove-no-damage-cooldown", true)); setForgiveRequestCooldown(config.getInt("forgive-request-cooldown", 30)); setForgiveRequestExpire(config.getInt("forgive-request-expire", 10)); setMinimumTps(config.getDouble("minimum-tps", 15.0D)); List enabledTagReasonNameList = config.getStringList("enabled-tag-reasons"); Set enabledTagReasons = parseEnums(enabledTagReasonNameList, TagReason.class); setEnabledTagReasons(enabledTagReasons); } public @NotNull String getGeneratedByVersion() { return this.generatedByVersion; } public void setGeneratedByVersion(@NotNull String generatedByVersion) { this.generatedByVersion = generatedByVersion; } public boolean isDebugMode() { return this.debugMode; } public void setDebugMode(boolean debugMode) { this.debugMode = debugMode; } public boolean isBroadcastOnLoad() { return this.broadcastOnLoad; } public void setBroadcastOnLoad(boolean broadcastOnLoad) { this.broadcastOnLoad = broadcastOnLoad; } public boolean isBroadcastOnEnable() { return this.broadcastOnEnable; } public void setBroadcastOnEnable(boolean broadcastOnEnable) { this.broadcastOnEnable = broadcastOnEnable; } public boolean isBroadcastOnDisable() { return this.broadcastOnDisable; } public void setBroadcastOnDisable(boolean broadcastOnDisable) { this.broadcastOnDisable = broadcastOnDisable; } public @NotNull Set getWorlds() { return Collections.unmodifiableSet(this.worldSet); } public void setWorlds(@NotNull Collection worlds) { this.worldSet.clear(); this.worldSet.addAll(worlds); } public boolean isWorldListInverted() { return this.worldListInverted; } public void setWorldListInverted(boolean worldListInverted) { this.worldListInverted = worldListInverted; } public boolean isLinkPets() { return this.linkPets; } public void setLinkPets(boolean linkPets) { this.linkPets = linkPets; } public boolean isLinkProjectiles() { return this.linkProjectiles; } public void setLinkProjectiles(boolean linkProjectiles) { this.linkProjectiles = linkProjectiles; } public boolean isLinkFishingRod() { return this.linkFishingRod; } public void setLinkFishingRod(boolean linkFishingRod) { this.linkFishingRod = linkFishingRod; } public boolean isLinkTnt() { return this.linkTnt; } public void setLinkTnt(boolean linkTnt) { this.linkTnt = linkTnt; } public boolean isLinkEndCrystals() { return this.linkEndCrystals; } public void setLinkEndCrystals(boolean linkEndCrystals) { this.linkEndCrystals = linkEndCrystals; } public @NotNull Set getIgnoredProjectiles() { return Collections.unmodifiableSet(this.ignoredProjectileSet); } public void setIgnoredProjectiles(@NotNull Collection ignoredProjectiles) { this.ignoredProjectileSet.clear(); this.ignoredProjectileSet.addAll(ignoredProjectiles); } public @NotNull TimerType getTimerType() { return this.timerType; } public void setTimerType(@NotNull TimerType timerType) { this.timerType = timerType; } public int getDefaultTimer() { return defaultTimer; } public void setDefaultTimer(int defaultTimer) { this.defaultTimer = defaultTimer; } public @Nullable String getBypassPermissionName() { return this.bypassPermissionName; } public void setBypassPermissionName(@Nullable String bypassPermissionName) { this.bypassPermissionName = bypassPermissionName; this.bypassPermission = null; } public Permission getBypassPermission() { if (this.bypassPermission != null) { return this.bypassPermission; } String permissionName = getBypassPermissionName(); if (permissionName == null || permissionName.isEmpty()) { return null; } String description = "CombatLogX bypass tagging permission."; this.bypassPermission = new Permission(permissionName, description, PermissionDefault.FALSE); return this.bypassPermission; } public boolean isSelfCombat() { return this.selfCombat; } public void setSelfCombat(boolean selfCombat) { this.selfCombat = selfCombat; } public boolean isUntagOnSelfDeath() { return this.untagOnSelfDeath; } public void setUntagOnSelfDeath(boolean untagOnSelfDeath) { this.untagOnSelfDeath = untagOnSelfDeath; } public boolean isUntagOnEnemyDeath() { return this.untagOnEnemyDeath; } public void setUntagOnEnemyDeath(boolean untagOnEnemyDeath) { this.untagOnEnemyDeath = untagOnEnemyDeath; } public boolean isRemoveNoDamageCooldown() { return this.removeNoDamageCooldown; } public void setRemoveNoDamageCooldown(boolean removeNoDamageCooldown) { this.removeNoDamageCooldown = removeNoDamageCooldown; } public int getForgiveRequestCooldown() { return this.forgiveRequestCooldown; } public void setForgiveRequestCooldown(int forgiveRequestCooldown) { this.forgiveRequestCooldown = forgiveRequestCooldown; } public int getForgiveRequestExpire() { return this.forgiveRequestExpire; } public void setForgiveRequestExpire(int forgiveRequestExpire) { this.forgiveRequestExpire = forgiveRequestExpire; } public double getMinimumTps() { return this.minimumTps; } public void setMinimumTps(double minimumTps) { this.minimumTps = minimumTps; } public boolean isDisabled(@NotNull World world) { Set worldNameSet = getWorlds(); boolean inverted = isWorldListInverted(); String worldName = world.getName(); boolean contains = worldNameSet.contains(worldName); return (inverted != contains); } public boolean isProjectileIgnored(@NotNull EntityType type) { Set ignoredProjectileSet = getIgnoredProjectiles(); return ignoredProjectileSet.contains(type); } public @NotNull Set getEnabledTagReasons() { return Collections.unmodifiableSet(this.enabledTagReasons); } public void setEnabledTagReasons(@NotNull Collection reasons) { this.enabledTagReasons.clear(); this.enabledTagReasons.addAll(reasons); } } ================================================ FILE: api/src/main/java/com/github/sirblobman/combatlogx/api/configuration/PunishConfiguration.java ================================================ package com.github.sirblobman.combatlogx.api.configuration; import java.util.ArrayList; import java.util.Collection; import java.util.Collections; import java.util.List; import org.jetbrains.annotations.NotNull; import org.bukkit.configuration.ConfigurationSection; import com.github.sirblobman.api.configuration.IConfigurable; import com.github.sirblobman.combatlogx.api.object.KillTime; import static com.github.sirblobman.api.utility.ConfigurationHelper.parseEnum; public final class PunishConfiguration implements IConfigurable { private final List kickIgnoreList; private final List customDeathMessageList; private boolean onDisconnect; private boolean onKick; private boolean onExpire; private KillTime killTime; private boolean enablePunishmentCounter; private boolean kickIgnoreListInverted; public PunishConfiguration() { this.onDisconnect = true; this.onKick = false; this.onExpire = false; this.killTime = KillTime.QUIT; this.enablePunishmentCounter = true; this.kickIgnoreListInverted = false; this.kickIgnoreList = new ArrayList<>(); this.customDeathMessageList = new ArrayList<>(); } @Override public void load(ConfigurationSection config) { setOnDisconnect(config.getBoolean("on-disconnect", true)); setOnKick(config.getBoolean("on-kick", false)); setOnExpire(config.getBoolean("on-expire", false)); setEnablePunishmentCounter(config.getBoolean("enable-punishment-counter")); String killTimeName = config.getString("kill-time", "QUIT"); setKillTime(parseEnum(KillTime.class, killTimeName, KillTime.QUIT)); setKickIgnoreList(config.getStringList("kick-ignore-list")); setCustomDeathMessages(config.getStringList("custom-death-message-list")); } public boolean isOnDisconnect() { return this.onDisconnect; } public void setOnDisconnect(boolean onDisconnect) { this.onDisconnect = onDisconnect; } public boolean isOnKick() { return this.onKick; } public void setOnKick(boolean onKick) { this.onKick = onKick; } public boolean isOnExpire() { return this.onExpire; } public void setOnExpire(boolean onExpire) { this.onExpire = onExpire; } public @NotNull KillTime getKillTime() { return this.killTime; } public void setKillTime(@NotNull KillTime killTime) { this.killTime = killTime; } public boolean isEnablePunishmentCounter() { return enablePunishmentCounter; } public void setEnablePunishmentCounter(boolean enablePunishmentCounter) { this.enablePunishmentCounter = enablePunishmentCounter; } public @NotNull List getKickIgnoreList() { return Collections.unmodifiableList(this.kickIgnoreList); } public void setKickIgnoreList(@NotNull Collection kickIgnores) { this.kickIgnoreList.clear(); this.kickIgnoreList.addAll(kickIgnores); } public boolean isKickIgnoreListInverted() { return this.kickIgnoreListInverted; } public void setKickIgnoreListInverted(boolean inverted) { this.kickIgnoreListInverted = inverted; } public boolean isKickIgnored(@NotNull String reason) { boolean ignore = isInIgnoreList(reason); boolean inverted = isKickIgnoreListInverted(); return (inverted != ignore); } private boolean isInIgnoreList(@NotNull String reason) { List kickIgnoreList = getKickIgnoreList(); if (kickIgnoreList.contains("*")) { return true; } for (String part : kickIgnoreList) { if (reason.contains(part)) { return true; } } return false; } public List getCustomDeathMessages() { return Collections.unmodifiableList(this.customDeathMessageList); } public void setCustomDeathMessages(@NotNull Collection deathMessages) { this.customDeathMessageList.clear(); this.customDeathMessageList.addAll(deathMessages); } } ================================================ FILE: api/src/main/java/com/github/sirblobman/combatlogx/api/event/CustomPlayerEvent.java ================================================ package com.github.sirblobman.combatlogx.api.event; import org.jetbrains.annotations.NotNull; import org.bukkit.entity.Player; import org.bukkit.event.player.PlayerEvent; public abstract class CustomPlayerEvent extends PlayerEvent { public CustomPlayerEvent(@NotNull Player player) { super(player); } } ================================================ FILE: api/src/main/java/com/github/sirblobman/combatlogx/api/event/CustomPlayerEventCancellable.java ================================================ package com.github.sirblobman.combatlogx.api.event; import org.jetbrains.annotations.NotNull; import org.bukkit.entity.Player; import org.bukkit.event.Cancellable; public abstract class CustomPlayerEventCancellable extends CustomPlayerEvent implements Cancellable { private boolean cancelled; public CustomPlayerEventCancellable(@NotNull Player player) { super(player); this.cancelled = false; } @Override public boolean isCancelled() { return this.cancelled; } @Override public void setCancelled(boolean cancel) { this.cancelled = cancel; } } ================================================ FILE: api/src/main/java/com/github/sirblobman/combatlogx/api/event/NPCDropItemEvent.java ================================================ package com.github.sirblobman.combatlogx.api.event; import org.jetbrains.annotations.NotNull; import org.bukkit.Location; import org.bukkit.OfflinePlayer; import org.bukkit.event.Cancellable; import org.bukkit.event.Event; import org.bukkit.event.HandlerList; import org.bukkit.inventory.ItemStack; import com.github.sirblobman.combatlogx.api.object.CitizensSlotType; /** * A custom event that will be called when an item is dropped from a combat logged NPC. * * @author SizzleMcGrizzle */ public final class NPCDropItemEvent extends Event implements Cancellable { private static final HandlerList HANDLER_LIST; static { HANDLER_LIST = new HandlerList(); } private final OfflinePlayer player; private final Location location; private final CitizensSlotType slotType; private boolean cancelled; private ItemStack item; public NPCDropItemEvent(@NotNull ItemStack item, @NotNull OfflinePlayer player, @NotNull Location location, @NotNull CitizensSlotType slotType) { this.player = player; this.location = location; this.item = item; this.slotType = slotType; this.cancelled = false; } public static @NotNull HandlerList getHandlerList() { return HANDLER_LIST; } @Override public HandlerList getHandlers() { return getHandlerList(); } /** * @return The player who combat logged */ public @NotNull OfflinePlayer getPlayer() { return player; } /** * @return The location at which the player combat logged */ public @NotNull Location getLocation() { return location; } /** * @return The item being dropped from the location * @see CitizensSlotType for various inventory slot locations this item could be from */ public @NotNull ItemStack getItem() { return item; } public void setItem(@NotNull ItemStack item) { this.item = item.clone(); } /** * @return The type of slot the item is from */ public @NotNull CitizensSlotType getSlotType() { return slotType; } @Override public boolean isCancelled() { return cancelled; } @Override public void setCancelled(boolean cancelled) { this.cancelled = cancelled; } } ================================================ FILE: api/src/main/java/com/github/sirblobman/combatlogx/api/event/PlayerEnemyRemoveEvent.java ================================================ package com.github.sirblobman.combatlogx.api.event; import org.jetbrains.annotations.NotNull; import org.bukkit.entity.Entity; import org.bukkit.entity.Player; import org.bukkit.event.HandlerList; import com.github.sirblobman.combatlogx.api.object.UntagReason; /** * A custom event that is fired when a player is removed from combat with a specific enemy. * The event may not be called for enemy entities that have already been removed from the server. * * @author SirBlobman * @see PlayerUntagEvent */ public final class PlayerEnemyRemoveEvent extends CustomPlayerEvent { private static final HandlerList HANDLER_LIST; static { HANDLER_LIST = new HandlerList(); } private final UntagReason untagReason; private final Entity enemy; public PlayerEnemyRemoveEvent(@NotNull Player player, @NotNull UntagReason untagReason, @NotNull Entity enemy) { super(player); this.untagReason = untagReason; this.enemy = enemy; } public static @NotNull HandlerList getHandlerList() { return HANDLER_LIST; } @Override public @NotNull HandlerList getHandlers() { return getHandlerList(); } /** * @return The reason that the player was removed from combat with the enemy. * @see #getPlayer() */ public @NotNull UntagReason getUntagReason() { return this.untagReason; } /** * @return The previous enemy of the player./ */ public @NotNull Entity getEnemy() { return this.enemy; } } ================================================ FILE: api/src/main/java/com/github/sirblobman/combatlogx/api/event/PlayerPreTagEvent.java ================================================ package com.github.sirblobman.combatlogx.api.event; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import org.bukkit.entity.Entity; import org.bukkit.entity.Player; import org.bukkit.event.HandlerList; import com.github.sirblobman.combatlogx.api.object.TagReason; import com.github.sirblobman.combatlogx.api.object.TagType; /** * A custom event that will be fired before a player is put into combat. * If the event is cancelled, the player will not be tagged. * * @author SirBlobman */ public final class PlayerPreTagEvent extends CustomPlayerEventCancellable { private static final HandlerList HANDLER_LIST; static { HANDLER_LIST = new HandlerList(); } private final Entity enemy; private final TagType tagType; private final TagReason tagReason; public PlayerPreTagEvent(@NotNull Player player, @Nullable Entity enemy, @NotNull TagType tagType, @NotNull TagReason tagReason) { super(player); this.enemy = enemy; this.tagType = tagType; this.tagReason = tagReason; } public static @NotNull HandlerList getHandlerList() { return HANDLER_LIST; } @Override public HandlerList getHandlers() { return getHandlerList(); } /** * @return The enemy that will tag the player or null if an enemy does not exist * @see #getPlayer() */ public @Nullable Entity getEnemy() { return this.enemy; } /** * @return The type of entity that will cause this player to be tagged * @see #getPlayer() */ public @NotNull TagType getTagType() { return this.tagType; } /** * @return The reason that will cause this player to be tagged. * @see #getPlayer() */ public @NotNull TagReason getTagReason() { return this.tagReason; } } ================================================ FILE: api/src/main/java/com/github/sirblobman/combatlogx/api/event/PlayerPunishEvent.java ================================================ package com.github.sirblobman.combatlogx.api.event; import java.util.ArrayList; import java.util.Collections; import java.util.List; import org.jetbrains.annotations.NotNull; import org.bukkit.entity.Entity; import org.bukkit.entity.Player; import org.bukkit.event.HandlerList; import com.github.sirblobman.combatlogx.api.object.UntagReason; /** * A custom event that will fire before a player is punished. * If the event is cancelled, the player will not be punished. * * @author SirBlobman */ public final class PlayerPunishEvent extends CustomPlayerEventCancellable { private static final HandlerList HANDLER_LIST; static { HANDLER_LIST = new HandlerList(); } private final UntagReason punishReason; private final List enemyList; public PlayerPunishEvent(@NotNull Player player, @NotNull UntagReason punishReason, @NotNull List enemyList) { super(player); this.punishReason = punishReason; this.enemyList = new ArrayList<>(enemyList); } public static @NotNull HandlerList getHandlerList() { return HANDLER_LIST; } @Override public HandlerList getHandlers() { return getHandlerList(); } /** * @return The original {@link UntagReason} that the player was punished for. */ public @NotNull UntagReason getPunishReason() { return this.punishReason; } /** * @return The list of enemies the player had when punished. */ public @NotNull List getEnemies() { return Collections.unmodifiableList(this.enemyList); } } ================================================ FILE: api/src/main/java/com/github/sirblobman/combatlogx/api/event/PlayerReTagEvent.java ================================================ package com.github.sirblobman.combatlogx.api.event; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import org.bukkit.entity.Entity; import org.bukkit.entity.Player; import org.bukkit.event.HandlerList; import com.github.sirblobman.combatlogx.api.manager.ICombatManager; import com.github.sirblobman.combatlogx.api.object.TagReason; import com.github.sirblobman.combatlogx.api.object.TagType; /** * A custom event that will be fired when a player's timer is extended * * @author SirBlobman */ public final class PlayerReTagEvent extends CustomPlayerEventCancellable { private static final HandlerList HANDLER_LIST; static { HANDLER_LIST = new HandlerList(); } private final Entity enemy; private final TagType tagType; private final TagReason tagReason; private long combatEndMillis; public PlayerReTagEvent(@NotNull Player player, @Nullable Entity enemy, @NotNull TagType tagType, @NotNull TagReason tagReason, long combatEndMillis) { super(player); this.enemy = enemy; this.tagType = tagType; this.tagReason = tagReason; this.combatEndMillis = combatEndMillis; } public static @NotNull HandlerList getHandlerList() { return HANDLER_LIST; } @Override public @NotNull HandlerList getHandlers() { return getHandlerList(); } /** * @return The enemy that will tag the player or null if an enemy does not exist * @see #getPlayer() */ public @Nullable Entity getEnemy() { return this.enemy; } /** * @return The type of entity that will cause this player to be tagged * @see #getPlayer() */ public @NotNull TagType getTagType() { return this.tagType; } /** * @return The reason that will cause this player to be tagged. * @see #getPlayer() */ public @NotNull TagReason getTagReason() { return this.tagReason; } /** * @return The time (in millis) that the combat timer will end. This can change if the player is tagged again * @see #getPlayer() */ public long getEndTime() { return this.combatEndMillis; } /** * Set the amount of time to wait before the player escapes from combat. * * @param millis The epoch time (in milliseconds) that the timer will end. * @see ICombatManager#getMaxTimerSeconds(Player) */ public void setEndTime(long millis) { this.combatEndMillis = millis; } } ================================================ FILE: api/src/main/java/com/github/sirblobman/combatlogx/api/event/PlayerTagEvent.java ================================================ package com.github.sirblobman.combatlogx.api.event; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import org.bukkit.entity.Entity; import org.bukkit.entity.Player; import org.bukkit.event.HandlerList; import com.github.sirblobman.combatlogx.api.manager.ICombatManager; import com.github.sirblobman.combatlogx.api.object.TagReason; import com.github.sirblobman.combatlogx.api.object.TagType; /** * A custom event that will be fired when a player is put into combat. * If you want to prevent a player from being tagged, check {@link PlayerPreTagEvent} * * @author SirBlobman */ public final class PlayerTagEvent extends CustomPlayerEvent { private static final HandlerList HANDLER_LIST; static { HANDLER_LIST = new HandlerList(); } private final Entity enemy; private final TagType tagType; private final TagReason tagReason; private long combatEndMillis; public PlayerTagEvent(@NotNull Player player, @Nullable Entity enemy, @NotNull TagType tagType, @NotNull TagReason tagReason, long combatEndMillis) { super(player); this.enemy = enemy; this.tagType = tagType; this.tagReason = tagReason; this.combatEndMillis = combatEndMillis; } public static @NotNull HandlerList getHandlerList() { return HANDLER_LIST; } @Override public @NotNull HandlerList getHandlers() { return getHandlerList(); } /** * @return The enemy that will tag the player or null if an enemy does not exist * @see #getPlayer() */ public @Nullable Entity getEnemy() { return this.enemy; } /** * @return The type of entity that will cause this player to be tagged * @see #getPlayer() */ public @NotNull TagType getTagType() { return this.tagType; } /** * @return The reason that will cause this player to be tagged. * @see #getPlayer() */ public @NotNull TagReason getTagReason() { return this.tagReason; } /** * @return The time (in millis) that the combat timer will end. This can change if the player is tagged again * @see #getPlayer() */ public long getEndTime() { return this.combatEndMillis; } /** * Set the amount of time to wait before the player escapes from combat. * * @param millis The epoch time (in milliseconds) that the timer will end. * @see ICombatManager#getMaxTimerSeconds(Player) */ public void setEndTime(long millis) { this.combatEndMillis = millis; } } ================================================ FILE: api/src/main/java/com/github/sirblobman/combatlogx/api/event/PlayerUntagEvent.java ================================================ package com.github.sirblobman.combatlogx.api.event; import java.util.ArrayList; import java.util.Collections; import java.util.List; import org.jetbrains.annotations.NotNull; import org.bukkit.entity.Entity; import org.bukkit.entity.Player; import org.bukkit.event.HandlerList; import com.github.sirblobman.combatlogx.api.object.UntagReason; /** * A custom event that is fired when a player is removed from combat. * * @author SirBlobman */ public final class PlayerUntagEvent extends CustomPlayerEvent { private static final HandlerList HANDLER_LIST; static { HANDLER_LIST = new HandlerList(); } private final UntagReason untagReason; private final List previousEnemyList; public PlayerUntagEvent(@NotNull Player player, @NotNull UntagReason untagReason, @NotNull List previousEnemyList) { super(player); this.untagReason = untagReason; this.previousEnemyList = new ArrayList<>(previousEnemyList); } public static @NotNull HandlerList getHandlerList() { return HANDLER_LIST; } @Override public @NotNull HandlerList getHandlers() { return getHandlerList(); } /** * @return The reason that the player was removed from combat. * @see #getPlayer() */ public @NotNull UntagReason getUntagReason() { return this.untagReason; } public @NotNull List getPreviousEnemies() { return Collections.unmodifiableList(this.previousEnemyList); } } ================================================ FILE: api/src/main/java/com/github/sirblobman/combatlogx/api/expansion/Expansion.java ================================================ package com.github.sirblobman.combatlogx.api.expansion; import java.io.File; import java.io.IOException; import java.io.InputStream; import java.net.URL; import java.net.URLClassLoader; import java.net.URLConnection; import java.util.ArrayList; import java.util.List; import java.util.Locale; import java.util.logging.Level; import java.util.logging.Logger; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import org.bukkit.Bukkit; import org.bukkit.event.Listener; import org.bukkit.plugin.Plugin; import org.bukkit.plugin.PluginDescriptionFile; import org.bukkit.plugin.PluginManager; import org.bukkit.plugin.java.JavaPlugin; import com.github.sirblobman.api.configuration.ConfigurationManager; import com.github.sirblobman.api.configuration.IResourceHolder; import com.github.sirblobman.combatlogx.api.ICombatLogX; public abstract class Expansion implements IResourceHolder { private final ICombatLogX plugin; private final List listenerList; private State state; private File dataFolder, file; private ExpansionLogger logger; private ExpansionDescription description; private ConfigurationManager configurationManager; public Expansion(@NotNull ICombatLogX plugin) { this.plugin = plugin; this.listenerList = new ArrayList<>(); this.state = State.UNLOADED; this.description = null; this.dataFolder = null; this.file = null; } final @NotNull List getListeners() { return this.listenerList; } public final @NotNull State getState() { return this.state; } final void setState(@NotNull State state) { this.state = state; } public final @NotNull ICombatLogX getPlugin() { return this.plugin; } public final @NotNull Logger getLogger() { if (this.logger == null) { this.logger = new ExpansionLogger(this); } return this.logger; } protected final @NotNull ConfigurationManager getConfigurationManager() { if (this.configurationManager == null) { this.configurationManager = new ConfigurationManager(this); } return this.configurationManager; } public final @NotNull File getDataFolder() { return this.dataFolder; } final void setDataFolder(@NotNull File dataFolder) { if (!dataFolder.isDirectory()) { throw new IllegalArgumentException("dataFolder must be a directory!"); } this.dataFolder = dataFolder; } public final @NotNull File getFile() { return this.file; } final void setFile(@NotNull File file) { if (file.isDirectory()) { throw new IllegalArgumentException("file must not be a directory!"); } this.file = file; } public final @NotNull ExpansionDescription getDescription() { return this.description; } final void setDescription(@NotNull ExpansionDescription description) { this.description = description; } public final @NotNull String getName() { ExpansionDescription description = getDescription(); return description.getName(); } public final @NotNull String getPrefix() { ExpansionDescription description = getDescription(); return description.getPrefix(); } @Override public final @NotNull String getKeyName() { String name = getName(); return name.toLowerCase(Locale.US); } @Override public final @Nullable InputStream getResource(@NotNull String name) { try { Class thisClass = getClass(); URLClassLoader classLoader = (URLClassLoader) thisClass.getClassLoader(); URL url = classLoader.findResource(name); if (url == null) { return null; } URLConnection connection = url.openConnection(); connection.setUseCaches(false); return connection.getInputStream(); } catch (IOException ex) { Logger logger = getLogger(); logger.log(Level.WARNING, "Failed to get resource '" + name + "':", ex); return null; } } protected final boolean checkDependency(@NotNull String pluginName, boolean checkEnabled) { PluginManager pluginManager = Bukkit.getPluginManager(); Logger logger = getLogger(); Plugin plugin = pluginManager.getPlugin(pluginName); if (plugin == null) { logger.warning("A dependency is not installed on the server: " + pluginName); return false; } if (checkEnabled && !plugin.isEnabled()) { logger.warning("A dependency was found but it was not enabled: " + pluginName); return false; } PluginDescriptionFile description = plugin.getDescription(); String fullName = description.getFullName(); logger.info("Successfully found a dependency: " + fullName); return true; } protected final boolean checkDependency(@NotNull String pluginName, boolean checkEnabled, @NotNull String versionStartsWith) { if (!checkDependency(pluginName, checkEnabled)) { return false; } PluginManager pluginManager = Bukkit.getPluginManager(); Logger logger = getLogger(); Plugin plugin = pluginManager.getPlugin(pluginName); if (plugin == null) { return false; } PluginDescriptionFile description = plugin.getDescription(); String version = description.getVersion(); if (!version.startsWith(versionStartsWith)) { logger.info("Dependency '" + pluginName + "' is not the correct version!"); return false; } return true; } protected final void registerListener(@NotNull Listener listener) { ICombatLogX plugin = getPlugin(); JavaPlugin javaPlugin = plugin.getPlugin(); PluginManager pluginManager = Bukkit.getPluginManager(); pluginManager.registerEvents(listener, javaPlugin); this.listenerList.add(listener); } protected final void selfDisable() { ICombatLogX plugin = getPlugin(); ExpansionManager expansionManager = plugin.getExpansionManager(); expansionManager.disableExpansion(this); } public abstract void onLoad(); public abstract void onEnable(); public abstract void onDisable(); public abstract void reloadConfig(); public enum State { LOADED, UNLOADED, ENABLED, ENABLING, DISABLED } } ================================================ FILE: api/src/main/java/com/github/sirblobman/combatlogx/api/expansion/ExpansionClassLoader.java ================================================ package com.github.sirblobman.combatlogx.api.expansion; import java.io.File; import java.lang.reflect.Constructor; import java.net.MalformedURLException; import java.net.URL; import java.net.URLClassLoader; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Locale; import java.util.Map; import java.util.Set; import java.util.logging.Logger; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import org.bukkit.configuration.file.YamlConfiguration; import com.github.sirblobman.combatlogx.api.ICombatLogX; class ExpansionClassLoader extends URLClassLoader { private final ExpansionManager manager; private final Map> classes; private Expansion expansion; ExpansionClassLoader(@NotNull ExpansionManager manager, @NotNull YamlConfiguration description, @NotNull File path, @NotNull ClassLoader parent) throws MalformedURLException { super(new URL[]{path.toURI().toURL()}, parent); this.manager = manager; this.classes = new HashMap<>(); registerExpansion(description, path); } @Override protected @Nullable Class findClass(String name) { return findClass(name, true); } public @Nullable Class findClass(String name, boolean checkGlobal) { Class result = classes.get(name); if (result == null) { if (checkGlobal) { result = this.manager.getClassByName(name); } if (result == null) { try { result = super.findClass(name); } catch (ClassNotFoundException | NoClassDefFoundError e) { // Do nothing. } catch (UnsupportedClassVersionError e) { ICombatLogX plugin = this.manager.getPlugin(); Logger logger = plugin.getLogger(); logger.warning("Could not load class with name=" + name + ", global=" + checkGlobal + " because an error occurred:"); logger.warning(e.getMessage()); } if (result != null) { this.manager.setClass(name, result); } } classes.put(name, result); } return result; } public @Nullable Expansion getExpansion() { return this.expansion; } public @NotNull Set getClasses() { return this.classes.keySet(); } private void registerExpansion(@NotNull YamlConfiguration description, @NotNull File path) { Class mainClass; try { String mainClassName = description.getString("main"); if (mainClassName == null) { throw new IllegalStateException("Could not find `main` in expansion.yml"); } mainClass = Class.forName(mainClassName, true, this); } catch (ReflectiveOperationException ex) { String newError = ("Could not load '" + path.getName() + "' from folder '" + path.getParent() + "'"); throw new IllegalStateException(newError, ex); } Class expansionClass; try { expansionClass = mainClass.asSubclass(Expansion.class); } catch (ClassCastException ex) { String newError = ("Main class is not an instance of 'Expansion'"); throw new IllegalStateException(newError, ex); } try { ICombatLogX plugin = this.manager.getPlugin(); Constructor constructor = expansionClass.getDeclaredConstructor(ICombatLogX.class); this.expansion = constructor.newInstance(plugin); ExpansionDescription expansionDescription = createDescription(description); this.expansion.setDescription(expansionDescription); } catch (ReflectiveOperationException ex) { String pathName = path.getName(); String pathParent = path.getParent(); String errorMessageFormat = "Could not load '%s' from folder '%s'."; String errorMessage = String.format(Locale.US, errorMessageFormat, pathName, pathParent); throw new IllegalStateException(errorMessage, ex); } } private ExpansionDescription createDescription(@NotNull YamlConfiguration configuration) throws IllegalStateException { String mainClass = configuration.getString("main"); if (mainClass == null) { throw new IllegalStateException("'main' is required in expansion.yml"); } String name = configuration.getString("name"); if (name == null) { throw new IllegalStateException("'name' is required in expansion.yml"); } String version = configuration.getString("version"); if (version == null) { throw new IllegalStateException("'version' is required in expansion.yml"); } String prefix = configuration.getString("display-name"); if (prefix == null) { prefix = configuration.getString("prefix"); } if (prefix == null) { prefix = name; } String description = configuration.getString("description", ""); String website = configuration.getString("website", null); List authorList = configuration.getStringList("authors"); if (authorList.isEmpty()) { authorList = new ArrayList<>(); } String author = configuration.getString("author", null); if (author != null) { authorList.add(author); } List pluginDependList = configuration.getStringList("plugin-depend"); List pluginSoftDependList = configuration.getStringList("plugin-soft-depend"); List expansionDependList = configuration.getStringList("expansion-depend"); List expansionSoftDependList = configuration.getStringList("expansion-soft-depend"); boolean lateLoad = configuration.getBoolean("late-load", false); ExpansionDescriptionBuilder builder = new ExpansionDescriptionBuilder(mainClass, name, version) .withPrefix(prefix) .withDescription(description) .withWebsite(website) .withAuthors(authorList) .withPluginDependencies(pluginDependList) .withPluginSoftDependencies(pluginSoftDependList) .withExpansionDependencies(expansionDependList) .withExpansionSoftDependencies(expansionSoftDependList) .withLateLoad(lateLoad); return builder.build(); } } ================================================ FILE: api/src/main/java/com/github/sirblobman/combatlogx/api/expansion/ExpansionComparator.java ================================================ package com.github.sirblobman.combatlogx.api.expansion; import java.util.Comparator; import java.util.List; import org.jetbrains.annotations.NotNull; public final class ExpansionComparator implements Comparator { @Override public int compare(@NotNull Expansion e1, @NotNull Expansion e2) { ExpansionDescription description1 = e1.getDescription(); ExpansionDescription description2 = e2.getDescription(); String expansionName1 = description1.getName(); String expansionName2 = description2.getName(); List expansionDependencyList1 = description1.getExpansionDependencies(); List expansionDependencyList2 = description2.getExpansionDependencies(); if (expansionDependencyList1.contains(expansionName2) && expansionDependencyList2.contains(expansionName1)) { throw new IllegalStateException("Cyclic Dependency: " + expansionName1 + ", " + expansionName2); } if (expansionDependencyList1.contains(expansionName2)) { return -1; } if (expansionDependencyList2.contains(expansionName1)) { return 1; } return expansionName1.compareTo(expansionName2); } } ================================================ FILE: api/src/main/java/com/github/sirblobman/combatlogx/api/expansion/ExpansionDescription.java ================================================ package com.github.sirblobman.combatlogx.api.expansion; import java.util.Collections; import java.util.List; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; public class ExpansionDescription { private final String mainClass; private final String name; private final String version; private final String prefix; private final String description; private final String website; private final List authorList; private final List pluginDependList; private final List pluginSoftDependList; private final List expansionDependList; private final List expansionSoftDependList; private final boolean lateLoad; ExpansionDescription(@NotNull String mainClass, @NotNull String name, @NotNull String version, @NotNull String prefix, @NotNull String description, @Nullable String website, @NotNull List authorList, @NotNull List pluginDependList, @NotNull List pluginSoftDependList, @NotNull List expansionDependList, @NotNull List expansionSoftDependList, boolean lateLoad) { this.mainClass = mainClass; this.name = name; this.version = version; this.prefix = prefix; this.description = description; this.website = website; this.authorList = authorList; this.pluginDependList = pluginDependList; this.pluginSoftDependList = pluginSoftDependList; this.expansionDependList = expansionDependList; this.expansionSoftDependList = expansionSoftDependList; this.lateLoad = lateLoad; } public @NotNull String getMainClass() { return this.mainClass; } public @NotNull String getName() { return this.name; } public @NotNull String getPrefix() { return this.prefix; } public @NotNull String getVersion() { return this.version; } public @NotNull String getDescription() { return this.description; } public @Nullable String getWebsite() { return this.website; } public @NotNull List getAuthors() { return Collections.unmodifiableList(this.authorList); } public @NotNull List getPluginDependencies() { return Collections.unmodifiableList(this.pluginDependList); } public @NotNull List getPluginSoftDependencies() { return Collections.unmodifiableList(this.pluginSoftDependList); } public @NotNull List getExpansionDependencies() { return Collections.unmodifiableList(this.expansionDependList); } public @NotNull List getExpansionSoftDependencies() { return Collections.unmodifiableList(this.expansionSoftDependList); } public @NotNull String getFullName() { String displayName = getPrefix(); String version = getVersion(); return (displayName + " v" + version); } public boolean isLateLoad() { return this.lateLoad; } } ================================================ FILE: api/src/main/java/com/github/sirblobman/combatlogx/api/expansion/ExpansionDescriptionBuilder.java ================================================ package com.github.sirblobman.combatlogx.api.expansion; import java.util.ArrayList; import java.util.List; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; public final class ExpansionDescriptionBuilder { private final String mainClass; private final String name; private final String version; private String prefix; private String description; private String website; private List authorList; private List pluginDependencyList; private List expansionDependencyList; private List pluginSoftDependencyList; private List expansionSoftDependencyList; private boolean lateLoad; public ExpansionDescriptionBuilder(@NotNull String mainClass, @NotNull String name, @NotNull String version) { this.mainClass = mainClass; this.name = name; this.version = version; this.prefix = null; this.description = null; this.website = null; this.authorList = new ArrayList<>(); this.pluginDependencyList = new ArrayList<>(); this.expansionDependencyList = new ArrayList<>(); this.pluginSoftDependencyList = new ArrayList<>(); this.expansionSoftDependencyList = new ArrayList<>(); this.lateLoad = false; } public @NotNull ExpansionDescriptionBuilder withPrefix(@Nullable String prefix) { this.prefix = prefix; return this; } public @NotNull ExpansionDescriptionBuilder withDescription(@Nullable String description) { this.description = description; return this; } public @NotNull ExpansionDescriptionBuilder withWebsite(@Nullable String website) { this.website = website; return this; } public @NotNull ExpansionDescriptionBuilder withAuthors(@NotNull List authorList) { this.authorList = new ArrayList<>(authorList); return this; } public @NotNull ExpansionDescriptionBuilder withPluginDependencies(@NotNull List list) { this.pluginDependencyList = new ArrayList<>(list); return this; } public @NotNull ExpansionDescriptionBuilder withPluginSoftDependencies(@NotNull List list) { this.pluginSoftDependencyList = new ArrayList<>(list); return this; } public @NotNull ExpansionDescriptionBuilder withExpansionDependencies(@NotNull List list) { this.expansionDependencyList = new ArrayList<>(list); return this; } public @NotNull ExpansionDescriptionBuilder withExpansionSoftDependencies(@NotNull List list) { this.expansionSoftDependencyList = new ArrayList<>(list); return this; } public @NotNull ExpansionDescriptionBuilder withLateLoad(boolean lateLoad) { this.lateLoad = lateLoad; return this; } public @NotNull ExpansionDescription build() { String prefix = (this.prefix == null ? this.name : this.prefix); String description = (this.description == null ? "" : this.description); return new ExpansionDescription(this.mainClass, this.name, this.version, prefix, description, this.website, this.authorList, this.pluginDependencyList, this.pluginSoftDependencyList, this.expansionDependencyList, this.expansionSoftDependencyList, this.lateLoad); } } ================================================ FILE: api/src/main/java/com/github/sirblobman/combatlogx/api/expansion/ExpansionListener.java ================================================ package com.github.sirblobman.combatlogx.api.expansion; import java.util.Locale; import java.util.logging.Level; import java.util.logging.Logger; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import com.github.sirblobman.combatlogx.api.listener.CombatListener; public abstract class ExpansionListener extends CombatListener { private final Expansion expansion; public ExpansionListener(@NotNull Expansion expansion) { super(expansion.getPlugin()); this.expansion = expansion; } @Override public final void register() { Expansion expansion = getExpansion(); expansion.registerListener(this); } @Override protected final void printDebug(@NotNull String message) { printDebug(message, null); } protected final void printDebug(@NotNull String message, @Nullable Throwable throwable) { if (isDebugModeDisabled()) { return; } Class thisClass = getClass(); String className = thisClass.getSimpleName(); String logMessage = String.format(Locale.US, "[Debug] [%s] %s", className, message); Logger expansionLogger = getExpansionLogger(); if (throwable == null) { expansionLogger.info(logMessage); } else { expansionLogger.log(Level.WARNING, logMessage, throwable); } } protected final @NotNull Expansion getExpansion() { return this.expansion; } protected final @NotNull Logger getExpansionLogger() { Expansion expansion = getExpansion(); return expansion.getLogger(); } } ================================================ FILE: api/src/main/java/com/github/sirblobman/combatlogx/api/expansion/ExpansionLogger.java ================================================ package com.github.sirblobman.combatlogx.api.expansion; import java.util.logging.LogRecord; import java.util.logging.Logger; import org.jetbrains.annotations.NotNull; import org.bukkit.plugin.java.JavaPlugin; import com.github.sirblobman.combatlogx.api.ICombatLogX; public final class ExpansionLogger extends Logger { private final Expansion expansion; public ExpansionLogger(@NotNull Expansion expansion) { super(expansion.getName(), null); this.expansion = expansion; } public @NotNull Expansion getExpansion() { return this.expansion; } @Override public void log(@NotNull LogRecord record) { Expansion expansion = getExpansion(); String expansionPrefix = expansion.getPrefix(); ICombatLogX combatLogX = expansion.getPlugin(); JavaPlugin plugin = combatLogX.getPlugin(); String pluginName = plugin.getName(); String originalMessage = record.getMessage(); String newMessage = ("[" + expansionPrefix + "] " + originalMessage); record.setMessage(newMessage); record.setLoggerName(pluginName); Logger logger = plugin.getLogger(); logger.log(record); } } ================================================ FILE: api/src/main/java/com/github/sirblobman/combatlogx/api/expansion/ExpansionManager.java ================================================ package com.github.sirblobman.combatlogx.api.expansion; import java.io.BufferedReader; import java.io.File; import java.io.FilenameFilter; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.util.ArrayList; import java.util.Collection; import java.util.Comparator; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.Objects; import java.util.Optional; import java.util.jar.JarEntry; import java.util.jar.JarFile; import java.util.logging.Level; import java.util.logging.Logger; import java.util.stream.Collectors; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import org.bukkit.Bukkit; import org.bukkit.configuration.InvalidConfigurationException; import org.bukkit.configuration.file.YamlConfiguration; import org.bukkit.event.HandlerList; import org.bukkit.event.Listener; import org.bukkit.plugin.Plugin; import org.bukkit.plugin.PluginManager; import com.github.sirblobman.api.folia.details.TaskDetails; import com.github.sirblobman.api.folia.scheduler.TaskScheduler; import com.github.sirblobman.combatlogx.api.ICombatLogX; import com.github.sirblobman.combatlogx.api.expansion.Expansion.State; public final class ExpansionManager { private final ICombatLogX plugin; private final Map expansionMap; private final Map expansionClassLoaderMap; private final Map> classNameMap; public ExpansionManager(@NotNull ICombatLogX plugin) { this.plugin = plugin; this.expansionMap = new HashMap<>(); this.expansionClassLoaderMap = new HashMap<>(); this.classNameMap = new HashMap<>(); } public @NotNull ICombatLogX getPlugin() { return this.plugin; } public void loadExpansions() { ICombatLogX plugin = getPlugin(); Logger logger = plugin.getLogger(); logger.info("Loading expansions..."); File dataFolder = plugin.getDataFolder(); if (!dataFolder.exists() && !dataFolder.mkdirs()) { logger.warning("The CombatLogX folder does not exist and could not be created!"); return; } File expansionsFolder = new File(dataFolder, "expansions"); if (!expansionsFolder.exists() && !expansionsFolder.mkdirs()) { logger.warning("The expansions folder does not exist and could not be created!"); return; } FilenameFilter filter = (folder, fileName) -> fileName.endsWith(".jar"); File[] fileArray = expansionsFolder.listFiles(filter); if (fileArray == null || fileArray.length == 0) { logger.info("There were no expansions to load."); return; } for (File file : fileArray) { if (file.isDirectory()) { continue; } loadExpansion(file); logger.info(" "); } List expansionList = sortExpansions(getLoadedExpansions()); int expansionListSize = expansionList.size(); String message = ("Successfully loaded " + expansionListSize + " expansion" + (expansionListSize == 1 ? "" : "s") + "."); logger.info(message); } public void enableExpansions() { ICombatLogX plugin = getPlugin(); Logger logger = plugin.getLogger(); logger.info("Enabling expansions..."); List loadedExpansionList = getLoadedExpansions(); if (loadedExpansionList.isEmpty()) { logger.info("There were no expansions to enable."); return; } sortExpansions(loadedExpansionList); List lateLoadExpansionList = new ArrayList<>(); for (Expansion expansion : loadedExpansionList) { ExpansionDescription description = expansion.getDescription(); if (description.isLateLoad()) { lateLoadExpansionList.add(expansion); continue; } enableExpansion(expansion); logger.info(" "); } List enabledExpansionList = getEnabledExpansions(); int expansionListSize = enabledExpansionList.size(); String message = ("Successfully enabled " + expansionListSize + " expansion" + (expansionListSize == 1 ? "" : "s") + "."); logger.info(message); TaskDetails task = new TaskDetails(plugin.getPlugin()) { @Override public void run() { for (Expansion expansion : lateLoadExpansionList) { enableExpansion(expansion); logger.info(" "); } List newEnabledExpansionList = getEnabledExpansions(); int newExpansionListSize = newEnabledExpansionList.size(); int newExpansionCount = (newExpansionListSize - expansionListSize); String newMessage = ("Successfully enabled " + newExpansionCount + " late-load expansion" + (expansionListSize == 1 ? "" : "s") + "."); logger.info(newMessage); } }; task.setDelay(1L); TaskScheduler scheduler = plugin.getFoliaHelper().getScheduler(); scheduler.scheduleTask(task); } public void disableExpansions() { ICombatLogX plugin = getPlugin(); Logger logger = plugin.getLogger(); logger.info("Disabling expansions..."); List enabledExpansionList = getEnabledExpansions(); if (enabledExpansionList.isEmpty()) { logger.info("There were no expansions to disable."); } else { for (Expansion expansion : enabledExpansionList) { disableExpansion(expansion); logger.info(" "); } } this.expansionMap.clear(); this.classNameMap.clear(); this.expansionClassLoaderMap.clear(); logger.info("Successfully disabled all expansions."); } public void reloadConfigs() { List expansionList = getEnabledExpansions(); expansionList.forEach(Expansion::reloadConfig); } public @NotNull Optional getExpansion(String name) { if (name == null) { return Optional.empty(); } Expansion expansion = this.expansionMap.getOrDefault(name, null); return Optional.ofNullable(expansion); } public @NotNull List getAllExpansions() { Collection expansionCollection = this.expansionMap.values(); return new ArrayList<>(expansionCollection); } public @NotNull List getLoadedExpansions() { List expansionList = getAllExpansions(); return expansionList.stream() .filter(expansion -> expansion.getState() == State.LOADED) .collect(Collectors.toList()); } public @NotNull List getEnabledExpansions() { List expansionList = getAllExpansions(); return expansionList.stream() .filter(expansion -> expansion.getState() == State.ENABLED) .sorted(Comparator.comparing(Expansion::getName)) .collect(Collectors.toList()); } public @Nullable ExpansionClassLoader getClassLoader(Expansion expansion) { return this.expansionClassLoaderMap.getOrDefault(expansion, null); } public @Nullable Class getClassByName(String name) { try { Class defaultValue = this.expansionClassLoaderMap.values() .stream().map(loader -> loader.findClass(name, false)) .filter(Objects::nonNull).findFirst().orElse(null); return this.classNameMap.getOrDefault(name, defaultValue); } catch (Exception ex) { return null; } } public void setClass(@NotNull String name, @NotNull Class clazz) { this.classNameMap.putIfAbsent(name, clazz); } private void loadExpansion(@NotNull File expansionFile) { ICombatLogX plugin = getPlugin(); Logger logger = plugin.getLogger(); plugin.printDebug("Attempting to load expansion from file '" + expansionFile + "'..."); Expansion expansion; ExpansionClassLoader expansionClassLoader; try (JarFile jarFile = new JarFile(expansionFile)) { YamlConfiguration description = getExpansionDescription(jarFile); Class managerClass = getClass(); ClassLoader managerClassLoader = managerClass.getClassLoader(); PluginManager pluginManager = Bukkit.getPluginManager(); if (description.isList("plugin-depend")) { List pluginDependList = description.getStringList("plugin-depend"); for (String pluginName : pluginDependList) { Plugin dependencyPlugin = pluginManager.getPlugin(pluginName); if (dependencyPlugin != null) { continue; } logger.warning("Failed to load expansion '" + expansionFile + "' because a plugin " + "dependency was not loaded: " + pluginName); return; } } if (description.isList("expansion-depend")) { List expansionDependList = description.getStringList("expansion-depend"); for (String expansionName : expansionDependList) { if (this.expansionMap.containsKey(expansionName)) { continue; } logger.warning("Failed to load expansion '" + expansionFile + "' because an expansion" + " dependency was missing: " + expansionName); return; } } expansionClassLoader = new ExpansionClassLoader(this, description, expansionFile, managerClassLoader); expansion = expansionClassLoader.getExpansion(); } catch (Exception ex) { logger.warning("An expansion failed to load because an error occurred."); logger.warning("If debug-mode is enabled, the full error will be displayed below."); this.plugin.printDebug(ex); return; } File pluginFolder = plugin.getDataFolder(); File expansionsFolder = new File(pluginFolder, "expansions"); String expansionName = expansion.getName(); File dataFolder = new File(expansionsFolder, expansionName); if (!dataFolder.exists() && !dataFolder.mkdirs()) { logger.warning("Failed to create folder for expansion '" + expansionName + "'."); return; } expansion.setFile(expansionFile); expansion.setDataFolder(dataFolder); this.expansionMap.put(expansionName, expansion); this.expansionClassLoaderMap.put(expansion, expansionClassLoader); try { ExpansionDescription description = expansion.getDescription(); String fullName = description.getFullName(); logger.info("Loading expansion '" + fullName + "'..."); expansion.onLoad(); expansion.setState(State.LOADED); } catch (Throwable ex) { logger.log(Level.SEVERE, "An error occurred while loading an expansion:", ex); logger.warning("Failed to load expansion from file '" + expansionFile + "'."); } } public void enableExpansion(@NotNull Expansion expansion) { State state = expansion.getState(); if (state == State.ENABLED) { return; } ICombatLogX plugin = getPlugin(); Logger logger = plugin.getLogger(); try { ExpansionDescription description = expansion.getDescription(); String fullName = description.getFullName(); logger.info("Enabling expansion '" + fullName + "'..."); expansion.setState(State.ENABLING); expansion.onEnable(); if (expansion.getState() == State.ENABLING) { expansion.setState(State.ENABLED); } } catch (Throwable ex) { logger.log(Level.SEVERE, "An error occurred while enabling an expansion:", ex); } } public void disableExpansion(@NotNull Expansion expansion) { State state = expansion.getState(); if (state != State.ENABLED && state != State.ENABLING) { return; } ICombatLogX plugin = getPlugin(); Logger logger = plugin.getLogger(); try { ExpansionDescription description = expansion.getDescription(); String fullName = description.getFullName(); logger.info("Disabling expansion '" + fullName + "'..."); List listenerList = expansion.getListeners(); listenerList.forEach(HandlerList::unregisterAll); listenerList.clear(); expansion.setState(State.DISABLED); expansion.onDisable(); } catch (Throwable ex) { logger.log(Level.SEVERE, "An error occurred while disabling an expansion:", ex); } } private @NotNull List sortExpansions(@NotNull List original) { ExpansionComparator comparator = new ExpansionComparator(); original.sort(comparator); return original; } private @NotNull YamlConfiguration getExpansionDescription(@NotNull JarFile jarFile) throws IllegalStateException, IOException, InvalidConfigurationException { JarEntry entry = jarFile.getJarEntry("expansion.yml"); if (entry == null) { String errorMessage = ("Expansion file '" + jarFile.getName() + "' does not contain an " + "expansion.yml file."); throw new IllegalStateException(errorMessage); } InputStream inputStream = jarFile.getInputStream(entry); InputStreamReader reader = new InputStreamReader(inputStream); BufferedReader buffer = new BufferedReader(reader); YamlConfiguration description = new YamlConfiguration(); description.load(buffer); return description; } } ================================================ FILE: api/src/main/java/com/github/sirblobman/combatlogx/api/expansion/ExpansionWithDependencies.java ================================================ package com.github.sirblobman.combatlogx.api.expansion; import java.util.logging.Logger; import org.jetbrains.annotations.NotNull; import com.github.sirblobman.combatlogx.api.ICombatLogX; public abstract class ExpansionWithDependencies extends Expansion { private boolean enabledSuccessfully; public ExpansionWithDependencies(@NotNull ICombatLogX plugin) { super(plugin); this.enabledSuccessfully = false; } @Override public final void onEnable() { if (!checkDependencies()) { Logger logger = getLogger(); logger.info("Some dependencies for this expansion are missing!"); selfDisable(); return; } onCheckedEnable(); this.enabledSuccessfully = true; } @Override public final void onDisable() { if (!isEnabledSuccessfully()) { return; } onCheckedDisable(); this.enabledSuccessfully = false; } public boolean isEnabledSuccessfully() { return this.enabledSuccessfully; } public abstract boolean checkDependencies(); public abstract void onCheckedEnable(); public abstract void onCheckedDisable(); } ================================================ FILE: api/src/main/java/com/github/sirblobman/combatlogx/api/expansion/disguise/DisguiseExpansion.java ================================================ package com.github.sirblobman.combatlogx.api.expansion.disguise; import org.jetbrains.annotations.NotNull; import com.github.sirblobman.combatlogx.api.ICombatLogX; import com.github.sirblobman.combatlogx.api.expansion.ExpansionWithDependencies; public abstract class DisguiseExpansion extends ExpansionWithDependencies { public DisguiseExpansion(@NotNull ICombatLogX plugin) { super(plugin); } @Override public void onLoad() { // Do Nothing } @Override public final void onCheckedEnable() { reloadConfig(); registerListeners(); afterEnable(); } @Override public final void onCheckedDisable() { afterDisable(); } @Override public void reloadConfig() { // Do Nothing } private void registerListeners() { new DisguiseListener(this).register(); } /** * You can override this method if you need to do something when the expansion is enabled. */ public void afterEnable() { // Do Nothing } /** * You can override this method if you need to do something when the expansion is disabled. */ public void afterDisable() { // Do Nothing } public abstract @NotNull DisguiseHandler getDisguiseHandler(); } ================================================ FILE: api/src/main/java/com/github/sirblobman/combatlogx/api/expansion/disguise/DisguiseExpansionListener.java ================================================ package com.github.sirblobman.combatlogx.api.expansion.disguise; import org.jetbrains.annotations.NotNull; import com.github.sirblobman.combatlogx.api.expansion.ExpansionListener; public abstract class DisguiseExpansionListener extends ExpansionListener { private final DisguiseExpansion expansion; public DisguiseExpansionListener(@NotNull DisguiseExpansion expansion) { super(expansion); this.expansion = expansion; } protected final @NotNull DisguiseExpansion getDisguiseExpansion() { return this.expansion; } protected final @NotNull DisguiseHandler getDisguiseHandler() { DisguiseExpansion expansion = getDisguiseExpansion(); return expansion.getDisguiseHandler(); } } ================================================ FILE: api/src/main/java/com/github/sirblobman/combatlogx/api/expansion/disguise/DisguiseHandler.java ================================================ package com.github.sirblobman.combatlogx.api.expansion.disguise; import org.jetbrains.annotations.NotNull; import org.bukkit.entity.Player; public abstract class DisguiseHandler { private final DE expansion; public DisguiseHandler(@NotNull DE expansion) { this.expansion = expansion; } protected final DE getExpansion() { return this.expansion; } public abstract boolean hasDisguise(@NotNull Player player); public abstract void removeDisguise(@NotNull Player player); } ================================================ FILE: api/src/main/java/com/github/sirblobman/combatlogx/api/expansion/disguise/DisguiseListener.java ================================================ package com.github.sirblobman.combatlogx.api.expansion.disguise; import org.jetbrains.annotations.NotNull; import org.bukkit.entity.Player; import org.bukkit.event.EventHandler; import org.bukkit.event.EventPriority; import com.github.sirblobman.api.language.LanguageManager; import com.github.sirblobman.combatlogx.api.event.PlayerTagEvent; public final class DisguiseListener extends DisguiseExpansionListener { public DisguiseListener(@NotNull DisguiseExpansion expansion) { super(expansion); } @EventHandler(priority = EventPriority.NORMAL, ignoreCancelled = true) public void onTag(PlayerTagEvent e) { Player player = e.getPlayer(); DisguiseHandler handler = getDisguiseHandler(); if (handler.hasDisguise(player)) { handler.removeDisguise(player); LanguageManager languageManager = getLanguageManager(); languageManager.sendMessageWithPrefix(player, "expansion.disguise-compatibility.remove-disguise"); } } } ================================================ FILE: api/src/main/java/com/github/sirblobman/combatlogx/api/expansion/region/RegionExpansion.java ================================================ package com.github.sirblobman.combatlogx.api.expansion.region; import java.io.File; import java.io.IOException; import java.util.logging.Level; import java.util.logging.Logger; import org.jetbrains.annotations.NotNull; import org.bukkit.configuration.file.YamlConfiguration; import com.github.sirblobman.api.configuration.ConfigurationManager; import com.github.sirblobman.api.plugin.ConfigurablePlugin; import com.github.sirblobman.combatlogx.api.ICombatLogX; import com.github.sirblobman.combatlogx.api.expansion.ExpansionWithDependencies; import com.github.sirblobman.combatlogx.api.expansion.region.configuration.RegionExpansionConfiguration; import com.github.sirblobman.combatlogx.api.expansion.region.listener.RegionMoveListener; import com.github.sirblobman.combatlogx.api.expansion.region.listener.RegionTeleportListener; import com.github.sirblobman.combatlogx.api.expansion.region.listener.RegionVulnerableListener; public abstract class RegionExpansion extends ExpansionWithDependencies { private final RegionExpansionConfiguration configuration; public RegionExpansion(@NotNull ICombatLogX plugin) { super(plugin); this.configuration = new RegionExpansionConfiguration(); } @Override public void onLoad() { File dataFolder = getDataFolder(); File configFile = new File(dataFolder, "config.yml"); if (!configFile.exists()) { saveDefaultRegionConfig(configFile); } } @Override public final void onCheckedEnable() { reloadConfig(); registerListeners(); afterEnable(); } @Override public final void onCheckedDisable() { afterDisable(); } private void registerListeners() { new RegionMoveListener(this).register(); new RegionTeleportListener(this).register(); new RegionVulnerableListener(this).register(); } @Override public void reloadConfig() { ConfigurationManager configurationManager = getConfigurationManager(); configurationManager.reload("config.yml"); getConfiguration().load(configurationManager.get("config.yml")); } public final @NotNull RegionExpansionConfiguration getConfiguration() { return this.configuration; } /** * You can override this method if you need to do something when the expansion is enabled. */ public void afterEnable() { // Do Nothing } /** * You can override this method if you need to do something when the expansion is disabled. */ public void afterDisable() { // Do Nothing } public abstract @NotNull RegionHandler getRegionHandler(); private void saveDefaultRegionConfig(File file) { ConfigurablePlugin plugin = getPlugin().getPlugin(); ConfigurationManager pluginConfigManager = plugin.getConfigurationManager(); try { String defaultConfigName = "default-region-expansion-config.yml"; YamlConfiguration defaultConfig = pluginConfigManager.getInternal(defaultConfigName); if (defaultConfig == null) { throw new IOException("Missing file 'default-region-expansion-config.yml' in jar."); } defaultConfig.save(file); } catch (IOException ex) { Logger logger = getLogger(); logger.log(Level.WARNING, "Failed to create the default region configuration:", ex); } } } ================================================ FILE: api/src/main/java/com/github/sirblobman/combatlogx/api/expansion/region/RegionHandler.java ================================================ package com.github.sirblobman.combatlogx.api.expansion.region; import java.util.Locale; import java.util.Map; import java.util.UUID; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.TimeUnit; import java.util.logging.Logger; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import org.bukkit.Location; import org.bukkit.entity.Entity; import org.bukkit.entity.Player; import org.bukkit.event.Cancellable; import org.bukkit.util.Vector; import com.github.sirblobman.api.folia.FoliaHelper; import com.github.sirblobman.api.folia.scheduler.TaskScheduler; import com.github.sirblobman.api.folia.teleport.TeleportHandler; import com.github.sirblobman.api.language.LanguageManager; import com.github.sirblobman.api.utility.VersionUtility; import com.github.sirblobman.combatlogx.api.ICombatLogX; import com.github.sirblobman.combatlogx.api.configuration.MainConfiguration; import com.github.sirblobman.combatlogx.api.expansion.region.configuration.RegionExpansionConfiguration; import com.github.sirblobman.combatlogx.api.expansion.region.task.KnockbackPlayerTask; import com.github.sirblobman.combatlogx.api.manager.ICombatManager; import com.github.sirblobman.combatlogx.api.object.NoEntryMode; import com.github.sirblobman.combatlogx.api.object.TagInformation; import com.github.sirblobman.combatlogx.api.object.TagType; public abstract class RegionHandler { private final RE expansion; private final Map cooldownMap; public RegionHandler(@NotNull RE expansion) { this.expansion = expansion; this.cooldownMap = new ConcurrentHashMap<>(); } protected final @NotNull RE getExpansion() { return this.expansion; } protected final @NotNull Logger getLogger() { RE expansion = getExpansion(); return expansion.getLogger(); } protected final void printDebug(@NotNull String message) { RE expansion = getExpansion(); ICombatLogX combatLogX = expansion.getPlugin(); MainConfiguration configuration = combatLogX.getConfiguration(); if (!configuration.isDebugMode()) { return; } Class thisClass = getClass(); String className = thisClass.getSimpleName(); String logMessage = String.format(Locale.US, "[Debug] [%s] %s", className, message); Logger expansionLogger = getLogger(); expansionLogger.info(logMessage); } private @NotNull RegionExpansionConfiguration getConfiguration() { RegionExpansion expansion = getExpansion(); return expansion.getConfiguration(); } public final void sendEntryDeniedMessage(@NotNull Player player, @NotNull TagInformation tagInformation) { TagType tagType = tagInformation.getCurrentTagType(); String messagePath = getEntryDeniedMessagePath(tagType); if (messagePath == null) { return; } UUID playerId = player.getUniqueId(); if (this.cooldownMap.containsKey(playerId)) { long expireMillis = this.cooldownMap.getOrDefault(playerId, 0L); long systemMillis = System.currentTimeMillis(); if (systemMillis < expireMillis) { return; } } ICombatLogX plugin = this.expansion.getPlugin(); LanguageManager languageManager = plugin.getLanguageManager(); languageManager.sendMessageWithPrefix(player, messagePath); long cooldownSeconds = getEntryDeniedMessageCooldown(); long cooldownMillis = TimeUnit.SECONDS.toMillis(cooldownSeconds); long systemMillis = System.currentTimeMillis(); long expireMillis = (systemMillis + cooldownMillis); this.cooldownMap.put(playerId, expireMillis); } public final void preventEntry(@NotNull Cancellable e, @NotNull Player player, @NotNull TagInformation tagInformation, @NotNull Location fromLocation, @NotNull Location toLocation) { RegionExpansion expansion = getExpansion(); ICombatLogX combatLogX = expansion.getPlugin(); ICombatManager combatManager = combatLogX.getCombatManager(); if (!combatManager.isInCombat(player)) { return; } Entity enemy = tagInformation.getCurrentEnemy(); NoEntryMode noEntryMode = getNoEntryMode(); if (noEntryMode != NoEntryMode.DISABLED) { if (player.isInsideVehicle()) { if (!player.leaveVehicle()) { printDebug("Failed to make a player leave their vehicle, there may be region entry prevention bugs."); } } } switch (noEntryMode) { case KILL_PLAYER: player.setHealth(0.0D); break; case TELEPORT_TO_ENEMY: teleportToEnemy(player, e, enemy); break; case CANCEL_EVENT: e.setCancelled(true); break; case KNOCKBACK_PLAYER: knockbackPlayer(player, e, fromLocation, toLocation); break; default: break; } sendEntryDeniedMessage(player, tagInformation); customPreventEntry(e, player, tagInformation, fromLocation, toLocation); } private void teleportToEnemy(@NotNull Player player, @NotNull Cancellable e, @Nullable Entity enemy) { if (enemy == null) { e.setCancelled(true); return; } FoliaHelper foliaHelper = getExpansion().getPlugin().getFoliaHelper(); TeleportHandler teleporter = foliaHelper.getTeleporter(); boolean teleport = teleporter.teleport(player, enemy).join(); if (teleport) { e.setCancelled(true); } } private void knockbackPlayer(@NotNull Player player, @NotNull Cancellable e, @NotNull Location fromLocation, @NotNull Location toLocation) { e.setCancelled(true); if (isGliding(player)) { player.setGliding(false); Vector zero = new Vector(0.0D, 0.0D, 0.0D); player.setVelocity(zero); } RegionExpansion expansion = getExpansion(); ICombatLogX combatLogX = expansion.getPlugin(); FoliaHelper foliaHelper = combatLogX.getFoliaHelper(); TaskScheduler scheduler = foliaHelper.getScheduler(); double strength = getKnockbackStrength(); KnockbackPlayerTask task = new KnockbackPlayerTask(combatLogX, player, fromLocation, toLocation, strength); scheduler.scheduleEntityTask(task); } protected void customPreventEntry(@NotNull Cancellable e, @NotNull Player player, @NotNull TagInformation tagInformation, @NotNull Location fromLocation, @NotNull Location toLocation) { // Override this to add custom stuff } public final long getEntryDeniedMessageCooldown() { RegionExpansionConfiguration configuration = getConfiguration(); return configuration.getMessageCooldown(); } public final @NotNull NoEntryMode getNoEntryMode() { RegionExpansionConfiguration configuration = getConfiguration(); return configuration.getNoEntryMode(); } public final double getKnockbackStrength() { RegionExpansionConfiguration configuration = getConfiguration(); return configuration.getKnockbackStrength(); } private boolean isGliding(@NotNull Player player) { int minorVersion = VersionUtility.getMinorVersion(); if (minorVersion < 9) { return false; } return player.isGliding(); } public abstract String getEntryDeniedMessagePath(@NotNull TagType tagType); public abstract boolean isSafeZone(@NotNull Player player, @NotNull Location location, @NotNull TagInformation tag); } ================================================ FILE: api/src/main/java/com/github/sirblobman/combatlogx/api/expansion/region/configuration/RegionExpansionConfiguration.java ================================================ package com.github.sirblobman.combatlogx.api.expansion.region.configuration; import java.util.Collection; import java.util.Collections; import java.util.EnumSet; import java.util.List; import java.util.Set; import org.jetbrains.annotations.NotNull; import org.bukkit.configuration.ConfigurationSection; import org.bukkit.event.player.PlayerTeleportEvent.TeleportCause; import com.github.sirblobman.api.configuration.IConfigurable; import com.github.sirblobman.combatlogx.api.object.NoEntryMode; import static com.github.sirblobman.api.utility.ConfigurationHelper.parseEnum; import static com.github.sirblobman.api.utility.ConfigurationHelper.parseEnums; public final class RegionExpansionConfiguration implements IConfigurable { private NoEntryMode noEntryMode; private double knockbackStrength; private int messageCooldown; private boolean preventTeleport; private Set ignoredTeleportCauseSet; public RegionExpansionConfiguration() { this.noEntryMode = NoEntryMode.KNOCKBACK_PLAYER; this.knockbackStrength = 1.5D; this.messageCooldown = 30; this.preventTeleport = true; this.ignoredTeleportCauseSet = EnumSet.noneOf(TeleportCause.class); } @Override public void load(ConfigurationSection config) { setKnockbackStrength(config.getDouble("knockback-strength", 1.5D)); setMessageCooldown(config.getInt("message-cooldown", 30)); setPreventTeleport(config.getBoolean("prevent-teleport", true)); String noEntryModeName = config.getString("no-entry-mode", "KNOCKBACK_PLAYER"); setNoEntryMode(parseEnum(NoEntryMode.class, noEntryModeName, NoEntryMode.KNOCKBACK_PLAYER)); List ignoredTeleportCauseNameList = config.getStringList("ignored-teleport-cause-list"); setIgnoredTeleportCauses(parseEnums(ignoredTeleportCauseNameList, TeleportCause.class)); } public boolean isPreventTeleport() { return this.preventTeleport; } public void setPreventTeleport(boolean preventTeleport) { this.preventTeleport = preventTeleport; } public @NotNull NoEntryMode getNoEntryMode() { return this.noEntryMode; } public void setNoEntryMode(@NotNull NoEntryMode noEntryMode) { this.noEntryMode = noEntryMode; } public double getKnockbackStrength() { return this.knockbackStrength; } public void setKnockbackStrength(double knockbackStrength) { this.knockbackStrength = knockbackStrength; } public int getMessageCooldown() { return this.messageCooldown; } public void setMessageCooldown(int messageCooldown) { this.messageCooldown = messageCooldown; } public @NotNull Set getIgnoredTeleportCauses() { return Collections.unmodifiableSet(this.ignoredTeleportCauseSet); } public void setIgnoredTeleportCauses(@NotNull Collection causes) { this.ignoredTeleportCauseSet.clear(); this.ignoredTeleportCauseSet.addAll(causes); } public boolean isIgnored(@NotNull TeleportCause cause) { Set causes = getIgnoredTeleportCauses(); return causes.contains(cause); } } ================================================ FILE: api/src/main/java/com/github/sirblobman/combatlogx/api/expansion/region/listener/RegionExpansionListener.java ================================================ package com.github.sirblobman.combatlogx.api.expansion.region.listener; import org.jetbrains.annotations.NotNull; import com.github.sirblobman.combatlogx.api.expansion.ExpansionListener; import com.github.sirblobman.combatlogx.api.expansion.region.RegionExpansion; import com.github.sirblobman.combatlogx.api.expansion.region.RegionHandler; import com.github.sirblobman.combatlogx.api.expansion.region.configuration.RegionExpansionConfiguration; public abstract class RegionExpansionListener extends ExpansionListener { private final RegionExpansion regionExpansion; public RegionExpansionListener(@NotNull RegionExpansion expansion) { super(expansion); this.regionExpansion = expansion; } protected final @NotNull RegionExpansion getRegionExpansion() { return this.regionExpansion; } protected final @NotNull RegionExpansionConfiguration getConfiguration() { RegionExpansion expansion = getRegionExpansion(); return expansion.getConfiguration(); } protected final @NotNull RegionHandler getRegionHandler() { RegionExpansion regionExpansion = getRegionExpansion(); return regionExpansion.getRegionHandler(); } } ================================================ FILE: api/src/main/java/com/github/sirblobman/combatlogx/api/expansion/region/listener/RegionMoveListener.java ================================================ package com.github.sirblobman.combatlogx.api.expansion.region.listener; import org.jetbrains.annotations.NotNull; import org.bukkit.Location; import org.bukkit.entity.Player; import org.bukkit.event.EventHandler; import org.bukkit.event.EventPriority; import org.bukkit.event.player.PlayerMoveEvent; import com.github.sirblobman.combatlogx.api.ICombatLogX; import com.github.sirblobman.combatlogx.api.expansion.region.RegionExpansion; import com.github.sirblobman.combatlogx.api.expansion.region.RegionHandler; import com.github.sirblobman.combatlogx.api.manager.ICombatManager; import com.github.sirblobman.combatlogx.api.object.TagInformation; public final class RegionMoveListener extends RegionExpansionListener { public RegionMoveListener(@NotNull RegionExpansion expansion) { super(expansion); } @EventHandler(priority = EventPriority.NORMAL, ignoreCancelled = true) public void onMove(PlayerMoveEvent e) { Location toLocation = e.getTo(); if (toLocation == null) { return; } Player player = e.getPlayer(); if (!isInCombat(player)) { return; } ICombatLogX combatLogX = getCombatLogX(); ICombatManager combatManager = combatLogX.getCombatManager(); TagInformation tagInformation = combatManager.getTagInformation(player); if (tagInformation == null) { return; } RegionHandler regionHandler = getRegionHandler(); if (regionHandler.isSafeZone(player, toLocation, tagInformation)) { Location fromLocation = e.getFrom(); if (!regionHandler.isSafeZone(player, fromLocation, tagInformation)) { regionHandler.preventEntry(e, player, tagInformation, fromLocation, toLocation); } } } } ================================================ FILE: api/src/main/java/com/github/sirblobman/combatlogx/api/expansion/region/listener/RegionTeleportListener.java ================================================ package com.github.sirblobman.combatlogx.api.expansion.region.listener; import org.jetbrains.annotations.NotNull; import org.bukkit.Location; import org.bukkit.entity.Player; import org.bukkit.event.EventHandler; import org.bukkit.event.EventPriority; import org.bukkit.event.player.PlayerTeleportEvent; import org.bukkit.event.player.PlayerTeleportEvent.TeleportCause; import com.github.sirblobman.combatlogx.api.expansion.region.RegionExpansion; import com.github.sirblobman.combatlogx.api.expansion.region.RegionHandler; import com.github.sirblobman.combatlogx.api.expansion.region.configuration.RegionExpansionConfiguration; import com.github.sirblobman.combatlogx.api.manager.ICombatManager; import com.github.sirblobman.combatlogx.api.object.TagInformation; public final class RegionTeleportListener extends RegionExpansionListener { public RegionTeleportListener(@NotNull RegionExpansion expansion) { super(expansion); } @EventHandler(priority = EventPriority.NORMAL, ignoreCancelled = true) public void onTeleport(PlayerTeleportEvent e) { TeleportCause cause = e.getCause(); RegionExpansionConfiguration configuration = getConfiguration(); if (configuration.isIgnored(cause)) { return; } Location toLocation = e.getTo(); if (toLocation == null) { return; } Player player = e.getPlayer(); if (!isInCombat(player)) { return; } ICombatManager combatManager = getCombatManager(); TagInformation tagInformation = combatManager.getTagInformation(player); if (tagInformation == null) { return; } RegionHandler regionHandler = getRegionHandler(); if (regionHandler.isSafeZone(player, toLocation, tagInformation)) { e.setCancelled(true); } } } ================================================ FILE: api/src/main/java/com/github/sirblobman/combatlogx/api/expansion/region/listener/RegionVulnerableListener.java ================================================ package com.github.sirblobman.combatlogx.api.expansion.region.listener; import java.util.Collections; import java.util.List; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import org.bukkit.Location; import org.bukkit.entity.Entity; import org.bukkit.entity.Player; import org.bukkit.event.EventHandler; import org.bukkit.event.EventPriority; import org.bukkit.event.entity.EntityDamageByEntityEvent; import com.github.sirblobman.api.utility.VersionUtility; import com.github.sirblobman.combatlogx.api.expansion.region.RegionExpansion; import com.github.sirblobman.combatlogx.api.expansion.region.RegionHandler; import com.github.sirblobman.combatlogx.api.expansion.region.configuration.RegionExpansionConfiguration; import com.github.sirblobman.combatlogx.api.manager.ICombatManager; import com.github.sirblobman.combatlogx.api.object.NoEntryMode; import com.github.sirblobman.combatlogx.api.object.TagInformation; public final class RegionVulnerableListener extends RegionExpansionListener { public RegionVulnerableListener(@NotNull RegionExpansion expansion) { super(expansion); } @EventHandler(priority = EventPriority.HIGHEST) public void onDamage(EntityDamageByEntityEvent e) { RegionExpansionConfiguration configuration = getConfiguration(); NoEntryMode noEntryMode = configuration.getNoEntryMode(); if (noEntryMode != NoEntryMode.VULNERABLE) { return; } Entity damaged = e.getEntity(); Player player = getPlayerOrPassenger(damaged); if (player == null) { return; } if (!isInCombat(player)) { return; } ICombatManager combatManager = getCombatManager(); TagInformation tagInformation = combatManager.getTagInformation(player); if (tagInformation == null) { return; } Entity damager = e.getDamager(); if (!tagInformation.isEnemy(damager)) { return; } Location location = player.getLocation(); RegionHandler regionHandler = getRegionHandler(); if (regionHandler.isSafeZone(player, location, tagInformation)) { e.setCancelled(false); } } private @Nullable Player getPlayerOrPassenger(@NotNull Entity entity) { if (entity instanceof Player) { return (Player) entity; } List passengerList = getPassengers(entity); if (passengerList.isEmpty()) { return null; } for (Entity passenger : passengerList) { if (passenger instanceof Player) { return (Player) passenger; } } return null; } private @NotNull List getPassengers(@NotNull Entity entity) { int minorVersion = VersionUtility.getMinorVersion(); return (minorVersion < 11 ? getPassengersLegacy(entity) : getPassengersModern(entity)); } private @NotNull List getPassengersModern(@NotNull Entity entity) { List passengerList = entity.getPassengers(); if (passengerList == null) { return Collections.emptyList(); } return Collections.unmodifiableList(passengerList); } @SuppressWarnings("deprecation") // Legacy Method private @NotNull List getPassengersLegacy(@NotNull Entity entity) { Entity passenger = entity.getPassenger(); if (passenger == null) { return Collections.emptyList(); } return Collections.singletonList(passenger); } } ================================================ FILE: api/src/main/java/com/github/sirblobman/combatlogx/api/expansion/region/task/KnockbackPlayerTask.java ================================================ package com.github.sirblobman.combatlogx.api.expansion.region.task; import org.jetbrains.annotations.NotNull; import org.bukkit.Location; import org.bukkit.entity.Player; import org.bukkit.util.Vector; import com.github.sirblobman.api.folia.details.EntityTaskDetails; import com.github.sirblobman.combatlogx.api.ICombatLogX; public final class KnockbackPlayerTask extends EntityTaskDetails { private final Location from; private final Location to; private final double strength; public KnockbackPlayerTask(@NotNull ICombatLogX plugin, @NotNull Player entity, @NotNull Location from, @NotNull Location to, double strength) { super(plugin.getPlugin(), entity); this.from = from; this.to = to; this.strength = strength; } private @NotNull Location getFrom() { return this.from; } private @NotNull Location getTo() { return this.to; } private double getKnockbackStrength() { return this.strength; } @Override public void run() { Player player = getEntity(); if (player == null) { return; } Location from = getFrom(); Location to = getTo(); knockbackPlayer(player, from, to); } private void knockbackPlayer(@NotNull Player player, @NotNull Location from, @NotNull Location to) { Vector velocity = getKnockback(from, to); player.setVelocity(velocity); } private @NotNull Vector getKnockback(@NotNull Location from, @NotNull Location to) { Vector fromVector = from.toVector(); Vector toVector = to.toVector(); Vector subtract = fromVector.subtract(toVector); Vector normal = subtract.normalize(); double strength = getKnockbackStrength(); Vector multiply = normal.multiply(strength); return makeFinite(multiply); } private @NotNull Vector makeFinite(@NotNull Vector original) { double originalX = original.getX(); double originalY = original.getY(); double originalZ = original.getZ(); double newX = makeFinite(originalX); double newY = makeFinite(originalY); double newZ = makeFinite(originalZ); return new Vector(newX, newY, newZ); } private double makeFinite(double original) { if (Double.isNaN(original)) { return 0.0D; } if (Double.isInfinite(original)) { return (original < 0 ? -1.0D : 1.0D); } return original; } } ================================================ FILE: api/src/main/java/com/github/sirblobman/combatlogx/api/expansion/skyblock/IslandWrapper.java ================================================ package com.github.sirblobman.combatlogx.api.expansion.skyblock; import java.util.Set; import java.util.UUID; import org.jetbrains.annotations.NotNull; import org.bukkit.OfflinePlayer; public abstract class IslandWrapper { public abstract @NotNull Set getMembers(); public boolean isMember(@NotNull OfflinePlayer player) { UUID playerId = player.getUniqueId(); Set memberIdSet = getMembers(); return memberIdSet.contains(playerId); } } ================================================ FILE: api/src/main/java/com/github/sirblobman/combatlogx/api/expansion/skyblock/SkyBlockExpansion.java ================================================ package com.github.sirblobman.combatlogx.api.expansion.skyblock; import org.jetbrains.annotations.NotNull; import com.github.sirblobman.combatlogx.api.ICombatLogX; import com.github.sirblobman.combatlogx.api.expansion.ExpansionWithDependencies; public abstract class SkyBlockExpansion extends ExpansionWithDependencies { public SkyBlockExpansion(@NotNull ICombatLogX plugin) { super(plugin); } @Override public void onLoad() { // Do Nothing } @Override public final void onCheckedEnable() { reloadConfig(); registerListeners(); afterEnable(); } @Override public final void onCheckedDisable() { afterDisable(); } @Override public void reloadConfig() { // Do Nothing } private void registerListeners() { new SkyBlockListener(this).register(); } /** * You can override this method if you need to do something when the expansion is enabled. */ public void afterEnable() { // Do Nothing } /** * You can override this method if you need to do something when the expansion is disabled. */ public void afterDisable() { // Do Nothing } public abstract @NotNull SkyBlockHandler getSkyBlockHandler(); } ================================================ FILE: api/src/main/java/com/github/sirblobman/combatlogx/api/expansion/skyblock/SkyBlockExpansionListener.java ================================================ package com.github.sirblobman.combatlogx.api.expansion.skyblock; import org.jetbrains.annotations.NotNull; import com.github.sirblobman.combatlogx.api.expansion.ExpansionListener; public abstract class SkyBlockExpansionListener extends ExpansionListener { private final SkyBlockExpansion expansion; public SkyBlockExpansionListener(@NotNull SkyBlockExpansion expansion) { super(expansion); this.expansion = expansion; } protected final @NotNull SkyBlockExpansion getSkyBlockExpansion() { return this.expansion; } protected final @NotNull SkyBlockHandler getSkyBlockHandler() { SkyBlockExpansion expansion = getSkyBlockExpansion(); return expansion.getSkyBlockHandler(); } } ================================================ FILE: api/src/main/java/com/github/sirblobman/combatlogx/api/expansion/skyblock/SkyBlockHandler.java ================================================ package com.github.sirblobman.combatlogx.api.expansion.skyblock; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import org.bukkit.Location; import org.bukkit.OfflinePlayer; public abstract class SkyBlockHandler { private final SE expansion; public SkyBlockHandler(@NotNull SE expansion) { this.expansion = expansion; } protected final SE getExpansion() { return this.expansion; } public abstract @Nullable IslandWrapper getIsland(@NotNull Location location); public abstract @Nullable IslandWrapper getIsland(@NotNull OfflinePlayer player); public abstract boolean doesIslandMatch(@NotNull OfflinePlayer player1, @NotNull OfflinePlayer player2); } ================================================ FILE: api/src/main/java/com/github/sirblobman/combatlogx/api/expansion/skyblock/SkyBlockListener.java ================================================ package com.github.sirblobman.combatlogx.api.expansion.skyblock; import org.jetbrains.annotations.NotNull; import org.bukkit.entity.Entity; import org.bukkit.entity.Player; import org.bukkit.event.EventHandler; import org.bukkit.event.EventPriority; import com.github.sirblobman.combatlogx.api.event.PlayerPreTagEvent; public final class SkyBlockListener extends SkyBlockExpansionListener { public SkyBlockListener(@NotNull SkyBlockExpansion expansion) { super(expansion); } @EventHandler(priority = EventPriority.NORMAL, ignoreCancelled = true) public void beforeTag(PlayerPreTagEvent e) { Entity enemy = e.getEnemy(); if (!(enemy instanceof Player)) { return; } Player player = e.getPlayer(); Player enemyPlayer = (Player) enemy; SkyBlockHandler handler = getSkyBlockHandler(); if (handler.doesIslandMatch(player, enemyPlayer)) { e.setCancelled(true); } } } ================================================ FILE: api/src/main/java/com/github/sirblobman/combatlogx/api/expansion/vanish/VanishExpansion.java ================================================ package com.github.sirblobman.combatlogx.api.expansion.vanish; import org.jetbrains.annotations.NotNull; import com.github.sirblobman.api.configuration.ConfigurationManager; import com.github.sirblobman.combatlogx.api.ICombatLogX; import com.github.sirblobman.combatlogx.api.expansion.ExpansionWithDependencies; public abstract class VanishExpansion extends ExpansionWithDependencies { private final VanishExpansionConfiguration configuration; public VanishExpansion(@NotNull ICombatLogX plugin) { super(plugin); this.configuration = new VanishExpansionConfiguration(); } @Override public void onLoad() { ConfigurationManager configurationManager = getConfigurationManager(); configurationManager.saveDefault("config.yml"); } @Override public final void onCheckedEnable() { reloadConfig(); registerListeners(); afterEnable(); } @Override public final void onCheckedDisable() { afterDisable(); } private void registerListeners() { new VanishListener(this).register(); } @Override public void reloadConfig() { ConfigurationManager configurationManager = getConfigurationManager(); configurationManager.reload("config.yml"); getConfiguration().load(configurationManager.get("config.yml")); } public final @NotNull VanishExpansionConfiguration getConfiguration() { return this.configuration; } /** * You can override this method if you need to do something when the expansion is enabled. */ public void afterEnable() { // Do Nothing } /** * You can override this method if you need to do something when the expansion is disabled. */ public void afterDisable() { // Do Nothing } public abstract @NotNull VanishHandler getVanishHandler(); } ================================================ FILE: api/src/main/java/com/github/sirblobman/combatlogx/api/expansion/vanish/VanishExpansionConfiguration.java ================================================ package com.github.sirblobman.combatlogx.api.expansion.vanish; import org.jetbrains.annotations.NotNull; import org.bukkit.configuration.ConfigurationSection; import com.github.sirblobman.api.configuration.IConfigurable; public final class VanishExpansionConfiguration implements IConfigurable { private boolean preventVanishTaggingSelf; private boolean preventVanishTaggingOther; public VanishExpansionConfiguration() { this.preventVanishTaggingSelf = true; this.preventVanishTaggingOther = true; } @Override public void load(@NotNull ConfigurationSection section) { setPreventVanishTaggingSelf(section.getBoolean("prevent-vanish-tagging-self", true)); setPreventVanishTaggingOther(section.getBoolean("prevent-vanish-tagging-other", true)); } public boolean isPreventVanishTaggingSelf() { return this.preventVanishTaggingSelf; } public void setPreventVanishTaggingSelf(boolean preventVanishTaggingSelf) { this.preventVanishTaggingSelf = preventVanishTaggingSelf; } public boolean isPreventVanishTaggingOther() { return this.preventVanishTaggingOther; } public void setPreventVanishTaggingOther(boolean preventVanishTaggingOther) { this.preventVanishTaggingOther = preventVanishTaggingOther; } } ================================================ FILE: api/src/main/java/com/github/sirblobman/combatlogx/api/expansion/vanish/VanishExpansionListener.java ================================================ package com.github.sirblobman.combatlogx.api.expansion.vanish; import org.jetbrains.annotations.NotNull; import com.github.sirblobman.combatlogx.api.expansion.ExpansionListener; public abstract class VanishExpansionListener extends ExpansionListener { private final VanishExpansion expansion; ; public VanishExpansionListener(@NotNull VanishExpansion expansion) { super(expansion); this.expansion = expansion; } protected final @NotNull VanishExpansion getVanishExpansion() { return this.expansion; } protected final @NotNull VanishHandler getVanishHandler() { VanishExpansion expansion = getVanishExpansion(); return expansion.getVanishHandler(); } protected final @NotNull VanishExpansionConfiguration getConfiguration() { VanishExpansion expansion = getVanishExpansion(); return expansion.getConfiguration(); } protected final boolean isPreventSelfTag() { VanishExpansionConfiguration configuration = getConfiguration(); return configuration.isPreventVanishTaggingSelf(); } protected final boolean isPreventOtherTag() { VanishExpansionConfiguration configuration = getConfiguration(); return configuration.isPreventVanishTaggingOther(); } } ================================================ FILE: api/src/main/java/com/github/sirblobman/combatlogx/api/expansion/vanish/VanishHandler.java ================================================ package com.github.sirblobman.combatlogx.api.expansion.vanish; import org.jetbrains.annotations.NotNull; import org.bukkit.entity.Player; public abstract class VanishHandler { private final VE expansion; public VanishHandler(@NotNull VE expansion) { this.expansion = expansion; } protected final VE getExpansion() { return this.expansion; } public abstract boolean isVanished(@NotNull Player player); } ================================================ FILE: api/src/main/java/com/github/sirblobman/combatlogx/api/expansion/vanish/VanishListener.java ================================================ package com.github.sirblobman.combatlogx.api.expansion.vanish; import org.jetbrains.annotations.NotNull; import org.bukkit.entity.Entity; import org.bukkit.entity.Player; import org.bukkit.event.EventHandler; import org.bukkit.event.EventPriority; import com.github.sirblobman.combatlogx.api.event.PlayerPreTagEvent; public final class VanishListener extends VanishExpansionListener { public VanishListener(@NotNull VanishExpansion expansion) { super(expansion); } @EventHandler(priority = EventPriority.NORMAL, ignoreCancelled = true) public void beforeTag(PlayerPreTagEvent e) { Player player = e.getPlayer(); VanishHandler vanishHandler = getVanishHandler(); if (vanishHandler.isVanished(player) && isPreventSelfTag()) { e.setCancelled(true); return; } Entity enemy = e.getEnemy(); if (enemy instanceof Player) { Player other = (Player) enemy; if (vanishHandler.isVanished(other) && isPreventOtherTag()) { e.setCancelled(true); } } } } ================================================ FILE: api/src/main/java/com/github/sirblobman/combatlogx/api/listener/CombatListener.java ================================================ package com.github.sirblobman.combatlogx.api.listener; import java.util.Locale; import java.util.logging.Logger; import org.jetbrains.annotations.NotNull; import org.bukkit.Bukkit; import org.bukkit.World; import org.bukkit.entity.Entity; import org.bukkit.entity.Player; import org.bukkit.event.Listener; import org.bukkit.plugin.PluginManager; import org.bukkit.plugin.java.JavaPlugin; import com.github.sirblobman.api.configuration.PlayerDataManager; import com.github.sirblobman.api.language.LanguageManager; import com.github.sirblobman.api.plugin.ConfigurablePlugin; import com.github.sirblobman.combatlogx.api.ICombatLogX; import com.github.sirblobman.combatlogx.api.configuration.MainConfiguration; import com.github.sirblobman.combatlogx.api.manager.ICombatManager; import com.github.sirblobman.combatlogx.api.manager.IDeathManager; public abstract class CombatListener implements Listener { private final ICombatLogX plugin; public CombatListener(@NotNull ICombatLogX plugin) { this.plugin = plugin; } public void register() { ICombatLogX combatLogX = getCombatLogX(); JavaPlugin plugin = combatLogX.getPlugin(); PluginManager pluginManager = Bukkit.getPluginManager(); pluginManager.registerEvents(this, plugin); } protected final @NotNull ICombatLogX getCombatLogX() { return this.plugin; } protected final @NotNull ConfigurablePlugin getJavaPlugin() { ICombatLogX combatLogX = getCombatLogX(); return combatLogX.getPlugin(); } protected final @NotNull Logger getPluginLogger() { ICombatLogX plugin = getCombatLogX(); return plugin.getLogger(); } protected final @NotNull LanguageManager getLanguageManager() { ICombatLogX combatLogX = getCombatLogX(); return combatLogX.getLanguageManager(); } protected final @NotNull PlayerDataManager getPlayerDataManager() { ICombatLogX combatLogX = getCombatLogX(); return combatLogX.getPlayerDataManager(); } protected final @NotNull ICombatManager getCombatManager() { ICombatLogX plugin = getCombatLogX(); return plugin.getCombatManager(); } protected final @NotNull IDeathManager getDeathManager() { ICombatLogX plugin = getCombatLogX(); return plugin.getDeathManager(); } protected final boolean isInCombat(@NotNull Player player) { ICombatManager combatManager = getCombatManager(); return combatManager.isInCombat(player); } protected final boolean isDebugModeDisabled() { ICombatLogX plugin = getCombatLogX(); return plugin.isDebugModeDisabled(); } protected void printDebug(@NotNull String message) { if (isDebugModeDisabled()) { return; } Class thisClass = getClass(); String className = thisClass.getSimpleName(); String logMessage = String.format(Locale.US, "[Debug] [%s] %s", className, message); Logger pluginLogger = getPluginLogger(); pluginLogger.info(logMessage); } protected final boolean isWorldDisabled(@NotNull Entity entity) { World world = entity.getWorld(); return isWorldDisabled(world); } protected final boolean isWorldDisabled(@NotNull World world) { ICombatLogX combatLogX = getCombatLogX(); MainConfiguration configuration = combatLogX.getConfiguration(); return configuration.isDisabled(world); } } ================================================ FILE: api/src/main/java/com/github/sirblobman/combatlogx/api/manager/ICombatManager.java ================================================ package com.github.sirblobman.combatlogx.api.manager; import java.util.List; import java.util.Set; import java.util.UUID; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import org.bukkit.entity.Entity; import org.bukkit.entity.Player; import org.bukkit.permissions.Permission; import com.github.sirblobman.combatlogx.api.ICombatLogXNeeded; import com.github.sirblobman.combatlogx.api.object.TagInformation; import com.github.sirblobman.combatlogx.api.object.TagReason; import com.github.sirblobman.combatlogx.api.object.TagType; import com.github.sirblobman.combatlogx.api.object.UntagReason; public interface ICombatManager extends ICombatLogXNeeded { /** * CombatTag a player into combat. * * @param player The {@link Player} to tag. * @param enemy The enemy that caused the player to be tagged. Can be {@code null} * @param tagType The type of tag, can be {@link TagType#UNKNOWN} * @param tagReason The reason for being tagged, can be {@link TagReason#UNKNOWN} * @return {@code true} if the player was successfully tagged. */ boolean tag(@NotNull Player player, @Nullable Entity enemy, @NotNull TagType tagType, @NotNull TagReason tagReason); /** * CombatTag a player into combat. * * @param player The {@link Player} to tag. * @param enemy The enemy that caused the player to be tagged. Can be {@code null} * @param tagType The type of tag, can be {@link TagType#UNKNOWN} * @param tagReason The reason for being tagged, can be {@link TagReason#UNKNOWN} * @param customEndMillis A custom timestamp for ending combat if the player is not tagged again. * @return {@code true} if the player was successfully tagged. */ boolean tag(@NotNull Player player, @Nullable Entity enemy, @NotNull TagType tagType, @NotNull TagReason tagReason, long customEndMillis); /** * Remove a player from combat with all enemies. * * @param player The {@link Player} to remove. * @param untagReason The reason for removing the player. Usually {@link UntagReason#EXPIRE} */ void untag(@NotNull Player player, @NotNull UntagReason untagReason); /** * Remove a player from combat with a specific enemy. * * @param player The {@link Player} to remove. * @param enemy The enemy to remove. * @param untagReason The reason for removing the player. Usually {@link UntagReason#EXPIRE} */ void untag(@NotNull Player player, @NotNull Entity enemy, @NotNull UntagReason untagReason); /** * Check if a player is tagged into combat. * * @param player The {@link Player} to check. * @return {@code true} if the player is currently tagged into combat. */ boolean isInCombat(@NotNull Player player); /** * @return A list of player ids that are currently tagged into combat. */ @NotNull Set getPlayerIdsInCombat(); /** * @return A list of players that are currently tagged into combat. */ @NotNull List getPlayersInCombat(); /** * Get combat tag information for the specified player. * * @param player The {@link Player} to check. * @return Information about a players combat tag, or {@code null} if the player is not tagged into combat. */ @Nullable TagInformation getTagInformation(@NotNull Player player); /** * Get the amount of seconds in combat this player will be tagged for. * * @param player The {@link Player} to check. * @return A number of seconds based on a permission or a global configuration setting. */ int getMaxTimerSeconds(@NotNull Player player); /** * @return The current bypass permission, or {@code null} if one is not set. */ @Nullable Permission getBypassPermission(); /** * Check if a player is able to bypass a combat tag. * * @param player The {@link Player} to check. * @return {@code true} if the player can bypass a combat tag. */ boolean canBypass(@NotNull Player player); } ================================================ FILE: api/src/main/java/com/github/sirblobman/combatlogx/api/manager/ICrystalManager.java ================================================ package com.github.sirblobman.combatlogx.api.manager; import java.util.UUID; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import org.bukkit.entity.Entity; import org.bukkit.entity.Player; import com.github.sirblobman.combatlogx.api.ICombatLogXNeeded; public interface ICrystalManager extends ICombatLogXNeeded { @Nullable Player getPlacer(@NotNull Entity crystal); void setPlacer(@NotNull Entity crystal, @NotNull Player player); void remove(@NotNull UUID crystalId); } ================================================ FILE: api/src/main/java/com/github/sirblobman/combatlogx/api/manager/IDeathManager.java ================================================ package com.github.sirblobman.combatlogx.api.manager; import java.util.List; import org.jetbrains.annotations.NotNull; import org.bukkit.entity.Entity; import org.bukkit.entity.Player; import com.github.sirblobman.combatlogx.api.ICombatLogXNeeded; public interface IDeathManager extends ICombatLogXNeeded { /** * Track and kill a player. * The player will be killed by setting their health to zero. * * @param player The {@link Player} to kill. */ void kill(@NotNull Player player, @NotNull List enemyList); /** * Check if a player was killed while tracked. * * @param player The {@link Player} to check. * @return {@code true} if the player died from CombatLogX, * {@code false} if they were killed by any other reason. */ boolean wasPunishKilled(@NotNull Player player); /** * Stop tracking a player. * * @param player The {@link Player} to stop tracking. * @return {@code true} if the player was previously being tracked. */ boolean stopTracking(@NotNull Player player); /** * @param player The player to check. * @return A list of tracked enemies for the player. */ @NotNull List getTrackedEnemies(@NotNull Player player); } ================================================ FILE: api/src/main/java/com/github/sirblobman/combatlogx/api/manager/IForgiveManager.java ================================================ package com.github.sirblobman.combatlogx.api.manager; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import org.bukkit.OfflinePlayer; import com.github.sirblobman.combatlogx.api.ICombatLogXNeeded; import com.github.sirblobman.combatlogx.api.object.CombatTag; public interface IForgiveManager extends ICombatLogXNeeded { boolean getToggleValue(@NotNull OfflinePlayer player); void setToggle(@NotNull OfflinePlayer player, boolean value); @Nullable CombatTag getActiveRequest(@NotNull OfflinePlayer player); void setRequest(@NotNull OfflinePlayer player, @NotNull CombatTag request); void removeRequest(@NotNull OfflinePlayer player); } ================================================ FILE: api/src/main/java/com/github/sirblobman/combatlogx/api/manager/IPlaceholderManager.java ================================================ package com.github.sirblobman.combatlogx.api.manager; import java.util.List; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import org.bukkit.entity.Entity; import org.bukkit.entity.Player; import com.github.sirblobman.combatlogx.api.ICombatLogXNeeded; import com.github.sirblobman.combatlogx.api.placeholder.IPlaceholderExpansion; import com.github.sirblobman.api.shaded.adventure.text.Component; public interface IPlaceholderManager extends ICombatLogXNeeded { void registerPlaceholderExpansion(@NotNull IPlaceholderExpansion expansion); @Nullable IPlaceholderExpansion getPlaceholderExpansion(@NotNull String id); @NotNull List getPlaceholderExpansions(); @Nullable String getPlaceholderReplacement(@NotNull Player player, @NotNull List enemyList, @NotNull String placeholder); @Nullable Component getPlaceholderReplacementComponent(@NotNull Player player, @NotNull List enemyList, @NotNull String placeholder); @NotNull String replaceAll(@NotNull Player player, @NotNull List enemyList, @NotNull String string); void runReplacedCommands(@NotNull Player player, @NotNull List enemyList, @NotNull Iterable commands); } ================================================ FILE: api/src/main/java/com/github/sirblobman/combatlogx/api/manager/IPunishManager.java ================================================ package com.github.sirblobman.combatlogx.api.manager; import java.util.List; import org.jetbrains.annotations.NotNull; import org.bukkit.OfflinePlayer; import org.bukkit.entity.Entity; import org.bukkit.entity.Player; import com.github.sirblobman.combatlogx.api.ICombatLogXNeeded; import com.github.sirblobman.combatlogx.api.object.UntagReason; public interface IPunishManager extends ICombatLogXNeeded { /** * Punish a player for logging out during combat. * Also called when expire punishing is enabled in the configuration. * * @param player The {@link Player} to punish. * @param punishReason The original reason that the player was removed from combat. * @param previousEnemies The list of enemies that the player had when they were untagged. * @return {@code true} if the plugin was able to punish the player successfully. */ boolean punish(@NotNull Player player, @NotNull UntagReason punishReason, @NotNull List previousEnemies); /** * Get the total amount of times a player was punished. * If the punishment tracker is disabled, this will always return a value of zero. * * @param player The {@link Player} to check. * @return The amount of times the player was punished. */ long getPunishmentCount(@NotNull OfflinePlayer player); void resetPunishmentCount(@NotNull OfflinePlayer player); } ================================================ FILE: api/src/main/java/com/github/sirblobman/combatlogx/api/manager/ITimerManager.java ================================================ package com.github.sirblobman.combatlogx.api.manager; import java.util.Set; import org.jetbrains.annotations.NotNull; import org.bukkit.entity.Player; import com.github.sirblobman.combatlogx.api.ICombatLogXNeeded; import com.github.sirblobman.combatlogx.api.object.TimerUpdater; public interface ITimerManager extends ICombatLogXNeeded { /** * @return A {@link Set} of {@link TimerUpdater}s that are currently registered. */ @NotNull Set getTimerUpdaters(); /** * Register a {@link TimerUpdater} instance. * * @param task The instance to register. */ void addUpdaterTask(@NotNull TimerUpdater task); /** * Remove all timers in this manager from the player. * * @param player The {@link Player} to remove the timers from. */ void remove(@NotNull Player player); /** * Register the manager */ void register(); } ================================================ FILE: api/src/main/java/com/github/sirblobman/combatlogx/api/object/CitizensSlotType.java ================================================ package com.github.sirblobman.combatlogx.api.object; import com.github.sirblobman.combatlogx.api.event.NPCDropItemEvent; /** * Citizens slot type, used for the {@link NPCDropItemEvent} * * @author SizzleMcGrizzle */ public enum CitizensSlotType { /** * Represents an item from the armor content of an inventory */ ARMOR, /** * Represents an item from the main container of an inventory (excludes offhand, includes mainhand) */ INVENTORY, /** * Represents an item from the off-hand of an inventory */ OFFHAND } ================================================ FILE: api/src/main/java/com/github/sirblobman/combatlogx/api/object/CombatTag.java ================================================ package com.github.sirblobman.combatlogx.api.object; import java.lang.ref.WeakReference; import java.util.UUID; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import org.bukkit.entity.Entity; public final class CombatTag implements Comparable { private final UUID enemyId; private final WeakReference enemyReference; private final TagType tagType; private final TagReason tagReason; private final long expireMillis; public CombatTag(@Nullable Entity enemy, @NotNull TagType tagType, @NotNull TagReason tagReason, long expireMillis) { if (enemy != null) { this.enemyId = enemy.getUniqueId(); this.enemyReference = new WeakReference<>(enemy); } else { this.enemyId = null; this.enemyReference = null; } this.tagType = tagType; this.tagReason = tagReason; this.expireMillis = expireMillis; } public @Nullable UUID getEnemyId() { return this.enemyId; } public @Nullable Entity getEnemy() { if (this.enemyReference == null) { return null; } return this.enemyReference.get(); } public boolean doesEnemyMatch(@NotNull Entity entity) { Entity enemy = getEnemy(); return (entity == enemy); } public @NotNull TagType getTagType() { return this.tagType; } public @NotNull TagReason getTagReason() { return this.tagReason; } public long getExpireMillis() { return this.expireMillis; } public boolean isExpired() { long systemMillis = System.currentTimeMillis(); long expireMillis = getExpireMillis(); return (systemMillis >= expireMillis); } @Override public int compareTo(@NotNull CombatTag other) { long thisExpireMillis = getExpireMillis(); long otherExpireMillis = other.getExpireMillis(); return Long.compare(thisExpireMillis, otherExpireMillis); } } ================================================ FILE: api/src/main/java/com/github/sirblobman/combatlogx/api/object/KillTime.java ================================================ package com.github.sirblobman.combatlogx.api.object; import com.github.sirblobman.combatlogx.api.configuration.PunishConfiguration; /** * The time that CombatLogX will kill players. * * @see PunishConfiguration#getKillTime() */ public enum KillTime { /** * Kill the player the instant that they disconnect from the server. */ QUIT, /** * Kill the player as soon as they log back in to the server. */ JOIN, /** * Tell CombatLogX to not handle player killing. */ NEVER } ================================================ FILE: api/src/main/java/com/github/sirblobman/combatlogx/api/object/NoEntryMode.java ================================================ package com.github.sirblobman.combatlogx.api.object; /** * No Entry Mode is used in region compatibility expansions. */ public enum NoEntryMode { /** * Tell the region expansion to not prevent entry. */ DISABLED, /** * The player will still take damage from their enemy even if they are in non-pvp areas. */ VULNERABLE, /** * The event will be cancelled. (e.g. undo move, prevent teleport) */ CANCEL_EVENT, /** * The player will be killed. */ KILL_PLAYER, /** * The player will be teleported to their enemy. */ TELEPORT_TO_ENEMY, /** * The player will be pushed away from the region with velocity. This option may trigger some anti-cheat plugins. */ KNOCKBACK_PLAYER } ================================================ FILE: api/src/main/java/com/github/sirblobman/combatlogx/api/object/SpecialPunishCommand.java ================================================ package com.github.sirblobman.combatlogx.api.object; import java.util.ArrayList; import java.util.Collection; import java.util.Collections; import java.util.List; import org.jetbrains.annotations.NotNull; import org.bukkit.configuration.ConfigurationSection; import com.github.sirblobman.api.configuration.IConfigurable; import com.github.sirblobman.api.utility.Validate; public final class SpecialPunishCommand implements IConfigurable { private final String id; private final List commandList; private int amountMin; private int amountMax; private boolean reset; public SpecialPunishCommand(@NotNull String id) { this.id = Validate.notEmpty(id, "id must not be empty!"); this.amountMin = 0; this.amountMax = 0; this.reset = false; this.commandList = new ArrayList<>(); } public @NotNull String getId() { return this.id; } @Override public void load(ConfigurationSection section) { ConfigurationSection amountSection = getOrCreateSection(section, "amount"); setAmountMin(amountSection.getInt("min", 0)); setAmountMax(amountSection.getInt("max", 0)); setReset(section.getBoolean("reset", false)); setCommands(section.getStringList("command-list")); } public int getAmountMin() { return amountMin; } public void setAmountMin(int amountMin) { this.amountMin = amountMin; } public int getAmountMax() { return amountMax; } public void setAmountMax(int amountMax) { this.amountMax = amountMax; } public boolean isReset() { return reset; } public void setReset(boolean reset) { this.reset = reset; } public @NotNull List getCommands() { return Collections.unmodifiableList(this.commandList); } public void setCommands(@NotNull Collection commands) { this.commandList.clear(); this.commandList.addAll(commands); } } ================================================ FILE: api/src/main/java/com/github/sirblobman/combatlogx/api/object/TagInformation.java ================================================ package com.github.sirblobman.combatlogx.api.object; import java.util.ArrayList; import java.util.Collections; import java.util.List; import java.util.UUID; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import org.bukkit.Bukkit; import org.bukkit.OfflinePlayer; import org.bukkit.entity.Entity; import org.bukkit.entity.Player; import com.github.sirblobman.api.utility.Validate; public final class TagInformation { private final UUID playerId; private final List tagList; public TagInformation(@NotNull OfflinePlayer player) { this(player.getUniqueId()); } public TagInformation(@NotNull UUID playerId) { this.playerId = playerId; this.tagList = new ArrayList<>(); } /** * @return The {@link UUID} of the player that is tagged. */ public @NotNull UUID getPlayerId() { return this.playerId; } /** * @return The {@link OfflinePlayer} that is tagged. * Can be null if the server cache is removed or the player doesn't exist. * @see #getPlayerId() */ public @Nullable OfflinePlayer getOfflinePlayer() { UUID playerId = getPlayerId(); return Bukkit.getOfflinePlayer(playerId); } /** * @return The {@link Player} that is tagged. * Can be null if the player is offline. * @see #getPlayerId() */ public @Nullable Player getPlayer() { UUID playerId = getPlayerId(); return Bukkit.getPlayer(playerId); } /** * @return A list of tags the player currently has. * The list is sorted by descending expire time. */ public @NotNull List getTags() { List tagList = new ArrayList<>(this.tagList); tagList.sort(Collections.reverseOrder()); return Collections.unmodifiableList(tagList); } /** * @return A list of entity {@link UUID}s that the player is currently tagged with. * The list is sorted by descending expire time. */ public @NotNull List getEnemyIds() { List tagList = getTags(); List enemyIdList = new ArrayList<>(); for (CombatTag combatTag : tagList) { UUID enemyId = combatTag.getEnemyId(); if (enemyId != null) { enemyIdList.add(enemyId); } } return Collections.unmodifiableList(enemyIdList); } /** * @return A list of {@link Entity} objects that the player is currently tagged with. * The list is sorted by descending expire time. */ public @NotNull List getEnemies() { List tagList = getTags(); List enemyList = new ArrayList<>(); for (CombatTag combatTag : tagList) { Entity enemy = combatTag.getEnemy(); if (enemy != null) { enemyList.add(enemy); } } return Collections.unmodifiableList(enemyList); } public boolean isEnemy(@NotNull Entity entity) { List tagList = getTags(); for (CombatTag combatTag : tagList) { if (combatTag.doesEnemyMatch(entity)) { return true; } } return false; } public void addTag(@NotNull CombatTag combatTag) { if (combatTag.isExpired()) { throw new IllegalArgumentException("combatTag is already expired!"); } if (this.tagList.contains(combatTag)) { throw new IllegalArgumentException("The player already has that combat tag."); } this.tagList.removeIf(otherTag -> otherTag.doesEnemyMatch(combatTag.getEnemy())); this.tagList.add(combatTag); } public void removeEnemy(@NotNull Entity entity) { this.tagList.removeIf(combatTag -> combatTag.doesEnemyMatch(entity)); } public long getExpireMillisCombined() { List tagList = getTags(); if (tagList.isEmpty()) { return 0L; } CombatTag latestTag = tagList.get(0); return latestTag.getExpireMillis(); } public long getMillisLeftCombined() { long expireMillis = getExpireMillisCombined(); if (expireMillis == 0L) { return 0L; } long systemMillis = System.currentTimeMillis(); long subtractMillis = (expireMillis - systemMillis); return Math.max(0L, subtractMillis); } public boolean isExpired() { this.tagList.removeIf(CombatTag::isExpired); return this.tagList.isEmpty(); } public @NotNull List getTagTypes() { List tagList = getTags(); List tagTypeList = new ArrayList<>(); for (CombatTag combatTag : tagList) { TagType tagType = combatTag.getTagType(); tagTypeList.add(tagType); } return Collections.unmodifiableList(tagTypeList); } public @NotNull TagType getCurrentTagType() { List tagTypeList = getTagTypes(); if (tagTypeList.isEmpty()) { return TagType.UNKNOWN; } return tagTypeList.get(0); } public @Nullable Entity getCurrentEnemy() { List enemyList = getEnemies(); if (enemyList.isEmpty()) { return null; } return enemyList.get(0); } public @Nullable CombatTag getTagForEnemy(Entity entity) { Validate.notNull(entity, "entity must not be null!"); List tagList = getTags(); for (CombatTag combatTag : tagList) { if (combatTag.doesEnemyMatch(entity)) { return combatTag; } } return null; } } ================================================ FILE: api/src/main/java/com/github/sirblobman/combatlogx/api/object/TagReason.java ================================================ package com.github.sirblobman.combatlogx.api.object; /** * The reason for putting a player into combat. */ public enum TagReason { /** * Unknown reason for being tagged. Usually occurs from the tag command. * This can also occur from the Damage Tagger expansion. */ UNKNOWN, /** * The player was damaged by an enemy. */ ATTACKED, /** * The player caused an enemy to take damage. */ ATTACKER; } ================================================ FILE: api/src/main/java/com/github/sirblobman/combatlogx/api/object/TagType.java ================================================ package com.github.sirblobman.combatlogx.api.object; /** * The type of combat that a player was tagged with. */ public enum TagType { /** * Unknown type for being tagged. Usually occurs from the tag command. */ UNKNOWN, /** * CombatTag was caused by another player or themselves. */ PLAYER, /** * CombatTag was caused by a mob. */ MOB, /** * CombatTag was caused by the Damage Tagger expansion. */ DAMAGE, /** * CombatTag was caused by a custom mob from the MythicMobs plugin. */ MYTHIC_MOB; } ================================================ FILE: api/src/main/java/com/github/sirblobman/combatlogx/api/object/TimerType.java ================================================ package com.github.sirblobman.combatlogx.api.object; /** * The type of timer that will be used by CombatLogX */ public enum TimerType { /** * Every player will be tagged for the same amount of time. */ GLOBAL, /** * Some players will have special combat times based on their permissions, others will use the global time. */ PERMISSION } ================================================ FILE: api/src/main/java/com/github/sirblobman/combatlogx/api/object/TimerUpdater.java ================================================ package com.github.sirblobman.combatlogx.api.object; import org.jetbrains.annotations.NotNull; import org.bukkit.entity.Player; import com.github.sirblobman.combatlogx.api.manager.ITimerManager; /** * If you are going to implement this class, don't forget to register your instance with the timer manager. * * @see ITimerManager * @see ITimerManager#addUpdaterTask(TimerUpdater) */ public interface TimerUpdater { /** * This method is executed every tick while a player is in combat. * * @param player The player for this update. * @param timeLeftMillis The amount of time left in combat for this player. */ void update(@NotNull Player player, long timeLeftMillis); /** * This method is executed whenever a player is untagged. * * @param player The player for this removal. */ void remove(@NotNull Player player); } ================================================ FILE: api/src/main/java/com/github/sirblobman/combatlogx/api/object/UntagReason.java ================================================ package com.github.sirblobman.combatlogx.api.object; /** * The reason for removing a player from combat. */ public enum UntagReason { /** * The player waited patiently until they were no longer in combat */ EXPIRE(true), /** * The player died and the config option was enabled to untag them */ SELF_DEATH(true), /** * The player's enemy died and the config option was enabled to untag them */ ENEMY_DEATH(true), /** * The enemy of the player forgave them. */ ENEMY_FORGIVE(true), /** * The player disconnected from the server */ QUIT, /** * The player was kicked by a plugin or timed out */ KICK; private final boolean expire; UntagReason() { this(false); } UntagReason(boolean expire) { this.expire = expire; } public boolean isExpire() { return this.expire; } } ================================================ FILE: api/src/main/java/com/github/sirblobman/combatlogx/api/placeholder/IPlaceholderExpansion.java ================================================ package com.github.sirblobman.combatlogx.api.placeholder; import java.util.List; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import org.bukkit.entity.Entity; import org.bukkit.entity.Player; import com.github.sirblobman.api.language.LanguageManager; import com.github.sirblobman.combatlogx.api.ICombatLogX; import com.github.sirblobman.combatlogx.api.ICombatLogXNeeded; import com.github.sirblobman.api.shaded.adventure.text.Component; import com.github.sirblobman.api.shaded.adventure.text.minimessage.MiniMessage; import com.github.sirblobman.api.shaded.adventure.text.serializer.legacy.LegacyComponentSerializer; /** * You must override all required methods and at least one of the following methods: *
    *
  • {@link #getReplacementString(Player, List, String)}
  • *
  • {@link #getReplacement(Player, List, String)}
  • *
*

* If you do not override at least one, you will get an infinite loop. */ public interface IPlaceholderExpansion extends ICombatLogXNeeded { @NotNull String getId(); default @Nullable String getReplacementString(@NotNull Player player, @NotNull List enemyList, @NotNull String placeholder) { Component replacement = getReplacement(player, enemyList, placeholder); if (replacement == null || Component.empty().equals(replacement)) { return ""; } LegacyComponentSerializer serializer = LegacyComponentSerializer.legacySection(); return serializer.serialize(replacement); } @SuppressWarnings("UnnecessaryUnicodeEscape") default @Nullable Component getReplacement(@NotNull Player player, @NotNull List enemyList, @NotNull String placeholder) { String string = getReplacementString(player, enemyList, placeholder); if (string == null || string.isEmpty()) { return Component.empty(); } if (string.contains("\u00A7")) { LegacyComponentSerializer serializer = LegacyComponentSerializer.legacySection(); return serializer.deserialize(string); } if (string.contains("&")) { LegacyComponentSerializer serializer = LegacyComponentSerializer.legacyAmpersand(); return serializer.deserialize(string); } ICombatLogX combatLogX = getCombatLogX(); LanguageManager languageManager = combatLogX.getLanguageManager(); MiniMessage miniMessage = languageManager.getMiniMessage(); return miniMessage.deserialize(string); } } ================================================ FILE: api/src/main/java/com/github/sirblobman/combatlogx/api/placeholder/PlaceholderHelper.java ================================================ package com.github.sirblobman.combatlogx.api.placeholder; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import org.bukkit.Bukkit; import org.bukkit.entity.Entity; import org.bukkit.entity.Player; import org.bukkit.plugin.PluginManager; import com.github.sirblobman.api.language.LanguageManager; import com.github.sirblobman.api.nms.EntityHandler; import com.github.sirblobman.api.nms.MultiVersionHandler; import com.github.sirblobman.api.utility.paper.PaperChecker; import com.github.sirblobman.api.utility.paper.PaperHelper; import com.github.sirblobman.combatlogx.api.ICombatLogX; import com.github.sirblobman.api.shaded.adventure.text.Component; import me.clip.placeholderapi.PlaceholderAPI; public final class PlaceholderHelper { public static @NotNull Component getEnemyName(@NotNull ICombatLogX plugin, @NotNull Player player, @Nullable Entity entity) { if (entity == null) { return getUnknownEnemy(plugin, player); } if (PaperChecker.hasNativeComponentSupport()) { Component customName = PaperHelper.getCustomName(entity); if (customName != null) { return customName; } } MultiVersionHandler multiVersionHandler = plugin.getMultiVersionHandler(); EntityHandler entityHandler = multiVersionHandler.getEntityHandler(); String entityName = entityHandler.getName(entity); return Component.text(entityName); } public static @NotNull Component getUnknownEnemy(@NotNull ICombatLogX plugin, @NotNull Player player) { LanguageManager languageManager = plugin.getLanguageManager(); return languageManager.getMessage(player, "placeholder.unknown-enemy"); } public static @NotNull String replacePlaceholderAPI(@NotNull Player player, @NotNull String string) { PluginManager pluginManager = Bukkit.getPluginManager(); if (pluginManager.isPluginEnabled("PlaceholderAPI")) { return PlaceholderAPI.setPlaceholders(player, string); } return string; } } ================================================ FILE: api/src/main/java/com/github/sirblobman/combatlogx/api/utility/CommandHelper.java ================================================ package com.github.sirblobman.combatlogx.api.utility; import java.util.Locale; import java.util.logging.Level; import java.util.logging.Logger; import org.jetbrains.annotations.NotNull; import org.bukkit.Bukkit; import org.bukkit.command.CommandSender; import org.bukkit.entity.Player; import com.github.sirblobman.api.folia.FoliaHelper; import com.github.sirblobman.api.folia.details.RunnableTask; import com.github.sirblobman.api.folia.scheduler.TaskScheduler; import com.github.sirblobman.combatlogx.api.ICombatLogX; public final class CommandHelper { public static void runSync(@NotNull ICombatLogX plugin, @NotNull Runnable runnable) { FoliaHelper foliaHelper = plugin.getFoliaHelper(); TaskScheduler scheduler = foliaHelper.getScheduler(); RunnableTask task = new RunnableTask(plugin.getPlugin(), runnable); scheduler.scheduleTask(task); } public static void runAsConsole(@NotNull ICombatLogX plugin, @NotNull String command) { try { CommandSender console = Bukkit.getConsoleSender(); Bukkit.dispatchCommand(console, command); } catch (Exception ex) { String messageFormat = "Failed to execute command '/%s' as the server console:"; String logMessage = String.format(Locale.US, messageFormat, command); Logger logger = plugin.getLogger(); logger.log(Level.SEVERE, logMessage, ex); } } public static void runAsPlayer(@NotNull ICombatLogX plugin, @NotNull Player player, @NotNull String command) { try { player.performCommand(command); } catch (Exception ex) { String playerName = player.getName(); String messageFormat = "Failed to execute command '/%s' as player '%s':"; String logMessage = String.format(Locale.US, messageFormat, command, playerName); Logger logger = plugin.getLogger(); logger.log(Level.SEVERE, logMessage, ex); } } public static void runAsOperator(@NotNull ICombatLogX plugin, @NotNull Player player, @NotNull String command) { if (player.isOp()) { runAsPlayer(plugin, player, command); return; } try { player.setOp(true); player.performCommand(command); } catch (Exception ex) { String playerName = player.getName(); String messageFormat = "Failed to execute command '/%s' as player '%s' with operator permissions:"; String logMessage = String.format(Locale.US, messageFormat, command, playerName); Logger logger = plugin.getLogger(); logger.log(Level.SEVERE, logMessage, ex); } finally { player.setOp(false); } } } ================================================ FILE: api/src/main/java/com/github/sirblobman/combatlogx/api/utility/EntityHelper.java ================================================ package com.github.sirblobman.combatlogx.api.utility; import org.jetbrains.annotations.NotNull; import org.bukkit.entity.AnimalTamer; import org.bukkit.entity.Entity; import org.bukkit.entity.EntityType; import org.bukkit.entity.Projectile; import org.bukkit.entity.TNTPrimed; import org.bukkit.entity.Tameable; import org.bukkit.projectiles.ProjectileSource; import com.github.sirblobman.combatlogx.api.ICombatLogX; import com.github.sirblobman.combatlogx.api.configuration.MainConfiguration; public final class EntityHelper { public static @NotNull Entity linkTNT(@NotNull Entity original) { if (!(original instanceof TNTPrimed)) { return original; } TNTPrimed tntEntity = (TNTPrimed) original; Entity source = tntEntity.getSource(); return (source == null ? original : source); } public static @NotNull Entity linkPet(@NotNull Entity original) { if (!(original instanceof Tameable)) { return original; } Tameable tameable = (Tameable) original; AnimalTamer animalTamer = tameable.getOwner(); if (!(animalTamer instanceof Entity)) { return original; } return (Entity) animalTamer; } public static @NotNull Entity linkProjectile(@NotNull ICombatLogX plugin, @NotNull Entity original) { if (!(original instanceof Projectile)) { return original; } Projectile projectile = (Projectile) original; if (isProjectileIgnored(plugin, projectile)) { return original; } ProjectileSource shooter = projectile.getShooter(); if (!(shooter instanceof Entity)) { return original; } return (Entity) shooter; } public static boolean isNPC(@NotNull Entity entity) { return entity.hasMetadata("NPC"); } private static boolean isProjectileIgnored(@NotNull ICombatLogX plugin, @NotNull Projectile projectile) { EntityType projectileType = projectile.getType(); MainConfiguration configuration = plugin.getConfiguration(); return configuration.isProjectileIgnored(projectileType); } } ================================================ FILE: api/src/main/resources/default-region-expansion-config.yml ================================================ # How should CombatLogX prevent players from entering non-pvp areas? # Valid Modes: # DISABLED - Ignore players. # KNOCKBACK_PLAYER - Add some opposite velocity to the player. They will be pushed backwards. # CANCEL_EVENT - Cancel the move event for the player. # VULNERABLE - Allow the player to enter the area, but disable the pvp protection from the region plugin. # KILL_PLAYER - Set the health of the player to zero. # TELEPORT_TO_ENEMY - Teleport the player to their current enemy, or cancel the event if there are no enemies. # Default: "KNOCKBACK_PLAYER" no-entry-mode: "KNOCKBACK_PLAYER" # This value is only used if 'no-entry-mode' is KNOCKBACK_PLAYER # How much should the backwards velocity be multiplied by? # Default: 1.5 knockback-strength: 1.5 # How much time (in seconds) should the plugin wait before sending another 'no-entry' message? # Default: 30 message-cooldown: 30 # Should the region plugin also prevent teleporting? # Teleport prevention will always use the CANCEL_EVENT mode. prevent-teleport: true # Are there any reasons that a teleport should not be cancelled? # You can find a list of valid values in the link below: # https://hub.spigotmc.org/javadocs/bukkit/org/bukkit/event/player/PlayerTeleportEvent.TeleportCause.html ignored-teleport-cause-list: - "PLUGIN" # Some plugins don't like when CombatLogX cancels their teleports - "UNKNOWN" # Allowing 'UNKNOWN' may fix some glitches with region protection plugins ================================================ FILE: build.gradle.kts ================================================ val baseVersion = providers.gradleProperty("version.base").get() val betaVersion = providers.gradleProperty("version.beta").get().toBooleanStrict() val betaString = if (betaVersion) "Beta-" else "" val jenkinsBuild = providers.environmentVariable("BUILD_NUMBER").orElse("Unofficial").get() rootProject.version = "${baseVersion}.${betaString}${jenkinsBuild}" plugins { id("java") } subprojects { apply(plugin = "java") java { sourceCompatibility = JavaVersion.VERSION_25 targetCompatibility = JavaVersion.VERSION_25 toolchain.languageVersion.set(JavaLanguageVersion.of(25)) } repositories { mavenCentral() maven("https://hub.spigotmc.org/nexus/content/repositories/snapshots/") maven("https://oss.sonatype.org/content/repositories/snapshots/") maven("https://nexus.sirblobman.xyz/public/") } dependencies { compileOnly("org.jetbrains:annotations:26.0.2-1") // JetBrains Annotations compileOnly("org.spigotmc:spigot-api:1.19.4-R0.1-SNAPSHOT") // Base Spigot API compileOnly("com.github.sirblobman.api:core:2.9-SNAPSHOT") // BlueSlimeCore } tasks.withType { options.encoding = "UTF-8" options.compilerArgs.add("-Xlint:deprecation") } } ================================================ FILE: builder/build.gradle.kts ================================================ plugins { id("distribution") } val coreJar: Configuration by configurations.creating val pluginJar: Configuration by configurations.creating val expansion: Configuration by configurations.creating dependencies { // BlueSlimeCore coreJar("com.github.sirblobman.api:core:2.9-SNAPSHOT") // CombatLogX pluginJar(project(path = ":plugin", configuration = "shadow")) // Normal Expansions expansion(project(":expansion:action-bar")) expansion(project(":expansion:boss-bar")) expansion(project(path = ":expansion:cheat-prevention", configuration = "shadow")) expansion(project(":expansion:damage-tagger")) expansion(project(":expansion:damage-effects")) expansion(project(":expansion:death-effects")) expansion(project(path = ":expansion:end-crystal", configuration = "shadow")) expansion(project(":expansion:force-field")) expansion(project(":expansion:glowing")) expansion(project(":expansion:logger")) expansion(project(path = ":expansion:loot-protection", configuration = "shadow")) expansion(project(":expansion:mob-tagger")) expansion(project(":expansion:newbie-helper")) expansion(project(":expansion:rewards")) expansion(project(":expansion:scoreboard")) // Compatibility expansions expansion(project(":expansion:compatibility:AngelChest")) expansion(project(":expansion:compatibility:ASkyBlock")) expansion(project(":expansion:compatibility:BSkyBlock")) expansion(project(":expansion:compatibility:Citizens")) expansion(project(":expansion:compatibility:CMI")) expansion(project(":expansion:compatibility:CrackShot")) expansion(project(":expansion:compatibility:CrashClaim")) expansion(project(":expansion:compatibility:EssentialsX")) expansion(project(":expansion:compatibility:FabledSkyBlock")) expansion(project(":expansion:compatibility:Factions")) expansion(project(":expansion:compatibility:FeatherBoard")) expansion(project(":expansion:compatibility:GriefDefender")) expansion(project(":expansion:compatibility:GriefPrevention")) expansion(project(":expansion:compatibility:HuskHomes")) expansion(project(":expansion:compatibility:HuskSync")) expansion(project(":expansion:compatibility:HuskTowns")) expansion(project(":expansion:compatibility:iDisguise")) expansion(project(":expansion:compatibility:IridiumSkyblock")) expansion(project(":expansion:compatibility:KingdomsX")) expansion(project(":expansion:compatibility:Konquest")) expansion(project(":expansion:compatibility:Lands")) expansion(project(":expansion:compatibility:LibsDisguises")) expansion(project(":expansion:compatibility:LuckPerms")) expansion(project(":expansion:compatibility:MarriageMaster")) expansion(project(":expansion:compatibility:MCPets")) expansion(project(":expansion:compatibility:MythicMobs")) expansion(project(":expansion:compatibility:PlaceholderAPI")) expansion(project(":expansion:compatibility:PlayerParticles")) expansion(project(":expansion:compatibility:PreciousStones")) expansion(project(":expansion:compatibility:ProtectionStones")) expansion(project(":expansion:compatibility:RedProtect")) expansion(project(":expansion:compatibility:Residence")) expansion(project(":expansion:compatibility:SuperiorSkyblock")) expansion(project(":expansion:compatibility:SuperVanish")) expansion(project(":expansion:compatibility:Towny")) expansion(project(":expansion:compatibility:UltimateClaims")) expansion(project(":expansion:compatibility:uSkyBlock")) expansion(project(":expansion:compatibility:VanishNoPacket")) expansion(project(path = ":expansion:compatibility:WorldGuard", configuration = "shadow")) // expansion(project(":expansion:compatibility:ZNPCsPlus")) } distributions { main { contents { into("/") { // README.TXT from(sourceSets.getByName("main").allSource) // CombatLogX.jar from(pluginJar) // BlueSlimeCore.jar from(coreJar) rename("core-2.9-SNAPSHOT.jar", "BlueSlimeCore.jar") } into("/CombatLogX/expansions/") { // All Expansions from(expansion) } } } } tasks { named("jar") { enabled = false } named("distTar") { enabled = false } named("distZip") { isPreserveFileTimestamps = true archiveBaseName.set("CombatLogX-${rootProject.version}") } } ================================================ FILE: builder/src/main/resources/README.TXT ================================================ Installation Guide: 1. Download the CombatLogX.zip file from Jenkins or SpigotMC. 2. Extract the contents of the CombatLogX.zip to your PC. 3. Click the stop button on the panel. If your server doesn't use a panel, type "stop" into the console. 4. Upload CombatLogX.jar and BlueSlimeCore.jar to your server /plugins/ folder. 5. Upload the contents of CombatLogX/expansions to your server /plugins/CombatLogX/expansions folder. 6. If the files were uploaded and extracted correctly, your server should have the following files: File: /plugins/CombatLogX.jar File /plugins/BlueSlimeCore.jar Folder: /plugins/CombatLogX/ Folder: /plugins/CombatLogX/expansions/ Multiple Files: /plugins/CombatLogX/expansions/*.jar 7. Delete the CombatLogX.zip file. 8. Restart your server using the panel or your startup script. 9. Edit the configuration files for the main plugin, languages, and expansions. 10. Type the command /clx reload to reload the configuration files. 11. If you want to remove an expansion, delete the jar file from /plugins/CombatLogX/expansions. Server Shutdown: - To stop your server properly, click the stop button on the panel. - If your server is hosted locally or does not have a panel, type 'stop' into the console window. Server Startup: - To start your server properly, click the start button on the panel. - If your server is hosted locally or does not have a panel, execute the start script. Server Files: If CombatLogX is installed correctly, your server will have the following files: - Folder: /plugins - Folder: /plugins/CombatLogX - Folder: /plugins/CombatLogX/expansions - File: /plugins/CombatLogX.jar - File: /plugins/BlueSlimeCore.jar - Multiple Files: /plugins/CombatLogX/expansions/*.jar ================================================ FILE: crowdin.yml ================================================ project_id: '459244' pull_request_title: 'Automatic Crowdin Translation Updates' files: - source: "/plugin/src/main/resources/language/en_us.lang.yml" translation: "/plugin/src/main/resources/language/%locale_with_underscore%.lang.yml" ================================================ FILE: expansion/action-bar/README.MD ================================================ # CombatLogX Expansion: Action Bar The action bar expansion shows an action bar to every player that is in combat. ## Features - Customizable action bar message and progress bar. - Progress bar changes as timer goes down. ## Commands - **/combatlogx toggle:** - **/combatlogx toggle actionbar:** Enable or disable your action bar display. ================================================ FILE: expansion/action-bar/gradle.properties ================================================ expansion.name=ActionBar expansion.prefix=Action Bar ================================================ FILE: expansion/action-bar/src/main/java/combatlogx/expansion/action/bar/ActionBarExpansion.java ================================================ package combatlogx.expansion.action.bar; import java.util.logging.Logger; import com.github.sirblobman.api.configuration.ConfigurationManager; import com.github.sirblobman.api.utility.VersionUtility; import com.github.sirblobman.combatlogx.api.ICombatLogX; import com.github.sirblobman.combatlogx.api.expansion.Expansion; import com.github.sirblobman.combatlogx.api.manager.ITimerManager; import combatlogx.expansion.action.bar.configuration.ActionBarConfiguration; public final class ActionBarExpansion extends Expansion { private final ActionBarConfiguration configuration; public ActionBarExpansion(ICombatLogX plugin) { super(plugin); this.configuration = new ActionBarConfiguration(); } @Override public void onLoad() { ConfigurationManager configurationManager = getConfigurationManager(); configurationManager.saveDefault("config.yml"); } @Override public void onEnable() { ICombatLogX plugin = getPlugin(); int majorVersion = VersionUtility.getMajorVersion(); int minorVersion = VersionUtility.getMinorVersion(); if (majorVersion == 1 && minorVersion < 8) { Logger logger = getLogger(); logger.warning("This expansion requires Spigot 1.8.8 or higher."); selfDisable(); return; } reloadConfig(); ITimerManager timerManager = plugin.getTimerManager(); timerManager.addUpdaterTask(new ActionBarUpdater(this)); } @Override public void onDisable() { // Do Nothing } @Override public void reloadConfig() { ConfigurationManager configurationManager = getConfigurationManager(); configurationManager.reload("config.yml"); getConfiguration().load(configurationManager.get("config.yml")); } ActionBarConfiguration getConfiguration() { return this.configuration; } } ================================================ FILE: expansion/action-bar/src/main/java/combatlogx/expansion/action/bar/ActionBarUpdater.java ================================================ package combatlogx.expansion.action.bar; import java.util.List; import java.util.concurrent.TimeUnit; import java.util.regex.Pattern; import org.bukkit.configuration.file.YamlConfiguration; import org.bukkit.entity.Entity; import org.bukkit.entity.Player; import com.github.sirblobman.api.configuration.PlayerDataManager; import com.github.sirblobman.api.language.LanguageManager; import com.github.sirblobman.api.utility.Validate; import com.github.sirblobman.combatlogx.api.ICombatLogX; import com.github.sirblobman.combatlogx.api.manager.ICombatManager; import com.github.sirblobman.combatlogx.api.manager.IPlaceholderManager; import com.github.sirblobman.combatlogx.api.object.TagInformation; import com.github.sirblobman.combatlogx.api.object.TimerUpdater; import com.github.sirblobman.api.shaded.adventure.text.Component; import com.github.sirblobman.api.shaded.adventure.text.TextComponent; import com.github.sirblobman.api.shaded.adventure.text.TextReplacementConfig; import com.github.sirblobman.api.shaded.adventure.text.format.TextColor; import combatlogx.expansion.action.bar.configuration.ActionBarConfiguration; public final class ActionBarUpdater implements TimerUpdater { private final ActionBarExpansion expansion; public ActionBarUpdater(ActionBarExpansion expansion) { this.expansion = Validate.notNull(expansion, "expansion must not be null!"); } private ActionBarExpansion getExpansion() { return this.expansion; } private ActionBarConfiguration getConfiguration() { ActionBarExpansion expansion = getExpansion(); return expansion.getConfiguration(); } private ICombatLogX getCombatLogX() { ActionBarExpansion expansion = getExpansion(); return expansion.getPlugin(); } private LanguageManager getLanguageManager() { ICombatLogX combatLogX = getCombatLogX(); return combatLogX.getLanguageManager(); } private PlayerDataManager getPlayerDataManager() { ICombatLogX combatLogX = getCombatLogX(); return combatLogX.getPlayerDataManager(); } @Override public void update(Player player, long timeLeftMillis) { if (isDisabled(player)) { return; } sendActionBar(player, timeLeftMillis); } @Override public void remove(Player player) { update(player, 0L); } private boolean isGlobalEnabled() { ActionBarConfiguration configuration = getConfiguration(); return configuration.isEnabled(); } private boolean isDisabled(Player player) { if (isGlobalEnabled()) { PlayerDataManager playerDataManager = getPlayerDataManager(); YamlConfiguration playerData = playerDataManager.get(player); return !playerData.getBoolean("actionbar", true); } return true; } private void sendActionBar(Player player, long timeLeftMillis) { LanguageManager languageManager = getLanguageManager(); if (timeLeftMillis <= 0) { String path = ("expansion.action-bar.ended"); languageManager.sendActionBar(player, path); return; } ICombatLogX combatLogX = getCombatLogX(); ICombatManager combatManager = combatLogX.getCombatManager(); IPlaceholderManager placeholderManager = combatLogX.getPlaceholderManager(); Component message = languageManager.getMessage(player, "expansion.action-bar.timer"); TextReplacementConfig replacementConfig = getBarsReplacement(player, timeLeftMillis); message = message.replaceText(replacementConfig); TagInformation tagInformation = combatManager.getTagInformation(player); if (tagInformation != null) { List enemyList = tagInformation.getEnemies(); Pattern placeholderPattern = Pattern.compile("\\{(\\S+)}"); TextReplacementConfig.Builder builder = TextReplacementConfig.builder(); builder.match(placeholderPattern); builder.replacement((matchResult, builderCopy) -> { String placeholder = matchResult.group(1); Component replacement = placeholderManager.getPlaceholderReplacementComponent(player, enemyList, placeholder); return (replacement == null ? Component.text(placeholder) : replacement); }); TextReplacementConfig replacement = builder.build(); message = message.replaceText(replacement); } languageManager.sendActionBar(player, message); } private TextReplacementConfig getBarsReplacement(Player player, long timeLeftMillis) { TextReplacementConfig.Builder builder = TextReplacementConfig.builder(); builder.matchLiteral("{bars}"); builder.replacement(getBars(player, timeLeftMillis)); return builder.build(); } private Component getBars(Player player, long timeLeftMillis) { ActionBarConfiguration configuration = getConfiguration(); long scale = configuration.getScale(); String leftSymbol = configuration.getLeftSymbol(); String rightSymbol = configuration.getRightSymbol(); TextColor leftColor = configuration.getLeftColor(); TextColor rightColor = configuration.getRightColor(); ICombatLogX plugin = getCombatLogX(); ICombatManager combatManager = plugin.getCombatManager(); long timerMaxSeconds = combatManager.getMaxTimerSeconds(player); double timerMaxMillis = TimeUnit.SECONDS.toMillis(timerMaxSeconds); double scaleDouble = (double) scale; double timeLeftMillisDouble = (double) timeLeftMillis; double percent = clamp(timeLeftMillisDouble / timerMaxMillis); long leftBarsCount = Math.round(scaleDouble * percent); long rightBarsCount = (scale - leftBarsCount); TextComponent.Builder builder = Component.text(); Component leftSymbolComponent = Component.text(leftSymbol, leftColor); Component rightSymbolComponent = Component.text(rightSymbol, rightColor); for (long i = 0; i < leftBarsCount; i++) { builder.append(leftSymbolComponent); } for (long i = 0; i < rightBarsCount; i++) { builder.append(rightSymbolComponent); } return builder.build(); } private double clamp(double value) { return Math.max(0.0D, Math.min(value, 1.0D)); } } ================================================ FILE: expansion/action-bar/src/main/java/combatlogx/expansion/action/bar/configuration/ActionBarConfiguration.java ================================================ package combatlogx.expansion.action.bar.configuration; import org.jetbrains.annotations.NotNull; import org.bukkit.configuration.ConfigurationSection; import com.github.sirblobman.api.configuration.IConfigurable; import com.github.sirblobman.api.shaded.adventure.text.format.NamedTextColor; import com.github.sirblobman.api.shaded.adventure.text.format.TextColor; public final class ActionBarConfiguration implements IConfigurable { private boolean enabled; private long scale; private String leftColorString; private String rightColorString; private String leftSymbol; private String rightSymbol; private transient TextColor leftColor; private transient TextColor rightColor; public ActionBarConfiguration() { setEnabled(true); setScale(15L); setLeftColorString("GREEN"); setRightColorString("RED"); setLeftSymbol("|"); setRightSymbol("|"); } @Override public void load(ConfigurationSection config) { setEnabled(config.getBoolean("enabled", true)); setScale(config.getLong("scale", 15L)); setLeftColorString(config.getString("left-color", "GREEN")); setRightColorString(config.getString("right-color", "RED")); setLeftSymbol(config.getString("left-symbol", "|")); setRightSymbol(config.getString("right-symbol", "|")); } public boolean isEnabled() { return this.enabled; } public void setEnabled(boolean enabled) { this.enabled = enabled; } public long getScale() { return this.scale; } public void setScale(long scale) { this.scale = scale; } public String getLeftColorString() { return this.leftColorString; } public void setLeftColorString(@NotNull String leftColorString) { this.leftColorString = leftColorString; this.leftColor = null; } public @NotNull String getRightColorString() { return this.rightColorString; } public void setRightColorString(@NotNull String rightColorString) { this.rightColorString = rightColorString; this.rightColor = null; } public @NotNull String getLeftSymbol() { return this.leftSymbol; } public void setLeftSymbol(@NotNull String leftSymbol) { this.leftSymbol = leftSymbol; } public @NotNull String getRightSymbol() { return rightSymbol; } public void setRightSymbol(@NotNull String rightSymbol) { this.rightSymbol = rightSymbol; } public @NotNull TextColor getLeftColor() { if (this.leftColor != null) { return this.leftColor; } String leftColorString = getLeftColorString(); return (this.leftColor = parseTextColor(leftColorString, NamedTextColor.GREEN)); } public @NotNull TextColor getRightColor() { if (this.rightColor != null) { return this.rightColor; } String rightColorString = getRightColorString(); return (this.rightColor = parseTextColor(rightColorString, NamedTextColor.RED)); } private @NotNull TextColor parseTextColor(@NotNull String colorString, @NotNull TextColor defaultColor) { if (colorString.isEmpty()) { return defaultColor; } if (colorString.startsWith("#") && colorString.length() == 7) { try { String colorHex = colorString.substring(1); int colorInt = Integer.parseInt(colorHex, 16); return TextColor.color(colorInt); } catch (IllegalArgumentException ex) { return defaultColor; } } NamedTextColor namedTextColor = NamedTextColor.NAMES.value(colorString); return (namedTextColor != null ? namedTextColor : defaultColor); } } ================================================ FILE: expansion/action-bar/src/main/resources/config.yml ================================================ # This option is here to quickly toggle this expansion on a live server that must stay online. # We recommend that you remove the Action Bar expansion jar if you will not use the feature. enabled: true # Scale is the amount of symbols for the {bars} placeholder. scale: 15 # Left Color is the color code for the left part of the {bars} placeholder. # A named color must be selected, or you can use the hex value. # You can find a list of official color names at the bottom of this file. # Example: "GREEN" # Example 2: "#00FF00" left-color: "GREEN" # Left Symbol is the symbol used for the left part of the {bars} placeholder # Unicode is supported, but must be converted. # Example: "\u00A7" # Default: "|" left-symbol: "|" # Right Color is the color code for the right part of the {bars} placeholder. # A named color must be selected, or you can use the hex value. # You can find a list of official color names at the bottom of this file. # Example: "RED" # Example 2: "#FF0000" right-color: "RED" # Right Symbol is the symbol used for the right part of the {bars} placeholder # Unicode is supported, but must be converted. # Example: "\u00A7" # Default: "|" right-symbol: "|" ## Reminder: ## The action bar format is in your selected language file ## (Default: en_us.lang.yml) ## Adventure NamedTextColor Value Map ## Legacy Color Code : Named Color # &0 : BLACK # &1 : DARK_BLUE # &2 : DARK_GREEN # &3 : DARK_AQUA # &4 : DARK_RED # &5 : DARK_PURPLE # &6 : GOLD # &7 : GRAY # &8 : DARK_GRAY # &9 : BLUE # &a : GREEN # &b : AQUA # &c : RED # &d : LIGHT_PURPLE # &e : YELLOW # &f : WHITE ================================================ FILE: expansion/action-bar/src/main/resources/expansion.yml ================================================ name: "${expansionName}" prefix: "${expansionPrefix}" description: "${expansionDescription}" main: "combatlogx.expansion.action.bar.ActionBarExpansion" version: "17.4" author: "SirBlobman" ================================================ FILE: expansion/boss-bar/README.MD ================================================ # CombatLogX Expansion: Boss Bar The boss bar expansion shows a boss bar to every player that is in combat. ## Features - Customizable bar color and style. - Customizable boss bar message. - Boss Bar health changes as timer goes down. ## Commands - **/combatlogx toggle:** - **/combatlogx toggle bossbar:** Enable or disable your boss bar display. ================================================ FILE: expansion/boss-bar/gradle.properties ================================================ expansion.name=BossBar expansion.prefix=Boss Bar ================================================ FILE: expansion/boss-bar/src/main/java/combatlogx/expansion/boss/bar/BossBarConfiguration.java ================================================ package combatlogx.expansion.boss.bar; import org.jetbrains.annotations.NotNull; import org.bukkit.configuration.ConfigurationSection; import com.github.sirblobman.api.configuration.IConfigurable; import com.github.sirblobman.api.shaded.adventure.bossbar.BossBar; import com.github.sirblobman.api.shaded.adventure.text.format.NamedTextColor; import com.github.sirblobman.api.shaded.adventure.text.format.TextColor; public final class BossBarConfiguration implements IConfigurable { private boolean enabled; private String bossBarColorName; private String bossBarStyleName; private long scale; private String leftColorString; private String rightColorString; private String leftSymbol; private String rightSymbol; private transient BossBar.Color bossBarColor; private transient BossBar.Overlay bossBarStyle; private transient TextColor leftColor; private transient TextColor rightColor; public BossBarConfiguration() { setEnabled(true); setBossBarColorName("YELLOW"); setBossBarStyleName("PROGRESS"); setScale(15L); setLeftColorString("GREEN"); setRightColorString("RED"); setLeftSymbol("|"); setRightSymbol("|"); } @Override public void load(ConfigurationSection config) { setEnabled(config.getBoolean("enabled", true)); setBossBarColorName(config.getString("bar-color", "YELLOW")); setBossBarStyleName(config.getString("bar-style", "PROGRESS")); setScale(config.getLong("scale", 15L)); setLeftColorString(config.getString("left-color", "GREEN")); setRightColorString(config.getString("right-color", "RED")); setLeftSymbol(config.getString("left-symbol", "|")); setRightSymbol(config.getString("right-symbol", "|")); } public boolean isEnabled() { return enabled; } public void setEnabled(boolean enabled) { this.enabled = enabled; } public long getScale() { return scale; } public void setScale(long scale) { this.scale = scale; } public String getLeftColorString() { return leftColorString; } public void setLeftColorString(String leftColorString) { this.leftColorString = leftColorString; this.leftColor = null; } public String getRightColorString() { return rightColorString; } public void setRightColorString(String rightColorString) { this.rightColorString = rightColorString; this.rightColor = null; } public String getLeftSymbol() { return leftSymbol; } public void setLeftSymbol(String leftSymbol) { this.leftSymbol = leftSymbol; } public String getRightSymbol() { return rightSymbol; } public void setRightSymbol(String rightSymbol) { this.rightSymbol = rightSymbol; } @NotNull public TextColor getLeftColor() { if (this.leftColor != null) { return this.leftColor; } String leftColorString = getLeftColorString(); return (this.leftColor = parseTextColor(leftColorString, NamedTextColor.GREEN)); } @NotNull public TextColor getRightColor() { if (this.rightColor != null) { return this.rightColor; } String rightColorString = getRightColorString(); return (this.rightColor = parseTextColor(rightColorString, NamedTextColor.RED)); } @NotNull private TextColor parseTextColor(String colorString, TextColor defaultColor) { if (colorString == null || colorString.isEmpty()) { return defaultColor; } if (colorString.startsWith("#") && colorString.length() == 7) { try { String colorHex = colorString.substring(1); int colorInt = Integer.parseInt(colorHex, 16); return TextColor.color(colorInt); } catch (IllegalArgumentException ex) { return defaultColor; } } NamedTextColor namedTextColor = NamedTextColor.NAMES.value(colorString); return (namedTextColor != null ? namedTextColor : defaultColor); } public String getBossBarColorName() { return bossBarColorName; } public void setBossBarColorName(String bossBarColorName) { this.bossBarColorName = bossBarColorName; this.bossBarColor = null; } public String getBossBarStyleName() { return bossBarStyleName; } public void setBossBarStyleName(String bossBarStyleName) { this.bossBarStyleName = bossBarStyleName; this.bossBarStyle = null; } @NotNull public BossBar.Color getBossBarColor() { if (this.bossBarColor != null) { return this.bossBarColor; } String bossBarColorName = getBossBarColorName(); return (this.bossBarColor = parseBossBarColor(bossBarColorName)); } @NotNull public BossBar.Overlay getBossBarStyle() { if (this.bossBarStyle != null) { return this.bossBarStyle; } String bossBarStyleName = getBossBarStyleName(); return (this.bossBarStyle = parseBossBarStyle(bossBarStyleName)); } private BossBar.Color parseBossBarColor(String name) { if (name == null || name.isEmpty()) { return BossBar.Color.YELLOW; } try { return BossBar.Color.valueOf(name); } catch (IllegalArgumentException ex) { return BossBar.Color.YELLOW; } } private BossBar.Overlay parseBossBarStyle(String name) { if (name == null || name.isEmpty()) { return BossBar.Overlay.PROGRESS; } try { return BossBar.Overlay.valueOf(name); } catch (IllegalArgumentException ex) { return BossBar.Overlay.PROGRESS; } } } ================================================ FILE: expansion/boss-bar/src/main/java/combatlogx/expansion/boss/bar/BossBarExpansion.java ================================================ package combatlogx.expansion.boss.bar; import org.jetbrains.annotations.NotNull; import org.bukkit.configuration.file.YamlConfiguration; import com.github.sirblobman.api.configuration.ConfigurationManager; import com.github.sirblobman.combatlogx.api.ICombatLogX; import com.github.sirblobman.combatlogx.api.expansion.Expansion; import com.github.sirblobman.combatlogx.api.manager.ITimerManager; public final class BossBarExpansion extends Expansion { private final BossBarConfiguration configuration; public BossBarExpansion(ICombatLogX plugin) { super(plugin); this.configuration = new BossBarConfiguration(); } @Override public void onLoad() { ConfigurationManager configurationManager = getConfigurationManager(); configurationManager.saveDefault("config.yml"); } @Override public void onEnable() { reloadConfig(); ITimerManager timerManager = getTimerManager(); timerManager.addUpdaterTask(new BossBarUpdater(this)); } @Override public void onDisable() { // Do Nothing } @Override public void reloadConfig() { ConfigurationManager configurationManager = getConfigurationManager(); configurationManager.reload("config.yml"); BossBarConfiguration configuration = getConfiguration(); YamlConfiguration yamlConfiguration = configurationManager.get("config.yml"); configuration.load(yamlConfiguration); } public @NotNull BossBarConfiguration getConfiguration() { return this.configuration; } private @NotNull ITimerManager getTimerManager() { ICombatLogX plugin = getPlugin(); return plugin.getTimerManager(); } } ================================================ FILE: expansion/boss-bar/src/main/java/combatlogx/expansion/boss/bar/BossBarUpdater.java ================================================ package combatlogx.expansion.boss.bar; import java.util.List; import java.util.Map; import java.util.UUID; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.TimeUnit; import java.util.regex.Pattern; import org.jetbrains.annotations.Contract; import org.jetbrains.annotations.NotNull; import org.bukkit.configuration.file.YamlConfiguration; import org.bukkit.entity.Entity; import org.bukkit.entity.Player; import com.github.sirblobman.api.configuration.PlayerDataManager; import com.github.sirblobman.api.folia.FoliaHelper; import com.github.sirblobman.api.folia.details.EntityTaskDetails; import com.github.sirblobman.api.folia.scheduler.TaskScheduler; import com.github.sirblobman.api.language.LanguageManager; import com.github.sirblobman.api.plugin.ConfigurablePlugin; import com.github.sirblobman.api.utility.Validate; import com.github.sirblobman.api.utility.VersionUtility; import com.github.sirblobman.combatlogx.api.ICombatLogX; import com.github.sirblobman.combatlogx.api.manager.ICombatManager; import com.github.sirblobman.combatlogx.api.manager.IPlaceholderManager; import com.github.sirblobman.combatlogx.api.object.TagInformation; import com.github.sirblobman.combatlogx.api.object.TimerUpdater; import com.github.sirblobman.api.shaded.adventure.audience.Audience; import com.github.sirblobman.api.shaded.adventure.bossbar.BossBar; import com.github.sirblobman.api.shaded.adventure.bossbar.BossBar.Color; import com.github.sirblobman.api.shaded.adventure.bossbar.BossBar.Overlay; import com.github.sirblobman.api.shaded.adventure.text.Component; import com.github.sirblobman.api.shaded.adventure.text.TextComponent; import com.github.sirblobman.api.shaded.adventure.text.TextReplacementConfig; import com.github.sirblobman.api.shaded.adventure.text.format.TextColor; public final class BossBarUpdater implements TimerUpdater { private final BossBarExpansion expansion; private final Map bossBarMap; public BossBarUpdater(BossBarExpansion expansion) { this.expansion = Validate.notNull(expansion, "expansion must not be null!"); this.bossBarMap = new ConcurrentHashMap<>(); } @Override public void update(@NotNull Player player, long timeLeftMillis) { if (isDisabled(player)) { actualRemove(player); return; } Component title = getTitle(player, timeLeftMillis); if (Component.empty().equals(title)) { actualRemove(player); return; } float progress = getProgress(player, timeLeftMillis); BossBar.Color color = getBossBarColor(); BossBar.Overlay overlay = getBossBarOverlay(); BossBar bossBar = getBossBar(player, true); bossBar.progress(progress); bossBar.color(color); bossBar.overlay(overlay); bossBar.name(title); Audience audience = getAudience(player); audience.showBossBar(bossBar); } @Override public void remove(@NotNull Player player) { update(player, 0L); ICombatLogX combatLogX = getCombatLogX(); ConfigurablePlugin plugin = combatLogX.getPlugin(); if (!plugin.isEnabled()) { return; } FoliaHelper foliaHelper = combatLogX.getFoliaHelper(); TaskScheduler scheduler = foliaHelper.getScheduler(); scheduler.scheduleEntityTask(new EntityTaskDetails(plugin, player) { @Override public void run() { Player player = getEntity(); if (player != null) { actualRemove(player); } } }); } private BossBarExpansion getExpansion() { return this.expansion; } private ICombatLogX getCombatLogX() { BossBarExpansion expansion = getExpansion(); return expansion.getPlugin(); } private LanguageManager getLanguageManager() { ICombatLogX combatLogX = getCombatLogX(); return combatLogX.getLanguageManager(); } private PlayerDataManager getPlayerDataManager() { ICombatLogX combatLogX = getCombatLogX(); return combatLogX.getPlayerDataManager(); } private ICombatManager getCombatManager() { ICombatLogX combatLogX = getCombatLogX(); return combatLogX.getCombatManager(); } private boolean isGlobalEnabled() { BossBarConfiguration configuration = getConfiguration(); return configuration.isEnabled(); } private boolean isDisabled(Player player) { if (isGlobalEnabled()) { PlayerDataManager playerDataManager = getPlayerDataManager(); YamlConfiguration playerData = playerDataManager.get(player); return !playerData.getBoolean("bossbar", true); } return true; } @Contract("_, true -> !null") private BossBar getBossBar(Player player, boolean create) { UUID playerId = player.getUniqueId(); if (this.bossBarMap.containsKey(playerId)) { return this.bossBarMap.get(playerId); } if (create) { Component defaultTitle = Component.text("Default Title"); BossBar defaultBossBar = BossBar.bossBar(defaultTitle, 1.0F, Color.PURPLE, Overlay.PROGRESS); this.bossBarMap.put(playerId, defaultBossBar); return defaultBossBar; } return null; } private Audience getAudience(Player player) { LanguageManager languageManager = getLanguageManager(); return languageManager.getAudience(player); } private void actualRemove(Player player) { BossBar bossBar = getBossBar(player, false); if (bossBar == null) { return; } Audience audience = getAudience(player); audience.hideBossBar(bossBar); UUID playerId = player.getUniqueId(); this.bossBarMap.remove(playerId); } private Color getBossBarColor() { int minorVersion = VersionUtility.getMinorVersion(); if (minorVersion < 9) { return Color.PURPLE; } BossBarConfiguration configuration = getConfiguration(); return configuration.getBossBarColor(); } private Overlay getBossBarOverlay() { int minorVersion = VersionUtility.getMinorVersion(); if (minorVersion < 9) { return Overlay.PROGRESS; } BossBarConfiguration configuration = getConfiguration(); return configuration.getBossBarStyle(); } private float getProgress(Player player, float timeLeftMillis) { ICombatManager combatManager = getCombatManager(); long timerMaxSeconds = combatManager.getMaxTimerSeconds(player); float timerMaxMillis = TimeUnit.SECONDS.toMillis(timerMaxSeconds); float barPercentage = (timeLeftMillis / timerMaxMillis); if (barPercentage <= 0.0F) { return 0.0F; } return Math.min(barPercentage, 1.0F); } private Component getTitle(Player player, long timeLeftMillis) { LanguageManager languageManager = getLanguageManager(); if (timeLeftMillis <= 0) { String path = ("expansion.boss-bar.ended"); return languageManager.getMessage(player, path); } ICombatLogX combatLogX = getCombatLogX(); ICombatManager combatManager = combatLogX.getCombatManager(); IPlaceholderManager placeholderManager = combatLogX.getPlaceholderManager(); Component message = languageManager.getMessage(player, "expansion.boss-bar.timer"); TextReplacementConfig replacementConfig = getBarsReplacement(player, timeLeftMillis); message = message.replaceText(replacementConfig); TagInformation tagInformation = combatManager.getTagInformation(player); if (tagInformation != null) { List enemyList = tagInformation.getEnemies(); Pattern placeholderPattern = Pattern.compile("\\{(\\S+)}"); TextReplacementConfig.Builder builder = TextReplacementConfig.builder(); builder.match(placeholderPattern); builder.replacement((matchResult, builderCopy) -> { String placeholder = matchResult.group(1); Component replacement = placeholderManager.getPlaceholderReplacementComponent(player, enemyList, placeholder); return (replacement == null ? Component.text(placeholder) : replacement); }); TextReplacementConfig replacement = builder.build(); message = message.replaceText(replacement); } return message; } private TextReplacementConfig getBarsReplacement(Player player, long timeLeftMillis) { TextReplacementConfig.Builder builder = TextReplacementConfig.builder(); builder.matchLiteral("{bars}"); builder.replacement(getBars(player, timeLeftMillis)); return builder.build(); } private BossBarConfiguration getConfiguration() { BossBarExpansion expansion = getExpansion(); return expansion.getConfiguration(); } private Component getBars(Player player, long timeLeftMillis) { BossBarConfiguration configuration = getConfiguration(); long scale = configuration.getScale(); String leftSymbol = configuration.getLeftSymbol(); String rightSymbol = configuration.getRightSymbol(); TextColor leftColor = configuration.getLeftColor(); TextColor rightColor = configuration.getRightColor(); ICombatLogX plugin = getCombatLogX(); ICombatManager combatManager = plugin.getCombatManager(); long timerMaxSeconds = combatManager.getMaxTimerSeconds(player); double timerMaxMillis = TimeUnit.SECONDS.toMillis(timerMaxSeconds); double scaleDouble = (double) scale; double timeLeftMillisDouble = (double) timeLeftMillis; double percent = clamp(timeLeftMillisDouble / timerMaxMillis); long leftBarsCount = Math.round(scaleDouble * percent); long rightBarsCount = (scale - leftBarsCount); TextComponent.Builder builder = Component.text(); Component leftSymbolComponent = Component.text(leftSymbol, leftColor); Component rightSymbolComponent = Component.text(rightSymbol, rightColor); for (long i = 0; i < leftBarsCount; i++) { builder.append(leftSymbolComponent); } for (long i = 0; i < rightBarsCount; i++) { builder.append(rightSymbolComponent); } return builder.build(); } private double clamp(double value) { return Math.max(0.0D, Math.min(value, 1.0D)); } } ================================================ FILE: expansion/boss-bar/src/main/resources/config.yml ================================================ # This option is here to quickly toggle this expansion on a live server that must stay online. # We recommend that you remove the Boss Bar expansion jar if you will not use the feature. enabled: true # You can find a list of colors here: # https://jd.adventure.kyori.net/api/4.11.0/net/kyori/adventure/bossbar/BossBar.Color.html bar-color: YELLOW # You can find a list of styles here: # https://jd.adventure.kyori.net/api/4.11.0/net/kyori/adventure/bossbar/BossBar.Overlay.html bar-style: PROGRESS # Scale is the amount of symbols for the {bars} placeholder. scale: 15 # Left Color is the color code for the left part of the {bars} placeholder. # A named color must be selected, or you can use the hex value. # You can find a list of official color names at the bottom of this file. # Example: "GREEN" # Example 2: "#00FF00" left-color: "GREEN" # Left Symbol is the symbol used for the left part of the {bars} placeholder # Unicode is supported, but must be converted. # Example: "\u00A7" # Default: "|" left-symbol: "|" # Right Color is the color code for the right part of the {bars} placeholder. # A named color must be selected, or you can use the hex value. # You can find a list of official color names at the bottom of this file. # Example: "RED" # Example 2: "#FF0000" right-color: "RED" # Right Symbol is the symbol used for the right part of the {bars} placeholder # Unicode is supported, but must be converted. # Example: "\u00A7" # Default: "|" right-symbol: "|" ## Reminder: ## The boss bar format is in your selected language file ## (Default: en_us.lang.yml) ## Adventure NamedTextColor Value Map ## Legacy Color Code : Named Color # &0 : BLACK # &1 : DARK_BLUE # &2 : DARK_GREEN # &3 : DARK_AQUA # &4 : DARK_RED # &5 : DARK_PURPLE # &6 : GOLD # &7 : GRAY # &8 : DARK_GRAY # &9 : BLUE # &a : GREEN # &b : AQUA # &c : RED # &d : LIGHT_PURPLE # &e : YELLOW # &f : WHITE ## Extra Information: ## Color and Style are only available in 1.9 or higher. ## 1.8 and below will always be PURPLE and PROGRESS. ## Reminder: ## The boss bar format is in your selected language file ## (Default: en_us.lang.yml) ================================================ FILE: expansion/boss-bar/src/main/resources/expansion.yml ================================================ name: "${expansionName}" prefix: "${expansionPrefix}" description: "${expansionDescription}" main: "combatlogx.expansion.boss.bar.BossBarExpansion" version: "17.1" author: "SirBlobman" ================================================ FILE: expansion/build.gradle.kts ================================================ tasks.named("jar") { enabled = false } subprojects { val expansionName = findProperty("expansion.name") ?: "invalid" val expansionPrefix = findProperty("expansion.prefix") ?: expansionName dependencies { compileOnly(project(":api")) } tasks { named("jar") { archiveFileName.set("$expansionPrefix.jar") } processResources { val expansionDescription = findProperty("expansion.description") ?: "" filesMatching("expansion.yml") { expand( mapOf( "expansionName" to expansionName, "expansionPrefix" to expansionPrefix, "expansionDescription" to expansionDescription ) ) } } } } ================================================ FILE: expansion/cheat-prevention/abstract/src/main/java/combatlogx/expansion/cheat/prevention/ICheatPreventionExpansion.java ================================================ package combatlogx.expansion.cheat.prevention; import org.jetbrains.annotations.NotNull; import com.github.sirblobman.combatlogx.api.expansion.Expansion; import combatlogx.expansion.cheat.prevention.configuration.IBlockConfiguration; import combatlogx.expansion.cheat.prevention.configuration.IBucketConfiguration; import combatlogx.expansion.cheat.prevention.configuration.IChatConfiguration; import combatlogx.expansion.cheat.prevention.configuration.ICommandConfiguration; import combatlogx.expansion.cheat.prevention.configuration.IConfiguration; import combatlogx.expansion.cheat.prevention.configuration.IEntityConfiguration; import combatlogx.expansion.cheat.prevention.configuration.IFlightConfiguration; import combatlogx.expansion.cheat.prevention.configuration.IGameModeConfiguration; import combatlogx.expansion.cheat.prevention.configuration.IInventoryConfiguration; import combatlogx.expansion.cheat.prevention.configuration.IItemConfiguration; import combatlogx.expansion.cheat.prevention.configuration.IPotionConfiguration; import combatlogx.expansion.cheat.prevention.configuration.ITeleportConfiguration; public interface ICheatPreventionExpansion { @NotNull Expansion getExpansion(); @NotNull IConfiguration getConfiguration(); @NotNull IBlockConfiguration getBlockConfiguration(); @NotNull IBucketConfiguration getBucketConfiguration(); @NotNull IChatConfiguration getChatConfiguration(); @NotNull ICommandConfiguration getCommandConfiguration(); @NotNull IEntityConfiguration getEntityConfiguration(); @NotNull IFlightConfiguration getFlightConfiguration(); @NotNull IGameModeConfiguration getGameModeConfiguration(); @NotNull IInventoryConfiguration getInventoryConfiguration(); @NotNull IItemConfiguration getItemConfiguration(); @NotNull IPotionConfiguration getPotionConfiguration(); @NotNull ITeleportConfiguration getTeleportConfiguration(); } ================================================ FILE: expansion/cheat-prevention/abstract/src/main/java/combatlogx/expansion/cheat/prevention/configuration/IBlockConfiguration.java ================================================ package combatlogx.expansion.cheat.prevention.configuration; import org.jetbrains.annotations.NotNull; import com.github.sirblobman.api.configuration.IConfigurable; import com.github.sirblobman.api.shaded.xseries.XMaterial; public interface IBlockConfiguration extends IConfigurable { boolean isPreventInteraction(); boolean isPreventBreaking(); boolean isPreventPlacing(); boolean isPreventPortalCreation(); boolean isPreventInteraction(@NotNull XMaterial blockType); boolean isPreventBreaking(@NotNull XMaterial blockType); boolean isPreventPlacing(@NotNull XMaterial blockType); } ================================================ FILE: expansion/cheat-prevention/abstract/src/main/java/combatlogx/expansion/cheat/prevention/configuration/IBucketConfiguration.java ================================================ package combatlogx.expansion.cheat.prevention.configuration; import org.jetbrains.annotations.NotNull; import com.github.sirblobman.api.configuration.IConfigurable; import com.github.sirblobman.api.shaded.xseries.XMaterial; public interface IBucketConfiguration extends IConfigurable { boolean isPreventBucketEmpty(); boolean isPreventBucketFill(); boolean isPreventEmpty(@NotNull XMaterial material); boolean isPreventFill(@NotNull XMaterial material); } ================================================ FILE: expansion/cheat-prevention/abstract/src/main/java/combatlogx/expansion/cheat/prevention/configuration/IChatConfiguration.java ================================================ package combatlogx.expansion.cheat.prevention.configuration; import com.github.sirblobman.api.configuration.IConfigurable; public interface IChatConfiguration extends IConfigurable { boolean isDisableChat(); } ================================================ FILE: expansion/cheat-prevention/abstract/src/main/java/combatlogx/expansion/cheat/prevention/configuration/ICommandConfiguration.java ================================================ package combatlogx.expansion.cheat.prevention.configuration; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import org.bukkit.permissions.Permission; import com.github.sirblobman.api.configuration.IConfigurable; public interface ICommandConfiguration extends IConfigurable { int getDelayAfterCombat(); boolean isBlocked(@NotNull String command); boolean isAllowed(@NotNull String command); @Nullable Permission getBypassPermission(); } ================================================ FILE: expansion/cheat-prevention/abstract/src/main/java/combatlogx/expansion/cheat/prevention/configuration/IConfiguration.java ================================================ package combatlogx.expansion.cheat.prevention.configuration; import com.github.sirblobman.api.configuration.IConfigurable; public interface IConfiguration extends IConfigurable { int getMessageCooldown(); } ================================================ FILE: expansion/cheat-prevention/abstract/src/main/java/combatlogx/expansion/cheat/prevention/configuration/IEntityConfiguration.java ================================================ package combatlogx.expansion.cheat.prevention.configuration; import com.github.sirblobman.api.configuration.IConfigurable; public interface IEntityConfiguration extends IConfigurable { boolean isPreventInteraction(); } ================================================ FILE: expansion/cheat-prevention/abstract/src/main/java/combatlogx/expansion/cheat/prevention/configuration/IFlightConfiguration.java ================================================ package combatlogx.expansion.cheat.prevention.configuration; import com.github.sirblobman.api.configuration.IConfigurable; public interface IFlightConfiguration extends IConfigurable { boolean isPreventFlying(); boolean isPreventFallDamage(); boolean isForceDisableFlight(); boolean isFlightRetag(); } ================================================ FILE: expansion/cheat-prevention/abstract/src/main/java/combatlogx/expansion/cheat/prevention/configuration/IGameModeConfiguration.java ================================================ package combatlogx.expansion.cheat.prevention.configuration; import org.bukkit.GameMode; import com.github.sirblobman.api.configuration.IConfigurable; public interface IGameModeConfiguration extends IConfigurable { boolean isPreventSwitching(); boolean isUntagOnSwitch(); boolean isForceSwitch(); GameMode getForceMode(); } ================================================ FILE: expansion/cheat-prevention/abstract/src/main/java/combatlogx/expansion/cheat/prevention/configuration/IInventoryConfiguration.java ================================================ package combatlogx.expansion.cheat.prevention.configuration; import org.jetbrains.annotations.NotNull; import org.bukkit.event.inventory.InventoryType; import com.github.sirblobman.api.configuration.IConfigurable; public interface IInventoryConfiguration extends IConfigurable { boolean isClose(); boolean isCloseOnRetag(); boolean isPreventOpening(); boolean isNoMessage(@NotNull InventoryType type); } ================================================ FILE: expansion/cheat-prevention/abstract/src/main/java/combatlogx/expansion/cheat/prevention/configuration/IItemConfiguration.java ================================================ package combatlogx.expansion.cheat.prevention.configuration; import com.github.sirblobman.api.configuration.IConfigurable; public interface IItemConfiguration extends IConfigurable { boolean isPreventDrop(); boolean isPreventPickup(); boolean isPreventElytra(); boolean isForcePreventElytra(); boolean isPreventFireworks(); boolean isElytraRetag(); boolean isPreventTotem(); boolean isPreventRiptide(); boolean isRiptideRetag(); } ================================================ FILE: expansion/cheat-prevention/abstract/src/main/java/combatlogx/expansion/cheat/prevention/configuration/IPotionConfiguration.java ================================================ package combatlogx.expansion.cheat.prevention.configuration; import org.jetbrains.annotations.NotNull; import org.bukkit.potion.PotionEffectType; import com.github.sirblobman.api.configuration.IConfigurable; public interface IPotionConfiguration extends IConfigurable { boolean isBlocked(@NotNull PotionEffectType effectType); } ================================================ FILE: expansion/cheat-prevention/abstract/src/main/java/combatlogx/expansion/cheat/prevention/configuration/ITeleportConfiguration.java ================================================ package combatlogx.expansion.cheat.prevention.configuration; import org.jetbrains.annotations.NotNull; import org.bukkit.event.player.PlayerTeleportEvent.TeleportCause; import com.github.sirblobman.api.configuration.IConfigurable; public interface ITeleportConfiguration extends IConfigurable { boolean isPreventPortals(); boolean isPreventTeleportation(); boolean isEnderPearlRetag(); boolean isUntag(); boolean isAllowed(@NotNull TeleportCause cause); boolean isForceDisableEnderPearl(); } ================================================ FILE: expansion/cheat-prevention/abstract/src/main/java/combatlogx/expansion/cheat/prevention/listener/CheatPreventionListener.java ================================================ package combatlogx.expansion.cheat.prevention.listener; import java.util.HashMap; import java.util.Map; import java.util.UUID; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.TimeUnit; import org.jetbrains.annotations.NotNull; import org.bukkit.entity.Player; import com.github.sirblobman.api.language.LanguageManager; import com.github.sirblobman.api.language.replacer.Replacer; import com.github.sirblobman.combatlogx.api.expansion.ExpansionListener; import combatlogx.expansion.cheat.prevention.ICheatPreventionExpansion; import combatlogx.expansion.cheat.prevention.configuration.IConfiguration; public abstract class CheatPreventionListener extends ExpansionListener { private final ICheatPreventionExpansion expansion; private final Map> messageCooldownMap; public CheatPreventionListener(@NotNull ICheatPreventionExpansion expansion) { super(expansion.getExpansion()); this.expansion = expansion; this.messageCooldownMap = new ConcurrentHashMap<>(); } protected final @NotNull ICheatPreventionExpansion getCheatPrevention() { return this.expansion; } protected final void sendMessageIgnoreCooldown(@NotNull Player player, @NotNull String key, Replacer @NotNull ... replacer) { LanguageManager languageManager = getLanguageManager(); languageManager.sendMessageWithPrefix(player, key, replacer); addMessageCooldown(player, key); } protected final void sendMessage(@NotNull Player player, @NotNull String key, Replacer @NotNull ... replacer) { long systemMillis = System.currentTimeMillis(); long expireMillis = getCooldownExpireTime(player, key); if (systemMillis < expireMillis) { return; } sendMessageIgnoreCooldown(player, key, replacer); } private long getNewMessageCooldownExpireTime() { ICheatPreventionExpansion cheatPrevention = getCheatPrevention(); IConfiguration configuration = cheatPrevention.getConfiguration(); long cooldownSeconds = configuration.getMessageCooldown(); long cooldownMillis = TimeUnit.SECONDS.toMillis(cooldownSeconds); long systemMillis = System.currentTimeMillis(); return (systemMillis + cooldownMillis); } private long getCooldownExpireTime(Player player, String key) { UUID playerId = player.getUniqueId(); Map expireTimeMap = this.messageCooldownMap.getOrDefault(playerId, new HashMap<>()); return expireTimeMap.getOrDefault(key, 0L); } private void addMessageCooldown(Player player, String key) { UUID playerId = player.getUniqueId(); Map expireTimeMap = this.messageCooldownMap.getOrDefault(playerId, new HashMap<>()); expireTimeMap.put(key, getNewMessageCooldownExpireTime()); this.messageCooldownMap.put(playerId, expireTimeMap); } } ================================================ FILE: expansion/cheat-prevention/build.gradle.kts ================================================ import com.github.jengelman.gradle.plugins.shadow.tasks.ShadowJar plugins { id("com.gradleup.shadow") version "9.2.2" } dependencies { implementation(project(":expansion:cheat-prevention:abstract")) implementation(project(":expansion:cheat-prevention:legacy")) implementation(project(":expansion:cheat-prevention:paper")) implementation(project(path = ":expansion:cheat-prevention:modern", configuration = "default")) } tasks { named("jar") { enabled = false } named("shadowJar") { val expansionName = findProperty("expansion.name") ?: "invalid" val expansionPrefix = findProperty("expansion.prefix") ?: expansionName archiveFileName.set("$expansionPrefix.jar") archiveClassifier.set(null as String?) } named("build") { dependsOn("shadowJar") } } ================================================ FILE: expansion/cheat-prevention/gradle.properties ================================================ version.spigot=1.16.5-R0.1-SNAPSHOT expansion.name=CheatPrevention expansion.prefix=Cheat Prevention ================================================ FILE: expansion/cheat-prevention/legacy/build.gradle.kts ================================================ dependencies { compileOnly(project(":expansion:cheat-prevention:abstract")) } ================================================ FILE: expansion/cheat-prevention/legacy/gradle.properties ================================================ version.spigot=1.8.8-R0.1-SNAPSHOT ================================================ FILE: expansion/cheat-prevention/legacy/src/main/java/combatlogx/expansion/cheat/prevention/listener/legacy/ListenerChat.java ================================================ package combatlogx.expansion.cheat.prevention.listener.legacy; import org.jetbrains.annotations.NotNull; import org.bukkit.entity.Player; import org.bukkit.event.EventHandler; import org.bukkit.event.EventPriority; import org.bukkit.event.player.AsyncPlayerChatEvent; import combatlogx.expansion.cheat.prevention.ICheatPreventionExpansion; import combatlogx.expansion.cheat.prevention.configuration.IChatConfiguration; import combatlogx.expansion.cheat.prevention.listener.CheatPreventionListener; public final class ListenerChat extends CheatPreventionListener { public ListenerChat(@NotNull ICheatPreventionExpansion expansion) { super(expansion); } @EventHandler(priority = EventPriority.NORMAL, ignoreCancelled = true) public void onChat(AsyncPlayerChatEvent e) { if (isChatDisabled()) { Player player = e.getPlayer(); if (!isInCombat(player)) { return; } e.setCancelled(true); sendMessage(player, "expansion.cheat-prevention.no-chat"); } } private @NotNull IChatConfiguration getChatConfiguration() { ICheatPreventionExpansion cheatPrevention = getCheatPrevention(); return cheatPrevention.getChatConfiguration(); } private boolean isChatDisabled() { IChatConfiguration chatConfiguration = getChatConfiguration(); return chatConfiguration.isDisableChat(); } } ================================================ FILE: expansion/cheat-prevention/legacy/src/main/java/combatlogx/expansion/cheat/prevention/listener/legacy/ListenerLegacyItemPickup.java ================================================ package combatlogx.expansion.cheat.prevention.listener.legacy; import org.jetbrains.annotations.NotNull; import org.bukkit.entity.Player; import org.bukkit.event.EventHandler; import org.bukkit.event.EventPriority; import org.bukkit.event.player.PlayerPickupItemEvent; import combatlogx.expansion.cheat.prevention.ICheatPreventionExpansion; import combatlogx.expansion.cheat.prevention.configuration.IItemConfiguration; import combatlogx.expansion.cheat.prevention.listener.CheatPreventionListener; public final class ListenerLegacyItemPickup extends CheatPreventionListener { public ListenerLegacyItemPickup(@NotNull ICheatPreventionExpansion expansion) { super(expansion); } @EventHandler(priority = EventPriority.NORMAL, ignoreCancelled = true) public void onPickup(PlayerPickupItemEvent e) { if (isPreventPickup()) { Player player = e.getPlayer(); if (!isInCombat(player)) { return; } e.setCancelled(true); sendMessage(player, "expansion.cheat-prevention.items.no-pickup"); } } private @NotNull IItemConfiguration getItemConfiguration() { ICheatPreventionExpansion expansion = getCheatPrevention(); return expansion.getItemConfiguration(); } private boolean isPreventPickup() { IItemConfiguration itemConfiguration = getItemConfiguration(); return itemConfiguration.isPreventPickup(); } } ================================================ FILE: expansion/cheat-prevention/legacy/src/main/java/combatlogx/expansion/cheat/prevention/listener/legacy/ListenerLegacyPortalCreate.java ================================================ package combatlogx.expansion.cheat.prevention.listener.legacy; import org.jetbrains.annotations.NotNull; import org.bukkit.entity.Entity; import org.bukkit.entity.Player; import org.bukkit.event.EventHandler; import org.bukkit.event.EventPriority; import org.bukkit.event.entity.EntityCreatePortalEvent; import combatlogx.expansion.cheat.prevention.ICheatPreventionExpansion; import combatlogx.expansion.cheat.prevention.configuration.IBlockConfiguration; import combatlogx.expansion.cheat.prevention.listener.CheatPreventionListener; public final class ListenerLegacyPortalCreate extends CheatPreventionListener { public ListenerLegacyPortalCreate(@NotNull ICheatPreventionExpansion expansion) { super(expansion); } @EventHandler(priority = EventPriority.NORMAL, ignoreCancelled = true) public void onPortalCreate(EntityCreatePortalEvent e) { Entity entity = e.getEntity(); if (!(entity instanceof Player)) { return; } Player player = (Player) entity; if (isPreventPortalCreation() && isInCombat(player)) { e.setCancelled(true); sendMessage(player, "expansion.cheat-prevention.blocks.prevent-portal-creation"); } } private @NotNull IBlockConfiguration getBlockConfiguration() { ICheatPreventionExpansion expansion = getCheatPrevention(); return expansion.getBlockConfiguration(); } private boolean isPreventPortalCreation() { IBlockConfiguration configuration = getBlockConfiguration(); return configuration.isPreventPortalCreation(); } } ================================================ FILE: expansion/cheat-prevention/legacy/src/main/java/combatlogx/expansion/cheat/prevention/listener/legacy/ListenerLegacyPotions.java ================================================ package combatlogx.expansion.cheat.prevention.listener.legacy; import java.util.Collection; import org.jetbrains.annotations.NotNull; import org.bukkit.entity.LivingEntity; import org.bukkit.entity.Player; import org.bukkit.entity.ThrownPotion; import org.bukkit.event.EventHandler; import org.bukkit.event.EventPriority; import org.bukkit.event.entity.PotionSplashEvent; import org.bukkit.event.player.PlayerItemConsumeEvent; import org.bukkit.inventory.ItemStack; import org.bukkit.potion.Potion; import org.bukkit.potion.PotionEffect; import org.bukkit.potion.PotionEffectType; import com.github.sirblobman.combatlogx.api.event.PlayerTagEvent; import com.github.sirblobman.api.shaded.xseries.XMaterial; import combatlogx.expansion.cheat.prevention.ICheatPreventionExpansion; import combatlogx.expansion.cheat.prevention.configuration.IPotionConfiguration; import combatlogx.expansion.cheat.prevention.listener.CheatPreventionListener; public final class ListenerLegacyPotions extends CheatPreventionListener { public ListenerLegacyPotions(@NotNull ICheatPreventionExpansion expansion) { super(expansion); } @EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true) public void onTag(PlayerTagEvent e) { Player player = e.getPlayer(); Collection activePotionEffectCollection = player.getActivePotionEffects(); for (PotionEffect potionEffect : activePotionEffectCollection) { PotionEffectType potionEffectType = potionEffect.getType(); if (isBlocked(potionEffectType)) { player.removePotionEffect(potionEffectType); } } } @EventHandler(priority = EventPriority.NORMAL, ignoreCancelled = true) public void onSplash(PotionSplashEvent e) { ThrownPotion thrownPotion = e.getPotion(); Collection potionEffectCollection = thrownPotion.getEffects(); Collection affectedEntityCollection = e.getAffectedEntities(); for (LivingEntity affectedEntity : affectedEntityCollection) { if (!(affectedEntity instanceof Player)) { continue; } Player player = (Player) affectedEntity; if (!isInCombat(player)) { continue; } for (PotionEffect potionEffect : potionEffectCollection) { PotionEffectType potionEffectType = potionEffect.getType(); if (!isBlocked(potionEffectType)) { continue; } e.setIntensity(player, 0); break; } } } @EventHandler(priority = EventPriority.NORMAL, ignoreCancelled = true) public void onPotionConsume(PlayerItemConsumeEvent e) { Player player = e.getPlayer(); if (!isInCombat(player)) { return; } ItemStack item = e.getItem(); XMaterial material = XMaterial.matchXMaterial(item); if (material != XMaterial.POTION) { return; } Potion potion = Potion.fromItemStack(item); Collection potionEffectCollection = potion.getEffects(); for (PotionEffect potionEffect : potionEffectCollection) { PotionEffectType potionEffectType = potionEffect.getType(); if (isBlocked(potionEffectType)) { e.setCancelled(true); return; } } } private @NotNull IPotionConfiguration getPotionConfiguration() { ICheatPreventionExpansion expansion = getCheatPrevention(); return expansion.getPotionConfiguration(); } private boolean isBlocked(@NotNull PotionEffectType effectType) { IPotionConfiguration potionConfiguration = getPotionConfiguration(); return potionConfiguration.isBlocked(effectType); } } ================================================ FILE: expansion/cheat-prevention/modern/build.gradle.kts ================================================ repositories { maven("https://repo.papermc.io/repository/maven-public/") } dependencies { compileOnly(project(":expansion:cheat-prevention:abstract")) compileOnly("io.papermc.paper:paper-api:1.21.1-R0.1-SNAPSHOT") } ================================================ FILE: expansion/cheat-prevention/modern/gradle.properties ================================================ version.spigot=1.21.1-R0.1-SNAPSHOT ================================================ FILE: expansion/cheat-prevention/modern/src/main/java/combatlogx/expansion/cheat/prevention/listener/modern/ListenerInventoriesModern.java ================================================ package combatlogx.expansion.cheat.prevention.listener.modern; import org.jetbrains.annotations.NotNull; import org.bukkit.entity.HumanEntity; import org.bukkit.entity.Player; import org.bukkit.event.EventHandler; import org.bukkit.event.EventPriority; import org.bukkit.event.inventory.InventoryOpenEvent; import org.bukkit.event.inventory.InventoryType; import org.bukkit.inventory.InventoryView; import com.github.sirblobman.combatlogx.api.event.PlayerReTagEvent; import com.github.sirblobman.combatlogx.api.event.PlayerTagEvent; import combatlogx.expansion.cheat.prevention.ICheatPreventionExpansion; import combatlogx.expansion.cheat.prevention.configuration.IInventoryConfiguration; import combatlogx.expansion.cheat.prevention.listener.CheatPreventionListener; // 1.20.6 use a InventoryView interface instead of an abstract class // No code difference, only compilation difference. public final class ListenerInventoriesModern extends CheatPreventionListener { public ListenerInventoriesModern(@NotNull ICheatPreventionExpansion expansion) { super(expansion); } @EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true) public void onTag(PlayerTagEvent e) { if (isClose()) { Player player = e.getPlayer(); InventoryView openView = player.getOpenInventory(); InventoryType viewType = openView.getType(); player.closeInventory(); if (isMessage(viewType)) { sendMessage(player, "expansion.cheat-prevention.inventory.force-closed"); } } } @EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true) public void onReTag(PlayerReTagEvent e) { if (isCloseOnRetag()) { Player player = e.getPlayer(); InventoryView openView = player.getOpenInventory(); InventoryType viewType = openView.getType(); player.closeInventory(); if (isMessage(viewType)) { sendMessage(player, "expansion.cheat-prevention.inventory.force-closed"); } } } @EventHandler(priority = EventPriority.NORMAL, ignoreCancelled = true) public void onOpen(InventoryOpenEvent e) { HumanEntity human = e.getPlayer(); if (!(human instanceof Player)) { return; } Player player = (Player) human; if (isPreventOpening() && isInCombat(player)) { e.setCancelled(true); sendMessage(player, "expansion.cheat-prevention.inventory.no-opening"); } } private @NotNull IInventoryConfiguration getInventoryConfiguration() { ICheatPreventionExpansion expansion = getCheatPrevention(); return expansion.getInventoryConfiguration(); } private boolean isClose() { IInventoryConfiguration inventoryConfiguration = getInventoryConfiguration(); return inventoryConfiguration.isClose(); } private boolean isCloseOnRetag() { IInventoryConfiguration inventoryConfiguration = getInventoryConfiguration(); return inventoryConfiguration.isCloseOnRetag(); } private boolean isPreventOpening() { IInventoryConfiguration inventoryConfiguration = getInventoryConfiguration(); return inventoryConfiguration.isPreventOpening(); } private boolean isMessage(@NotNull InventoryType type) { IInventoryConfiguration inventoryConfiguration = getInventoryConfiguration(); return !inventoryConfiguration.isNoMessage(type); } } ================================================ FILE: expansion/cheat-prevention/paper/build.gradle.kts ================================================ repositories { maven("https://repo.papermc.io/repository/maven-public/") } dependencies { val spigotVersion = property("version.spigot") as String compileOnly("com.destroystokyo.paper:paper-api:$spigotVersion") compileOnly(project(":expansion:cheat-prevention:abstract")) } ================================================ FILE: expansion/cheat-prevention/paper/gradle.properties ================================================ version.spigot=1.16.5-R0.1-SNAPSHOT ================================================ FILE: expansion/cheat-prevention/paper/src/main/java/combatlogx/expansion/cheat/prevention/listener/paper/ListenerPaperChat.java ================================================ package combatlogx.expansion.cheat.prevention.listener.paper; import org.jetbrains.annotations.NotNull; import org.bukkit.entity.Player; import org.bukkit.event.EventHandler; import org.bukkit.event.EventPriority; import io.papermc.paper.event.player.AsyncChatEvent; import combatlogx.expansion.cheat.prevention.ICheatPreventionExpansion; import combatlogx.expansion.cheat.prevention.configuration.IChatConfiguration; import combatlogx.expansion.cheat.prevention.listener.CheatPreventionListener; public final class ListenerPaperChat extends CheatPreventionListener { public ListenerPaperChat(@NotNull ICheatPreventionExpansion expansion) { super(expansion); } @EventHandler(priority = EventPriority.NORMAL, ignoreCancelled = true) public void onChat(AsyncChatEvent e) { Player player = e.getPlayer(); if (isChatDisabled() && isInCombat(player)) { e.setCancelled(true); sendMessage(player, "expansion.cheat-prevention.no-chat"); } } private @NotNull IChatConfiguration getChatConfiguration() { ICheatPreventionExpansion cheatPrevention = getCheatPrevention(); return cheatPrevention.getChatConfiguration(); } private boolean isChatDisabled() { IChatConfiguration chatConfiguration = getChatConfiguration(); return chatConfiguration.isDisableChat(); } } ================================================ FILE: expansion/cheat-prevention/paper/src/main/java/combatlogx/expansion/cheat/prevention/listener/paper/ListenerPaperEntityInsideBlock.java ================================================ package combatlogx.expansion.cheat.prevention.listener.paper; import org.jetbrains.annotations.NotNull; import org.bukkit.Material; import org.bukkit.block.Block; import org.bukkit.entity.Entity; import org.bukkit.entity.Player; import org.bukkit.event.EventHandler; import org.bukkit.event.EventPriority; import io.papermc.paper.event.entity.EntityInsideBlockEvent; import combatlogx.expansion.cheat.prevention.ICheatPreventionExpansion; import combatlogx.expansion.cheat.prevention.configuration.ITeleportConfiguration; import combatlogx.expansion.cheat.prevention.listener.CheatPreventionListener; public final class ListenerPaperEntityInsideBlock extends CheatPreventionListener { public ListenerPaperEntityInsideBlock(@NotNull ICheatPreventionExpansion expansion) { super(expansion); } @EventHandler(priority = EventPriority.NORMAL, ignoreCancelled = true) public void onEntityInsideBlock(EntityInsideBlockEvent e) { Entity entity = e.getEntity(); if (!(entity instanceof Player)) { return; } Player player = (Player) entity; if (isPreventPortals() && isInCombat(player)) { check(player, e); } } private void check(@NotNull Player player, @NotNull EntityInsideBlockEvent e) { Block block = e.getBlock(); Material blockType = block.getType(); if (blockType != Material.END_PORTAL && blockType != Material.NETHER_PORTAL && blockType != Material.END_GATEWAY) { return; } e.setCancelled(true); sendMessage(player, "expansion.cheat-prevention.teleportation.block-portal"); } private @NotNull ITeleportConfiguration getTeleportationConfiguration() { ICheatPreventionExpansion expansion = getCheatPrevention(); return expansion.getTeleportConfiguration(); } private boolean isPreventPortals() { ITeleportConfiguration teleportationConfiguration = getTeleportationConfiguration(); return teleportationConfiguration.isPreventPortals(); } } ================================================ FILE: expansion/cheat-prevention/src/main/java/combatlogx/expansion/cheat/prevention/CheatPreventionExpansion.java ================================================ package combatlogx.expansion.cheat.prevention; import java.util.logging.Logger; import combatlogx.expansion.cheat.prevention.listener.*; import org.jetbrains.annotations.NotNull; import com.github.sirblobman.api.configuration.ConfigurationManager; import com.github.sirblobman.api.utility.VersionUtility; import com.github.sirblobman.combatlogx.api.ICombatLogX; import com.github.sirblobman.combatlogx.api.expansion.Expansion; import combatlogx.expansion.cheat.prevention.configuration.BlockConfiguration; import combatlogx.expansion.cheat.prevention.configuration.BucketConfiguration; import combatlogx.expansion.cheat.prevention.configuration.ChatConfiguration; import combatlogx.expansion.cheat.prevention.configuration.CheatPreventionConfiguration; import combatlogx.expansion.cheat.prevention.configuration.CommandConfiguration; import combatlogx.expansion.cheat.prevention.configuration.EntityConfiguration; import combatlogx.expansion.cheat.prevention.configuration.FlightConfiguration; import combatlogx.expansion.cheat.prevention.configuration.GameModeConfiguration; import combatlogx.expansion.cheat.prevention.configuration.IBlockConfiguration; import combatlogx.expansion.cheat.prevention.configuration.IBucketConfiguration; import combatlogx.expansion.cheat.prevention.configuration.IChatConfiguration; import combatlogx.expansion.cheat.prevention.configuration.ICommandConfiguration; import combatlogx.expansion.cheat.prevention.configuration.IConfiguration; import combatlogx.expansion.cheat.prevention.configuration.IEntityConfiguration; import combatlogx.expansion.cheat.prevention.configuration.IFlightConfiguration; import combatlogx.expansion.cheat.prevention.configuration.IGameModeConfiguration; import combatlogx.expansion.cheat.prevention.configuration.IInventoryConfiguration; import combatlogx.expansion.cheat.prevention.configuration.IItemConfiguration; import combatlogx.expansion.cheat.prevention.configuration.IPotionConfiguration; import combatlogx.expansion.cheat.prevention.configuration.ITeleportConfiguration; import combatlogx.expansion.cheat.prevention.configuration.InventoryConfiguration; import combatlogx.expansion.cheat.prevention.configuration.ItemConfiguration; import combatlogx.expansion.cheat.prevention.configuration.PotionConfiguration; import combatlogx.expansion.cheat.prevention.configuration.TeleportConfiguration; import combatlogx.expansion.cheat.prevention.listener.legacy.ListenerChat; import combatlogx.expansion.cheat.prevention.listener.legacy.ListenerLegacyItemPickup; import combatlogx.expansion.cheat.prevention.listener.legacy.ListenerLegacyPortalCreate; import combatlogx.expansion.cheat.prevention.listener.legacy.ListenerLegacyPotions; import combatlogx.expansion.cheat.prevention.listener.modern.ListenerInventoriesModern; import combatlogx.expansion.cheat.prevention.listener.modern.ListenerModernItemPickup; import combatlogx.expansion.cheat.prevention.listener.modern.ListenerModernPortalCreate; import combatlogx.expansion.cheat.prevention.listener.modern.ListenerModernPotions; import combatlogx.expansion.cheat.prevention.listener.paper.ListenerPaperChat; import combatlogx.expansion.cheat.prevention.listener.paper.ListenerPaperEntityInsideBlock; import combatlogx.expansion.cheat.prevention.task.ElytraRetagTask; import combatlogx.expansion.cheat.prevention.task.FlightRetagTask; public final class CheatPreventionExpansion extends Expansion implements ICheatPreventionExpansion { private final CheatPreventionConfiguration configuration; private final BlockConfiguration blockConfiguration; private final BucketConfiguration bucketConfiguration; private final ChatConfiguration chatConfiguration; private final CommandConfiguration commandConfiguration; private final EntityConfiguration entityConfiguration; private final FlightConfiguration flightConfiguration; private final GameModeConfiguration gameModeConfiguration; private final InventoryConfiguration inventoryConfiguration; private final ItemConfiguration itemConfiguration; private final PotionConfiguration potionConfiguration; private final TeleportConfiguration teleportConfiguration; public CheatPreventionExpansion(ICombatLogX plugin) { super(plugin); this.configuration = new CheatPreventionConfiguration(); this.blockConfiguration = new BlockConfiguration(); this.bucketConfiguration = new BucketConfiguration(); this.chatConfiguration = new ChatConfiguration(); this.commandConfiguration = new CommandConfiguration(); this.entityConfiguration = new EntityConfiguration(); this.flightConfiguration = new FlightConfiguration(); this.gameModeConfiguration = new GameModeConfiguration(); this.inventoryConfiguration = new InventoryConfiguration(); this.itemConfiguration = new ItemConfiguration(); this.potionConfiguration = new PotionConfiguration(); this.teleportConfiguration = new TeleportConfiguration(); } @Override public void onLoad() { ConfigurationManager configurationManager = getConfigurationManager(); configurationManager.saveDefault("blocks.yml"); configurationManager.saveDefault("buckets.yml"); configurationManager.saveDefault("chat.yml"); configurationManager.saveDefault("commands.yml"); configurationManager.saveDefault("config.yml"); configurationManager.saveDefault("entities.yml"); configurationManager.saveDefault("flight.yml"); configurationManager.saveDefault("game-mode.yml"); configurationManager.saveDefault("inventories.yml"); configurationManager.saveDefault("items.yml"); configurationManager.saveDefault("potions.yml"); configurationManager.saveDefault("teleportation.yml"); } @Override public void onEnable() { reloadConfig(); registerListeners(); registerTasks(); int minorVersion = VersionUtility.getMinorVersion(); registerVersionListeners(minorVersion); registerVersionTasks(minorVersion); registerPaperListeners(); } @Override public void onDisable() { // Do Nothing } @Override public void reloadConfig() { ConfigurationManager configurationManager = getConfigurationManager(); configurationManager.reload("blocks.yml"); configurationManager.reload("buckets.yml"); configurationManager.reload("chat.yml"); configurationManager.reload("commands.yml"); configurationManager.reload("config.yml"); configurationManager.reload("entities.yml"); configurationManager.reload("flight.yml"); configurationManager.reload("game-mode.yml"); configurationManager.reload("inventories.yml"); configurationManager.reload("items.yml"); configurationManager.reload("potions.yml"); configurationManager.reload("teleportation.yml"); getBlockConfiguration().load(configurationManager.get("blocks.yml")); getBucketConfiguration().load(configurationManager.get("buckets.yml")); getChatConfiguration().load(configurationManager.get("chat.yml")); getCommandConfiguration().load(configurationManager.get("commands.yml")); getConfiguration().load(configurationManager.get("config.yml")); getEntityConfiguration().load(configurationManager.get("entities.yml")); getFlightConfiguration().load(configurationManager.get("flight.yml")); getGameModeConfiguration().load(configurationManager.get("game-mode.yml")); getInventoryConfiguration().load(configurationManager.get("inventories.yml")); getItemConfiguration().load(configurationManager.get("items.yml")); getPotionConfiguration().load(configurationManager.get("potions.yml")); getTeleportConfiguration().load(configurationManager.get("teleportation.yml")); } @Override public @NotNull Expansion getExpansion() { return this; } @Override public @NotNull IConfiguration getConfiguration() { return this.configuration; } @Override public @NotNull IBlockConfiguration getBlockConfiguration() { return this.blockConfiguration; } @Override public @NotNull IBucketConfiguration getBucketConfiguration() { return this.bucketConfiguration; } @Override public @NotNull IChatConfiguration getChatConfiguration() { return this.chatConfiguration; } @Override public @NotNull ICommandConfiguration getCommandConfiguration() { return this.commandConfiguration; } @Override public @NotNull IEntityConfiguration getEntityConfiguration() { return this.entityConfiguration; } @Override public @NotNull IFlightConfiguration getFlightConfiguration() { return this.flightConfiguration; } @Override public @NotNull IGameModeConfiguration getGameModeConfiguration() { return this.gameModeConfiguration; } @Override public @NotNull IInventoryConfiguration getInventoryConfiguration() { return this.inventoryConfiguration; } @Override public @NotNull IItemConfiguration getItemConfiguration() { return this.itemConfiguration; } @Override public @NotNull IPotionConfiguration getPotionConfiguration() { return this.potionConfiguration; } @Override public @NotNull ITeleportConfiguration getTeleportConfiguration() { return this.teleportConfiguration; } private void registerListeners() { new ListenerBlocks(this).register(); new ListenerBuckets(this).register(); new ListenerCommands(this).register(); new ListenerDrop(this).register(); new ListenerEntities(this).register(); new ListenerFlight(this).register(); new ListenerGameMode(this).register(); new ListenerTeleport(this).register(); new ListenerEnderPearl(this).register(); } private void registerVersionListeners(int minorVersion) { // Elytra were added in 1.9. if (minorVersion >= 9) { new ListenerElytra(this).register(); } // Totem of Undying was added in 1.11. if (minorVersion >= 11) { new ListenerTotem(this).register(); } // PlayerPickupItemEvent was deprecated in favor of EntityPickupItemEvent in 1.12. if (minorVersion < 12) { new ListenerLegacyItemPickup(this).register(); } else { new ListenerModernItemPickup(this).register(); } // The Riptide enchantment was added in 1.13. if (minorVersion >= 13) { new ListenerRiptide(this).register(); } // EntityPotionEffect was added in 1.13. if (minorVersion >= 13) { new ListenerModernPotions(this).register(); } else { new ListenerLegacyPotions(this).register(); } // EntityCreatePortalEvent was replaced with PortalCreateEvent#getEntity in 1.14. if (minorVersion < 14) { new ListenerLegacyPortalCreate(this).register(); } else { new ListenerModernPortalCreate(this).register(); } // InventoryView can be an interface or abstract class depending on version if (isAbstractInventoryView()) { new ListenerInventoriesModern(this).register(); } else { new ListenerInventories(this).register(); } } private boolean isAbstractInventoryView() { int minorVersion = VersionUtility.getMinorVersion(); if (minorVersion > 20) { return true; } String minecraftVersion = VersionUtility.getMinecraftVersion(); return (minecraftVersion.equals("1.20.5") || minecraftVersion.equals("1.20.6")); } private void registerTasks() { new FlightRetagTask(this).register(); } private void registerVersionTasks(int minorVersion) { // Elytra were added in 1.9. if (minorVersion >= 9) { new ElytraRetagTask(this).register(); } } // Paper has some custom event classes that don't exist on Spigot. private void registerPaperListeners() { if (checkPaperClass("io.papermc.paper.event.player.AsyncChatEvent")) { new ListenerPaperChat(this).register(); } else { new ListenerChat(this).register(); } if (checkPaperClass("io.papermc.paper.event.entity.EntityInsideBlockEvent")) { new ListenerPaperEntityInsideBlock(this).register(); } } private boolean checkPaperClass(String className) { try { Class.forName(className); return true; } catch (ReflectiveOperationException ex) { Logger logger = getLogger(); logger.info(className + " is not supported on this server version."); return false; } } } ================================================ FILE: expansion/cheat-prevention/src/main/java/combatlogx/expansion/cheat/prevention/configuration/BlockConfiguration.java ================================================ package combatlogx.expansion.cheat.prevention.configuration; import java.util.Collection; import java.util.Collections; import java.util.EnumSet; import java.util.Set; import org.jetbrains.annotations.NotNull; import org.bukkit.configuration.ConfigurationSection; import com.github.sirblobman.api.shaded.xseries.XMaterial; import static com.github.sirblobman.api.utility.ConfigurationHelper.parseEnums; public final class BlockConfiguration implements IBlockConfiguration { private final Set preventInteractionSet; private final Set preventBreakingSet; private final Set preventPlacingSet; private boolean preventInteraction; private boolean preventBreaking; private boolean preventPlacing; private boolean preventPortalCreation; public BlockConfiguration() { this.preventInteraction = false; this.preventBreaking = true; this.preventPlacing = true; this.preventPortalCreation = false; this.preventInteractionSet = EnumSet.noneOf(XMaterial.class); this.preventBreakingSet = EnumSet.noneOf(XMaterial.class); this.preventPlacingSet = EnumSet.noneOf(XMaterial.class); } @Override public void load(ConfigurationSection config) { setPreventInteraction(config.getBoolean("prevent-interaction", false)); setPreventBreaking(config.getBoolean("prevent-breaking", true)); setPreventPlacing(config.getBoolean("prevent-placing", true)); setPreventPortalCreation(config.getBoolean("prevent-portal-creation", false)); setPreventInteractionTypes(parseEnums(config.getStringList("prevent-interaction-list"), XMaterial.class)); setPreventBreakingTypes(parseEnums(config.getStringList("prevent-breaking-list"), XMaterial.class)); setPreventPlacingTypes(parseEnums(config.getStringList("prevent-placing-list"), XMaterial.class)); } @Override public boolean isPreventInteraction() { return this.preventInteraction; } public void setPreventInteraction(boolean value) { this.preventInteraction = value; } @Override public boolean isPreventBreaking() { return this.preventBreaking; } public void setPreventBreaking(boolean value) { this.preventBreaking = value; } @Override public boolean isPreventPlacing() { return this.preventPlacing; } public void setPreventPlacing(boolean value) { this.preventPlacing = value; } @Override public boolean isPreventPortalCreation() { return this.preventPortalCreation; } public void setPreventPortalCreation(boolean value) { this.preventPortalCreation = value; } public @NotNull Set getPreventInteractionTypes() { return Collections.unmodifiableSet(this.preventInteractionSet); } public void setPreventInteractionTypes(@NotNull Collection types) { this.preventInteractionSet.clear(); this.preventInteractionSet.addAll(types); } public @NotNull Set getPreventBreakingTypes() { return Collections.unmodifiableSet(this.preventBreakingSet); } public void setPreventBreakingTypes(@NotNull Collection types) { this.preventBreakingSet.clear(); this.preventBreakingSet.addAll(types); } public @NotNull Set getPreventPlacingTypes() { return Collections.unmodifiableSet(this.preventPlacingSet); } public void setPreventPlacingTypes(@NotNull Collection types) { this.preventPlacingSet.clear(); this.preventPlacingSet.addAll(types); } @Override public boolean isPreventInteraction(@NotNull XMaterial blockType) { Set typeSet = getPreventInteractionTypes(); return typeSet.contains(blockType); } @Override public boolean isPreventBreaking(@NotNull XMaterial blockType) { Set typeSet = getPreventBreakingTypes(); return typeSet.contains(blockType); } @Override public boolean isPreventPlacing(@NotNull XMaterial blockType) { Set typeSet = getPreventPlacingTypes(); return typeSet.contains(blockType); } } ================================================ FILE: expansion/cheat-prevention/src/main/java/combatlogx/expansion/cheat/prevention/configuration/BucketConfiguration.java ================================================ package combatlogx.expansion.cheat.prevention.configuration; import java.util.Collection; import java.util.Collections; import java.util.EnumSet; import java.util.Set; import org.jetbrains.annotations.NotNull; import org.bukkit.configuration.ConfigurationSection; import com.github.sirblobman.api.shaded.xseries.XMaterial; import static com.github.sirblobman.api.utility.ConfigurationHelper.parseEnums; public final class BucketConfiguration implements IBucketConfiguration { private final Set preventBucketEmptyTypeSet; private final Set preventBucketFillTypeSet; private boolean preventBucketEmpty; private boolean preventBucketFill; public BucketConfiguration() { this.preventBucketEmpty = false; this.preventBucketFill = false; this.preventBucketEmptyTypeSet = EnumSet.noneOf(XMaterial.class); this.preventBucketFillTypeSet = EnumSet.noneOf(XMaterial.class); } @Override public void load(@NotNull ConfigurationSection config) { setPreventBucketEmpty(config.getBoolean("prevent-bucket-empty", false)); setPreventBucketFill(config.getBoolean("prevent-bucket-fill", false)); setPreventBucketEmptyTypes(parseEnums(config.getStringList("prevent-bucket-empty-list"), XMaterial.class)); setPreventBucketFillTypes(parseEnums(config.getStringList("prevent-bucket-fill-list"), XMaterial.class)); } @Override public boolean isPreventBucketEmpty() { return this.preventBucketEmpty; } public void setPreventBucketEmpty(boolean value) { this.preventBucketEmpty = value; } @Override public boolean isPreventBucketFill() { return this.preventBucketFill; } public void setPreventBucketFill(boolean value) { this.preventBucketFill = value; } public @NotNull Set getPreventBucketEmptyTypes() { return Collections.unmodifiableSet(this.preventBucketEmptyTypeSet); } public void setPreventBucketEmptyTypes(@NotNull Collection types) { this.preventBucketEmptyTypeSet.clear(); this.preventBucketEmptyTypeSet.addAll(types); } public @NotNull Set getPreventBucketFillTypes() { return Collections.unmodifiableSet(this.preventBucketFillTypeSet); } public void setPreventBucketFillTypes(@NotNull Collection types) { this.preventBucketFillTypeSet.clear(); this.preventBucketFillTypeSet.addAll(types); } @Override public boolean isPreventEmpty(@NotNull XMaterial material) { Set typeSet = getPreventBucketEmptyTypes(); return typeSet.contains(material); } @Override public boolean isPreventFill(@NotNull XMaterial material) { Set typeSet = getPreventBucketFillTypes(); return typeSet.contains(material); } } ================================================ FILE: expansion/cheat-prevention/src/main/java/combatlogx/expansion/cheat/prevention/configuration/ChatConfiguration.java ================================================ package combatlogx.expansion.cheat.prevention.configuration; import org.bukkit.configuration.ConfigurationSection; public final class ChatConfiguration implements IChatConfiguration { private boolean disableChat; public ChatConfiguration() { this.disableChat = false; } @Override public void load(ConfigurationSection config) { setDisableChat(config.getBoolean("disable-chat", false)); } @Override public boolean isDisableChat() { return this.disableChat; } public void setDisableChat(boolean disableChat) { this.disableChat = disableChat; } } ================================================ FILE: expansion/cheat-prevention/src/main/java/combatlogx/expansion/cheat/prevention/configuration/CheatPreventionConfiguration.java ================================================ package combatlogx.expansion.cheat.prevention.configuration; import org.bukkit.configuration.ConfigurationSection; public final class CheatPreventionConfiguration implements IConfiguration { private int messageCooldown; public CheatPreventionConfiguration() { this.messageCooldown = 30; } @Override public void load(ConfigurationSection config) { setMessageCooldown(config.getInt("message-cooldown", 30)); } @Override public int getMessageCooldown() { return this.messageCooldown; } public void setMessageCooldown(int messageCooldown) { this.messageCooldown = messageCooldown; } } ================================================ FILE: expansion/cheat-prevention/src/main/java/combatlogx/expansion/cheat/prevention/configuration/CommandConfiguration.java ================================================ package combatlogx.expansion.cheat.prevention.configuration; import java.util.ArrayList; import java.util.Collection; import java.util.Collections; import java.util.List; import java.util.Locale; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import org.bukkit.configuration.ConfigurationSection; import org.bukkit.permissions.Permission; import org.bukkit.permissions.PermissionDefault; public final class CommandConfiguration implements ICommandConfiguration { private final List blockedCommandList; private final List allowedCommandList; private int delayAfterCombat; private String bypassPermissionName; private transient Permission bypassPermission; public CommandConfiguration() { this.delayAfterCombat = 0; this.blockedCommandList = new ArrayList<>(); this.allowedCommandList = new ArrayList<>(); this.bypassPermissionName = null; this.bypassPermission = null; } @Override public void load(ConfigurationSection config) { setDelayAfterCombat(config.getInt("delay-after-combat", 0)); setBlockedCommands(config.getStringList("blocked-command-list")); setAllowedCommands(config.getStringList("allowed-command-list")); setBypassPermissionName(config.getString("bypass-permission")); } @Override public int getDelayAfterCombat() { return this.delayAfterCombat; } public void setDelayAfterCombat(int delay) { this.delayAfterCombat = delay; } public @Nullable String getBypassPermissionName() { return this.bypassPermissionName; } public void setBypassPermissionName(@Nullable String permissionName) { this.bypassPermissionName = permissionName; this.bypassPermission = null; } @Override public @Nullable Permission getBypassPermission() { if (this.bypassPermission != null) { return this.bypassPermission; } String permissionName = getBypassPermissionName(); if (permissionName == null || permissionName.isEmpty()) { return null; } String permissionDescription = "CombatLogX CheatPrevention command blocker bypass."; this.bypassPermission = new Permission(permissionName, permissionDescription, PermissionDefault.FALSE); return this.bypassPermission; } public @NotNull List getAllowedCommands() { return Collections.unmodifiableList(this.allowedCommandList); } public void setAllowedCommands(@NotNull Collection commands) { this.allowedCommandList.clear(); this.allowedCommandList.addAll(commands); } @Override public boolean isAllowed(@NotNull String command) { List allowedCommandList = getAllowedCommands(); if (allowedCommandList.contains("*")) { return true; } String commandLowercase = command.toLowerCase(Locale.US); for (String allowedCommand : allowedCommandList) { String allowedCommandLowercase = allowedCommand.toLowerCase(Locale.US); if (commandLowercase.equals(allowedCommandLowercase)) { return true; } String withSpace = (allowedCommand + " "); if (commandLowercase.startsWith(withSpace)) { return true; } } return false; } public @NotNull List getBlockedCommands() { return Collections.unmodifiableList(this.blockedCommandList); } public void setBlockedCommands(@NotNull Collection commands) { this.blockedCommandList.clear(); this.blockedCommandList.addAll(commands); } @Override public boolean isBlocked(@NotNull String command) { List blockedCommandList = getBlockedCommands(); if (blockedCommandList.contains("*")) { return true; } String commandLowercase = command.toLowerCase(Locale.US); for (String blockedCommand : blockedCommandList) { String blockedCommandLowercase = blockedCommand.toLowerCase(Locale.US); if (commandLowercase.equals(blockedCommandLowercase)) { return true; } String withSpace = (blockedCommand + " "); if (commandLowercase.startsWith(withSpace)) { return true; } } return false; } } ================================================ FILE: expansion/cheat-prevention/src/main/java/combatlogx/expansion/cheat/prevention/configuration/EntityConfiguration.java ================================================ package combatlogx.expansion.cheat.prevention.configuration; import org.bukkit.configuration.ConfigurationSection; public final class EntityConfiguration implements IEntityConfiguration { private boolean preventInteraction; public EntityConfiguration() { this.preventInteraction = false; } @Override public void load(ConfigurationSection config) { setPreventInteraction(config.getBoolean("prevent-interaction", false)); } @Override public boolean isPreventInteraction() { return this.preventInteraction; } public void setPreventInteraction(boolean value) { this.preventInteraction = value; } } ================================================ FILE: expansion/cheat-prevention/src/main/java/combatlogx/expansion/cheat/prevention/configuration/FlightConfiguration.java ================================================ package combatlogx.expansion.cheat.prevention.configuration; import org.bukkit.configuration.ConfigurationSection; public final class FlightConfiguration implements IFlightConfiguration { private boolean preventFlying; private boolean preventFallDamage; private boolean forceDisableFlight; private boolean flightRetag; public FlightConfiguration() { this.preventFlying = true; this.preventFallDamage = true; this.forceDisableFlight = false; this.flightRetag = false; } @Override public void load(ConfigurationSection config) { setPreventFlying(config.getBoolean("prevent-flying", true)); setPreventFallDamage(config.getBoolean("prevent-fall-damahe", true)); setForceDisableFlight(config.getBoolean("force-disable-flight", false)); setFlightRetag(config.getBoolean("flight-retag", false)); } @Override public boolean isPreventFlying() { return this.preventFlying; } public void setPreventFlying(boolean preventFlying) { this.preventFlying = preventFlying; } @Override public boolean isPreventFallDamage() { return this.preventFallDamage; } public void setPreventFallDamage(boolean preventFallDamage) { this.preventFallDamage = preventFallDamage; } @Override public boolean isForceDisableFlight() { return this.forceDisableFlight; } public void setForceDisableFlight(boolean forceDisableFlight) { this.forceDisableFlight = forceDisableFlight; } @Override public boolean isFlightRetag() { return this.flightRetag; } public void setFlightRetag(boolean flightRetag) { this.flightRetag = flightRetag; } } ================================================ FILE: expansion/cheat-prevention/src/main/java/combatlogx/expansion/cheat/prevention/configuration/GameModeConfiguration.java ================================================ package combatlogx.expansion.cheat.prevention.configuration; import org.jetbrains.annotations.NotNull; import org.bukkit.GameMode; import org.bukkit.configuration.ConfigurationSection; import static com.github.sirblobman.api.utility.ConfigurationHelper.parseEnum; public final class GameModeConfiguration implements IGameModeConfiguration { private boolean preventSwitching; private boolean untagOnSwitch; private boolean forceSwitch; private GameMode forceMode; public GameModeConfiguration() { this.preventSwitching = true; this.untagOnSwitch = false; this.forceSwitch = false; this.forceMode = GameMode.SURVIVAL; } @Override public void load(ConfigurationSection config) { setPreventSwitching(config.getBoolean("prevent-switching", true)); setUntagOnSwitch(config.getBoolean("untag-on-switch", false)); setForceSwitch(config.getBoolean("force-switch", false)); String forceModeName = config.getString("force-mode", "SURVIVAL"); setForceMode(parseEnum(GameMode.class, forceModeName, GameMode.SURVIVAL)); } @Override public boolean isPreventSwitching() { return this.preventSwitching; } public void setPreventSwitching(boolean preventSwitching) { this.preventSwitching = preventSwitching; } @Override public boolean isUntagOnSwitch() { return this.untagOnSwitch; } public void setUntagOnSwitch(boolean untagOnSwitch) { this.untagOnSwitch = untagOnSwitch; } @Override public boolean isForceSwitch() { return this.forceSwitch; } public void setForceSwitch(boolean forceSwitch) { this.forceSwitch = forceSwitch; } @Override public @NotNull GameMode getForceMode() { return this.forceMode; } public void setForceMode(@NotNull GameMode forceMode) { this.forceMode = forceMode; } } ================================================ FILE: expansion/cheat-prevention/src/main/java/combatlogx/expansion/cheat/prevention/configuration/InventoryConfiguration.java ================================================ package combatlogx.expansion.cheat.prevention.configuration; import java.util.Collection; import java.util.Collections; import java.util.EnumSet; import java.util.List; import java.util.Set; import org.jetbrains.annotations.NotNull; import org.bukkit.configuration.ConfigurationSection; import org.bukkit.event.inventory.InventoryType; import static com.github.sirblobman.api.utility.ConfigurationHelper.parseEnums; public final class InventoryConfiguration implements IInventoryConfiguration { private final Set noCloseMessageTypeSet; private boolean close; private boolean closeOnRetag; private boolean preventOpening; public InventoryConfiguration() { this.close = true; this.closeOnRetag = true; this.preventOpening = true; this.noCloseMessageTypeSet = EnumSet.noneOf(InventoryType.class); } @Override public void load(ConfigurationSection config) { setClose(config.getBoolean("close", true)); setCloseOnRetag(config.getBoolean("close-on-retag", true)); setPreventOpening(config.getBoolean("prevent-opening", true)); List inventoryTypeNameList = config.getStringList("no-close-message-type-list"); setNoCloseMessageTypes(parseEnums(inventoryTypeNameList, InventoryType.class)); } @Override public boolean isClose() { return this.close; } public void setClose(boolean close) { this.close = close; } @Override public boolean isCloseOnRetag() { return this.closeOnRetag; } public void setCloseOnRetag(boolean closeOnRetag) { this.closeOnRetag = closeOnRetag; } @Override public boolean isPreventOpening() { return this.preventOpening; } public void setPreventOpening(boolean preventOpening) { this.preventOpening = preventOpening; } public @NotNull Set getNoCloseMessageTypes() { return Collections.unmodifiableSet(this.noCloseMessageTypeSet); } public void setNoCloseMessageTypes(@NotNull Collection types) { this.noCloseMessageTypeSet.clear(); this.noCloseMessageTypeSet.addAll(types); } @Override public boolean isNoMessage(@NotNull InventoryType type) { Set typeSet = getNoCloseMessageTypes(); return typeSet.contains(type); } } ================================================ FILE: expansion/cheat-prevention/src/main/java/combatlogx/expansion/cheat/prevention/configuration/ItemConfiguration.java ================================================ package combatlogx.expansion.cheat.prevention.configuration; import org.bukkit.configuration.ConfigurationSection; public final class ItemConfiguration implements IItemConfiguration { private boolean preventDrop; private boolean preventPickup; private boolean preventElytra; private boolean forcePreventElytra; private boolean preventFireworks; private boolean elytraRetag; private boolean preventTotem; private boolean preventRiptide; private boolean riptideRetag; public ItemConfiguration() { this.preventDrop = true; this.preventPickup = true; this.preventElytra = true; this.forcePreventElytra = false; this.preventFireworks = false; this.elytraRetag = false; this.preventTotem = false; this.preventRiptide = false; this.riptideRetag = false; } @Override public void load(ConfigurationSection config) { setPreventDrop(config.getBoolean("prevent-drop", true)); setPreventPickup(config.getBoolean("prevent-pickup", true)); setPreventElytra(config.getBoolean("prevent-elytra", true)); setForcePreventElytra(config.getBoolean("force-prevent-elytra", true)); setPreventFireworks(config.getBoolean("prevent-fireworks", false)); setElytraRetag(config.getBoolean("elytra-retag", false)); setPreventTotem(config.getBoolean("prevent-totem", false)); setPreventRiptide(config.getBoolean("prevent-riptide", false)); setRiptideRetag(config.getBoolean("riptide-retag", false)); } @Override public boolean isPreventDrop() { return this.preventDrop; } public void setPreventDrop(boolean preventDrop) { this.preventDrop = preventDrop; } @Override public boolean isPreventPickup() { return this.preventPickup; } public void setPreventPickup(boolean preventPickup) { this.preventPickup = preventPickup; } @Override public boolean isPreventElytra() { return this.preventElytra; } public void setPreventElytra(boolean preventElytra) { this.preventElytra = preventElytra; } @Override public boolean isForcePreventElytra() { return this.forcePreventElytra; } public void setForcePreventElytra(boolean forcePreventElytra) { this.forcePreventElytra = forcePreventElytra; } @Override public boolean isElytraRetag() { return this.elytraRetag; } public void setElytraRetag(boolean elytraRetag) { this.elytraRetag = elytraRetag; } @Override public boolean isPreventTotem() { return this.preventTotem; } public void setPreventTotem(boolean preventTotem) { this.preventTotem = preventTotem; } @Override public boolean isPreventRiptide() { return this.preventRiptide; } public void setPreventRiptide(boolean preventRiptide) { this.preventRiptide = preventRiptide; } @Override public boolean isRiptideRetag() { return this.riptideRetag; } public void setRiptideRetag(boolean riptideRetag) { this.riptideRetag = riptideRetag; } @Override public boolean isPreventFireworks() { return this.preventFireworks; } public void setPreventFireworks(boolean preventFireworks) { this.preventFireworks = preventFireworks; } } ================================================ FILE: expansion/cheat-prevention/src/main/java/combatlogx/expansion/cheat/prevention/configuration/PotionConfiguration.java ================================================ package combatlogx.expansion.cheat.prevention.configuration; import java.util.ArrayList; import java.util.Collection; import java.util.Collections; import java.util.HashSet; import java.util.List; import java.util.Set; import org.jetbrains.annotations.NotNull; import org.bukkit.configuration.ConfigurationSection; import org.bukkit.potion.PotionEffectType; public final class PotionConfiguration implements IPotionConfiguration { private final Set blockedPotionTypeSet; private boolean blockedPotionTypeSetInverted; public PotionConfiguration() { this.blockedPotionTypeSet = new HashSet<>(); this.blockedPotionTypeSetInverted = false; } @Override public void load(ConfigurationSection config) { setBlockedPotionTypeSetInverted(config.getBoolean("blocked-potion-type-list-inverted", false)); List potionTypeNameList = config.getStringList("blocked-potion-type-list"); List potionEffectTypeList = new ArrayList<>(); for (String potionTypeName : potionTypeNameList) { PotionEffectType potionEffectType = PotionEffectType.getByName(potionTypeName); if (potionEffectType != null) { potionEffectTypeList.add(potionEffectType); } } setBlockedPotionTypes(potionEffectTypeList); } public boolean isBlockedPotionTypeSetInverted() { return this.blockedPotionTypeSetInverted; } public void setBlockedPotionTypeSetInverted(boolean blockedPotionTypeSetInverted) { this.blockedPotionTypeSetInverted = blockedPotionTypeSetInverted; } public @NotNull Set getBlockedPotionTypes() { return Collections.unmodifiableSet(this.blockedPotionTypeSet); } public void setBlockedPotionTypes(@NotNull Collection types) { this.blockedPotionTypeSet.clear(); this.blockedPotionTypeSet.addAll(types); } @Override public boolean isBlocked(@NotNull PotionEffectType effectType) { Set blockedPotionTypeSet = getBlockedPotionTypes(); boolean inverted = isBlockedPotionTypeSetInverted(); boolean contains = blockedPotionTypeSet.contains(effectType); return (inverted != contains); } } ================================================ FILE: expansion/cheat-prevention/src/main/java/combatlogx/expansion/cheat/prevention/configuration/TeleportConfiguration.java ================================================ package combatlogx.expansion.cheat.prevention.configuration; import java.util.Collection; import java.util.Collections; import java.util.EnumSet; import java.util.List; import java.util.Set; import org.jetbrains.annotations.NotNull; import org.bukkit.configuration.ConfigurationSection; import org.bukkit.event.player.PlayerTeleportEvent.TeleportCause; import static com.github.sirblobman.api.utility.ConfigurationHelper.parseEnums; public final class TeleportConfiguration implements ITeleportConfiguration { private final Set allowedTeleportCauseSet; private boolean preventPortals; private boolean preventTeleportation; private boolean enderPearlRetag; private boolean untag; private boolean forceDisableEnderPearl; public TeleportConfiguration() { this.preventPortals = true; this.preventTeleportation = true; this.enderPearlRetag = false; this.untag = false; this.allowedTeleportCauseSet = EnumSet.noneOf(TeleportCause.class); this.forceDisableEnderPearl = false; } @Override public void load(ConfigurationSection config) { setPreventPortals(config.getBoolean("prevent-portals", true)); setPreventTeleportation(config.getBoolean("prevent-teleportation", true)); setEnderPearlRetag(config.getBoolean("ender-pearl-retag", false)); setUntag(config.getBoolean("untag", false)); setForceDisableEnderPearl(config.getBoolean("force-disable-ender-pearl", false)); List allowedTeleportCauseNameList = config.getStringList("allowed-teleport-cause-list"); setAllowedTeleportCauses(parseEnums(allowedTeleportCauseNameList, TeleportCause.class)); } @Override public boolean isPreventPortals() { return this.preventPortals; } public void setPreventPortals(boolean preventPortals) { this.preventPortals = preventPortals; } @Override public boolean isPreventTeleportation() { return this.preventTeleportation; } public void setPreventTeleportation(boolean preventTeleportation) { this.preventTeleportation = preventTeleportation; } @Override public boolean isEnderPearlRetag() { return this.enderPearlRetag; } public void setEnderPearlRetag(boolean enderPearlRetag) { this.enderPearlRetag = enderPearlRetag; } @Override public boolean isUntag() { return this.untag; } public void setUntag(boolean untag) { this.untag = untag; } public @NotNull Set getAllowedTeleportCauses() { return Collections.unmodifiableSet(this.allowedTeleportCauseSet); } public void setAllowedTeleportCauses(@NotNull Collection causes) { this.allowedTeleportCauseSet.clear(); this.allowedTeleportCauseSet.addAll(causes); } @Override public boolean isAllowed(@NotNull TeleportCause cause) { Set causeSet = getAllowedTeleportCauses(); return causeSet.contains(cause); } @Override public boolean isForceDisableEnderPearl() { return this.forceDisableEnderPearl; } public void setForceDisableEnderPearl(boolean forceDisableEnderPearl) { this.forceDisableEnderPearl = forceDisableEnderPearl; } } ================================================ FILE: expansion/cheat-prevention/src/main/java/combatlogx/expansion/cheat/prevention/listener/ListenerBlocks.java ================================================ package combatlogx.expansion.cheat.prevention.listener; import java.util.Locale; import org.jetbrains.annotations.NotNull; import org.bukkit.Material; import org.bukkit.block.Block; import org.bukkit.entity.Player; import org.bukkit.event.EventHandler; import org.bukkit.event.EventPriority; import org.bukkit.event.block.Action; import org.bukkit.event.block.BlockBreakEvent; import org.bukkit.event.block.BlockPlaceEvent; import org.bukkit.event.player.PlayerInteractEvent; import com.github.sirblobman.api.utility.VersionUtility; import com.github.sirblobman.api.shaded.xseries.XMaterial; import combatlogx.expansion.cheat.prevention.ICheatPreventionExpansion; import combatlogx.expansion.cheat.prevention.configuration.IBlockConfiguration; public final class ListenerBlocks extends CheatPreventionListener { public ListenerBlocks(@NotNull ICheatPreventionExpansion expansion) { super(expansion); } @EventHandler(priority = EventPriority.NORMAL, ignoreCancelled = true) public void onInteract(PlayerInteractEvent e) { Action action = e.getAction(); if (action != Action.RIGHT_CLICK_BLOCK && action != Action.LEFT_CLICK_BLOCK && action != Action.PHYSICAL) { return; } Block block = e.getClickedBlock(); if (block == null) { return; } Player player = e.getPlayer(); if (isPreventInteract(fetchMaterial(block)) && isInCombat(player)) { e.setCancelled(true); sendMessage(player, "expansion.cheat-prevention.blocks.prevent-interaction"); } } @EventHandler(priority = EventPriority.NORMAL, ignoreCancelled = true) public void onBreak(BlockBreakEvent e) { Player player = e.getPlayer(); Block block = e.getBlock(); if (isPreventBreak(fetchMaterial(block)) && isInCombat(player)) { e.setCancelled(true); sendMessage(player, "expansion.cheat-prevention.blocks.prevent-breaking"); } } @EventHandler(priority = EventPriority.NORMAL, ignoreCancelled = true) public void onPlace(BlockPlaceEvent e) { Player player = e.getPlayer(); Block block = e.getBlock(); if (isPreventPlace(fetchMaterial(block)) && isInCombat(player)) { e.setCancelled(true); sendMessage(player, "expansion.cheat-prevention.blocks.prevent-placing"); } } private @NotNull IBlockConfiguration getBlockConfiguration() { ICheatPreventionExpansion expansion = getCheatPrevention(); return expansion.getBlockConfiguration(); } private boolean isPreventBreak(@NotNull XMaterial material) { IBlockConfiguration blockConfiguration = getBlockConfiguration(); if (blockConfiguration.isPreventBreaking()) { return blockConfiguration.isPreventBreaking(material); } return false; } private boolean isPreventPlace(@NotNull XMaterial material) { IBlockConfiguration blockConfiguration = getBlockConfiguration(); if (blockConfiguration.isPreventPlacing()) { return blockConfiguration.isPreventPlacing(material); } return false; } private boolean isPreventInteract(@NotNull XMaterial material) { IBlockConfiguration blockConfiguration = getBlockConfiguration(); if (blockConfiguration.isPreventInteraction()) { return blockConfiguration.isPreventInteraction(material); } return false; } @SuppressWarnings("deprecation") private @NotNull XMaterial fetchMaterial(@NotNull Block block) { int minorVersion = VersionUtility.getMinorVersion(); Material bukkitType = block.getType(); if (minorVersion < 13) { int data = block.getData(); String materialName = String.format(Locale.US, "%s:%s", bukkitType.name(), data); return XMaterial.matchXMaterial(materialName).orElse(XMaterial.AIR); } else { return XMaterial.matchXMaterial(bukkitType); } } } ================================================ FILE: expansion/cheat-prevention/src/main/java/combatlogx/expansion/cheat/prevention/listener/ListenerBuckets.java ================================================ package combatlogx.expansion.cheat.prevention.listener; import org.jetbrains.annotations.NotNull; import org.bukkit.Material; import org.bukkit.entity.Player; import org.bukkit.event.EventHandler; import org.bukkit.event.EventPriority; import org.bukkit.event.player.PlayerBucketEmptyEvent; import org.bukkit.event.player.PlayerBucketFillEvent; import com.github.sirblobman.api.shaded.xseries.XMaterial; import combatlogx.expansion.cheat.prevention.ICheatPreventionExpansion; import combatlogx.expansion.cheat.prevention.configuration.IBucketConfiguration; public final class ListenerBuckets extends CheatPreventionListener { public ListenerBuckets(@NotNull ICheatPreventionExpansion expansion) { super(expansion); } @EventHandler(priority = EventPriority.NORMAL, ignoreCancelled = true) public void onBucketEmpty(PlayerBucketEmptyEvent e) { Player player = e.getPlayer(); Material bukkitMaterial = e.getBucket(); XMaterial material = XMaterial.matchXMaterial(bukkitMaterial); if (isInCombat(player) && isPreventEmpty(material)) { e.setCancelled(true); sendMessage(player, "expansion.cheat-prevention.buckets.no-empty"); } } @EventHandler(priority = EventPriority.NORMAL, ignoreCancelled = true) public void onBucketEmpty(PlayerBucketFillEvent e) { Player player = e.getPlayer(); Material bukkitMaterial = e.getBucket(); XMaterial material = XMaterial.matchXMaterial(bukkitMaterial); if (isInCombat(player) && isPreventFill(material)) { e.setCancelled(true); sendMessage(player, "expansion.cheat-prevention.buckets.no-fill"); } } private @NotNull IBucketConfiguration getBucketConfiguration() { ICheatPreventionExpansion expansion = getCheatPrevention(); return expansion.getBucketConfiguration(); } private boolean isPreventEmpty(@NotNull XMaterial material) { IBucketConfiguration configuration = getBucketConfiguration(); return (configuration.isPreventBucketEmpty() && configuration.isPreventEmpty(material)); } private boolean isPreventFill(@NotNull XMaterial material) { IBucketConfiguration configuration = getBucketConfiguration(); return (configuration.isPreventBucketFill() && configuration.isPreventFill(material)); } } ================================================ FILE: expansion/cheat-prevention/src/main/java/combatlogx/expansion/cheat/prevention/listener/ListenerCommands.java ================================================ package combatlogx.expansion.cheat.prevention.listener; import java.util.HashMap; import java.util.Map; import java.util.UUID; import java.util.concurrent.TimeUnit; import org.jetbrains.annotations.NotNull; import org.bukkit.entity.Player; import org.bukkit.event.EventHandler; import org.bukkit.event.EventPriority; import org.bukkit.event.player.PlayerCommandPreprocessEvent; import org.bukkit.permissions.Permission; import com.github.sirblobman.api.language.replacer.Replacer; import com.github.sirblobman.api.language.replacer.StringReplacer; import com.github.sirblobman.combatlogx.api.event.PlayerUntagEvent; import com.github.sirblobman.combatlogx.api.object.UntagReason; import combatlogx.expansion.cheat.prevention.ICheatPreventionExpansion; import combatlogx.expansion.cheat.prevention.configuration.ICommandConfiguration; public final class ListenerCommands extends CheatPreventionListener { private final Map cooldownMap; public ListenerCommands(@NotNull ICheatPreventionExpansion expansion) { super(expansion); this.cooldownMap = new HashMap<>(); } @EventHandler(priority = EventPriority.LOWEST, ignoreCancelled = true) public void beforeCommandLowest(PlayerCommandPreprocessEvent e) { checkEvent(e); } @EventHandler(priority = EventPriority.HIGH, ignoreCancelled = true) public void beforeCommandHigh(PlayerCommandPreprocessEvent e) { checkEvent(e); } @EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true) public void onUntag(PlayerUntagEvent e) { UntagReason untagReason = e.getUntagReason(); if (!untagReason.isExpire()) { return; } Player player = e.getPlayer(); addCooldown(player); } private @NotNull ICommandConfiguration getCommandConfiguration() { ICheatPreventionExpansion expansion = getCheatPrevention(); return expansion.getCommandConfiguration(); } private boolean hasBypassPermission(Player player) { ICommandConfiguration commandConfiguration = getCommandConfiguration(); Permission bypassPermission = commandConfiguration.getBypassPermission(); if (bypassPermission == null) { return false; } return player.hasPermission(bypassPermission); } private long getNewExpireTime() { ICommandConfiguration commandConfiguration = getCommandConfiguration(); long cooldownSeconds = commandConfiguration.getDelayAfterCombat(); long cooldownMillis = TimeUnit.SECONDS.toMillis(cooldownSeconds); long systemMillis = System.currentTimeMillis(); return (systemMillis + cooldownMillis); } private boolean isInCooldown(Player player) { UUID uuid = player.getUniqueId(); if (this.cooldownMap.containsKey(uuid)) { long expireMillis = this.cooldownMap.get(uuid); long systemMillis = System.currentTimeMillis(); if (systemMillis < expireMillis) { return true; } this.cooldownMap.remove(uuid); return false; } return false; } private void addCooldown(Player player) { UUID playerId = player.getUniqueId(); long expireMillis = getNewExpireTime(); this.cooldownMap.put(playerId, expireMillis); } private String fixCommand(String command) { if (command.startsWith("/")) { return command; } return ("/" + command); } private boolean isBlocked(String command) { ICommandConfiguration commandConfiguration = getCommandConfiguration(); return commandConfiguration.isBlocked(command); } private boolean isAllowed(String command) { ICommandConfiguration commandConfiguration = getCommandConfiguration(); return commandConfiguration.isAllowed(command); } private void checkEvent(PlayerCommandPreprocessEvent e) { Player player = e.getPlayer(); if (!isInCombat(player) && !isInCooldown(player)) { return; } if (hasBypassPermission(player)) { return; } String command = e.getMessage(); String realCommand = fixCommand(command); if (isAllowed(realCommand) || !isBlocked(realCommand)) { return; } e.setCancelled(true); Replacer replacer = new StringReplacer("{command}", realCommand); sendMessageIgnoreCooldown(player, "expansion.cheat-prevention.command-blocked", replacer); } } ================================================ FILE: expansion/cheat-prevention/src/main/java/combatlogx/expansion/cheat/prevention/listener/ListenerDrop.java ================================================ package combatlogx.expansion.cheat.prevention.listener; import org.jetbrains.annotations.NotNull; import org.bukkit.entity.Player; import org.bukkit.event.EventHandler; import org.bukkit.event.EventPriority; import org.bukkit.event.player.PlayerDropItemEvent; import combatlogx.expansion.cheat.prevention.ICheatPreventionExpansion; import combatlogx.expansion.cheat.prevention.configuration.IItemConfiguration; public final class ListenerDrop extends CheatPreventionListener { public ListenerDrop(@NotNull ICheatPreventionExpansion expansion) { super(expansion); } @EventHandler(priority = EventPriority.NORMAL, ignoreCancelled = true) public void onDrop(PlayerDropItemEvent e) { Player player = e.getPlayer(); if (isPreventDrop() && isInCombat(player)) { e.setCancelled(true); sendMessage(player, "expansion.cheat-prevention.items.no-dropping"); } } private @NotNull IItemConfiguration getItemConfiguration() { ICheatPreventionExpansion expansion = getCheatPrevention(); return expansion.getItemConfiguration(); } private boolean isPreventDrop() { IItemConfiguration itemConfiguration = getItemConfiguration(); return itemConfiguration.isPreventDrop(); } } ================================================ FILE: expansion/cheat-prevention/src/main/java/combatlogx/expansion/cheat/prevention/listener/ListenerElytra.java ================================================ package combatlogx.expansion.cheat.prevention.listener; import org.jetbrains.annotations.NotNull; import org.bukkit.entity.Entity; import org.bukkit.entity.Firework; import org.bukkit.entity.Player; import org.bukkit.entity.Projectile; import org.bukkit.event.EventHandler; import org.bukkit.event.EventPriority; import org.bukkit.event.entity.EntityToggleGlideEvent; import org.bukkit.event.entity.ProjectileLaunchEvent; import org.bukkit.projectiles.ProjectileSource; import com.github.sirblobman.combatlogx.api.event.PlayerTagEvent; import combatlogx.expansion.cheat.prevention.ICheatPreventionExpansion; import combatlogx.expansion.cheat.prevention.configuration.IItemConfiguration; public final class ListenerElytra extends CheatPreventionListener { public ListenerElytra(@NotNull ICheatPreventionExpansion expansion) { super(expansion); } @EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true) public void onTag(PlayerTagEvent e) { Player player = e.getPlayer(); if (player.isGliding() && isForcePreventElytra()) { player.setGliding(false); sendMessage(player, "expansion.cheat-prevention.elytra.force-disabled"); } } @EventHandler(priority = EventPriority.NORMAL, ignoreCancelled = true) public void onToggle(EntityToggleGlideEvent e) { if (!e.isGliding()) { return; } Entity entity = e.getEntity(); if (!(entity instanceof Player player)) { return; } if (isInCombat(player) && isPreventElytra()) { e.setCancelled(true); sendMessage(player, "expansion.cheat-prevention.elytra.no-gliding"); } } @EventHandler(priority = EventPriority.NORMAL, ignoreCancelled = true) public void onLaunch(ProjectileLaunchEvent e) { if (!isPreventFireworks()) { return; } Projectile projectile = e.getEntity(); if (projectile instanceof Firework firework) { ProjectileSource shooter = firework.getShooter(); if (shooter instanceof Player player && isInCombat(player)) { e.setCancelled(true); sendMessage(player, "expansion.cheat-prevention.elytra.no-fireworks"); } } } private @NotNull IItemConfiguration getItemConfiguration() { ICheatPreventionExpansion expansion = getCheatPrevention(); return expansion.getItemConfiguration(); } private boolean isPreventElytra() { return getItemConfiguration().isPreventElytra(); } private boolean isForcePreventElytra() { return getItemConfiguration().isForcePreventElytra(); } private boolean isPreventFireworks() { return getItemConfiguration().isPreventFireworks(); } } ================================================ FILE: expansion/cheat-prevention/src/main/java/combatlogx/expansion/cheat/prevention/listener/ListenerEnderPearl.java ================================================ package combatlogx.expansion.cheat.prevention.listener; import combatlogx.expansion.cheat.prevention.ICheatPreventionExpansion; import combatlogx.expansion.cheat.prevention.configuration.ITeleportConfiguration; import org.bukkit.entity.EnderPearl; import org.bukkit.entity.Player; import org.bukkit.entity.Projectile; import org.bukkit.event.EventHandler; import org.bukkit.event.EventPriority; import org.bukkit.event.entity.ProjectileLaunchEvent; import org.bukkit.projectiles.ProjectileSource; import org.jetbrains.annotations.NotNull; public final class ListenerEnderPearl extends CheatPreventionListener { public ListenerEnderPearl(@NotNull ICheatPreventionExpansion expansion) { super(expansion); } @EventHandler(priority = EventPriority.NORMAL, ignoreCancelled = true) public void onLand(ProjectileLaunchEvent e) { ICheatPreventionExpansion expansion = getCheatPrevention(); ITeleportConfiguration teleportConfiguration = expansion.getTeleportConfiguration(); if (!teleportConfiguration.isForceDisableEnderPearl()) { return; } Projectile projectile = e.getEntity(); if (!(projectile instanceof EnderPearl enderPearl)) { return; } ProjectileSource shooter = enderPearl.getShooter(); if (shooter instanceof Player player && isInCombat(player)) { e.setCancelled(true); sendMessage(player, "expansion.cheat-prevention.teleportation.block-pearl"); } } } ================================================ FILE: expansion/cheat-prevention/src/main/java/combatlogx/expansion/cheat/prevention/listener/ListenerEntities.java ================================================ package combatlogx.expansion.cheat.prevention.listener; import org.jetbrains.annotations.NotNull; import org.bukkit.entity.Player; import org.bukkit.event.EventHandler; import org.bukkit.event.EventPriority; import org.bukkit.event.player.PlayerInteractEntityEvent; import combatlogx.expansion.cheat.prevention.ICheatPreventionExpansion; import combatlogx.expansion.cheat.prevention.configuration.IEntityConfiguration; public final class ListenerEntities extends CheatPreventionListener { public ListenerEntities(@NotNull ICheatPreventionExpansion expansion) { super(expansion); } @EventHandler(priority = EventPriority.NORMAL, ignoreCancelled = true) public void onInteract(PlayerInteractEntityEvent e) { Player player = e.getPlayer(); if (isInCombat(player) && isPreventInteraction()) { e.setCancelled(true); sendMessage(player, "expansion.cheat-prevention.no-entity-interaction"); } } private @NotNull IEntityConfiguration getEntityConfiguration() { ICheatPreventionExpansion expansion = getCheatPrevention(); return expansion.getEntityConfiguration(); } private boolean isPreventInteraction() { IEntityConfiguration entityConfiguration = getEntityConfiguration(); return entityConfiguration.isPreventInteraction(); } } ================================================ FILE: expansion/cheat-prevention/src/main/java/combatlogx/expansion/cheat/prevention/listener/ListenerFlight.java ================================================ package combatlogx.expansion.cheat.prevention.listener; import java.util.HashSet; import java.util.Set; import java.util.UUID; import org.jetbrains.annotations.NotNull; import org.bukkit.entity.Entity; import org.bukkit.entity.Player; import org.bukkit.event.EventHandler; import org.bukkit.event.EventPriority; import org.bukkit.event.entity.EntityDamageEvent; import org.bukkit.event.entity.EntityDamageEvent.DamageCause; import org.bukkit.event.player.PlayerToggleFlightEvent; import com.github.sirblobman.combatlogx.api.event.PlayerTagEvent; import combatlogx.expansion.cheat.prevention.ICheatPreventionExpansion; import combatlogx.expansion.cheat.prevention.configuration.IFlightConfiguration; public final class ListenerFlight extends CheatPreventionListener { private final Set noFallDamageSet; public ListenerFlight(@NotNull ICheatPreventionExpansion expansion) { super(expansion); this.noFallDamageSet = new HashSet<>(); } @EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true) public void onTag(PlayerTagEvent e) { printDebug("Detected PlayerTagEvent..."); Player player = e.getPlayer(); printDebug("Checking player allow flight value..."); checkAllowFlight(player); printDebug("Checking player flying value..."); checkFlight(player); } @EventHandler(priority = EventPriority.NORMAL, ignoreCancelled = true) public void onToggle(PlayerToggleFlightEvent e) { Player player = e.getPlayer(); if (e.isFlying() && isPreventFlight() && isInCombat(player)) { e.setCancelled(true); sendMessage(player, "expansion.cheat-prevention.flight.no-flying"); } } @EventHandler(priority = EventPriority.NORMAL, ignoreCancelled = true) public void onDamage(EntityDamageEvent e) { DamageCause damageCause = e.getCause(); if (damageCause != DamageCause.FALL) { return; } Entity entity = e.getEntity(); if (!(entity instanceof Player)) { return; } Player player = (Player) entity; UUID playerId = player.getUniqueId(); if (isPreventFallDamage() && this.noFallDamageSet.remove(playerId)) { e.setCancelled(true); } } private @NotNull IFlightConfiguration getFlightConfiguration() { ICheatPreventionExpansion expansion = getCheatPrevention(); return expansion.getFlightConfiguration(); } private boolean isPreventFlight() { IFlightConfiguration flightConfiguration = getFlightConfiguration(); return flightConfiguration.isPreventFlying(); } private boolean isForceDisableFlight() { IFlightConfiguration flightConfiguration = getFlightConfiguration(); return flightConfiguration.isForceDisableFlight(); } private boolean isPreventFallDamage() { IFlightConfiguration flightConfiguration = getFlightConfiguration(); return flightConfiguration.isPreventFallDamage(); } private void checkFlight(Player player) { if (isPreventFlight() && player.isFlying()) { player.setFlying(false); if (isPreventFallDamage()) { UUID playerId = player.getUniqueId(); this.noFallDamageSet.add(playerId); } sendMessage(player, "expansion.cheat-prevention.flight.force-disabled"); } } private void checkAllowFlight(Player player) { if (player.getAllowFlight() && isForceDisableFlight()) { player.setAllowFlight(false); sendMessage(player, "expansion.cheat-prevention.flight.force-disabled"); } } } ================================================ FILE: expansion/cheat-prevention/src/main/java/combatlogx/expansion/cheat/prevention/listener/ListenerGameMode.java ================================================ package combatlogx.expansion.cheat.prevention.listener; import org.jetbrains.annotations.NotNull; import org.bukkit.GameMode; import org.bukkit.entity.Player; import org.bukkit.event.EventHandler; import org.bukkit.event.EventPriority; import org.bukkit.event.player.PlayerGameModeChangeEvent; import com.github.sirblobman.api.language.replacer.Replacer; import com.github.sirblobman.api.language.replacer.StringReplacer; import com.github.sirblobman.combatlogx.api.event.PlayerTagEvent; import com.github.sirblobman.combatlogx.api.manager.ICombatManager; import com.github.sirblobman.combatlogx.api.object.UntagReason; import combatlogx.expansion.cheat.prevention.ICheatPreventionExpansion; import combatlogx.expansion.cheat.prevention.configuration.IGameModeConfiguration; public final class ListenerGameMode extends CheatPreventionListener { public ListenerGameMode(@NotNull ICheatPreventionExpansion expansion) { super(expansion); } @EventHandler(priority = EventPriority.NORMAL, ignoreCancelled = true) public void onSwitch(PlayerGameModeChangeEvent e) { Player player = e.getPlayer(); if (isInCombat(player)) { GameMode gameMode = e.getNewGameMode(); GameMode forceMode = getForceSwitchMode(); if (gameMode == forceMode) { return; } if (isPreventSwitching()) { e.setCancelled(true); sendMessage(player, "expansion.cheat-prevention.game-mode.no-switch"); return; } checkUntag(player); } } @EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true) public void onTag(PlayerTagEvent e) { if (isForceSwitch()) { Player player = e.getPlayer(); GameMode gameMode = getForceSwitchMode(); player.setGameMode(gameMode); String gameModeName = gameMode.name(); Replacer replacer = new StringReplacer("{game_mode}", gameModeName); sendMessage(player, "expansion.cheat-prevention.game-mode.force-switch", replacer); } } private void checkUntag(@NotNull Player player) { if (isUntagOnSwitch()) { ICombatManager combatManager = getCombatManager(); combatManager.untag(player, UntagReason.EXPIRE); } } private @NotNull IGameModeConfiguration getGameModeConfiguration() { ICheatPreventionExpansion expansion = getCheatPrevention(); return expansion.getGameModeConfiguration(); } private boolean isPreventSwitching() { IGameModeConfiguration gameModeConfiguration = getGameModeConfiguration(); return gameModeConfiguration.isPreventSwitching(); } private boolean isForceSwitch() { IGameModeConfiguration gameModeConfiguration = getGameModeConfiguration(); return gameModeConfiguration.isForceSwitch(); } private boolean isUntagOnSwitch() { IGameModeConfiguration gameModeConfiguration = getGameModeConfiguration(); return gameModeConfiguration.isUntagOnSwitch(); } private @NotNull GameMode getForceSwitchMode() { IGameModeConfiguration gameModeConfiguration = getGameModeConfiguration(); return gameModeConfiguration.getForceMode(); } } ================================================ FILE: expansion/cheat-prevention/src/main/java/combatlogx/expansion/cheat/prevention/listener/ListenerInventories.java ================================================ package combatlogx.expansion.cheat.prevention.listener; import org.jetbrains.annotations.NotNull; import org.bukkit.entity.HumanEntity; import org.bukkit.entity.Player; import org.bukkit.event.EventHandler; import org.bukkit.event.EventPriority; import org.bukkit.event.inventory.InventoryOpenEvent; import org.bukkit.event.inventory.InventoryType; import org.bukkit.inventory.InventoryView; import com.github.sirblobman.combatlogx.api.event.PlayerReTagEvent; import com.github.sirblobman.combatlogx.api.event.PlayerTagEvent; import combatlogx.expansion.cheat.prevention.ICheatPreventionExpansion; import combatlogx.expansion.cheat.prevention.configuration.IInventoryConfiguration; public final class ListenerInventories extends CheatPreventionListener { public ListenerInventories(@NotNull ICheatPreventionExpansion expansion) { super(expansion); } @EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true) public void onTag(PlayerTagEvent e) { if (isClose()) { Player player = e.getPlayer(); InventoryView openView = player.getOpenInventory(); InventoryType viewType = openView.getType(); player.closeInventory(); if (isMessage(viewType)) { sendMessage(player, "expansion.cheat-prevention.inventory.force-closed"); } } } @EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true) public void onReTag(PlayerReTagEvent e) { if (isCloseOnRetag()) { Player player = e.getPlayer(); InventoryView openView = player.getOpenInventory(); InventoryType viewType = openView.getType(); player.closeInventory(); if (isMessage(viewType)) { sendMessage(player, "expansion.cheat-prevention.inventory.force-closed"); } } } @EventHandler(priority = EventPriority.NORMAL, ignoreCancelled = true) public void onOpen(InventoryOpenEvent e) { HumanEntity human = e.getPlayer(); if (!(human instanceof Player)) { return; } Player player = (Player) human; if (isPreventOpening() && isInCombat(player)) { e.setCancelled(true); sendMessage(player, "expansion.cheat-prevention.inventory.no-opening"); } } private @NotNull IInventoryConfiguration getInventoryConfiguration() { ICheatPreventionExpansion expansion = getCheatPrevention(); return expansion.getInventoryConfiguration(); } private boolean isClose() { IInventoryConfiguration inventoryConfiguration = getInventoryConfiguration(); return inventoryConfiguration.isClose(); } private boolean isCloseOnRetag() { IInventoryConfiguration inventoryConfiguration = getInventoryConfiguration(); return inventoryConfiguration.isCloseOnRetag(); } private boolean isPreventOpening() { IInventoryConfiguration inventoryConfiguration = getInventoryConfiguration(); return inventoryConfiguration.isPreventOpening(); } private boolean isMessage(@NotNull InventoryType type) { IInventoryConfiguration inventoryConfiguration = getInventoryConfiguration(); return !inventoryConfiguration.isNoMessage(type); } } ================================================ FILE: expansion/cheat-prevention/src/main/java/combatlogx/expansion/cheat/prevention/listener/ListenerRiptide.java ================================================ package combatlogx.expansion.cheat.prevention.listener; import org.jetbrains.annotations.NotNull; import org.bukkit.entity.Player; import org.bukkit.event.EventHandler; import org.bukkit.event.EventPriority; import org.bukkit.event.player.PlayerMoveEvent; import com.github.sirblobman.combatlogx.api.manager.ICombatManager; import com.github.sirblobman.combatlogx.api.object.TagReason; import com.github.sirblobman.combatlogx.api.object.TagType; import combatlogx.expansion.cheat.prevention.ICheatPreventionExpansion; import combatlogx.expansion.cheat.prevention.configuration.IItemConfiguration; public final class ListenerRiptide extends CheatPreventionListener { public ListenerRiptide(@NotNull ICheatPreventionExpansion expansion) { super(expansion); } @EventHandler(priority = EventPriority.NORMAL, ignoreCancelled = true) public void onMove(PlayerMoveEvent e) { Player player = e.getPlayer(); if (!player.isRiptiding()) { return; } if (!isInCombat(player)) { return; } if (isPreventRiptide()) { e.setCancelled(true); sendMessage(player, "expansion.cheat-prevention.no-riptide"); } if (isRiptideRetag()) { ICombatManager combatManager = getCombatManager(); combatManager.tag(player, null, TagType.UNKNOWN, TagReason.UNKNOWN); } } private @NotNull IItemConfiguration getItemConfiguration() { ICheatPreventionExpansion expansion = getCheatPrevention(); return expansion.getItemConfiguration(); } private boolean isPreventRiptide() { IItemConfiguration itemConfiguration = getItemConfiguration(); return itemConfiguration.isPreventRiptide(); } private boolean isRiptideRetag() { IItemConfiguration itemConfiguration = getItemConfiguration(); return itemConfiguration.isRiptideRetag(); } } ================================================ FILE: expansion/cheat-prevention/src/main/java/combatlogx/expansion/cheat/prevention/listener/ListenerTeleport.java ================================================ package combatlogx.expansion.cheat.prevention.listener; import org.jetbrains.annotations.NotNull; import org.bukkit.entity.Player; import org.bukkit.event.EventHandler; import org.bukkit.event.EventPriority; import org.bukkit.event.player.PlayerPortalEvent; import org.bukkit.event.player.PlayerTeleportEvent; import org.bukkit.event.player.PlayerTeleportEvent.TeleportCause; import com.github.sirblobman.combatlogx.api.manager.ICombatManager; import com.github.sirblobman.combatlogx.api.object.TagReason; import com.github.sirblobman.combatlogx.api.object.TagType; import com.github.sirblobman.combatlogx.api.object.UntagReason; import combatlogx.expansion.cheat.prevention.ICheatPreventionExpansion; import combatlogx.expansion.cheat.prevention.configuration.ITeleportConfiguration; public final class ListenerTeleport extends CheatPreventionListener { public ListenerTeleport(@NotNull ICheatPreventionExpansion expansion) { super(expansion); } @EventHandler(priority = EventPriority.NORMAL, ignoreCancelled = true) public void onTeleport(PlayerTeleportEvent e) { Player player = e.getPlayer(); if (isInCombat(player)) { checkPrevention(e); checkEnderPearlRetag(e); checkUntag(e); } } @EventHandler(priority = EventPriority.NORMAL, ignoreCancelled = true) public void onPortal(PlayerPortalEvent e) { Player player = e.getPlayer(); if (isInCombat(player) && isPreventPortals()) { e.setCancelled(true); sendMessage(player, "expansion.cheat-prevention.teleportation.block-portal"); } } private void checkPrevention(PlayerTeleportEvent e) { printDebug("Checking if teleport event should be prevented..."); if (e.isCancelled()) { printDebug("Event is already cancelled."); return; } if (isPreventTeleportation()) { TeleportCause teleportCause = e.getCause(); if (isAllowed(teleportCause)) { printDebug("Teleportation cause '" + teleportCause + "' is allowed by the config."); return; } printDebug("Cancelling teleport event."); e.setCancelled(true); Player player = e.getPlayer(); String messagePath = getMessagePath(teleportCause); sendMessage(player, messagePath); } } private void checkEnderPearlRetag(PlayerTeleportEvent e) { printDebug("Checking if ender pearl should re-tag player..."); if (e.isCancelled()) { printDebug("Event was cancelled, ignoring."); return; } if (isEnderPearlRetag() && e.getCause() == TeleportCause.ENDER_PEARL) { Player player = e.getPlayer(); ICombatManager combatManager = getCombatManager(); combatManager.tag(player, null, TagType.UNKNOWN, TagReason.UNKNOWN); printDebug("Player will be re-tagged. Done."); } } private void checkUntag(PlayerTeleportEvent e) { printDebug("Checking if player should be untagged by teleport event..."); if (e.isCancelled()) { printDebug("Event was cancelled, not untagging."); return; } if (isUntag() && e.getCause() != TeleportCause.UNKNOWN) { Player player = e.getPlayer(); ICombatManager combatManager = getCombatManager(); combatManager.untag(player, UntagReason.EXPIRE); printDebug("Untagging player due to teleport event."); } } private String getMessagePath(TeleportCause cause) { String mainPath = ("expansion.cheat-prevention.teleportation.block-"); String causeName = (cause == TeleportCause.ENDER_PEARL ? "pearl" : "other"); return (mainPath + causeName); } private @NotNull ITeleportConfiguration getTeleportConfiguration() { ICheatPreventionExpansion expansion = getCheatPrevention(); return expansion.getTeleportConfiguration(); } private boolean isPreventTeleportation() { ITeleportConfiguration teleportConfiguration = getTeleportConfiguration(); return teleportConfiguration.isPreventTeleportation(); } private boolean isPreventPortals() { ITeleportConfiguration teleportConfiguration = getTeleportConfiguration(); return teleportConfiguration.isPreventPortals(); } private boolean isEnderPearlRetag() { ITeleportConfiguration teleportConfiguration = getTeleportConfiguration(); return teleportConfiguration.isEnderPearlRetag(); } private boolean isUntag() { ITeleportConfiguration teleportConfiguration = getTeleportConfiguration(); return teleportConfiguration.isUntag(); } private boolean isAllowed(@NotNull TeleportCause cause) { ITeleportConfiguration teleportConfiguration = getTeleportConfiguration(); return teleportConfiguration.isAllowed(cause); } } ================================================ FILE: expansion/cheat-prevention/src/main/java/combatlogx/expansion/cheat/prevention/listener/ListenerTotem.java ================================================ package combatlogx.expansion.cheat.prevention.listener; import org.jetbrains.annotations.NotNull; import org.bukkit.entity.LivingEntity; import org.bukkit.entity.Player; import org.bukkit.event.EventHandler; import org.bukkit.event.EventPriority; import org.bukkit.event.entity.EntityResurrectEvent; import combatlogx.expansion.cheat.prevention.ICheatPreventionExpansion; import combatlogx.expansion.cheat.prevention.configuration.IItemConfiguration; public final class ListenerTotem extends CheatPreventionListener { public ListenerTotem(@NotNull ICheatPreventionExpansion expansion) { super(expansion); } @EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true) public void onResurrect(EntityResurrectEvent e) { LivingEntity entity = e.getEntity(); if (!(entity instanceof Player)) { return; } Player player = (Player) entity; if (isInCombat(player) && isPreventTotem()) { e.setCancelled(true); sendMessage(player, "expansion.cheat-prevention.no-totem"); } } private @NotNull IItemConfiguration getItemConfiguration() { ICheatPreventionExpansion expansion = getCheatPrevention(); return expansion.getItemConfiguration(); } private boolean isPreventTotem() { IItemConfiguration itemConfiguration = getItemConfiguration(); return itemConfiguration.isPreventTotem(); } } ================================================ FILE: expansion/cheat-prevention/src/main/java/combatlogx/expansion/cheat/prevention/listener/modern/ListenerModernItemPickup.java ================================================ package combatlogx.expansion.cheat.prevention.listener.modern; import org.jetbrains.annotations.NotNull; import org.bukkit.entity.Entity; import org.bukkit.entity.Player; import org.bukkit.event.EventHandler; import org.bukkit.event.EventPriority; import org.bukkit.event.entity.EntityPickupItemEvent; import combatlogx.expansion.cheat.prevention.ICheatPreventionExpansion; import combatlogx.expansion.cheat.prevention.configuration.IItemConfiguration; import combatlogx.expansion.cheat.prevention.listener.CheatPreventionListener; public final class ListenerModernItemPickup extends CheatPreventionListener { public ListenerModernItemPickup(@NotNull ICheatPreventionExpansion expansion) { super(expansion); } @EventHandler(priority = EventPriority.NORMAL, ignoreCancelled = true) public void onPickup(EntityPickupItemEvent e) { Entity entity = e.getEntity(); if (!(entity instanceof Player)) { return; } Player player = (Player) entity; if (isPreventPickup() && isInCombat(player)) { e.setCancelled(true); sendMessage(player, "expansion.cheat-prevention.items.no-pickup"); } } private @NotNull IItemConfiguration getItemConfiguration() { ICheatPreventionExpansion expansion = getCheatPrevention(); return expansion.getItemConfiguration(); } private boolean isPreventPickup() { IItemConfiguration itemConfiguration = getItemConfiguration(); return itemConfiguration.isPreventPickup(); } } ================================================ FILE: expansion/cheat-prevention/src/main/java/combatlogx/expansion/cheat/prevention/listener/modern/ListenerModernPortalCreate.java ================================================ package combatlogx.expansion.cheat.prevention.listener.modern; import org.jetbrains.annotations.NotNull; import org.bukkit.entity.Entity; import org.bukkit.entity.Player; import org.bukkit.event.EventHandler; import org.bukkit.event.EventPriority; import org.bukkit.event.world.PortalCreateEvent; import combatlogx.expansion.cheat.prevention.ICheatPreventionExpansion; import combatlogx.expansion.cheat.prevention.configuration.IBlockConfiguration; import combatlogx.expansion.cheat.prevention.listener.CheatPreventionListener; public final class ListenerModernPortalCreate extends CheatPreventionListener { public ListenerModernPortalCreate(@NotNull ICheatPreventionExpansion expansion) { super(expansion); } @EventHandler(priority = EventPriority.NORMAL, ignoreCancelled = true) public void onPortalCreate(PortalCreateEvent e) { Entity entity = e.getEntity(); if (!(entity instanceof Player)) { return; } Player player = (Player) entity; if (isPreventPortalCreation() && isInCombat(player)) { e.setCancelled(true); sendMessage(player, "expansion.cheat-prevention.blocks.prevent-portal-creation"); } } private @NotNull IBlockConfiguration getBlockConfiguration() { ICheatPreventionExpansion expansion = getCheatPrevention(); return expansion.getBlockConfiguration(); } private boolean isPreventPortalCreation() { IBlockConfiguration configuration = getBlockConfiguration(); return configuration.isPreventPortalCreation(); } } ================================================ FILE: expansion/cheat-prevention/src/main/java/combatlogx/expansion/cheat/prevention/listener/modern/ListenerModernPotions.java ================================================ package combatlogx.expansion.cheat.prevention.listener.modern; import java.util.Collection; import org.jetbrains.annotations.NotNull; import org.bukkit.entity.EntityType; import org.bukkit.entity.Player; import org.bukkit.event.EventHandler; import org.bukkit.event.EventPriority; import org.bukkit.event.entity.EntityPotionEffectEvent; import org.bukkit.event.entity.EntityPotionEffectEvent.Action; import org.bukkit.potion.PotionEffect; import org.bukkit.potion.PotionEffectType; import com.github.sirblobman.combatlogx.api.event.PlayerTagEvent; import combatlogx.expansion.cheat.prevention.ICheatPreventionExpansion; import combatlogx.expansion.cheat.prevention.configuration.IPotionConfiguration; import combatlogx.expansion.cheat.prevention.listener.CheatPreventionListener; public class ListenerModernPotions extends CheatPreventionListener { public ListenerModernPotions(@NotNull ICheatPreventionExpansion expansion) { super(expansion); } @EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true) public void onTag(PlayerTagEvent e) { Player player = e.getPlayer(); Collection activePotionEffectCollection = player.getActivePotionEffects(); for (PotionEffect potionEffect : activePotionEffectCollection) { PotionEffectType potionEffectType = potionEffect.getType(); if (isBlocked(potionEffectType)) { player.removePotionEffect(potionEffectType); } } } @EventHandler(priority = EventPriority.NORMAL, ignoreCancelled = true) public void onAddEffect(EntityPotionEffectEvent e) { Action action = e.getAction(); if (action != Action.ADDED) { return; } EntityType entityType = e.getEntityType(); if (entityType != EntityType.PLAYER) { return; } Player player = (Player) e.getEntity(); if (!isInCombat(player)) { return; } PotionEffectType potionEffectType = e.getModifiedType(); if (isBlocked(potionEffectType)) { e.setCancelled(true); } } private @NotNull IPotionConfiguration getPotionConfiguration() { ICheatPreventionExpansion expansion = getCheatPrevention(); return expansion.getPotionConfiguration(); } private boolean isBlocked(@NotNull PotionEffectType effectType) { IPotionConfiguration potionConfiguration = getPotionConfiguration(); return potionConfiguration.isBlocked(effectType); } } ================================================ FILE: expansion/cheat-prevention/src/main/java/combatlogx/expansion/cheat/prevention/task/ElytraRetagTask.java ================================================ package combatlogx.expansion.cheat.prevention.task; import java.util.List; import org.jetbrains.annotations.NotNull; import org.bukkit.entity.Player; import com.github.sirblobman.api.folia.details.TaskDetails; import com.github.sirblobman.api.folia.scheduler.TaskScheduler; import com.github.sirblobman.api.utility.Validate; import com.github.sirblobman.combatlogx.api.ICombatLogX; import com.github.sirblobman.combatlogx.api.expansion.Expansion; import com.github.sirblobman.combatlogx.api.manager.ICombatManager; import com.github.sirblobman.combatlogx.api.object.TagReason; import com.github.sirblobman.combatlogx.api.object.TagType; import combatlogx.expansion.cheat.prevention.ICheatPreventionExpansion; import combatlogx.expansion.cheat.prevention.configuration.IItemConfiguration; public final class ElytraRetagTask extends TaskDetails { private final ICheatPreventionExpansion expansion; public ElytraRetagTask(@NotNull ICheatPreventionExpansion expansion) { super(expansion.getExpansion().getPlugin().getPlugin()); this.expansion = Validate.notNull(expansion, "expansion must not be null!"); } @Override public void run() { IItemConfiguration itemConfiguration = getItemConfiguration(); if (itemConfiguration.isElytraRetag()) { run0(); } } private void run0() { ICombatLogX combatLogX = getCombatLogX(); ICombatManager combatManager = combatLogX.getCombatManager(); List playerList = combatManager.getPlayersInCombat(); for (Player player : playerList) { if (player.isGliding()) { combatManager.tag(player, null, TagType.UNKNOWN, TagReason.UNKNOWN); } } } public void register() { TaskScheduler scheduler = getCombatLogX().getFoliaHelper().getScheduler(); setDelay(10L); setPeriod(10L); scheduler.scheduleTask(this); } private @NotNull ICheatPreventionExpansion getCheatPrevention() { return this.expansion; } private @NotNull IItemConfiguration getItemConfiguration() { ICheatPreventionExpansion expansion = getCheatPrevention(); return expansion.getItemConfiguration(); } private @NotNull Expansion getExpansion() { ICheatPreventionExpansion cheatPrevention = getCheatPrevention(); return cheatPrevention.getExpansion(); } private @NotNull ICombatLogX getCombatLogX() { Expansion expansion = getExpansion(); return expansion.getPlugin(); } } ================================================ FILE: expansion/cheat-prevention/src/main/java/combatlogx/expansion/cheat/prevention/task/FlightRetagTask.java ================================================ package combatlogx.expansion.cheat.prevention.task; import java.util.List; import org.jetbrains.annotations.NotNull; import org.bukkit.entity.Player; import com.github.sirblobman.api.folia.details.TaskDetails; import com.github.sirblobman.api.folia.scheduler.TaskScheduler; import com.github.sirblobman.combatlogx.api.ICombatLogX; import com.github.sirblobman.combatlogx.api.expansion.Expansion; import com.github.sirblobman.combatlogx.api.manager.ICombatManager; import com.github.sirblobman.combatlogx.api.object.TagReason; import com.github.sirblobman.combatlogx.api.object.TagType; import combatlogx.expansion.cheat.prevention.ICheatPreventionExpansion; import combatlogx.expansion.cheat.prevention.configuration.IFlightConfiguration; public final class FlightRetagTask extends TaskDetails { private final ICheatPreventionExpansion expansion; public FlightRetagTask(@NotNull ICheatPreventionExpansion expansion) { super(expansion.getExpansion().getPlugin().getPlugin()); this.expansion = expansion; } @Override public void run() { IFlightConfiguration flightConfiguration = getFlightConfiguration(); if (flightConfiguration.isFlightRetag()) { run0(); } } private void run0() { ICombatLogX combatLogX = getCombatLogX(); ICombatManager combatManager = combatLogX.getCombatManager(); List playerList = combatManager.getPlayersInCombat(); for (Player player : playerList) { if (player.isFlying()) { combatManager.tag(player, null, TagType.UNKNOWN, TagReason.UNKNOWN); } } } public void register() { TaskScheduler scheduler = getCombatLogX().getFoliaHelper().getScheduler(); setDelay(10L); setPeriod(10L); scheduler.scheduleTask(this); } private @NotNull ICheatPreventionExpansion getCheatPrevention() { return this.expansion; } private @NotNull IFlightConfiguration getFlightConfiguration() { ICheatPreventionExpansion expansion = getCheatPrevention(); return expansion.getFlightConfiguration(); } private @NotNull Expansion getExpansion() { ICheatPreventionExpansion cheatPrevention = getCheatPrevention(); return cheatPrevention.getExpansion(); } private @NotNull ICombatLogX getCombatLogX() { Expansion expansion = getExpansion(); return expansion.getPlugin(); } } ================================================ FILE: expansion/cheat-prevention/src/main/resources/blocks.yml ================================================ # Should players be prevented from interacting with blocks during combat? # Default: false prevent-interaction: false # This is a list of blocks that players should not interact with during combat. # Spigot Material List: https://hub.spigotmc.org/javadocs/spigot/org/bukkit/Material.html # This defaults to prevent all block interactions. prevent-interaction-list: - "*" # Should players be prevented from breaking blocks during combat? # Default: true prevent-breaking: true # This is a list of blocks that should be prevented from breaking # Spigot Material List: https://hub.spigotmc.org/javadocs/spigot/org/bukkit/Material.html # This defaults to prevent all block breaking prevent-breaking-list: - "*" # Should players be prevented from placing blocks during combat? # Default: true prevent-placing: true # This is a list of blocks that should be prevented from placing # Spigot Material List: https://hub.spigotmc.org/javadocs/spigot/org/bukkit/Material.html # This defaults to prevent all block placing prevent-placing-list: - "*" # Should players be prevented from creating portals during combat? # This option only works in 1.14.4+ # Default: false prevent-portal-creation: false ================================================ FILE: expansion/cheat-prevention/src/main/resources/buckets.yml ================================================ # Should players be prevented from emptying buckets during combat? # Default: false prevent-bucket-empty: false # Should players be prevented from filling buckets during combat? # Default: false prevent-bucket-fill: false # Which bucket types cannot be emptied during combat? # Requires 'prevent-bucket-empty: true' # Use '*' for all bucket types. # Use XMaterial names for custom types: # https://github.com/CryptoMorin/XSeries/blob/master/src/main/java/com/cryptomorin/xseries/XMaterial.java prevent-bucket-empty-list: - "*" # Which bucket types cannot be filled during combat? # Requires 'prevent-bucket-fill: true' # Use '*' for all bucket types. # Use XMaterial names for custom types: # https://github.com/CryptoMorin/XSeries/blob/master/src/main/java/com/cryptomorin/xseries/XMaterial.java prevent-bucket-fill-list: - "LAVA_BUCKET" ================================================ FILE: expansion/cheat-prevention/src/main/resources/chat.yml ================================================ # Should players be prevented from typing in chat during combat? # Default: false disable-chat: false ================================================ FILE: expansion/cheat-prevention/src/main/resources/commands.yml ================================================ # How much time do players have to wait to run commands AFTER the combat timer has ended? # The time is in seconds # Default: 0 delay-after-combat: 0 # Which commands are blocked during combat? # DO NOT forget the `/` in front of the commands. # You can add "*" to the list to block ALL commands. blocked-command-list: - "/tp" - "/fly" - "/gamemode" - "/gm" - "//wand" - "/spawn" - "/home" - "/sethome" - "/msg" # Which commands are allowed during combat? # This list is used if you want to un-block a command that is blocked the the other list. # You can add "*" to the list to allow ALL commands. # # Extra Information: This list overrides the blocked command list allowed-command-list: - "/msg SirBlobman" # Players with this permission will have every command unblocked. # The permission is not given to OPs by default, you must set it manually. bypass-permission: "combatlogx.bypass.cheat.prevention.commands" ================================================ FILE: expansion/cheat-prevention/src/main/resources/config.yml ================================================ # How long should the expansion wait before sending the same message again? # Default: 30 (seconds) message-cooldown: 30 ================================================ FILE: expansion/cheat-prevention/src/main/resources/entities.yml ================================================ # Should players be prevented from right-clicking entities during combat? # Default: false prevent-interaction: false ================================================ FILE: expansion/cheat-prevention/src/main/resources/expansion.yml ================================================ name: "${expansionName}" prefix: "${expansionPrefix}" description: "${expansionDescription}" main: "combatlogx.expansion.cheat.prevention.CheatPreventionExpansion" version: "17.10" author: "SirBlobman" ================================================ FILE: expansion/cheat-prevention/src/main/resources/flight.yml ================================================ # Should players be prevented from flying during combat? # Default: true prevent-flying: true # If a players flight is deactivated by CombatLogX, should the plugin prevent them from taking fall damage? # The fall damage prevention only works once after flight is disabled. # Default: true prevent-fall-damage: true # Should the 'allow-flight' flag be set to false on a player? # This may prevent toggle spam but players won't be able to fly after combat ends. # Default: false force-disable-flight: false # Should flying cause a player's timer to reset during combat? # This option is not useful unless you set 'prevent-flying' and 'force-disable-flight' to 'false'. # Default: false flight-retag: false ================================================ FILE: expansion/cheat-prevention/src/main/resources/game-mode.yml ================================================ # Should players be prevented from changing game modes during combat? # Default: true prevent-switching: true # If 'prevent-switching' is false, should players be untagged when they change modes? # Default: false untag-on-switch: false # Should players be forced into a specific game mode when they get into combat? # Default: false force-switch: false # If 'force-switch' is enabled, which mode should be used? # Valid options can be found in the link below: # https://hub.spigotmc.org/javadocs/spigot/org/bukkit/GameMode.html force-mode: SURVIVAL ================================================ FILE: expansion/cheat-prevention/src/main/resources/inventories.yml ================================================ # Should CombatLogX close a player's inventory when they are first tagged into combat? # Default: true close: true # Should CombatLogX close a player's inventory when they are tagged while already in combat? close-on-retag: true # Which inventory types should not trigger an inventory closed message? # To the server, a player always has an inventory open, even if its just the hotbar. no-close-message-type-list: - CREATIVE - CRAFTING # Should CombatLogX prevent players from opening new inventories while they are tagged? # This does not affect client-side-only inventories. # Default: true prevent-opening: true ================================================ FILE: expansion/cheat-prevention/src/main/resources/items.yml ================================================ # Should players be prevented from dropping items during combat? # Default: true prevent-drop: true # Should players be prevented from picking up items during combat? # Default: false prevent-pickup: true # Should players be prevented from using Elytra during combat? # Default: true prevent-elytra: true # Should player's that are gliding have their elytra forcefully disabled when tagged? # Default: false force-prevent-elytra: false # Should CombatLogX prevent players from launching fireworks during combat? # This can be used as an alternative to allow gliding but prevent rocket-based flight. # Default: false prevent-fireworks: false # Should gliding cause a player's timer to reset during combat? # This option is not useful unless you set 'prevent-elytra' and 'force-prevent-elytra' to 'false'. # Default: false elytra-retag: false # Should players be prevented from using Totems of Undying during combat? # Default: false prevent-totem: false # Should players be prevented from using tridents with the riptide enchantment during combat? # Default: false prevent-riptide: false # Should players that use tridents and the riptide effect increase the combat timer? # May conflict if both 'prevent-riptide' and 'riptide-retag' are enabled. # Default: false riptide-retag: false ================================================ FILE: expansion/cheat-prevention/src/main/resources/potions.yml ================================================ # This is a list of potion effects that will be removed when a player is tagged. # You can find a list of valid potion types in the link below: # https://hub.spigotmc.org/javadocs/spigot/org/bukkit/potion/PotionEffectType.html # You can unblock all potion effects by setting the value of this list to [] # Example: 'blocked-potion-type-list: []' blocked-potion-type-list: - INCREASE_DAMAGE - INVISIBILITY # Set this to 'true' to turn the 'blocked' list to an 'allowed' list. blocked-potion-type-list-inverted: false ================================================ FILE: expansion/cheat-prevention/src/main/resources/teleportation.yml ================================================ # Should players be prevented from using nether/end portals during combat? # Default: true prevent-portals: true # Should players be prevented from teleporting away during combat? # Default: true prevent-teleportation: true # Are there any reasons that a teleport should not be cancelled? # You can find a list of valid values in the link below: # https://hub.spigotmc.org/javadocs/bukkit/org/bukkit/event/player/PlayerTeleportEvent.TeleportCause.html allowed-teleport-cause-list: - PLUGIN # Some plugins don't like when CombatLogX cancels their teleports - UNKNOWN # Allowing 'UNKNOWN' may fix some glitches with region protection plugins - ENDER_PEARL # Most servers think that ender pearls are fair game during combat. # Should ender pearls cause a player's timer to reset during combat? # The combat type and combat reason will be marked as UNKNOWN. # Default: false ender-pearl-retag: false # This option is required for Folia servers. # This enables a separate listener for ender pearls, separate from PlayerTeleportEvent. # Disabled by default since ender pearls are allowed by most servers. # Default: false force-disable-ender-pearl: false # If a player teleports away, should their tag be removed? # Default: false untag: false ================================================ FILE: expansion/compatibility/ASkyBlock/build.gradle.kts ================================================ repositories { maven("https://repo.codemc.io/repository/maven-public/") } dependencies { compileOnly("com.wasteofplastic:askyblock:3.0.9.4") } ================================================ FILE: expansion/compatibility/ASkyBlock/gradle.properties ================================================ expansion.name=CompatASkyBlock expansion.prefix=ASkyBlock Compatibility ================================================ FILE: expansion/compatibility/ASkyBlock/src/main/java/combatlogx/expansion/compatibility/askyblock/ASkyBlockExpansion.java ================================================ package combatlogx.expansion.compatibility.askyblock; import com.github.sirblobman.combatlogx.api.ICombatLogX; import com.github.sirblobman.combatlogx.api.expansion.Expansion; import combatlogx.expansion.compatibility.askyblock.listener.ListenerASkyBlock; public final class ASkyBlockExpansion extends Expansion { public ASkyBlockExpansion(ICombatLogX plugin) { super(plugin); } @Override public void onLoad() { // Do Nothing } @Override public void onEnable() { if (!checkDependency("ASkyBlock", true)) { selfDisable(); } new ListenerASkyBlock(this).register(); } @Override public void onDisable() { // Do Nothing } @Override public void reloadConfig() { // Do Nothing } } ================================================ FILE: expansion/compatibility/ASkyBlock/src/main/java/combatlogx/expansion/compatibility/askyblock/listener/ListenerASkyBlock.java ================================================ package combatlogx.expansion.compatibility.askyblock.listener; import java.util.List; import java.util.UUID; import org.jetbrains.annotations.Nullable; import org.bukkit.entity.Entity; import org.bukkit.entity.Player; import org.bukkit.event.EventHandler; import org.bukkit.event.EventPriority; import com.github.sirblobman.combatlogx.api.event.PlayerPreTagEvent; import com.github.sirblobman.combatlogx.api.expansion.Expansion; import com.github.sirblobman.combatlogx.api.expansion.ExpansionListener; import com.wasteofplastic.askyblock.ASkyBlockAPI; import com.wasteofplastic.askyblock.Island; public final class ListenerASkyBlock extends ExpansionListener { public ListenerASkyBlock(Expansion expansion) { super(expansion); } @EventHandler(priority = EventPriority.NORMAL, ignoreCancelled = true) public void beforeTag(PlayerPreTagEvent e) { Entity enemy = e.getEnemy(); if (!(enemy instanceof Player)) { return; } Player playerEnemy = (Player) enemy; Player player = e.getPlayer(); if (doesTeamMatch(player, playerEnemy)) { e.setCancelled(true); } } @Nullable private Island getIsland(Player player) { if (player == null) { return null; } UUID playerId = player.getUniqueId(); ASkyBlockAPI api = ASkyBlockAPI.getInstance(); return api.getIslandOwnedBy(playerId); } private boolean doesTeamMatch(Player player1, Player player2) { UUID playerId1 = player1.getUniqueId(); UUID playerId2 = player2.getUniqueId(); if (playerId1.equals(playerId2)) { return true; } Island island = getIsland(player1); if (island == null) { return false; } List memberIdList = island.getMembers(); return memberIdList.contains(playerId2); } } ================================================ FILE: expansion/compatibility/ASkyBlock/src/main/resources/expansion.yml ================================================ name: "${expansionName}" prefix: "${expansionPrefix}" description: "${expansionDescription}" main: "combatlogx.expansion.compatibility.askyblock.ASkyBlockExpansion" version: "17.0" author: "SirBlobman" plugin-depend: - "ASkyBlock" ================================================ FILE: expansion/compatibility/AngelChest/build.gradle.kts ================================================ repositories { maven("https://nexus.sirblobman.xyz/proxy-public") } dependencies { compileOnly("de.jeff_media:AngelChest:13.9.4") } ================================================ FILE: expansion/compatibility/AngelChest/gradle.properties ================================================ expansion.name=CompatAngelChest expansion.prefix=AngelChest Compatibility ================================================ FILE: expansion/compatibility/AngelChest/src/main/java/combatlogx/expansion/compatibility/angelchest/AngelChestConfiguration.java ================================================ package combatlogx.expansion.compatibility.angelchest; import org.jetbrains.annotations.NotNull; import org.bukkit.configuration.ConfigurationSection; import com.github.sirblobman.api.configuration.IConfigurable; public class AngelChestConfiguration implements IConfigurable { private boolean preventBreaking; private boolean preventOpening; private boolean preventFastLooting; public AngelChestConfiguration() { this.preventBreaking = true; this.preventOpening = true; this.preventFastLooting = true; } @Override public void load(@NotNull ConfigurationSection section) { setPreventBreaking(section.getBoolean("prevent-breaking", true)); setPreventOpening(section.getBoolean("prevent-opening", true)); setPreventFastLooting(section.getBoolean("prevent-fast-looting", true)); } public boolean isPreventBreaking() { return this.preventBreaking; } public void setPreventBreaking(boolean preventBreaking) { this.preventBreaking = preventBreaking; } public boolean isPreventOpening() { return this.preventOpening; } public void setPreventOpening(boolean preventOpening) { this.preventOpening = preventOpening; } public boolean isPreventFastLooting() { return this.preventFastLooting; } public void setPreventFastLooting(boolean preventFastLooting) { this.preventFastLooting = preventFastLooting; } } ================================================ FILE: expansion/compatibility/AngelChest/src/main/java/combatlogx/expansion/compatibility/angelchest/AngelChestExpansion.java ================================================ package combatlogx.expansion.compatibility.angelchest; import org.jetbrains.annotations.NotNull; import com.github.sirblobman.api.configuration.ConfigurationManager; import com.github.sirblobman.combatlogx.api.ICombatLogX; import com.github.sirblobman.combatlogx.api.expansion.Expansion; public final class AngelChestExpansion extends Expansion { private final AngelChestConfiguration configuration; public AngelChestExpansion(ICombatLogX plugin) { super(plugin); this.configuration = new AngelChestConfiguration(); } @Override public void onLoad() { ConfigurationManager configurationManager = getConfigurationManager(); configurationManager.saveDefault("config.yml"); } @Override public void onEnable() { if (!checkDependency("AngelChest", true)) { selfDisable(); return; } reloadConfig(); new ListenerAngelChest(this).register(); } @Override public void onDisable() { // Do Nothing } @Override public void reloadConfig() { ConfigurationManager configurationManager = getConfigurationManager(); configurationManager.reload("config.yml"); getConfiguration().load(configurationManager.get("config.yml")); } public @NotNull AngelChestConfiguration getConfiguration() { return this.configuration; } } ================================================ FILE: expansion/compatibility/AngelChest/src/main/java/combatlogx/expansion/compatibility/angelchest/ListenerAngelChest.java ================================================ package combatlogx.expansion.compatibility.angelchest; import org.jetbrains.annotations.NotNull; import org.bukkit.entity.Player; import org.bukkit.event.Cancellable; import org.bukkit.event.EventHandler; import org.bukkit.event.EventPriority; import com.github.sirblobman.api.language.LanguageManager; import com.github.sirblobman.combatlogx.api.expansion.ExpansionListener; import de.jeff_media.angelchest.events.AngelChestOpenEvent; import de.jeff_media.angelchest.events.AngelChestOpenEvent.Reason; public final class ListenerAngelChest extends ExpansionListener { private final AngelChestExpansion expansion; public ListenerAngelChest(@NotNull AngelChestExpansion expansion) { super(expansion); this.expansion = expansion; } @EventHandler(priority = EventPriority.NORMAL, ignoreCancelled = true) public void onAngelChestOpen(AngelChestOpenEvent e) { Player player = e.getPlayer(); if (!isInCombat(player)) { return; } Reason reason = e.getReason(); switch (reason) { case BREAK: checkBreaking(player, e); break; case OPEN_GUI: checkOpening(player, e); break; case FAST_LOOT: checkFastLooting(player, e); break; default: break; } } private @NotNull AngelChestExpansion getAngelChestExpansion() { return this.expansion; } private @NotNull AngelChestConfiguration getConfiguration() { AngelChestExpansion expansion = getAngelChestExpansion(); return expansion.getConfiguration(); } private void checkBreaking(Player player, Cancellable e) { AngelChestConfiguration configuration = getConfiguration(); if (configuration.isPreventBreaking()) { e.setCancelled(true); LanguageManager languageManager = getLanguageManager(); languageManager.sendMessageWithPrefix(player, "expansion.angel-chest.prevent-breaking"); } } private void checkOpening(Player player, Cancellable e) { AngelChestConfiguration configuration = getConfiguration(); if (configuration.isPreventOpening()) { e.setCancelled(true); LanguageManager languageManager = getLanguageManager(); languageManager.sendMessageWithPrefix(player, "expansion.angel-chest.prevent-opening"); } } private void checkFastLooting(Player player, Cancellable e) { AngelChestConfiguration configuration = getConfiguration(); if (configuration.isPreventFastLooting()) { e.setCancelled(true); LanguageManager languageManager = getLanguageManager(); languageManager.sendMessageWithPrefix(player, "expansion.angel-chest.prevent-fast-looting"); } } } ================================================ FILE: expansion/compatibility/AngelChest/src/main/resources/config.yml ================================================ # Should CombatLogX prevent players from breaking AngelChests during combat? # Default: true prevent-breaking: true # Should CombatLogX prevent players from opening AngelChests during combat? # Default: true prevent-opening: true # Should CombatLogX prevent players from fast looting AngelChests during combat? # Default: true prevent-fast-looting: true ================================================ FILE: expansion/compatibility/AngelChest/src/main/resources/expansion.yml ================================================ name: "${expansionName}" prefix: "${expansionPrefix}" description: "${expansionDescription}" main: "combatlogx.expansion.compatibility.angelchest.AngelChestExpansion" version: "17.2" author: "olivolja3" plugin-depend: - "AngelChest" ================================================ FILE: expansion/compatibility/BSkyBlock/build.gradle.kts ================================================ repositories { maven("https://repo.codemc.io/repository/bentoboxworld/") maven("https://repo.codemc.io/repository/maven-snapshots/") maven("https://repo.codemc.io/repository/maven-public/") } dependencies { compileOnly("world.bentobox:bentobox:3.3.5-SNAPSHOT") // BentoBox compileOnly("world.bentobox:bskyblock:1.19.1-SNAPSHOT") // BSkyBlock } ================================================ FILE: expansion/compatibility/BSkyBlock/gradle.properties ================================================ expansion.name=CompatBSkyBlock expansion.prefix=BSkyBlock Compatibility ================================================ FILE: expansion/compatibility/BSkyBlock/src/main/java/combatlogx/expansion/compatibility/bskyblock/BSkyBlockExpansion.java ================================================ package combatlogx.expansion.compatibility.bskyblock; import com.github.sirblobman.combatlogx.api.ICombatLogX; import com.github.sirblobman.combatlogx.api.expansion.Expansion; import combatlogx.expansion.compatibility.bskyblock.hook.HookBentoBox; import combatlogx.expansion.compatibility.bskyblock.listener.ListenerBSkyBlock; public final class BSkyBlockExpansion extends Expansion { public BSkyBlockExpansion(ICombatLogX plugin) { super(plugin); } @Override public void onLoad() { // Do Nothing } @Override public void onEnable() { if (!checkDependency("BentoBox", true)) { selfDisable(); return; } if (!HookBentoBox.findBSkyBlock(this)) { selfDisable(); return; } new ListenerBSkyBlock(this).register(); } @Override public void onDisable() { // Do Nothing } @Override public void reloadConfig() { // Do Nothing } } ================================================ FILE: expansion/compatibility/BSkyBlock/src/main/java/combatlogx/expansion/compatibility/bskyblock/hook/HookBentoBox.java ================================================ package combatlogx.expansion.compatibility.bskyblock.hook; import java.util.Locale; import java.util.Optional; import java.util.logging.Logger; import org.bukkit.plugin.java.JavaPlugin; import combatlogx.expansion.compatibility.bskyblock.BSkyBlockExpansion; import world.bentobox.bentobox.BentoBox; import world.bentobox.bentobox.api.addons.Addon; import world.bentobox.bentobox.api.addons.AddonDescription; import world.bentobox.bentobox.managers.AddonsManager; public final class HookBentoBox { public static boolean findBSkyBlock(BSkyBlockExpansion expansion) { Logger logger = expansion.getLogger(); logger.info("Checking BentoBox for BSkyBlock..."); BentoBox bentoBox = JavaPlugin.getPlugin(BentoBox.class); AddonsManager addonsManager = bentoBox.getAddonsManager(); Optional optionalAddon = addonsManager.getAddonByName("BSkyBlock"); if (optionalAddon.isEmpty()) { logger.info("Failed to find BSkyBlock in BentoBox."); return false; } Addon addon = optionalAddon.get(); AddonDescription description = addon.getDescription(); String addonName = description.getName(); String addonVersion = description.getVersion(); String message = String.format(Locale.US, "Successfully found a dependency: %s v%s", addonName, addonVersion); logger.info(message); return true; } } ================================================ FILE: expansion/compatibility/BSkyBlock/src/main/java/combatlogx/expansion/compatibility/bskyblock/listener/ListenerBSkyBlock.java ================================================ package combatlogx.expansion.compatibility.bskyblock.listener; import java.util.Optional; import java.util.Set; import java.util.UUID; import org.bukkit.World; import org.bukkit.entity.Entity; import org.bukkit.entity.Player; import org.bukkit.event.EventHandler; import org.bukkit.event.EventPriority; import org.bukkit.plugin.java.JavaPlugin; import com.github.sirblobman.combatlogx.api.event.PlayerPreTagEvent; import com.github.sirblobman.combatlogx.api.expansion.Expansion; import com.github.sirblobman.combatlogx.api.expansion.ExpansionListener; import world.bentobox.bentobox.BentoBox; import world.bentobox.bentobox.api.addons.Addon; import world.bentobox.bentobox.database.objects.Island; import world.bentobox.bentobox.managers.AddonsManager; import world.bentobox.bentobox.managers.IslandsManager; public final class ListenerBSkyBlock extends ExpansionListener { public ListenerBSkyBlock(Expansion expansion) { super(expansion); } @EventHandler(priority = EventPriority.NORMAL, ignoreCancelled = true) public void beforeTag(PlayerPreTagEvent e) { Entity enemy = e.getEnemy(); if (!(enemy instanceof Player playerEnemy)) { return; } Player player = e.getPlayer(); if (doesTeamMatch(player, playerEnemy)) { e.setCancelled(true); } } private Island getIsland(Player player) { if (player == null) { return null; } UUID playerId = player.getUniqueId(); World world = player.getWorld(); BentoBox bentoBox = JavaPlugin.getPlugin(BentoBox.class); AddonsManager addonsManager = bentoBox.getAddonsManager(); Optional optionalAddon = addonsManager.getAddonByName("BSkyBlock"); if (optionalAddon.isPresent()) { Addon addon = optionalAddon.get(); IslandsManager islandManager = addon.getIslands(); return islandManager.getIsland(world, playerId); } return null; } private boolean doesTeamMatch(Player player1, Player player2) { World world1 = player1.getWorld(); World world2 = player2.getWorld(); UUID worldId1 = world1.getUID(); UUID worldId2 = world2.getUID(); if (!worldId1.equals(worldId2)) { return false; } UUID playerId1 = player1.getUniqueId(); UUID playerId2 = player2.getUniqueId(); if (playerId1.equals(playerId2)) { return true; } Island island = getIsland(player1); if (island == null) { return false; } Set memberSet = island.getMemberSet(); return memberSet.contains(playerId2); } } ================================================ FILE: expansion/compatibility/BSkyBlock/src/main/resources/expansion.yml ================================================ name: "${expansionName}" prefix: "${expansionPrefix}" description: "${expansionDescription}" main: "combatlogx.expansion.compatibility.bskyblock.BSkyBlockExpansion" version: "17.3" author: "SirBlobman" plugin-depend: - "BentoBox" ================================================ FILE: expansion/compatibility/CMI/build.gradle.kts ================================================ dependencies { compileOnly("net.zrips:CMI-API:9.7.4.1") } ================================================ FILE: expansion/compatibility/CMI/gradle.properties ================================================ expansion.name=CompatCMI expansion.prefix=CMI Compatibility ================================================ FILE: expansion/compatibility/CMI/src/main/java/combatlogx/expansion/compatibility/cmi/CMIExpansion.java ================================================ package combatlogx.expansion.compatibility.cmi; import org.jetbrains.annotations.NotNull; import com.github.sirblobman.combatlogx.api.ICombatLogX; import com.github.sirblobman.combatlogx.api.expansion.vanish.VanishExpansion; import com.github.sirblobman.combatlogx.api.expansion.vanish.VanishHandler; public final class CMIExpansion extends VanishExpansion { private VanishHandler vanishHandler; public CMIExpansion(@NotNull ICombatLogX plugin) { super(plugin); this.vanishHandler = null; } @Override public boolean checkDependencies() { return checkDependency("CMI", true, "9"); } @Override public @NotNull VanishHandler getVanishHandler() { if (this.vanishHandler == null) { this.vanishHandler = new VanishHandlerCMI(this); } return this.vanishHandler; } } ================================================ FILE: expansion/compatibility/CMI/src/main/java/combatlogx/expansion/compatibility/cmi/VanishHandlerCMI.java ================================================ package combatlogx.expansion.compatibility.cmi; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import org.bukkit.entity.Player; import com.github.sirblobman.combatlogx.api.expansion.vanish.VanishHandler; import com.Zrips.CMI.CMI; import com.Zrips.CMI.Containers.CMIUser; import com.Zrips.CMI.PlayerManager; public final class VanishHandlerCMI extends VanishHandler { public VanishHandlerCMI(@NotNull CMIExpansion expansion) { super(expansion); } @Override public boolean isVanished(@NotNull Player player) { CMIUser user = getUser(player); return (user != null && user.isVanished()); } private @NotNull CMI getCMI() { return CMI.getInstance(); } private @NotNull PlayerManager getPlayerManager() { CMI cmi = getCMI(); return cmi.getPlayerManager(); } private @Nullable CMIUser getUser(@NotNull Player player) { PlayerManager playerManager = getPlayerManager(); return playerManager.getUser(player); } } ================================================ FILE: expansion/compatibility/CMI/src/main/resources/config.yml ================================================ # Should players in vanish be preventing from going into combat? prevent-vanish-tagging-self: true # Should players in vanish be unable to tag other players? prevent-vanish-tagging-other: true ================================================ FILE: expansion/compatibility/CMI/src/main/resources/expansion.yml ================================================ name: "${expansionName}" prefix: "${expansionPrefix}" description: "${expansionDescription}" main: "combatlogx.expansion.compatibility.cmi.CMIExpansion" version: "17.1" author: "SirBlobman" plugin-depend: - "CMI" ================================================ FILE: expansion/compatibility/Citizens/build.gradle.kts ================================================ repositories { maven("https://nexus.sirblobman.xyz/proxy-public") } dependencies { compileOnly("net.citizensnpcs:citizensapi:2.0.40-SNAPSHOT") compileOnly("org.mcmonkey:sentinel:2.9.0-SNAPSHOT") } ================================================ FILE: expansion/compatibility/Citizens/gradle.properties ================================================ version.spigot=1.13.2-R0.1-SNAPSHOT expansion.name=CompatCitizens expansion.prefix=Citizens Compatibility ================================================ FILE: expansion/compatibility/Citizens/src/main/java/combatlogx/expansion/compatibility/citizens/CitizensExpansion.java ================================================ package combatlogx.expansion.compatibility.citizens; import java.util.Arrays; import java.util.List; import java.util.logging.Logger; import org.jetbrains.annotations.NotNull; import org.bukkit.Bukkit; import org.bukkit.plugin.Plugin; import org.bukkit.plugin.PluginManager; import com.github.sirblobman.api.configuration.ConfigurationManager; import com.github.sirblobman.api.utility.VersionUtility; import com.github.sirblobman.combatlogx.api.ICombatLogX; import com.github.sirblobman.combatlogx.api.expansion.Expansion; import combatlogx.expansion.compatibility.citizens.configuration.CitizensConfiguration; import combatlogx.expansion.compatibility.citizens.configuration.Configuration; import combatlogx.expansion.compatibility.citizens.configuration.SentinelConfiguration; import combatlogx.expansion.compatibility.citizens.listener.ListenerCombat; import combatlogx.expansion.compatibility.citizens.listener.ListenerConvert; import combatlogx.expansion.compatibility.citizens.listener.ListenerDeath; import combatlogx.expansion.compatibility.citizens.listener.ListenerJoin; import combatlogx.expansion.compatibility.citizens.listener.ListenerPunish; import combatlogx.expansion.compatibility.citizens.listener.ListenerQuit; import combatlogx.expansion.compatibility.citizens.listener.ListenerResurrect; import combatlogx.expansion.compatibility.citizens.manager.CombatNpcManager; import combatlogx.expansion.compatibility.citizens.manager.InventoryManager; public final class CitizensExpansion extends Expansion { private static final List SUPPORTED_VERSION_LIST; static { SUPPORTED_VERSION_LIST = Arrays.asList("2.0.35", "2.0.36", "2.0.37", "2.0.38", "2.0.39", "2.0.40"); } private final Configuration configuration; private final CitizensConfiguration citizensConfiguration; private final SentinelConfiguration sentinelConfiguration; private final CombatNpcManager combatNpcManager; private final InventoryManager inventoryManager; public CitizensExpansion(@NotNull ICombatLogX plugin) { super(plugin); this.configuration = new Configuration(); this.citizensConfiguration = new CitizensConfiguration(this); this.sentinelConfiguration = new SentinelConfiguration(this); this.combatNpcManager = new CombatNpcManager(this); this.inventoryManager = new InventoryManager(this); } @Override public void onLoad() { ConfigurationManager configurationManager = getConfigurationManager(); configurationManager.saveDefault("config.yml"); configurationManager.saveDefault("citizens.yml"); configurationManager.saveDefault("sentinel.yml"); } @Override public void onEnable() { if (!checkDependency("Citizens", true)) { selfDisable(); return; } Logger logger = getLogger(); PluginManager pluginManager = Bukkit.getPluginManager(); Plugin citizens = pluginManager.getPlugin("Citizens"); if (citizens == null) { logger.info("Dependency 'Citizens' not enabled."); selfDisable(); return; } String citizensVersion = citizens.getDescription().getVersion(); if (!isCitizensSupported(citizensVersion)) { logger.info("Dependency 'Citizens' is not the correct version."); selfDisable(); return; } reloadConfig(); registerListeners(); } @Override public void onDisable() { CombatNpcManager combatNpcManager = getCombatNpcManager(); combatNpcManager.removeAll(); } @Override public void reloadConfig() { ConfigurationManager configurationManager = getConfigurationManager(); configurationManager.reload("config.yml"); configurationManager.reload("citizens.yml"); configurationManager.reload("sentinel.yml"); getConfiguration().load(configurationManager.get("config.yml")); getCitizensConfiguration().load(configurationManager.get("citizens.yml")); getSentinelConfiguration().load(configurationManager.get("sentinel.yml")); } public @NotNull CombatNpcManager getCombatNpcManager() { return this.combatNpcManager; } public @NotNull InventoryManager getInventoryManager() { return this.inventoryManager; } public boolean isSentinelEnabled() { Configuration configuration = getConfiguration(); SentinelConfiguration sentinelConfiguration = getSentinelConfiguration(); return (configuration.isEnableSentinel() && sentinelConfiguration.isSentinelPluginEnabled()); } private void registerListeners() { new ListenerCombat(this).register(); new ListenerDeath(this).register(); new ListenerJoin(this).register(); new ListenerPunish(this).register(); new ListenerQuit(this).register(); // Totem of Undying was added in 1.11. int minorVersion = VersionUtility.getMinorVersion(); if (minorVersion >= 11) { new ListenerResurrect(this).register(); } // EntityTransformEvent was added in 1.13 if (minorVersion >= 13) { new ListenerConvert(this).register(); } } private boolean isCitizensSupported(@NotNull String version) { for(String start : SUPPORTED_VERSION_LIST) { if(version.startsWith(start)) { return true; } } return false; } public @NotNull Configuration getConfiguration() { return this.configuration; } public @NotNull CitizensConfiguration getCitizensConfiguration() { return this.citizensConfiguration; } public @NotNull SentinelConfiguration getSentinelConfiguration() { return this.sentinelConfiguration; } } ================================================ FILE: expansion/compatibility/Citizens/src/main/java/combatlogx/expansion/compatibility/citizens/configuration/CitizensConfiguration.java ================================================ package combatlogx.expansion.compatibility.citizens.configuration; import java.util.logging.Logger; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import org.bukkit.configuration.ConfigurationSection; import org.bukkit.entity.EntityType; import com.github.sirblobman.api.configuration.IConfigurable; import com.github.sirblobman.api.utility.Validate; import combatlogx.expansion.compatibility.citizens.CitizensExpansion; public final class CitizensConfiguration implements IConfigurable { private final CitizensExpansion expansion; private boolean preventPunishments; private boolean preventLogin; private EntityType mobType; private boolean storeInventory; private boolean storeLocation; private boolean mobTarget; private double mobTargetRadius; private int survivalTime; private boolean stayUntilEnemyEscapes; private boolean stayUntilNoDamage; private boolean preventResurrect; private boolean tagPlayer; private boolean alwaysSpawnNpcOnQuit; private String customNpcNameFormat; public CitizensConfiguration(@NotNull CitizensExpansion expansion) { this.expansion = expansion; this.preventPunishments = true; this.preventLogin = false; this.mobType = EntityType.PLAYER; this.storeInventory = true; this.storeLocation = true; this.mobTarget = true; this.mobTargetRadius = 10.0D; this.survivalTime = 30; this.stayUntilEnemyEscapes = false; this.stayUntilNoDamage = false; this.preventResurrect = true; this.tagPlayer = true; this.alwaysSpawnNpcOnQuit = false; this.customNpcNameFormat = "{player_name}"; } private @NotNull CitizensExpansion getExpansion() { return this.expansion; } private @NotNull Logger getLogger() { CitizensExpansion expansion = getExpansion(); return expansion.getLogger(); } @Override public void load(ConfigurationSection config) { setPreventPunishments(config.getBoolean("prevent-punishments", true)); setPreventLogin(config.getBoolean("prevent-login", false)); setMobType(config.getString("mob-type", "PLAYER")); setStoreInventory(config.getBoolean("store-inventory", true)); setStoreLocation(config.getBoolean("store-location", true)); setMobTarget(config.getBoolean("mob-target", true)); setMobTargetRadius(config.getDouble("mob-target-radius", 10.0D)); setSurvivalTime(config.getInt("survival-time", 30)); setStayUntilEnemyEscapes(config.getBoolean("stay-until-enemy-escapes", false)); setStayUntilNoDamage(config.getBoolean("stay-until-no-damage", false)); setPreventResurrect(config.getBoolean("prevent-resurrect", true)); setTagPlayer(config.getBoolean("tag-player", true)); setAlwaysSpawnNpcOnQuit(config.getBoolean("always-spawn-npc-on-quit", false)); setCustomNpcNameFormat(config.getString("custom-npc-name", "{player_name}")); } public boolean isPreventPunishments() { return preventPunishments; } public void setPreventPunishments(boolean preventPunishments) { this.preventPunishments = preventPunishments; } public boolean isPreventLogin() { return preventLogin; } public void setPreventLogin(boolean preventLogin) { this.preventLogin = preventLogin; } public @NotNull EntityType getMobType() { return mobType; } public void setMobType(@NotNull EntityType mobType) { this.mobType = mobType; } private void setMobType(@Nullable String mobTypeName) { if (mobTypeName == null) { mobTypeName = "PLAYER"; } try { EntityType mobType = EntityType.valueOf(mobTypeName); if (!mobType.isAlive()) { Logger logger = getLogger(); logger.warning("'" + mobType + "' is a non-living value, default to PLAYER."); setMobType(EntityType.PLAYER); return; } setMobType(mobType); } catch (IllegalArgumentException ex) { Logger logger = getLogger(); logger.warning("'" + mobTypeName + "' is not a valid EntityType."); logger.warning("Defaulting to PLAYER."); setMobType(EntityType.PLAYER); } } public boolean isStoreInventory() { return storeInventory; } public void setStoreInventory(boolean storeInventory) { this.storeInventory = storeInventory; } public boolean isStoreLocation() { return storeLocation; } public void setStoreLocation(boolean storeLocation) { this.storeLocation = storeLocation; } public boolean isMobTarget() { return mobTarget; } public void setMobTarget(boolean mobTarget) { this.mobTarget = mobTarget; } public double getMobTargetRadius() { return mobTargetRadius; } public void setMobTargetRadius(double mobTargetRadius) { this.mobTargetRadius = mobTargetRadius; } public int getSurvivalTime() { return survivalTime; } public void setSurvivalTime(int survivalTime) { this.survivalTime = survivalTime; } public boolean isStayUntilEnemyEscapes() { return stayUntilEnemyEscapes; } public void setStayUntilEnemyEscapes(boolean stayUntilEnemyEscapes) { this.stayUntilEnemyEscapes = stayUntilEnemyEscapes; } public boolean isStayUntilNoDamage() { return stayUntilNoDamage; } public void setStayUntilNoDamage(boolean stayUntilNoDamage) { this.stayUntilNoDamage = stayUntilNoDamage; } public boolean isPreventResurrect() { return preventResurrect; } public void setPreventResurrect(boolean preventResurrect) { this.preventResurrect = preventResurrect; } public boolean isTagPlayer() { return tagPlayer; } public void setTagPlayer(boolean tagPlayer) { this.tagPlayer = tagPlayer; } public boolean isAlwaysSpawnNpcOnQuit() { return alwaysSpawnNpcOnQuit; } public void setAlwaysSpawnNpcOnQuit(boolean alwaysSpawnNpcOnQuit) { this.alwaysSpawnNpcOnQuit = alwaysSpawnNpcOnQuit; } public @NotNull String getCustomNpcNameFormat() { return customNpcNameFormat; } public void setCustomNpcNameFormat(@Nullable String customNpcNameFormat) { Validate.notEmpty(customNpcNameFormat, "customNpcNameFormat must not be null or empty!"); this.customNpcNameFormat = customNpcNameFormat; } } ================================================ FILE: expansion/compatibility/Citizens/src/main/java/combatlogx/expansion/compatibility/citizens/configuration/Configuration.java ================================================ package combatlogx.expansion.compatibility.citizens.configuration; import org.jetbrains.annotations.NotNull; import org.bukkit.configuration.ConfigurationSection; import com.github.sirblobman.api.configuration.IConfigurable; public final class Configuration implements IConfigurable { private boolean npcTagging; private boolean enableSentinel; public Configuration() { this.npcTagging = false; this.enableSentinel = true; } @Override public void load(@NotNull ConfigurationSection config) { setNpcTagging(config.getBoolean("npc-tagging", false)); setEnableSentinel(config.getBoolean("enable-sentinel", true)); } public boolean isNpcTagging() { return this.npcTagging; } public void setNpcTagging(boolean npcTagging) { this.npcTagging = npcTagging; } public boolean isEnableSentinel() { return this.enableSentinel; } public void setEnableSentinel(boolean enableSentinel) { this.enableSentinel = enableSentinel; } } ================================================ FILE: expansion/compatibility/Citizens/src/main/java/combatlogx/expansion/compatibility/citizens/configuration/SentinelConfiguration.java ================================================ package combatlogx.expansion.compatibility.citizens.configuration; import org.jetbrains.annotations.NotNull; import org.bukkit.Bukkit; import org.bukkit.configuration.ConfigurationSection; import org.bukkit.plugin.PluginManager; import com.github.sirblobman.api.configuration.IConfigurable; import combatlogx.expansion.compatibility.citizens.CitizensExpansion; public final class SentinelConfiguration implements IConfigurable { private final CitizensExpansion expansion; private boolean attackFirst; private transient boolean sentinelPluginEnabled; public SentinelConfiguration(@NotNull CitizensExpansion expansion) { this.expansion = expansion; this.attackFirst = false; this.sentinelPluginEnabled = false; } private @NotNull CitizensExpansion getExpansion() { return this.expansion; } @Override public void load(@NotNull ConfigurationSection config) { setAttackFirst(config.getBoolean("attack-first", false)); CitizensExpansion expansion = getExpansion(); Configuration configuration = expansion.getConfiguration(); if (configuration.isEnableSentinel()) { PluginManager pluginManager = Bukkit.getPluginManager(); this.sentinelPluginEnabled = pluginManager.isPluginEnabled("Sentinel"); } else { this.sentinelPluginEnabled = false; } } public boolean isAttackFirst() { return this.attackFirst; } public void setAttackFirst(boolean attackFirst) { this.attackFirst = attackFirst; } public boolean isSentinelPluginEnabled() { return this.sentinelPluginEnabled; } } ================================================ FILE: expansion/compatibility/Citizens/src/main/java/combatlogx/expansion/compatibility/citizens/listener/CitizensExpansionListener.java ================================================ package combatlogx.expansion.compatibility.citizens.listener; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import org.bukkit.entity.Entity; import com.github.sirblobman.combatlogx.api.expansion.ExpansionListener; import combatlogx.expansion.compatibility.citizens.CitizensExpansion; import combatlogx.expansion.compatibility.citizens.configuration.CitizensConfiguration; import combatlogx.expansion.compatibility.citizens.configuration.Configuration; import combatlogx.expansion.compatibility.citizens.configuration.SentinelConfiguration; import combatlogx.expansion.compatibility.citizens.manager.CombatNpcManager; import combatlogx.expansion.compatibility.citizens.manager.InventoryManager; import combatlogx.expansion.compatibility.citizens.object.CombatNPC; import net.citizensnpcs.api.CitizensAPI; import net.citizensnpcs.api.npc.NPC; import net.citizensnpcs.api.npc.NPCRegistry; public abstract class CitizensExpansionListener extends ExpansionListener { private final CitizensExpansion expansion; public CitizensExpansionListener(@NotNull CitizensExpansion expansion) { super(expansion); this.expansion = expansion; } protected final @NotNull CitizensExpansion getCitizensExpansion() { return this.expansion; } protected final @NotNull Configuration getConfiguration() { CitizensExpansion expansion = getCitizensExpansion(); return expansion.getConfiguration(); } protected final @NotNull CitizensConfiguration getCitizensConfiguration() { CitizensExpansion expansion = getCitizensExpansion(); return expansion.getCitizensConfiguration(); } protected final @NotNull SentinelConfiguration getSentinelConfiguration() { CitizensExpansion expansion = getCitizensExpansion(); return expansion.getSentinelConfiguration(); } protected final @NotNull CombatNpcManager getCombatNpcManager() { CitizensExpansion expansion = getCitizensExpansion(); return expansion.getCombatNpcManager(); } protected final @NotNull InventoryManager getInventoryManager() { CitizensExpansion expansion = getCitizensExpansion(); return expansion.getInventoryManager(); } protected final @Nullable CombatNPC getCombatNPC(NPC npc) { CombatNpcManager combatNpcManager = getCombatNpcManager(); return combatNpcManager.getCombatNPC(npc); } protected final @Nullable NPC getNPC(@NotNull Entity entity) { NPCRegistry npcRegistry = CitizensAPI.getNPCRegistry(); return npcRegistry.getNPC(entity); } } ================================================ FILE: expansion/compatibility/Citizens/src/main/java/combatlogx/expansion/compatibility/citizens/listener/ListenerCombat.java ================================================ package combatlogx.expansion.compatibility.citizens.listener; import org.jetbrains.annotations.NotNull; import org.bukkit.entity.Entity; import org.bukkit.event.EventHandler; import org.bukkit.event.EventPriority; import com.github.sirblobman.combatlogx.api.event.PlayerPreTagEvent; import com.github.sirblobman.combatlogx.api.utility.EntityHelper; import combatlogx.expansion.compatibility.citizens.CitizensExpansion; import combatlogx.expansion.compatibility.citizens.configuration.Configuration; public final class ListenerCombat extends CitizensExpansionListener { public ListenerCombat(@NotNull CitizensExpansion expansion) { super(expansion); } @EventHandler(priority = EventPriority.NORMAL, ignoreCancelled = true) public void beforeTag(PlayerPreTagEvent e) { printDebug("Detected PlayerPreTagEvent...."); Configuration configuration = getConfiguration(); if (configuration.isNpcTagging()) { printDebug("NPC tagging is allowed, ignoring event."); return; } Entity entity = e.getEnemy(); if (entity == null) { printDebug("enemy is null, ignoring."); return; } if (EntityHelper.isNPC(entity)) { printDebug("enemy is an NPC, cancelling event."); e.setCancelled(true); } } } ================================================ FILE: expansion/compatibility/Citizens/src/main/java/combatlogx/expansion/compatibility/citizens/listener/ListenerConvert.java ================================================ package combatlogx.expansion.compatibility.citizens.listener; import org.jetbrains.annotations.NotNull; import org.bukkit.entity.Entity; import org.bukkit.event.EventHandler; import org.bukkit.event.EventPriority; import org.bukkit.event.entity.EntityTransformEvent; import com.github.sirblobman.combatlogx.api.utility.EntityHelper; import combatlogx.expansion.compatibility.citizens.CitizensExpansion; import combatlogx.expansion.compatibility.citizens.object.CombatNPC; import net.citizensnpcs.api.npc.NPC; public final class ListenerConvert extends CitizensExpansionListener { public ListenerConvert(@NotNull CitizensExpansion expansion) { super(expansion); } @EventHandler(priority = EventPriority.NORMAL, ignoreCancelled = true) public void onConvert(EntityTransformEvent e) { Entity entity = e.getEntity(); if (!EntityHelper.isNPC(entity)) { return; } NPC npc = getNPC(entity); if (npc == null) { return; } CombatNPC combatNPC = getCombatNPC(npc); if (combatNPC != null) { e.setCancelled(true); } } } ================================================ FILE: expansion/compatibility/Citizens/src/main/java/combatlogx/expansion/compatibility/citizens/listener/ListenerDeath.java ================================================ package combatlogx.expansion.compatibility.citizens.listener; import org.jetbrains.annotations.NotNull; import org.bukkit.Location; import org.bukkit.OfflinePlayer; import org.bukkit.configuration.file.YamlConfiguration; import org.bukkit.event.EventHandler; import org.bukkit.event.EventPriority; import org.bukkit.event.entity.EntityDeathEvent; import org.bukkit.event.entity.PlayerDeathEvent; import com.github.sirblobman.api.folia.details.RunnableTask; import com.github.sirblobman.api.folia.scheduler.TaskScheduler; import combatlogx.expansion.compatibility.citizens.CitizensExpansion; import combatlogx.expansion.compatibility.citizens.configuration.CitizensConfiguration; import combatlogx.expansion.compatibility.citizens.manager.CombatNpcManager; import combatlogx.expansion.compatibility.citizens.manager.InventoryManager; import combatlogx.expansion.compatibility.citizens.object.CombatNPC; import net.citizensnpcs.api.event.DespawnReason; import net.citizensnpcs.api.event.NPCDamageByEntityEvent; import net.citizensnpcs.api.event.NPCDeathEvent; import net.citizensnpcs.api.event.NPCDespawnEvent; import net.citizensnpcs.api.npc.NPC; public final class ListenerDeath extends CitizensExpansionListener { public ListenerDeath(@NotNull CitizensExpansion expansion) { super(expansion); } @EventHandler(priority = EventPriority.NORMAL, ignoreCancelled = true) public void onDeathNPC(NPCDeathEvent e) { printDebug("Detected NPCDeathEvent..."); NPC npc = e.getNPC(); CombatNPC combatNPC = getCombatNPC(npc); if (combatNPC == null) { printDebug("NPC was not a CombatNPC, ignoring event."); return; } printDebug("Setting drops and exp to zero and sending custom death message."); e.setDroppedExp(0); e.getDrops().clear(); checkForDeathMessages(e, combatNPC); } @EventHandler(priority = EventPriority.NORMAL, ignoreCancelled = true) public void onDamageNPC(NPCDamageByEntityEvent e) { printDebug("Detected NPCDamageByEntityEvent..."); CitizensConfiguration configuration = getCitizensConfiguration(); if (!configuration.isStayUntilNoDamage()) { printDebug("Stay until no damage setting is not enabled, ignoring event."); return; } NPC npc = e.getNPC(); CombatNPC combatNPC = getCombatNPC(npc); if (combatNPC == null) { printDebug("NPC was not a CombatNPC, ignoring event."); return; } printDebug("Resetting NPC survival time."); combatNPC.resetSurvivalTime(); } @EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true) public void onDespawnNPC(NPCDespawnEvent e) { printDebug("Detected NPCDespawnEvent..."); DespawnReason despawnReason = e.getReason(); if (despawnReason == DespawnReason.PENDING_RESPAWN) { printDebug("Despawn reason is PENDING_RESPAWN, ignoring event."); return; } NPC npc = e.getNPC(); CombatNPC combatNPC = getCombatNPC(npc); if (combatNPC == null) { printDebug("NPC was not a CombatNPC, ignoring event."); return; } CombatNpcManager combatNpcManager = getCombatNpcManager(); OfflinePlayer offlinePlayer = combatNPC.getOfflineOwner(); if (despawnReason == DespawnReason.DEATH) { Location location = combatNpcManager.getLocation(npc); printDebug("Despawn reason was death, drop NPC inventory."); InventoryManager inventoryManager = getInventoryManager(); inventoryManager.dropInventory(offlinePlayer, location); } if (despawnReason != DespawnReason.REMOVAL) { printDebug("Despawn reason was not removal, destroying NPC."); combatNpcManager.remove(combatNPC); printDebug("Destroy NPC later."); TaskScheduler scheduler = getCombatLogX().getFoliaHelper().getScheduler(); scheduler.scheduleTask(new RunnableTask(getJavaPlugin(), npc::destroy)); } printDebug("Setting player to be punished when they next join."); YamlConfiguration data = combatNpcManager.getData(offlinePlayer); data.set("citizens-compatibility.punish-next-join", true); combatNpcManager.saveData(offlinePlayer); } private void checkForDeathMessages(@NotNull NPCDeathEvent e, @NotNull CombatNPC npc) { OfflinePlayer offlineOwner = npc.getOfflineOwner(); EntityDeathEvent entityDeathEvent = e.getEvent(); if (!(entityDeathEvent instanceof PlayerDeathEvent playerDeathEvent)) { return; } String message = playerDeathEvent.getDeathMessage(); CombatNpcManager combatNpcManager = getCombatNpcManager(); YamlConfiguration data = combatNpcManager.getData(offlineOwner); data.set("citizens-compatibility.last-death-message", message); combatNpcManager.saveData(offlineOwner); } } ================================================ FILE: expansion/compatibility/Citizens/src/main/java/combatlogx/expansion/compatibility/citizens/listener/ListenerJoin.java ================================================ package combatlogx.expansion.compatibility.citizens.listener; import java.util.UUID; import org.jetbrains.annotations.NotNull; import org.bukkit.Bukkit; import org.bukkit.OfflinePlayer; import org.bukkit.command.CommandSender; import org.bukkit.entity.Player; import org.bukkit.event.EventHandler; import org.bukkit.event.EventPriority; import org.bukkit.event.player.AsyncPlayerPreLoginEvent; import org.bukkit.event.player.AsyncPlayerPreLoginEvent.Result; import org.bukkit.event.player.PlayerJoinEvent; import com.github.sirblobman.api.folia.scheduler.TaskScheduler; import com.github.sirblobman.api.language.ComponentHelper; import com.github.sirblobman.api.language.LanguageManager; import com.github.sirblobman.api.shaded.adventure.text.Component; import combatlogx.expansion.compatibility.citizens.CitizensExpansion; import combatlogx.expansion.compatibility.citizens.configuration.CitizensConfiguration; import combatlogx.expansion.compatibility.citizens.manager.CombatNpcManager; import combatlogx.expansion.compatibility.citizens.object.CombatNPC; import combatlogx.expansion.compatibility.citizens.task.PunishTask; import net.citizensnpcs.api.npc.NPC; public final class ListenerJoin extends CitizensExpansionListener { public ListenerJoin(@NotNull CitizensExpansion expansion) { super(expansion); } @EventHandler(priority = EventPriority.NORMAL, ignoreCancelled = true) public void beforeLogin(AsyncPlayerPreLoginEvent e) { printDebug("Detected AsyncPlayerPreLoginEvent..."); UUID playerId = e.getUniqueId(); printDebug("Checking if player with uuid=" + playerId + " can login..."); if (shouldAllowLogin(playerId)) { printDebug("Login allowed, ignoring event."); return; } CommandSender console = Bukkit.getConsoleSender(); LanguageManager languageManager = getLanguageManager(); String path = ("expansion.citizens-compatibility.prevent-join"); Component npcMessage = languageManager.getMessage(console, path); e.disallow(Result.KICK_OTHER, ComponentHelper.toLegacy(npcMessage)); } @EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true) public void onJoin(PlayerJoinEvent e) { printDebug("Detected PlayerJoinEvent..."); Player player = e.getPlayer(); printDebug("Player: " + player.getName()); printDebug("Disabled item pickup for player."); player.setCanPickupItems(false); CombatNpcManager combatNpcManager = getCombatNpcManager(); CombatNPC combatNPC = combatNpcManager.getNPC(player); if (combatNPC != null) { printDebug("Combat NPC exists for player, removing."); combatNpcManager.remove(combatNPC); } PunishTask punishTask = new PunishTask(getCitizensExpansion(), player); TaskScheduler scheduler = getCombatLogX().getFoliaHelper().getScheduler(); scheduler.scheduleEntityTask(punishTask); } private boolean shouldAllowLogin(@NotNull UUID uuid) { CitizensConfiguration configuration = getCitizensConfiguration(); if (!configuration.isPreventLogin()) { printDebug("Prevent login option disabled, login allowed."); return true; } OfflinePlayer offlinePlayer = Bukkit.getOfflinePlayer(uuid); CombatNpcManager combatNpcManager = getCombatNpcManager(); CombatNPC combatNPC = combatNpcManager.getNPC(offlinePlayer); if (combatNPC == null) { printDebug("Combat NPC not found for that player, login allowed."); return true; } NPC originalNPC = combatNPC.getOriginalNPC(); if (!originalNPC.isSpawned()) { printDebug("Combat NPC was removed, login allowed."); return true; } printDebug("Combat NPC exists and is spawned, login blocked."); return false; } } ================================================ FILE: expansion/compatibility/Citizens/src/main/java/combatlogx/expansion/compatibility/citizens/listener/ListenerPunish.java ================================================ package combatlogx.expansion.compatibility.citizens.listener; import java.util.List; import org.jetbrains.annotations.NotNull; import org.bukkit.configuration.file.YamlConfiguration; import org.bukkit.entity.Entity; import org.bukkit.entity.Player; import org.bukkit.event.EventHandler; import org.bukkit.event.EventPriority; import com.github.sirblobman.combatlogx.api.event.PlayerPunishEvent; import combatlogx.expansion.compatibility.citizens.CitizensExpansion; import combatlogx.expansion.compatibility.citizens.configuration.CitizensConfiguration; import combatlogx.expansion.compatibility.citizens.manager.CombatNpcManager; public final class ListenerPunish extends CitizensExpansionListener { public ListenerPunish(@NotNull CitizensExpansion expansion) { super(expansion); } @EventHandler(priority = EventPriority.NORMAL, ignoreCancelled = true) public void beforePunish(PlayerPunishEvent e) { printDebug("Detected PlayerPunishEvent."); CitizensConfiguration configuration = getCitizensConfiguration(); if (configuration.isPreventPunishments()) { printDebug("Cancelling all other CombatLogX punishments."); e.setCancelled(true); } Player player = e.getPlayer(); CombatNpcManager combatNpcManager = getCombatNpcManager(); YamlConfiguration playerData = combatNpcManager.getData(player); printDebug("Spawning NPC for player " + player.getName()); playerData.set("citizens-compatibility.punish", true); combatNpcManager.saveData(player); combatNpcManager.createNPC(player, e.getEnemies()); } } ================================================ FILE: expansion/compatibility/Citizens/src/main/java/combatlogx/expansion/compatibility/citizens/listener/ListenerQuit.java ================================================ package combatlogx.expansion.compatibility.citizens.listener; import java.util.Collections; import org.jetbrains.annotations.NotNull; import org.bukkit.configuration.file.YamlConfiguration; import org.bukkit.entity.Player; import org.bukkit.event.EventHandler; import org.bukkit.event.EventPriority; import org.bukkit.event.player.PlayerQuitEvent; import combatlogx.expansion.compatibility.citizens.CitizensExpansion; import combatlogx.expansion.compatibility.citizens.configuration.CitizensConfiguration; import combatlogx.expansion.compatibility.citizens.manager.CombatNpcManager; public final class ListenerQuit extends CitizensExpansionListener { public ListenerQuit(@NotNull CitizensExpansion expansion) { super(expansion); } @EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true) public void onQuit(PlayerQuitEvent e) { if (!isAlwaysSpawnOnQuit()) { return; } Player player = e.getPlayer(); CombatNpcManager combatNpcManager = getCombatNpcManager(); YamlConfiguration playerData = combatNpcManager.getData(player); printDebug("Spawning always-quit NPC for player " + player.getName()); playerData.set("citizens-compatibility.punish", true); combatNpcManager.saveData(player); combatNpcManager.createNPC(player, Collections.emptyList()); } private boolean isAlwaysSpawnOnQuit() { CitizensConfiguration configuration = getCitizensConfiguration(); return configuration.isAlwaysSpawnNpcOnQuit(); } } ================================================ FILE: expansion/compatibility/Citizens/src/main/java/combatlogx/expansion/compatibility/citizens/listener/ListenerResurrect.java ================================================ package combatlogx.expansion.compatibility.citizens.listener; import org.jetbrains.annotations.NotNull; import org.bukkit.entity.LivingEntity; import org.bukkit.event.EventHandler; import org.bukkit.event.EventPriority; import org.bukkit.event.entity.EntityResurrectEvent; import combatlogx.expansion.compatibility.citizens.CitizensExpansion; import combatlogx.expansion.compatibility.citizens.configuration.CitizensConfiguration; import combatlogx.expansion.compatibility.citizens.object.CombatNPC; import net.citizensnpcs.api.CitizensAPI; import net.citizensnpcs.api.npc.NPC; import net.citizensnpcs.api.npc.NPCRegistry; public final class ListenerResurrect extends CitizensExpansionListener { public ListenerResurrect(@NotNull CitizensExpansion expansion) { super(expansion); } @EventHandler(priority = EventPriority.NORMAL, ignoreCancelled = true) public void onResurrect(EntityResurrectEvent e) { CitizensConfiguration configuration = getCitizensConfiguration(); if (!configuration.isPreventResurrect()) { return; } LivingEntity entity = e.getEntity(); NPCRegistry npcRegistry = CitizensAPI.getNPCRegistry(); NPC npc = npcRegistry.getNPC(entity); if (npc == null) { return; } CombatNPC combatNPC = getCombatNPC(npc); if (combatNPC == null) { return; } e.setCancelled(true); } } ================================================ FILE: expansion/compatibility/Citizens/src/main/java/combatlogx/expansion/compatibility/citizens/manager/CombatNpcManager.java ================================================ package combatlogx.expansion.compatibility.citizens.manager; import java.util.Collection; import java.util.HashMap; import java.util.List; import java.util.Locale; import java.util.Map; import java.util.UUID; import java.util.concurrent.ConcurrentHashMap; import java.util.logging.Logger; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import org.bukkit.Location; import org.bukkit.OfflinePlayer; import org.bukkit.configuration.file.YamlConfiguration; import org.bukkit.entity.Entity; import org.bukkit.entity.EntityType; import org.bukkit.entity.LivingEntity; import org.bukkit.entity.Monster; import org.bukkit.entity.Player; import org.bukkit.inventory.PlayerInventory; import com.github.sirblobman.api.configuration.PlayerDataManager; import com.github.sirblobman.api.folia.details.RunnableTask; import com.github.sirblobman.api.folia.scheduler.TaskScheduler; import com.github.sirblobman.api.nms.EntityHandler; import com.github.sirblobman.api.nms.MultiVersionHandler; import com.github.sirblobman.combatlogx.api.ICombatLogX; import combatlogx.expansion.compatibility.citizens.CitizensExpansion; import combatlogx.expansion.compatibility.citizens.configuration.CitizensConfiguration; import combatlogx.expansion.compatibility.citizens.configuration.SentinelConfiguration; import combatlogx.expansion.compatibility.citizens.object.CombatNPC; import net.citizensnpcs.api.CitizensAPI; import net.citizensnpcs.api.npc.NPC; import net.citizensnpcs.api.npc.NPC.Metadata; import net.citizensnpcs.api.npc.NPCRegistry; import net.citizensnpcs.api.trait.trait.Owner; import org.mcmonkey.sentinel.SentinelTrait; import org.mcmonkey.sentinel.targeting.SentinelTargetLabel; public final class CombatNpcManager { private final CitizensExpansion expansion; private final Map playerNpcMap; private final Map npcCombatMap; public CombatNpcManager(@NotNull CitizensExpansion expansion) { this.expansion = expansion; this.playerNpcMap = new ConcurrentHashMap<>(); this.npcCombatMap = new ConcurrentHashMap<>(); } private @NotNull CitizensExpansion getExpansion() { return this.expansion; } private @NotNull ICombatLogX getCombatLogX() { CitizensExpansion expansion = getExpansion(); return expansion.getPlugin(); } public @Nullable CombatNPC getCombatNPC(@Nullable NPC npc) { if (npc == null) { return null; } UUID npcId = npc.getUniqueId(); return this.npcCombatMap.getOrDefault(npcId, null); } public @NotNull YamlConfiguration getData(@NotNull OfflinePlayer player) { ICombatLogX plugin = getCombatLogX(); PlayerDataManager playerDataManager = plugin.getPlayerDataManager(); return playerDataManager.get(player); } public void saveData(@NotNull OfflinePlayer player) { ICombatLogX plugin = getCombatLogX(); PlayerDataManager playerDataManager = plugin.getPlayerDataManager(); playerDataManager.save(player); } public void remove(@NotNull CombatNPC combatNPC) { OfflinePlayer owner = combatNPC.getOfflineOwner(); NPC originalNPC = combatNPC.getOriginalNPC(); try { combatNPC.cancel(); } catch (IllegalStateException ignored) { // Do Nothing } saveNPC(owner, originalNPC); this.playerNpcMap.remove(owner.getUniqueId()); this.npcCombatMap.remove(originalNPC.getUniqueId()); TaskScheduler scheduler = getCombatLogX().getFoliaHelper().getScheduler(); scheduler.scheduleTask(new RunnableTask(getCombatLogX().getPlugin(), originalNPC::destroy)); } public void removeAll() { Map copyMap = new HashMap<>(this.playerNpcMap); this.playerNpcMap.clear(); Collection npcCollection = copyMap.values(); npcCollection.forEach(this::remove); } public void createNPC(@NotNull Player player, @NotNull List enemyList) { if (player.hasMetadata("NPC")) { printDebug("player is an NPC, not spawning."); return; } UUID uuid = player.getUniqueId(); String playerName = player.getName(); printDebug("Spawning NPC for player '" + playerName + "'."); EntityType entityType = getEntityType(); NPCRegistry npcRegistry = CitizensAPI.getNPCRegistry(); NPC npc = npcRegistry.createNPC(entityType, playerName); npc.setProtected(false); npc.data().set(Metadata.SHOULD_SAVE, false); printDebug("Created NPC with entity type " + entityType + "."); String npcNameFormat = getConfiguration().getCustomNpcNameFormat(); printDebug("NPC Name Format: " + npcNameFormat); String npcName = npcNameFormat.replace("{player_name}", playerName); npc.setName(npcName); printDebug("Set NPC custom name to '" + npcName + "'."); Location location = player.getLocation(); boolean spawn = npc.spawn(location); if (!spawn) { printDebug("Failed to spawn an NPC. (npc.spawn() returned false)"); return; } Entity entity = npc.getEntity(); if (!(entity instanceof LivingEntity livingEntity)) { printDebug("NPC for player '" + playerName + "' is not a LivingEntity, removing..."); npc.destroy(); return; } livingEntity.setNoDamageTicks(0); livingEntity.setMaximumNoDamageTicks(0); printDebug("Forced NPC to be damageable (no damage ticks = 0)"); if (npc.hasTrait(Owner.class)) { npc.removeTrait(Owner.class); } printDebug("Forced NPC to be damageable (removed owner trait)"); ICombatLogX plugin = this.expansion.getPlugin(); MultiVersionHandler multiVersionHandler = plugin.getMultiVersionHandler(); EntityHandler entityHandler = multiVersionHandler.getEntityHandler(); double health = player.getHealth(); double maxHealth = entityHandler.getMaxHealth(livingEntity); if (maxHealth < health) { entityHandler.setMaxHealth(livingEntity, health); printDebug("Fixed NPC max health."); } livingEntity.setHealth(health); CitizensConfiguration configuration = getConfiguration(); if (configuration.isMobTarget()) { // npc.data().set(Metadata.TARGETABLE, true); double radius = configuration.getMobTargetRadius(); if (radius >= 0.0D) { forceTargetAllNearby(livingEntity, radius); printDebug("Forced NPC to target nearby enemies."); } } CombatNPC combatNPC = new CombatNPC(this.expansion, npc, player); printDebug("Created CombatNPC data."); this.playerNpcMap.put(uuid, combatNPC); this.npcCombatMap.put(npc.getUniqueId(), combatNPC); if (!enemyList.isEmpty()) { Entity mainEnemy = enemyList.getFirst(); if (mainEnemy instanceof Player) { combatNPC.setEnemy((Player) mainEnemy); printDebug("Main enemy was player, setting enemy in combat npc."); } printDebug("Checking sentinel data..."); checkSentinel(npc, enemyList); } else { printDebug("Enemy list was empty for player."); } saveLocation(player, npc); printDebug("Saving last location if configured."); saveInventory(player); printDebug("Saving inventory if configured."); equipNPC(player, npc); printDebug("Setting NPC equipment to match original player inventory."); printDebug("Finished setting combat NPC data."); combatNPC.start(); printDebug("Finished spawning combat NPC."); } private void forceTargetAllNearby(@NotNull LivingEntity entity, double radius) { List nearbyEntityList = entity.getNearbyEntities(radius, radius, radius); for (Entity nearby : nearbyEntityList) { if (nearby instanceof Monster monster) { monster.setTarget(entity); } } } public @Nullable CombatNPC getNPC(@NotNull OfflinePlayer player) { UUID playerId = player.getUniqueId(); return this.playerNpcMap.get(playerId); } private void saveNPC(@NotNull OfflinePlayer owner, @NotNull NPC npc) { saveHealth(owner, npc); saveLocation(owner, npc); YamlConfiguration data = getData(owner); data.set("citizens-compatibility.punish", true); saveData(owner); } private void saveHealth(@NotNull OfflinePlayer owner, @NotNull NPC npc) { double health = getHealth(npc); YamlConfiguration data = getData(owner); data.set("citizens-compatibility.health", health); saveData(owner); } private void saveLocation(@NotNull OfflinePlayer owner, @NotNull NPC npc) { Location location = getLocation(npc); YamlConfiguration data = getData(owner); data.set("citizens-compatibility.location", location); saveData(owner); } public void saveInventory(@NotNull Player player) { CitizensConfiguration configuration = getConfiguration(); if (!configuration.isStoreInventory()) { return; } CitizensExpansion expansion = getExpansion(); InventoryManager inventoryManager = expansion.getInventoryManager(); inventoryManager.storeInventory(player); PlayerInventory playerInventory = player.getInventory(); playerInventory.clear(); player.updateInventory(); } public void equipNPC(@NotNull Player player, @NotNull NPC npc) { CitizensExpansion expansion = getExpansion(); InventoryManager inventoryManager = expansion.getInventoryManager(); inventoryManager.equipNPC(player, npc); } public double loadHealth(@NotNull Player player) { YamlConfiguration data = getData(player); return data.getDouble("citizens-compatibility.health"); } public @Nullable Location loadLocation(@NotNull Player player) { YamlConfiguration data = getData(player); Object locationObject = data.get("citizens-compatibility.location"); if (locationObject instanceof Location) { return (Location) locationObject; } return null; } private double getHealth(@NotNull NPC npc) { if (!npc.isSpawned()) { return 0.0D; } Entity entity = npc.getEntity(); if (!(entity instanceof LivingEntity livingEntity)) { return 0.0D; } return livingEntity.getHealth(); } public @NotNull Location getLocation(@NotNull NPC npc) { if (!npc.isSpawned()) { return npc.getStoredLocation(); } Entity entity = npc.getEntity(); return entity.getLocation(); } private @NotNull CitizensConfiguration getConfiguration() { CitizensExpansion expansion = getExpansion(); return expansion.getCitizensConfiguration(); } private @NotNull EntityType getEntityType() { CitizensConfiguration configuration = getConfiguration(); return configuration.getMobType(); } private void printDebug(@NotNull String message) { ICombatLogX combatLogX = getCombatLogX(); if (combatLogX.isDebugModeDisabled()) { return; } Logger logger = getExpansion().getLogger(); logger.info("[Debug] [CombatNpcManager] " + message); } private void checkSentinel(@NotNull NPC npc, @NotNull List enemyList) { printDebug("Checking sentinel data..."); CitizensExpansion expansion = getExpansion(); if (!expansion.isSentinelEnabled()) { printDebug("Sentinel is not enabled. Check the configuration and Sentinel plugin."); return; } SentinelTrait sentinelTrait = npc.getOrAddTrait(SentinelTrait.class); printDebug("Added sentinel trait to NPC."); sentinelTrait.setInvincible(false); printDebug("Set sentinel as not invincible."); sentinelTrait.respawnTime = -1; printDebug("Disabled respawn time."); sentinelTrait.fightback = true; printDebug("Enabled sentinel fightback."); SentinelConfiguration configuration = expansion.getSentinelConfiguration(); if (!configuration.isAttackFirst()) { printDebug("Attack first is disabled."); return; } printDebug("Adding attack first targets to Sentinel."); for (Entity enemy : enemyList) { UUID enemyId = enemy.getUniqueId(); String enemyIdString = String.format(Locale.US, "uuid:%s", enemyId); SentinelTargetLabel targetLabel = new SentinelTargetLabel(enemyIdString); targetLabel.addToList(sentinelTrait.allTargets); } printDebug("Finished setting sentinel data."); } } ================================================ FILE: expansion/compatibility/Citizens/src/main/java/combatlogx/expansion/compatibility/citizens/manager/InventoryManager.java ================================================ package combatlogx.expansion.compatibility.citizens.manager; import java.util.HashMap; import java.util.Map; import java.util.UUID; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import org.bukkit.Bukkit; import org.bukkit.Location; import org.bukkit.OfflinePlayer; import org.bukkit.World; import org.bukkit.configuration.ConfigurationSection; import org.bukkit.configuration.file.YamlConfiguration; import org.bukkit.entity.Player; import org.bukkit.inventory.EquipmentSlot; import org.bukkit.inventory.ItemStack; import org.bukkit.inventory.PlayerInventory; import org.bukkit.plugin.PluginManager; import com.github.sirblobman.api.configuration.PlayerDataManager; import com.github.sirblobman.api.item.ArmorType; import com.github.sirblobman.api.utility.ItemUtility; import com.github.sirblobman.api.utility.Validate; import com.github.sirblobman.api.utility.VersionUtility; import com.github.sirblobman.combatlogx.api.ICombatLogX; import com.github.sirblobman.combatlogx.api.event.NPCDropItemEvent; import com.github.sirblobman.combatlogx.api.object.CitizensSlotType; import combatlogx.expansion.compatibility.citizens.CitizensExpansion; import combatlogx.expansion.compatibility.citizens.object.StoredInventory; import net.citizensnpcs.api.npc.NPC; import net.citizensnpcs.api.trait.trait.Equipment; public final class InventoryManager { private final CitizensExpansion expansion; private final Map storedInventoryMap; public InventoryManager(@NotNull CitizensExpansion expansion) { this.expansion = expansion; this.storedInventoryMap = new HashMap<>(); } public void storeInventory(@NotNull Player player) { if (player.hasMetadata("NPC")) { throw new IllegalArgumentException("player must not be an NPC!"); } PlayerInventory playerInventory = player.getInventory(); StoredInventory storedInventory = StoredInventory.createFrom(playerInventory); UUID playerId = player.getUniqueId(); this.storedInventoryMap.put(playerId, storedInventory); PlayerDataManager playerDataManager = getPlayerDataManager(); YamlConfiguration configuration = playerDataManager.get(player); ConfigurationSection section = configuration.createSection("citizens-compatibility.stored-inventory"); CitizensExpansion expansion = getExpansion(); storedInventory.save(expansion, section); playerDataManager.save(player); } public @Nullable StoredInventory getStoredInventory(@NotNull OfflinePlayer player) { UUID playerId = player.getUniqueId(); if (this.storedInventoryMap.containsKey(playerId)) { return this.storedInventoryMap.get(playerId); } PlayerDataManager playerDataManager = getPlayerDataManager(); YamlConfiguration configuration = playerDataManager.get(player); String storagePath = ("citizens-compatibility.stored-inventory"); ConfigurationSection section = configuration.getConfigurationSection(storagePath); if (section == null) { return null; } CitizensExpansion expansion = getExpansion(); return StoredInventory.createFrom(expansion, section); } public void removeStoredInventory(@NotNull OfflinePlayer player) { UUID playerId = player.getUniqueId(); this.storedInventoryMap.remove(playerId); PlayerDataManager playerDataManager = getPlayerDataManager(); YamlConfiguration configuration = playerDataManager.get(player); String storagePath = ("citizens-compatibility.stored-inventory"); configuration.set(storagePath, null); playerDataManager.save(player); } public void restoreInventory(@NotNull Player player) { if (player.hasMetadata("NPC")) { throw new IllegalArgumentException("player must not be an NPC!"); } StoredInventory storedInventory = getStoredInventory(player); if (storedInventory == null) { return; } PlayerInventory playerInventory = player.getInventory(); playerInventory.clear(); for (int slot = 0; slot < 36; slot++) { ItemStack item = storedInventory.getItem(slot); playerInventory.setItem(slot, item); } playerInventory.setHelmet(storedInventory.getArmor(ArmorType.HELMET)); playerInventory.setChestplate(storedInventory.getArmor(ArmorType.CHESTPLATE)); playerInventory.setLeggings(storedInventory.getArmor(ArmorType.LEGGINGS)); playerInventory.setBoots(storedInventory.getArmor(ArmorType.BOOTS)); int minorVersion = VersionUtility.getMinorVersion(); if (minorVersion < 9) { restoreHandsLegacy(storedInventory, playerInventory); } else { restoreHandsModern(storedInventory, playerInventory); } removeStoredInventory(player); player.updateInventory(); } public void dropInventory(@NotNull OfflinePlayer player, @NotNull Location location) { World world = location.getWorld(); Validate.notNull(world, "location must have a valid world!"); StoredInventory storedInventory = getStoredInventory(player); if (storedInventory == null) { return; } for (int slot = 0; slot < 36; slot++) { ItemStack item = storedInventory.getItem(slot); if (item == null) { continue; } dropItem(item, player, location, CitizensSlotType.INVENTORY); } ArmorType[] armorTypeArray = ArmorType.values(); for (ArmorType armorType : armorTypeArray) { ItemStack item = storedInventory.getArmor(armorType); if (item == null) { continue; } dropItem(item, player, location, CitizensSlotType.ARMOR); } ItemStack item = storedInventory.getOffHandItem(); if (item != null) { dropItem(item, player, location, CitizensSlotType.OFFHAND); } removeStoredInventory(player); } private void dropItem(@NotNull ItemStack item, @NotNull OfflinePlayer player, @NotNull Location location, @NotNull CitizensSlotType type) { World world = location.getWorld(); if (ItemUtility.isAir(item) || world == null) { return; } NPCDropItemEvent event = new NPCDropItemEvent(item, player, location, type); PluginManager pluginManager = Bukkit.getPluginManager(); pluginManager.callEvent(event); if (!event.isCancelled()) { world.dropItemNaturally(location, event.getItem()); } } public void equipNPC(@NotNull OfflinePlayer player, @NotNull NPC npc) { Equipment equipmentTrait = npc.getOrAddTrait(Equipment.class); StoredInventory storedInventory = getStoredInventory(player); if (storedInventory == null) { return; } ItemStack mainHandItem = storedInventory.getMainHandItem(); if (mainHandItem != null) { equipmentTrait.set(Equipment.EquipmentSlot.HAND, mainHandItem); } if (VersionUtility.getMinorVersion() > 8) { ItemStack offHandItem = storedInventory.getOffHandItem(); if (offHandItem != null) { equipmentTrait.set(Equipment.EquipmentSlot.OFF_HAND, offHandItem); } } ArmorType[] armorTypeArray = ArmorType.values(); for (ArmorType armorType : armorTypeArray) { ItemStack item = storedInventory.getArmor(armorType); if (item != null) { EquipmentSlot bukkitSlot = armorType.getEquipmentSlot(); Equipment.EquipmentSlot slot = getNpcSlotFromBukkitSlot(bukkitSlot); equipmentTrait.set(slot, item); } } } private @NotNull CitizensExpansion getExpansion() { return this.expansion; } private @NotNull ICombatLogX getICombatLogX() { CitizensExpansion expansion = getExpansion(); return expansion.getPlugin(); } private @NotNull PlayerDataManager getPlayerDataManager() { ICombatLogX plugin = getICombatLogX(); return plugin.getPlayerDataManager(); } @SuppressWarnings("deprecation") private void restoreHandsLegacy(@NotNull StoredInventory storedInventory, @NotNull PlayerInventory inventory) { ItemStack item = storedInventory.getMainHandItem(); inventory.setItemInHand(item); } private void restoreHandsModern(@NotNull StoredInventory storedInventory, @NotNull PlayerInventory inventory) { ItemStack mainHand = storedInventory.getMainHandItem(); ItemStack offHand = storedInventory.getOffHandItem(); inventory.setItemInMainHand(mainHand); inventory.setItemInOffHand(offHand); } private Equipment.EquipmentSlot getNpcSlotFromBukkitSlot(@NotNull EquipmentSlot slot) { if (VersionUtility.getMinorVersion() > 8) { if (slot == EquipmentSlot.OFF_HAND) { return Equipment.EquipmentSlot.OFF_HAND; } } return switch (slot) { case HEAD -> Equipment.EquipmentSlot.HELMET; case CHEST -> Equipment.EquipmentSlot.CHESTPLATE; case LEGS -> Equipment.EquipmentSlot.LEGGINGS; case FEET -> Equipment.EquipmentSlot.BOOTS; case HAND -> Equipment.EquipmentSlot.HAND; default -> null; }; } } ================================================ FILE: expansion/compatibility/Citizens/src/main/java/combatlogx/expansion/compatibility/citizens/object/CombatNPC.java ================================================ package combatlogx.expansion.compatibility.citizens.object; import java.util.UUID; import org.jetbrains.annotations.NotNull; import org.bukkit.Bukkit; import org.bukkit.OfflinePlayer; import org.bukkit.entity.Player; import com.github.sirblobman.api.folia.details.TaskDetails; import com.github.sirblobman.api.folia.scheduler.TaskScheduler; import com.github.sirblobman.combatlogx.api.ICombatLogX; import com.github.sirblobman.combatlogx.api.manager.ICombatManager; import com.github.sirblobman.combatlogx.api.object.TagInformation; import combatlogx.expansion.compatibility.citizens.CitizensExpansion; import combatlogx.expansion.compatibility.citizens.configuration.CitizensConfiguration; import combatlogx.expansion.compatibility.citizens.manager.CombatNpcManager; import net.citizensnpcs.api.npc.NPC; public final class CombatNPC extends TaskDetails { private final CitizensExpansion expansion; private final NPC originalNPC; private final UUID ownerId; private UUID enemyId; private long survivalTicks; public CombatNPC(@NotNull CitizensExpansion expansion, @NotNull NPC originalNPC, @NotNull OfflinePlayer owner) { super(expansion.getPlugin().getPlugin()); this.expansion = expansion; this.originalNPC = originalNPC; this.ownerId = owner.getUniqueId(); } @Override public void run() { this.survivalTicks--; if (this.survivalTicks > 0) { return; } CitizensExpansion expansion = getExpansion(); CitizensConfiguration configuration = expansion.getCitizensConfiguration(); if (configuration.isStayUntilEnemyEscapes() && this.enemyId != null) { Player player = Bukkit.getPlayer(this.enemyId); if (player != null) { ICombatManager combatManager = expansion.getPlugin().getCombatManager(); TagInformation tagInformation = combatManager.getTagInformation(player); if (tagInformation != null) { long timeLeftMillis = tagInformation.getMillisLeftCombined(); this.survivalTicks = (timeLeftMillis / 50L) + 1; return; } } } CombatNpcManager combatNpcManager = expansion.getCombatNpcManager(); combatNpcManager.remove(this); } public void start() { resetSurvivalTime(); setDelay(1L); setPeriod(1L); TaskScheduler scheduler = getCombatLogX().getFoliaHelper().getScheduler(); scheduler.scheduleTask(this); } public @NotNull NPC getOriginalNPC() { return this.originalNPC; } public @NotNull UUID getOwnerId() { return this.ownerId; } public @NotNull OfflinePlayer getOfflineOwner() { UUID ownerId = getOwnerId(); return Bukkit.getOfflinePlayer(ownerId); } public void resetSurvivalTime() { CitizensExpansion expansion = getExpansion(); CitizensConfiguration configuration = expansion.getCitizensConfiguration(); long survivalSeconds = configuration.getSurvivalTime(); this.survivalTicks = (survivalSeconds * 20L); } public void setEnemy(@NotNull Player enemy) { this.enemyId = enemy.getUniqueId(); } private @NotNull CitizensExpansion getExpansion() { return this.expansion; } private @NotNull ICombatLogX getCombatLogX() { CitizensExpansion expansion = getExpansion(); return expansion.getPlugin(); } } ================================================ FILE: expansion/compatibility/Citizens/src/main/java/combatlogx/expansion/compatibility/citizens/object/StoredInventory.java ================================================ package combatlogx.expansion.compatibility.citizens.object; import java.util.EnumMap; import java.util.HashMap; import java.util.Map; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import org.bukkit.configuration.ConfigurationSection; import org.bukkit.inventory.ItemStack; import org.bukkit.inventory.PlayerInventory; import com.github.sirblobman.api.item.ArmorType; import com.github.sirblobman.api.nms.ItemHandler; import com.github.sirblobman.api.nms.MultiVersionHandler; import com.github.sirblobman.api.utility.ItemUtility; import com.github.sirblobman.api.utility.VersionUtility; import com.github.sirblobman.combatlogx.api.ICombatLogX; import combatlogx.expansion.compatibility.citizens.CitizensExpansion; public final class StoredInventory { private final Map contentMap; private final Map armorMap; private ItemStack mainHand; private ItemStack offHand; private StoredInventory() { this.contentMap = new HashMap<>(); this.armorMap = new EnumMap<>(ArmorType.class); this.mainHand = null; this.offHand = null; } public static @NotNull StoredInventory createFrom(@NotNull PlayerInventory playerInventory) { StoredInventory storedInventory = new StoredInventory(); storedInventory.setArmor(ArmorType.HELMET, playerInventory.getHelmet()); storedInventory.setArmor(ArmorType.CHESTPLATE, playerInventory.getChestplate()); storedInventory.setArmor(ArmorType.LEGGINGS, playerInventory.getLeggings()); storedInventory.setArmor(ArmorType.BOOTS, playerInventory.getBoots()); for (int slot = 0; slot < 36; slot++) { ItemStack item = playerInventory.getItem(slot); storedInventory.setItemStack(slot, item); } int minorVersion = VersionUtility.getMinorVersion(); if (minorVersion < 9) { setHandLegacy(storedInventory, playerInventory); } else { setHandModern(storedInventory, playerInventory); } return storedInventory; } public static @NotNull StoredInventory createFrom(@NotNull CitizensExpansion expansion, @NotNull ConfigurationSection configuration) { StoredInventory storedInventory = new StoredInventory(); ArmorType[] armorTypeArray = ArmorType.values(); for (ArmorType armorType : armorTypeArray) { String armorTypeName = armorType.name(); String armorTypePath = ("armor." + armorTypeName); ItemStack item = loadItemStack(expansion, configuration, armorTypePath); storedInventory.setArmor(armorType, item); } ItemStack mainHand = loadItemStack(expansion, configuration, "main-hand"); ItemStack offHand = loadItemStack(expansion, configuration, "off-hand"); storedInventory.setMainHand(mainHand); storedInventory.setOffHand(offHand); for (int slot = 0; slot < 36; slot++) { String slotName = Integer.toString(slot); String slotPath = ("content." + slotName); ItemStack item = loadItemStack(expansion, configuration, slotPath); storedInventory.setItemStack(slot, item); } return storedInventory; } @SuppressWarnings("deprecation") private static void setHandLegacy(@NotNull StoredInventory stored, @NotNull PlayerInventory playerInventory) { ItemStack item = playerInventory.getItemInHand(); stored.setMainHand(item); stored.setOffHand(null); } private static void setHandModern(@NotNull StoredInventory stored, @NotNull PlayerInventory playerInventory) { stored.setMainHand(playerInventory.getItemInMainHand()); stored.setOffHand(playerInventory.getItemInOffHand()); } private static @Nullable ItemStack loadItemStack(@NotNull CitizensExpansion expansion, @NotNull ConfigurationSection section, @NotNull String path) { if (!section.isSet(path)) { return null; } if (!section.isString(path)) { return null; } String value = section.getString(path); if (value == null) { return null; } ICombatLogX plugin = expansion.getPlugin(); MultiVersionHandler multiVersionHandler = plugin.getMultiVersionHandler(); ItemHandler itemHandler = multiVersionHandler.getItemHandler(); return itemHandler.fromBase64String(value); } private static void saveItemStack(@NotNull CitizensExpansion expansion, @NotNull ConfigurationSection section, @NotNull String path, @Nullable ItemStack item) { if (ItemUtility.isAir(item)) { section.set(path, null); return; } ICombatLogX plugin = expansion.getPlugin(); MultiVersionHandler multiVersionHandler = plugin.getMultiVersionHandler(); ItemHandler itemHandler = multiVersionHandler.getItemHandler(); String base64 = itemHandler.toBase64String(item); section.set(path, base64); } public @Nullable ItemStack getMainHandItem() { return (this.mainHand == null ? null : this.mainHand.clone()); } public @Nullable ItemStack getOffHandItem() { return (this.offHand == null ? null : this.offHand.clone()); } public @Nullable ItemStack getArmor(@NotNull ArmorType type) { ItemStack item = this.armorMap.get(type); return (item == null ? null : item.clone()); } public @Nullable ItemStack getItem(int slot) { ItemStack item = this.contentMap.get(slot); return (item == null ? null : item.clone()); } public void save(@NotNull CitizensExpansion expansion, @NotNull ConfigurationSection configuration) { ItemStack mainHand = getMainHandItem(); saveItemStack(expansion, configuration, "main-hand", mainHand); ItemStack offHand = getOffHandItem(); saveItemStack(expansion, configuration, "off-hand", offHand); ArmorType[] armorTypeArray = ArmorType.values(); for (ArmorType armorType : armorTypeArray) { ItemStack item = getArmor(armorType); String armorTypeName = armorType.name(); String armorTypePath = ("armor." + armorTypeName); saveItemStack(expansion, configuration, armorTypePath, item); } for (int slot = 0; slot < 36; slot++) { ItemStack item = getItem(slot); String slotName = Integer.toString(slot); String slotPath = ("content." + slotName); saveItemStack(expansion, configuration, slotPath, item); } } private void setItemStack(int slot, @Nullable ItemStack item) { if (item == null) { this.contentMap.remove(slot); } else { this.contentMap.put(slot, item.clone()); } } private void setArmor(@NotNull ArmorType type, @Nullable ItemStack item) { if (item == null) { this.armorMap.remove(type); } else { this.armorMap.put(type, item.clone()); } } private void setMainHand(@Nullable ItemStack item) { this.mainHand = (item == null ? null : item.clone()); } private void setOffHand(@Nullable ItemStack item) { this.offHand = (item == null ? null : item.clone()); } } ================================================ FILE: expansion/compatibility/Citizens/src/main/java/combatlogx/expansion/compatibility/citizens/task/PunishTask.java ================================================ package combatlogx.expansion.compatibility.citizens.task; import org.jetbrains.annotations.NotNull; import org.bukkit.Location; import org.bukkit.configuration.file.YamlConfiguration; import org.bukkit.entity.Player; import org.bukkit.inventory.PlayerInventory; import com.github.sirblobman.api.folia.FoliaHelper; import com.github.sirblobman.api.folia.details.EntityTaskDetails; import com.github.sirblobman.api.folia.teleport.TeleportHandler; import com.github.sirblobman.api.nms.EntityHandler; import com.github.sirblobman.api.nms.MultiVersionHandler; import com.github.sirblobman.combatlogx.api.ICombatLogX; import com.github.sirblobman.combatlogx.api.manager.ICombatManager; import com.github.sirblobman.combatlogx.api.object.TagReason; import com.github.sirblobman.combatlogx.api.object.TagType; import combatlogx.expansion.compatibility.citizens.CitizensExpansion; import combatlogx.expansion.compatibility.citizens.configuration.CitizensConfiguration; import combatlogx.expansion.compatibility.citizens.manager.CombatNpcManager; import combatlogx.expansion.compatibility.citizens.manager.InventoryManager; public final class PunishTask extends EntityTaskDetails { private final CitizensExpansion expansion; public PunishTask(@NotNull CitizensExpansion expansion, @NotNull Player entity) { super(expansion.getPlugin().getPlugin(), entity); setDelay(1L); this.expansion = expansion; } @Override public void run() { Player player = getEntity(); if (player == null) { return; } punish(player); player.setCanPickupItems(true); } private @NotNull CitizensExpansion getExpansion() { return this.expansion; } private @NotNull CitizensConfiguration getCitizensConfiguration() { CitizensExpansion expansion = getExpansion(); return expansion.getCitizensConfiguration(); } private @NotNull CombatNpcManager getCombatNpcManager() { CitizensExpansion expansion = getExpansion(); return expansion.getCombatNpcManager(); } private @NotNull InventoryManager getInventoryManager() { CitizensExpansion expansion = getExpansion(); return expansion.getInventoryManager(); } private @NotNull ICombatLogX getCombatLogX() { CitizensExpansion expansion = getExpansion(); return expansion.getPlugin(); } private @NotNull ICombatManager getCombatManager() { ICombatLogX plugin = getCombatLogX(); return plugin.getCombatManager(); } private void punish(@NotNull Player player) { if (player.hasMetadata("NPC")) { return; } CombatNpcManager combatNpcManager = getCombatNpcManager(); YamlConfiguration playerData = combatNpcManager.getData(player); if (!playerData.getBoolean("citizens-compatibility.punish")) { return; } playerData.set("citizens-compatibility.punish", false); combatNpcManager.saveData(player); CitizensConfiguration configuration = getCitizensConfiguration(); if (configuration.isStoreLocation()) { Location location = combatNpcManager.loadLocation(player); if (location != null) { FoliaHelper foliaHelper = getExpansion().getPlugin().getFoliaHelper(); TeleportHandler teleporter = foliaHelper.getTeleporter(); teleporter.teleport(player, location).join(); } playerData.set("citizens-compatibility.location", null); } if (configuration.isStoreInventory()) { PlayerInventory playerInventory = player.getInventory(); playerInventory.clear(); } double health = combatNpcManager.loadHealth(player); setHealth(player, health); if (health <= 0.0D) { playerData.set("citizens-compatibility.inventory", null); playerData.set("citizens-compatibility.armor", null); } if (configuration.isStoreInventory()) { InventoryManager inventoryManager = getInventoryManager(); inventoryManager.restoreInventory(player); } if (configuration.isTagPlayer() && health > 0.0D) { ICombatManager combatManager = getCombatManager(); combatManager.tag(player, null, TagType.UNKNOWN, TagReason.UNKNOWN); } } private void setHealth(@NotNull Player player, double health) { if (Double.isInfinite(health) || Double.isNaN(health)) { health = 0.0D; } ICombatLogX combatLogX = getCombatLogX(); MultiVersionHandler multiVersionHandler = combatLogX.getMultiVersionHandler(); EntityHandler entityHandler = multiVersionHandler.getEntityHandler(); double maxHealth = entityHandler.getMaxHealth(player); if (maxHealth < health) { entityHandler.setMaxHealth(player, health); } player.setHealth(health); } } ================================================ FILE: expansion/compatibility/Citizens/src/main/resources/citizens.yml ================================================ # Should this expansion prevent other punishments from executing? (e.g. kill, commands, etc...) # This prevents issues such as killing AND spawning an NPC # Default: true prevent-punishments: true # Should this expansion prevent a player from logging in if they have an NPC active? # This means they will have to wait until it is killed or despawned. # Default: false prevent-login: false # Which entity type should be used to create NPCs? # You can find a list of valid EntityTypes in the link below: # https://hub.spigotmc.org/javadocs/spigot/org/bukkit/entity/EntityType.html # Default: PLAYER mob-type: PLAYER # Should we take the player's inventory and put it into the NPC? # This will prevent items from being dropped unless the NPC is killed. # Items will be taken when the NPC is spawned and restored to the player once they log back in. # Armor and held items will be placed in the correct slots. # Default: true store-inventory: true # Should we store the NPC's last location? # The player will be teleported to that location once they log bck in. # Default: true store-location: true # Should nearby mobs target combat NPCs? # Default: true mob-target: true # How close do mobs need to be to force-target an NPC? # Set this to 0 to disable this feature. # Default: 10 mob-target-radius: 10 # How long do combat NPCs last if they are not attacked by mobs or players? # NPC survival time is in seconds. # Default: 30 survival-time: 30 # Should an NPC stay alive until their last known enemy is out of combat? # Default: false stay-until-enemy-escape: false # Should the survival time on an NPC reset every time they are hit? # Default: false stay-until-no-damage: false # Should combat NPCs be prevented from using totems of undying? # Default: true prevent-resurrect: true # Should players receive a combat tag when they log back in? # This only applies if their NPC still had health when it respawned. tag-player: true # Should CombatLogX always spawn an NPC, even if the player is not tagged? always-spawn-npc-on-quit: false # Custom NPC name # May be character limited to 16 on some versions. # Available Placeholders: {player_name} # DO NOT set this to null or empty. custom-npc-name: "{player_name}" ================================================ FILE: expansion/compatibility/Citizens/src/main/resources/config.yml ================================================ # Should players be tagged by NPCs? # Default: false npc-tagging: false # Should we use the Sentinel plugin to create combat NPCs? # Requires Sentinel, which can be found at the link below: # https://www.spigotmc.org/resources/22017/ # Default: true enable-sentinel: true ================================================ FILE: expansion/compatibility/Citizens/src/main/resources/expansion.yml ================================================ name: "${expansionName}" prefix: "${expansionPrefix}" description: "${expansionDescription}" main: "combatlogx.expansion.compatibility.citizens.CitizensExpansion" version: "17.18" author: "SirBlobman" plugin-depend: - "Citizens" plugin-soft-depend: - "Sentinel" ================================================ FILE: expansion/compatibility/Citizens/src/main/resources/sentinel.yml ================================================ # true: Combat NPCs will attack their enemy first. # false: Combat NPCs will only attack if they are attacked first. # Default: false attack-first: false ================================================ FILE: expansion/compatibility/CrackShot/build.gradle.kts ================================================ dependencies { compileOnly("com.github.Shampaggon:CrackShot:0.98.13") } ================================================ FILE: expansion/compatibility/CrackShot/gradle.properties ================================================ expansion.name=CompatCrackShot expansion.prefix=CrackShot Compatibility ================================================ FILE: expansion/compatibility/CrackShot/src/main/java/combatlogx/expansion/compatibility/crackshot/CrackShotExpansion.java ================================================ package combatlogx.expansion.compatibility.crackshot; import org.jetbrains.annotations.NotNull; import com.github.sirblobman.combatlogx.api.ICombatLogX; import com.github.sirblobman.combatlogx.api.expansion.Expansion; import combatlogx.expansion.compatibility.crackshot.listener.ListenerCrackShot; public final class CrackShotExpansion extends Expansion { public CrackShotExpansion(@NotNull ICombatLogX plugin) { super(plugin); } @Override public void onLoad() { // Do Nothing } @Override public void onEnable() { if (!checkDependency("CrackShot", true)) { selfDisable(); return; } new ListenerCrackShot(this).register(); } @Override public void onDisable() { // Do Nothing } @Override public void reloadConfig() { // Do Nothing } } ================================================ FILE: expansion/compatibility/CrackShot/src/main/java/combatlogx/expansion/compatibility/crackshot/listener/ListenerCrackShot.java ================================================ package combatlogx.expansion.compatibility.crackshot.listener; import org.jetbrains.annotations.NotNull; import org.bukkit.entity.Entity; import org.bukkit.entity.Player; import org.bukkit.event.EventHandler; import org.bukkit.event.EventPriority; import com.github.sirblobman.combatlogx.api.expansion.ExpansionListener; import com.github.sirblobman.combatlogx.api.manager.ICombatManager; import com.github.sirblobman.combatlogx.api.object.TagReason; import com.github.sirblobman.combatlogx.api.object.TagType; import com.shampaggon.crackshot.events.WeaponDamageEntityEvent; import combatlogx.expansion.compatibility.crackshot.CrackShotExpansion; public final class ListenerCrackShot extends ExpansionListener { public ListenerCrackShot(@NotNull CrackShotExpansion expansion) { super(expansion); } @EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true) public void onAttack(WeaponDamageEntityEvent e) { Entity entity = e.getVictim(); if (!(entity instanceof Player damaged)) { return; } Player damager = e.getPlayer(); ICombatManager combatManager = getCombatManager(); combatManager.tag(damager, damaged, TagType.PLAYER, TagReason.ATTACKER); combatManager.tag(damaged, damager, TagType.PLAYER, TagReason.ATTACKED); } } ================================================ FILE: expansion/compatibility/CrackShot/src/main/resources/expansion.yml ================================================ name: "${expansionName}" prefix: "${expansionPrefix}" description: "${expansionDescription}" main: "combatlogx.expansion.compatibility.crackshot.CrackShotExpansion" version: "17.1" author: "SirBlobman" plugin-depend: - "CrackShot" ================================================ FILE: expansion/compatibility/CrashClaim/build.gradle.kts ================================================ repositories { maven("https://nexus.sirblobman.xyz/proxy-public") } dependencies { compileOnly("com.github.WhipDevelopment:CrashClaim:c697d3e9ef") } ================================================ FILE: expansion/compatibility/CrashClaim/gradle.properties ================================================ expansion.name=CompatCrashClaim expansion.prefix=CrashClaim Compatibility ================================================ FILE: expansion/compatibility/CrashClaim/src/main/java/combatlogx/expansion/compatibility/region/crash/claim/CrashClaimExpansion.java ================================================ package combatlogx.expansion.compatibility.region.crash.claim; import org.jetbrains.annotations.NotNull; import com.github.sirblobman.combatlogx.api.ICombatLogX; import com.github.sirblobman.combatlogx.api.expansion.region.RegionExpansion; import com.github.sirblobman.combatlogx.api.expansion.region.RegionHandler; public final class CrashClaimExpansion extends RegionExpansion { private RegionHandler regionHandler; public CrashClaimExpansion(ICombatLogX plugin) { super(plugin); this.regionHandler = null; } @Override public boolean checkDependencies() { return checkDependency("CrashClaim", true, "1.0"); } @Override public @NotNull RegionHandler getRegionHandler() { if (this.regionHandler == null) { this.regionHandler = new CrashClaimRegionHandler(this); } return this.regionHandler; } } ================================================ FILE: expansion/compatibility/CrashClaim/src/main/java/combatlogx/expansion/compatibility/region/crash/claim/CrashClaimRegionHandler.java ================================================ package combatlogx.expansion.compatibility.region.crash.claim; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import org.bukkit.Location; import org.bukkit.entity.Player; import org.bukkit.plugin.java.JavaPlugin; import com.github.sirblobman.combatlogx.api.expansion.region.RegionHandler; import com.github.sirblobman.combatlogx.api.object.TagInformation; import com.github.sirblobman.combatlogx.api.object.TagType; import net.crashcraft.crashclaim.CrashClaim; import net.crashcraft.crashclaim.api.CrashClaimAPI; import net.crashcraft.crashclaim.claimobjects.Claim; public final class CrashClaimRegionHandler extends RegionHandler { public CrashClaimRegionHandler(@NotNull CrashClaimExpansion expansion) { super(expansion); } @Override public @NotNull String getEntryDeniedMessagePath(@NotNull TagType tagType) { return "expansion.region-protection.crashclaim.no-entry"; } @Override public boolean isSafeZone(@NotNull Player player, @NotNull Location location, @NotNull TagInformation tag) { Claim claim = getClaim(location); return (claim != null); } private @NotNull CrashClaim getCrashClaim() { return JavaPlugin.getPlugin(CrashClaim.class); } private @NotNull CrashClaimAPI getAPI() { CrashClaim crashClaim = getCrashClaim(); return crashClaim.getApi(); } private @Nullable Claim getClaim(@NotNull Location location) { CrashClaimAPI api = getAPI(); return api.getClaim(location); } } ================================================ FILE: expansion/compatibility/CrashClaim/src/main/resources/expansion.yml ================================================ name: "${expansionName}" prefix: "${expansionPrefix}" description: "${expansionDescription}" main: "combatlogx.expansion.compatibility.region.crash.claim.CrashClaimExpansion" version: "17.1" author: "SirBlobman" plugin-depend: - "CrashClaim" ================================================ FILE: expansion/compatibility/EssentialsX/build.gradle.kts ================================================ repositories { maven("https://repo.essentialsx.net/releases/") } dependencies { compileOnly("net.essentialsx:EssentialsX:2.21.0") { exclude("io.papermc") } } ================================================ FILE: expansion/compatibility/EssentialsX/gradle.properties ================================================ expansion.name=CompatEssentialsX expansion.prefix=EssentialsX Compatibility ================================================ FILE: expansion/compatibility/EssentialsX/src/main/java/combatlogx/expansion/compatibility/essentials/EssentialsExpansion.java ================================================ package combatlogx.expansion.compatibility.essentials; import java.util.logging.Logger; import org.jetbrains.annotations.NotNull; import com.github.sirblobman.api.configuration.ConfigurationManager; import com.github.sirblobman.combatlogx.api.ICombatLogX; import com.github.sirblobman.combatlogx.api.expansion.vanish.VanishExpansion; import com.github.sirblobman.combatlogx.api.expansion.vanish.VanishHandler; import combatlogx.expansion.compatibility.essentials.listener.ListenerEssentials; public final class EssentialsExpansion extends VanishExpansion { private final EssentialsExpansionConfiguration configuration; private VanishHandler vanishHandler; public EssentialsExpansion(@NotNull ICombatLogX plugin) { super(plugin); this.configuration = new EssentialsExpansionConfiguration(); this.vanishHandler = null; } @Override public boolean checkDependencies() { Logger logger = getLogger(); if (checkDependency("Essentials", true)) { try { Class.forName("net.ess3.api.events.TPARequestEvent"); logger.info("Detected EssentialsX successfully."); return true; } catch (ReflectiveOperationException ex) { logger.info("The installed Essentials plugin is not EssentialsX or is out of date."); } } return false; } @Override public void afterEnable() { new ListenerEssentials(this).register(); } @Override public void reloadConfig() { super.reloadConfig(); ConfigurationManager configurationManager = getConfigurationManager(); getEssentialsConfiguration().load(configurationManager.get("config.yml")); } @Override public @NotNull VanishHandler getVanishHandler() { if (this.vanishHandler == null) { this.vanishHandler = new VanishHandlerEssentialsX(this); } return this.vanishHandler; } public @NotNull EssentialsExpansionConfiguration getEssentialsConfiguration() { return this.configuration; } } ================================================ FILE: expansion/compatibility/EssentialsX/src/main/java/combatlogx/expansion/compatibility/essentials/EssentialsExpansionConfiguration.java ================================================ package combatlogx.expansion.compatibility.essentials; import org.jetbrains.annotations.NotNull; import org.bukkit.configuration.ConfigurationSection; import com.github.sirblobman.api.configuration.IConfigurable; public final class EssentialsExpansionConfiguration implements IConfigurable { private boolean preventTeleportRequest; public EssentialsExpansionConfiguration() { this.preventTeleportRequest = true; } @Override public void load(@NotNull ConfigurationSection config) { setPreventTeleportRequest(config.getBoolean("prevent-teleport-request", true)); } public boolean isPreventTeleportRequest() { return this.preventTeleportRequest; } public void setPreventTeleportRequest(boolean preventTeleportRequest) { this.preventTeleportRequest = preventTeleportRequest; } } ================================================ FILE: expansion/compatibility/EssentialsX/src/main/java/combatlogx/expansion/compatibility/essentials/VanishHandlerEssentialsX.java ================================================ package combatlogx.expansion.compatibility.essentials; import org.jetbrains.annotations.NotNull; import org.bukkit.entity.Player; import org.bukkit.plugin.java.JavaPlugin; import com.github.sirblobman.combatlogx.api.expansion.vanish.VanishHandler; import com.earth2me.essentials.Essentials; import com.earth2me.essentials.User; public final class VanishHandlerEssentialsX extends VanishHandler { public VanishHandlerEssentialsX(@NotNull EssentialsExpansion expansion) { super(expansion); } @Override public boolean isVanished(@NotNull Player player) { User user = getUser(player); return user.isVanished(); } private @NotNull Essentials getEssentials() { return JavaPlugin.getPlugin(Essentials.class); } private @NotNull User getUser(@NotNull Player player) { Essentials essentials = getEssentials(); return essentials.getUser(player); } } ================================================ FILE: expansion/compatibility/EssentialsX/src/main/java/combatlogx/expansion/compatibility/essentials/listener/ListenerEssentials.java ================================================ package combatlogx.expansion.compatibility.essentials.listener; import org.jetbrains.annotations.NotNull; import org.bukkit.entity.Player; import org.bukkit.event.EventHandler; import org.bukkit.event.EventPriority; import com.github.sirblobman.api.language.LanguageManager; import com.github.sirblobman.combatlogx.api.expansion.vanish.VanishExpansionListener; import com.earth2me.essentials.CommandSource; import combatlogx.expansion.compatibility.essentials.EssentialsExpansion; import combatlogx.expansion.compatibility.essentials.EssentialsExpansionConfiguration; import net.ess3.api.IUser; import net.ess3.api.events.TPARequestEvent; public final class ListenerEssentials extends VanishExpansionListener { private final EssentialsExpansion expansion; public ListenerEssentials(@NotNull EssentialsExpansion expansion) { super(expansion); this.expansion = expansion; } @EventHandler(priority = EventPriority.NORMAL, ignoreCancelled = true) public void onTeleportRequest(TPARequestEvent e) { if (!isPreventTeleportRequest()) { return; } CommandSource requester = e.getRequester(); Player player = requester.getPlayer(); if (player == null) { return; } LanguageManager languageManager = getLanguageManager(); if (isInCombat(player)) { e.setCancelled(true); String messagePath = "expansion.essentials-compatibility.prevent-teleport-request-self"; languageManager.sendMessageWithPrefix(player, messagePath); return; } IUser targetUser = e.getTarget(); Player target = targetUser.getBase(); if (target == null) { return; } if (isInCombat(target)) { e.setCancelled(true); String messagePath = "expansion.essentials-compatibility.prevent-teleport-request-other"; languageManager.sendMessageWithPrefix(player, messagePath); } } private @NotNull EssentialsExpansion getEssentialsExpansion() { return this.expansion; } private @NotNull EssentialsExpansionConfiguration getEssentialsConfiguration() { EssentialsExpansion expansion = getEssentialsExpansion(); return expansion.getEssentialsConfiguration(); } private boolean isPreventTeleportRequest() { EssentialsExpansionConfiguration configuration = getEssentialsConfiguration(); return configuration.isPreventTeleportRequest(); } } ================================================ FILE: expansion/compatibility/EssentialsX/src/main/resources/config.yml ================================================ # Should players in vanish be preventing from going into combat? prevent-vanish-tagging-self: true # Should players in vanish be unable to tag other players? prevent-vanish-tagging-other: true # Should teleport requests be disabled during combat? prevent-teleport-request: true ================================================ FILE: expansion/compatibility/EssentialsX/src/main/resources/expansion.yml ================================================ name: "${expansionName}" prefix: "${expansionPrefix}" description: "${expansionDescription}" main: "combatlogx.expansion.compatibility.essentials.EssentialsExpansion" version: "17.3" author: "SirBlobman" plugin-depend: - "Essentials" ================================================ FILE: expansion/compatibility/FabledSkyBlock/build.gradle.kts ================================================ fun getEnvOrProp(variableName: String, propertyName: String): String { val environmentProvider = providers.environmentVariable(variableName) val propertyProvider = providers.gradleProperty(propertyName) return environmentProvider.orElse(propertyProvider).orElse("").get() } repositories { maven("https://nexus.sirblobman.xyz/private/") { credentials { username = getEnvOrProp("MAVEN_DEPLOY_USR", "maven.username.sirblobman") password = getEnvOrProp("MAVEN_DEPLOY_PSW", "maven.password.sirblobman") } } } dependencies { compileOnly("com.songoda:FabledSkyBlock:4.2.0") } ================================================ FILE: expansion/compatibility/FabledSkyBlock/gradle.properties ================================================ expansion.name=CompatFabledSkyBlock expansion.prefix=FabledSkyBlock Compatibility ================================================ FILE: expansion/compatibility/FabledSkyBlock/src/main/java/combatlogx/expansion/compatibility/fabled/skyblock/FabledSkyBlockExpansion.java ================================================ package combatlogx.expansion.compatibility.fabled.skyblock; import org.jetbrains.annotations.NotNull; import com.github.sirblobman.combatlogx.api.ICombatLogX; import com.github.sirblobman.combatlogx.api.expansion.skyblock.SkyBlockExpansion; import com.github.sirblobman.combatlogx.api.expansion.skyblock.SkyBlockHandler; public final class FabledSkyBlockExpansion extends SkyBlockExpansion { private SkyBlockHandler skyBlockHandler; public FabledSkyBlockExpansion(@NotNull ICombatLogX plugin) { super(plugin); this.skyBlockHandler = null; } @Override public boolean checkDependencies() { return checkDependency("FabledSkyBlock", true, "4"); } @Override public @NotNull SkyBlockHandler getSkyBlockHandler() { if (this.skyBlockHandler == null) { this.skyBlockHandler = new SkyBlockHandlerFabled(this); } return this.skyBlockHandler; } } ================================================ FILE: expansion/compatibility/FabledSkyBlock/src/main/java/combatlogx/expansion/compatibility/fabled/skyblock/IslandWrapperFabled.java ================================================ package combatlogx.expansion.compatibility.fabled.skyblock; import java.util.Collections; import java.util.HashSet; import java.util.Set; import java.util.UUID; import org.jetbrains.annotations.NotNull; import org.bukkit.OfflinePlayer; import com.github.sirblobman.combatlogx.api.expansion.skyblock.IslandWrapper; import com.songoda.skyblock.api.island.Island; public final class IslandWrapperFabled extends IslandWrapper { private final Island island; public IslandWrapperFabled(@NotNull Island island) { this.island = island; } private @NotNull Island getIsland() { return this.island; } @Override public boolean isMember(@NotNull OfflinePlayer player) { Island island = getIsland(); UUID ownerId = island.getOwnerUUID(); if (player.getUniqueId().equals(ownerId)) { return true; } return island.isCoopPlayer(player); } @Override public @NotNull Set getMembers() { Island island = getIsland(); UUID islandOwner = island.getOwnerUUID(); Set memberSet = new HashSet<>(1); memberSet.add(islandOwner); memberSet.addAll(island.getCoopPlayers().keySet()); return Collections.unmodifiableSet(memberSet); } } ================================================ FILE: expansion/compatibility/FabledSkyBlock/src/main/java/combatlogx/expansion/compatibility/fabled/skyblock/SkyBlockHandlerFabled.java ================================================ package combatlogx.expansion.compatibility.fabled.skyblock; import java.util.UUID; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import org.bukkit.Location; import org.bukkit.OfflinePlayer; import com.github.sirblobman.combatlogx.api.expansion.skyblock.IslandWrapper; import com.github.sirblobman.combatlogx.api.expansion.skyblock.SkyBlockHandler; import com.songoda.skyblock.api.SkyBlockAPI; import com.songoda.skyblock.api.island.Island; import com.songoda.skyblock.api.island.IslandManager; public final class SkyBlockHandlerFabled extends SkyBlockHandler { public SkyBlockHandlerFabled(@NotNull FabledSkyBlockExpansion expansion) { super(expansion); } @Override public @Nullable IslandWrapper getIsland(@NotNull Location location) { IslandManager islandManager = getIslandManager(); return wrap(islandManager.getIslandAtLocation(location)); } @Override public @NotNull IslandWrapper getIsland(@NotNull OfflinePlayer player) { IslandManager islandManager = getIslandManager(); return wrap(islandManager.getIsland(player)); } @Override public boolean doesIslandMatch(@NotNull OfflinePlayer player1, @NotNull OfflinePlayer player2) { IslandManager islandManager = getIslandManager(); Island island1 = islandManager.getIsland(player1); Island island2 = islandManager.getIsland(player2); if (island1 == null || island2 == null) { return false; } UUID islandId1 = island1.getIslandUUID(); UUID islandId2 = island2.getIslandUUID(); return islandId1.equals(islandId2); } private @NotNull IslandManager getIslandManager() { return SkyBlockAPI.getIslandManager(); } private @Nullable IslandWrapper wrap(@Nullable Island island) { if (island != null) { return new IslandWrapperFabled(island); } return null; } } ================================================ FILE: expansion/compatibility/FabledSkyBlock/src/main/resources/expansion.yml ================================================ name: "${expansionName}" prefix: "${expansionPrefix}" description: "${expansionDescription}" main: "combatlogx.expansion.compatibility.fabled.skyblock.FabledSkyBlockExpansion" version: "17.1" author: "SirBlobman" plugin-depend: - "FabledSkyBlock" ================================================ FILE: expansion/compatibility/Factions/gradle.properties ================================================ expansion.name=CompatFactions expansion.prefix=Factions Compatibility ================================================ FILE: expansion/compatibility/Factions/src/main/java/combatlogx/expansion/compatibility/region/factions/FactionsExpansion.java ================================================ package combatlogx.expansion.compatibility.region.factions; import org.jetbrains.annotations.NotNull; import org.bukkit.plugin.java.JavaPlugin; import com.github.sirblobman.api.factions.FactionsHandler; import com.github.sirblobman.api.factions.FactionsHelper; import com.github.sirblobman.combatlogx.api.ICombatLogX; import com.github.sirblobman.combatlogx.api.expansion.region.RegionExpansion; import com.github.sirblobman.combatlogx.api.expansion.region.RegionHandler; public final class FactionsExpansion extends RegionExpansion { private RegionHandler regionHandler; private FactionsHandler factionsHandler; public FactionsExpansion(@NotNull ICombatLogX plugin) { super(plugin); this.regionHandler = null; this.factionsHandler = null; } @Override public boolean checkDependencies() { ICombatLogX combatLogX = getPlugin(); JavaPlugin plugin = combatLogX.getPlugin(); FactionsHelper factionsHelper = new FactionsHelper(plugin); this.factionsHandler = factionsHelper.getFactionsHandler(); return (this.factionsHandler != null); } @Override public @NotNull RegionHandler getRegionHandler() { if (this.regionHandler == null) { this.regionHandler = new RegionHandlerFactions(this); } return this.regionHandler; } public @NotNull FactionsHandler getFactionsHandler() { return this.factionsHandler; } } ================================================ FILE: expansion/compatibility/Factions/src/main/java/combatlogx/expansion/compatibility/region/factions/RegionHandlerFactions.java ================================================ package combatlogx.expansion.compatibility.region.factions; import org.jetbrains.annotations.NotNull; import org.bukkit.Location; import org.bukkit.entity.Player; import com.github.sirblobman.api.factions.FactionWrapper; import com.github.sirblobman.api.factions.FactionsHandler; import com.github.sirblobman.combatlogx.api.expansion.region.RegionHandler; import com.github.sirblobman.combatlogx.api.object.TagInformation; import com.github.sirblobman.combatlogx.api.object.TagType; public final class RegionHandlerFactions extends RegionHandler { private final FactionsHandler factionsHandler; public RegionHandlerFactions(@NotNull FactionsExpansion expansion) { super(expansion); this.factionsHandler = expansion.getFactionsHandler(); } private @NotNull FactionsHandler getFactionsHandler() { return this.factionsHandler; } @Override public @NotNull String getEntryDeniedMessagePath(@NotNull TagType tagType) { return "expansion.region-protection.factions-no-entry"; } @Override public boolean isSafeZone(@NotNull Player player, @NotNull Location location, @NotNull TagInformation tag) { FactionsHandler factionsHandler = getFactionsHandler(); FactionWrapper faction = factionsHandler.getFactionAt(location); if (faction == null) { return false; } return faction.isSafeZone(); } } ================================================ FILE: expansion/compatibility/Factions/src/main/resources/config.yml ================================================ # How should CombatLogX prevent players from entering non-pvp areas? # Valid Modes: # DISABLED - Don't do anything, just let them in # KNOCKBACK_PLAYER - Add some opposite velocity to the player so they are pushed backwards # CANCEL_EVENT - Cancel the player's move event # VULNERABLE - Let the player in, but remove their pvp protection # KILL_PLAYER - Set the player's health to 0 # TELEPORT_TO_ENEMY - Teleport the player to their enemy if they have one, or CANCEL if they don't have one. # Default: KNOCKBACK_PLAYER no-entry-mode: "KNOCKBACK_PLAYER" # This value is only used if 'no-entry-mode' is KNOCKBACK_PLAYER # How much should the backwards velocity be multiplied by? # Default: 1.5 knockback-strength: 1.5 # How much time (in seconds) should the plugin wait before sending another 'no-entry' message? # Default: 30 message-cooldown: 30 ================================================ FILE: expansion/compatibility/Factions/src/main/resources/expansion.yml ================================================ name: "${expansionName}" prefix: "${expansionPrefix}" description: "${expansionDescription}" main: "combatlogx.expansion.compatibility.region.factions.FactionsExpansion" version: "17.0" author: "SirBlobman" plugin-soft-depend: - "Factions" - "FactionsX" - "LegacyFactions" ================================================ FILE: expansion/compatibility/FeatherBoard/build.gradle.kts ================================================ fun getEnvOrProp(variableName: String, propertyName: String): String { val environmentProvider = providers.environmentVariable(variableName) val propertyProvider = providers.gradleProperty(propertyName) return environmentProvider.orElse(propertyProvider).orElse("").get() } repositories { maven("https://nexus.sirblobman.xyz/private/") { credentials { username = getEnvOrProp("MAVEN_DEPLOY_USR", "maven.username.sirblobman") password = getEnvOrProp("MAVEN_DEPLOY_PSW", "maven.password.sirblobman") } } } dependencies { compileOnly("com.mvdw-software:FeatherBoard:6.0.7") } ================================================ FILE: expansion/compatibility/FeatherBoard/gradle.properties ================================================ expansion.name=CompatFeatherBoard expansion.prefix=FeatherBoard Compatibility ================================================ FILE: expansion/compatibility/FeatherBoard/src/main/java/combatlogx/expansion/compatibility/featherboard/FeatherBoardConfiguration.java ================================================ package combatlogx.expansion.compatibility.featherboard; import org.jetbrains.annotations.NotNull; import org.bukkit.configuration.ConfigurationSection; import com.github.sirblobman.api.configuration.IConfigurable; public class FeatherBoardConfiguration implements IConfigurable { private String triggerName; public FeatherBoardConfiguration() { this.triggerName = "combatlogx"; } @Override public void load(@NotNull ConfigurationSection config) { setTriggerName(config.getString("trigger-name", "combatlogx")); } public @NotNull String getTriggerName() { return this.triggerName; } public void setTriggerName(@NotNull String triggerName) { this.triggerName = triggerName; } } ================================================ FILE: expansion/compatibility/FeatherBoard/src/main/java/combatlogx/expansion/compatibility/featherboard/FeatherBoardExpansion.java ================================================ package combatlogx.expansion.compatibility.featherboard; import org.jetbrains.annotations.NotNull; import com.github.sirblobman.api.configuration.ConfigurationManager; import com.github.sirblobman.combatlogx.api.ICombatLogX; import com.github.sirblobman.combatlogx.api.expansion.Expansion; import combatlogx.expansion.compatibility.featherboard.listener.ListenerFeatherBoard; public final class FeatherBoardExpansion extends Expansion { private final FeatherBoardConfiguration configuration; public FeatherBoardExpansion(ICombatLogX plugin) { super(plugin); this.configuration = new FeatherBoardConfiguration(); } @Override public void onLoad() { ConfigurationManager configurationManager = getConfigurationManager(); configurationManager.saveDefault("config.yml"); } @Override public void onEnable() { if (!checkDependency("FeatherBoard", true, "6")) { selfDisable(); return; } new ListenerFeatherBoard(this).register(); } @Override public void onDisable() { // Do Nothing } @Override public void reloadConfig() { ConfigurationManager configurationManager = getConfigurationManager(); configurationManager.reload("config.yml"); getConfiguration().load(configurationManager.get("config.yml")); } public @NotNull FeatherBoardConfiguration getConfiguration() { return this.configuration; } } ================================================ FILE: expansion/compatibility/FeatherBoard/src/main/java/combatlogx/expansion/compatibility/featherboard/listener/ListenerFeatherBoard.java ================================================ package combatlogx.expansion.compatibility.featherboard.listener; import org.jetbrains.annotations.NotNull; import org.bukkit.entity.Player; import org.bukkit.event.EventHandler; import org.bukkit.event.EventPriority; import com.github.sirblobman.combatlogx.api.event.PlayerTagEvent; import com.github.sirblobman.combatlogx.api.event.PlayerUntagEvent; import com.github.sirblobman.combatlogx.api.expansion.ExpansionListener; import be.maximvdw.featherboard.api.FeatherBoardAPI; import combatlogx.expansion.compatibility.featherboard.FeatherBoardConfiguration; import combatlogx.expansion.compatibility.featherboard.FeatherBoardExpansion; public final class ListenerFeatherBoard extends ExpansionListener { private final FeatherBoardExpansion expansion; public ListenerFeatherBoard(@NotNull FeatherBoardExpansion expansion) { super(expansion); this.expansion = expansion; } @EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true) public void onTag(PlayerTagEvent e) { Player player = e.getPlayer(); showTrigger(player); } @EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true) public void onUntag(PlayerUntagEvent e) { Player player = e.getPlayer(); removeTrigger(player); } private @NotNull FeatherBoardExpansion getFeatherBoardExpansion() { return this.expansion; } private @NotNull FeatherBoardConfiguration getConfiguration() { FeatherBoardExpansion expansion = getFeatherBoardExpansion(); return expansion.getConfiguration(); } private @NotNull String getTriggerName() { FeatherBoardConfiguration configuration = getConfiguration(); String triggerName = configuration.getTriggerName(); return (triggerName.isEmpty() ? "combatlogx" : triggerName); } private void showTrigger(@NotNull Player player) { String triggerName = getTriggerName(); FeatherBoardAPI.showScoreboard(player, triggerName, true); } private void removeTrigger(@NotNull Player player) { String triggerName = getTriggerName(); FeatherBoardAPI.hideScoreboard(player, triggerName, true); } } ================================================ FILE: expansion/compatibility/FeatherBoard/src/main/resources/config.yml ================================================ # Which trigger name should be sent to FeatherBoard whenever a player is tagged? trigger-name: "combatlogx" ================================================ FILE: expansion/compatibility/FeatherBoard/src/main/resources/expansion.yml ================================================ name: "${expansionName}" prefix: "${expansionPrefix}" description: "${expansionDescription}" main: "combatlogx.expansion.compatibility.featherboard.FeatherBoardExpansion" version: "17.3" author: "SirBlobman" plugin-depend: - "FeatherBoard" ================================================ FILE: expansion/compatibility/GriefDefender/build.gradle.kts ================================================ repositories { maven("https://repo.glaremasters.me/repository/bloodshot/") } dependencies { compileOnly("com.griefdefender:api:2.1.1-SNAPSHOT") } ================================================ FILE: expansion/compatibility/GriefDefender/gradle.properties ================================================ expansion.name=CompatGriefDefender expansion.prefix=GriefDefender Compatibility ================================================ FILE: expansion/compatibility/GriefDefender/src/main/java/combatlogx/expansion/compatibility/region/grief/defender/GriefDefenderExpansion.java ================================================ package combatlogx.expansion.compatibility.region.grief.defender; import org.jetbrains.annotations.NotNull; import com.github.sirblobman.combatlogx.api.ICombatLogX; import com.github.sirblobman.combatlogx.api.expansion.region.RegionExpansion; import com.github.sirblobman.combatlogx.api.expansion.region.RegionHandler; public final class GriefDefenderExpansion extends RegionExpansion { private RegionHandler regionHandler; public GriefDefenderExpansion(ICombatLogX plugin) { super(plugin); this.regionHandler = null; } @Override public boolean checkDependencies() { return checkDependency("GriefDefender", true); } @Override public @NotNull RegionHandler getRegionHandler() { if (this.regionHandler == null) { this.regionHandler = new RegionHandlerGriefDefender(this); } return this.regionHandler; } } ================================================ FILE: expansion/compatibility/GriefDefender/src/main/java/combatlogx/expansion/compatibility/region/grief/defender/RegionHandlerGriefDefender.java ================================================ package combatlogx.expansion.compatibility.region.grief.defender; import java.util.UUID; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import org.bukkit.Location; import org.bukkit.World; import org.bukkit.entity.Player; import com.github.sirblobman.combatlogx.api.expansion.region.RegionHandler; import com.github.sirblobman.combatlogx.api.object.TagInformation; import com.github.sirblobman.combatlogx.api.object.TagType; import com.griefdefender.api.Core; import com.griefdefender.api.GriefDefender; import com.griefdefender.api.User; import com.griefdefender.api.claim.Claim; public final class RegionHandlerGriefDefender extends RegionHandler { public RegionHandlerGriefDefender(@NotNull GriefDefenderExpansion expansion) { super(expansion); } @Override public @NotNull String getEntryDeniedMessagePath(@NotNull TagType tagType) { return "expansion.region-protection.griefdefender-no-entry"; } @Override public boolean isSafeZone(@NotNull Player player, @NotNull Location location, @NotNull TagInformation tag) { TagType tagType = tag.getCurrentTagType(); if (tagType != TagType.PLAYER) { return false; } Claim claim = getClaimAt(location); if (claim == null) { return false; } User user = getUser(player); if (user == null) { return false; } return !user.canPvp(claim); } private @NotNull Core getCore() { return GriefDefender.getCore(); } private @Nullable Claim getClaimAt(Location location) { World world = location.getWorld(); if (world == null) { return null; } Core core = getCore(); return core.getClaimAt(location); } private @Nullable User getUser(Player player) { Core core = getCore(); UUID playerId = player.getUniqueId(); return core.getUser(playerId); } } ================================================ FILE: expansion/compatibility/GriefDefender/src/main/resources/expansion.yml ================================================ name: "${expansionName}" prefix: "${expansionPrefix}" description: "${expansionDescription}" main: "combatlogx.expansion.compatibility.region.grief.defender.GriefDefenderExpansion" version: "17.2" author: "SirBlobman" plugin-depend: - "GriefDefender" ================================================ FILE: expansion/compatibility/GriefPrevention/build.gradle.kts ================================================ repositories { maven("https://nexus.sirblobman.xyz/proxy-public") } dependencies { compileOnly("com.github.GriefPrevention:GriefPrevention:17.0.0") } ================================================ FILE: expansion/compatibility/GriefPrevention/gradle.properties ================================================ expansion.name=CompatGriefPrevention expansion.prefix=GriefPrevention Compatibility ================================================ FILE: expansion/compatibility/GriefPrevention/src/main/java/combatlogx/expansion/compatibility/region/grief/prevention/GriefPreventionExpansion.java ================================================ package combatlogx.expansion.compatibility.region.grief.prevention; import org.jetbrains.annotations.NotNull; import com.github.sirblobman.combatlogx.api.ICombatLogX; import com.github.sirblobman.combatlogx.api.expansion.region.RegionExpansion; import com.github.sirblobman.combatlogx.api.expansion.region.RegionHandler; public final class GriefPreventionExpansion extends RegionExpansion { private RegionHandler regionHandler; public GriefPreventionExpansion(ICombatLogX plugin) { super(plugin); this.regionHandler = null; } @Override public boolean checkDependencies() { return checkDependency("GriefPrevention", true); } @Override public @NotNull RegionHandler getRegionHandler() { if (this.regionHandler == null) { this.regionHandler = new RegionHandlerGriefPrevention(this); } return this.regionHandler; } } ================================================ FILE: expansion/compatibility/GriefPrevention/src/main/java/combatlogx/expansion/compatibility/region/grief/prevention/RegionHandlerGriefPrevention.java ================================================ package combatlogx.expansion.compatibility.region.grief.prevention; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import org.bukkit.Location; import org.bukkit.entity.Player; import org.bukkit.plugin.java.JavaPlugin; import com.github.sirblobman.combatlogx.api.expansion.region.RegionHandler; import com.github.sirblobman.combatlogx.api.object.TagInformation; import com.github.sirblobman.combatlogx.api.object.TagType; import me.ryanhamshire.GriefPrevention.Claim; import me.ryanhamshire.GriefPrevention.GriefPrevention; public final class RegionHandlerGriefPrevention extends RegionHandler { public RegionHandlerGriefPrevention(GriefPreventionExpansion expansion) { super(expansion); } @Override public @NotNull String getEntryDeniedMessagePath(@NotNull TagType tagType) { return "expansion.region-protection.griefprevention-no-entry"; } @Override public boolean isSafeZone(@NotNull Player player, @NotNull Location location, @NotNull TagInformation tag) { TagType tagType = tag.getCurrentTagType(); if (tagType != TagType.PLAYER) { return false; } Claim claim = getClaim(location); GriefPrevention griefPrevention = getGriefPrevention(); return (claim != null && griefPrevention.claimIsPvPSafeZone(claim)); } private @NotNull GriefPrevention getGriefPrevention() { return JavaPlugin.getPlugin(GriefPrevention.class); } private @Nullable Claim getClaim(@NotNull Location location) { GriefPrevention griefPrevention = getGriefPrevention(); return griefPrevention.dataStore.getClaimAt(location, false, null); } } ================================================ FILE: expansion/compatibility/GriefPrevention/src/main/resources/expansion.yml ================================================ name: "${expansionName}" prefix: "${expansionPrefix}" description: "${expansionDescription}" main: "combatlogx.expansion.compatibility.region.grief.prevention.GriefPreventionExpansion" version: "17.1" author: "SirBlobman" late-load: true plugin-depend: - "GriefPrevention" ================================================ FILE: expansion/compatibility/HuskHomes/build.gradle.kts ================================================ repositories { maven("https://repo.william278.net/releases/") } dependencies { compileOnly("net.william278:huskhomes:4.5.5") } ================================================ FILE: expansion/compatibility/HuskHomes/gradle.properties ================================================ expansion.name=CompatHuskHomes expansion.prefix=HuskHomes Compatibility ================================================ FILE: expansion/compatibility/HuskHomes/src/main/java/combatlogx/expansion/compatibility/huskhomes/HuskHomesExpansion.java ================================================ package combatlogx.expansion.compatibility.huskhomes; import org.jetbrains.annotations.NotNull; import com.github.sirblobman.api.configuration.ConfigurationManager; import com.github.sirblobman.combatlogx.api.ICombatLogX; import com.github.sirblobman.combatlogx.api.expansion.Expansion; import combatlogx.expansion.compatibility.huskhomes.listener.ListenerHuskHomes; public final class HuskHomesExpansion extends Expansion { public HuskHomesExpansion(@NotNull ICombatLogX plugin) { super(plugin); } @Override public void onLoad() { ConfigurationManager configurationManager = getConfigurationManager(); configurationManager.saveDefault("config.yml"); } @Override public void onEnable() { if (!checkDependency("HuskHomes", true, "4.5")) { selfDisable(); return; } new ListenerHuskHomes(this).register(); } @Override public void onDisable() { } @Override public void reloadConfig() { ConfigurationManager configurationManager = getConfigurationManager(); configurationManager.reload("config.yml"); } } ================================================ FILE: expansion/compatibility/HuskHomes/src/main/java/combatlogx/expansion/compatibility/huskhomes/listener/ListenerHuskHomes.java ================================================ package combatlogx.expansion.compatibility.huskhomes.listener; import java.util.UUID; import org.jetbrains.annotations.NotNull; import org.bukkit.Bukkit; import org.bukkit.entity.Player; import org.bukkit.event.EventHandler; import org.bukkit.event.EventPriority; import com.github.sirblobman.api.language.LanguageManager; import com.github.sirblobman.combatlogx.api.expansion.ExpansionListener; import combatlogx.expansion.compatibility.huskhomes.HuskHomesExpansion; import net.william278.huskhomes.event.TeleportWarmupEvent; import net.william278.huskhomes.teleport.Teleport; import net.william278.huskhomes.teleport.Teleportable; import net.william278.huskhomes.user.BukkitUser; public final class ListenerHuskHomes extends ExpansionListener { public ListenerHuskHomes(@NotNull HuskHomesExpansion expansion) { super(expansion); } @EventHandler(priority = EventPriority.NORMAL, ignoreCancelled = true) public void beforeTeleport(TeleportWarmupEvent e) { printDebug("Detected TeleportWarmupEvent..."); Teleport timedTeleport = e.getTimedTeleport(); Teleportable teleporter = timedTeleport.getTeleporter(); if (!(teleporter instanceof BukkitUser bukkitTeleporter)) { return; } UUID teleporterId = bukkitTeleporter.getUuid(); printDebug("Teleporter ID: " + teleporterId); Player player = Bukkit.getPlayer(teleporterId); if (player == null) { printDebug("Teleporter is not a valid player, ignoring."); return; } if (!isInCombat(player)) { printDebug("Player is not in combat, ignoring."); return; } printDebug("Sent message and cancelled event."); e.setCancelled(true); String messagePath = "expansion.huskhomes-compatibility.prevent-teleport"; LanguageManager languageManager = getLanguageManager(); languageManager.sendMessageWithPrefix(player, messagePath); } } ================================================ FILE: expansion/compatibility/HuskHomes/src/main/resources/config.yml ================================================ # Should teleports be prevented during combat? prevent-teleport: true ================================================ FILE: expansion/compatibility/HuskHomes/src/main/resources/expansion.yml ================================================ name: "${expansionName}" prefix: "${expansionPrefix}" description: "${expansionDescription}" main: "combatlogx.expansion.compatibility.huskhomes.HuskHomesExpansion" version: "17.2" author: "SirBlobman" plugin-depend: - "HuskHomes" ================================================ FILE: expansion/compatibility/HuskSync/build.gradle.kts ================================================ repositories { maven("https://repo.william278.net/releases/") } dependencies { compileOnly("net.william278.husksync:husksync-bukkit:3.8.5+1.21.6") } ================================================ FILE: expansion/compatibility/HuskSync/gradle.properties ================================================ expansion.name=CompatHuskSync expansion.name=HuskSync Compatibility ================================================ FILE: expansion/compatibility/HuskSync/src/main/java/combatlogx/expansion/compatibility/husksync/DropItemsTask.java ================================================ package combatlogx.expansion.compatibility.husksync; import java.util.Collection; import org.jetbrains.annotations.NotNull; import org.bukkit.Location; import org.bukkit.World; import org.bukkit.inventory.ItemStack; import org.bukkit.plugin.Plugin; import com.github.sirblobman.api.folia.details.LocationTaskDetails; import com.github.sirblobman.api.utility.ItemUtility; public final class DropItemsTask extends LocationTaskDetails { private final Collection dropList; public DropItemsTask(@NotNull Plugin plugin, @NotNull Location location, @NotNull Collection drops) { super(plugin, location); this.dropList = drops; setDelay(1L); } @Override public void run() { Location location = getLocation(); World world = location.getWorld(); for (ItemStack stack : this.dropList) { if (ItemUtility.isAir(stack)) { continue; } world.dropItemNaturally(location, stack); } } } ================================================ FILE: expansion/compatibility/HuskSync/src/main/java/combatlogx/expansion/compatibility/husksync/HuskSyncExpansion.java ================================================ package combatlogx.expansion.compatibility.husksync; import com.github.sirblobman.api.configuration.ConfigurationManager; import org.jetbrains.annotations.NotNull; import com.github.sirblobman.combatlogx.api.ICombatLogX; import com.github.sirblobman.combatlogx.api.expansion.Expansion; import java.util.HashSet; import java.util.Set; public final class HuskSyncExpansion extends Expansion { public HuskSyncExpansion(@NotNull ICombatLogX plugin) { super(plugin); } @Override public void onLoad() { // Do Nothing } @Override public void onEnable() { if (!checkDependency("HuskSync", true, "3.8")) { selfDisable(); return; } new ListenerHuskSync(this).register(); } @Override public void onDisable() { // Do Nothing } @Override public void reloadConfig() { // Do Nothing } } ================================================ FILE: expansion/compatibility/HuskSync/src/main/java/combatlogx/expansion/compatibility/husksync/ListenerHuskSync.java ================================================ package combatlogx.expansion.compatibility.husksync; import com.github.sirblobman.api.plugin.ConfigurablePlugin; import com.github.sirblobman.api.utility.ItemUtility; import com.github.sirblobman.combatlogx.api.ICombatLogX; import com.github.sirblobman.combatlogx.api.configuration.PunishConfiguration; import com.github.sirblobman.combatlogx.api.event.PlayerPunishEvent; import com.github.sirblobman.combatlogx.api.expansion.ExpansionListener; import com.github.sirblobman.combatlogx.api.object.KillTime; import net.william278.husksync.HuskSync; import net.william278.husksync.api.BukkitHuskSyncAPI; import net.william278.husksync.api.HuskSyncAPI; import net.william278.husksync.data.BukkitData; import net.william278.husksync.data.Data; import net.william278.husksync.data.DataSnapshot; import net.william278.husksync.event.BukkitDataSaveEvent; import net.william278.husksync.user.User; import org.bukkit.Location; import org.bukkit.entity.Player; import org.bukkit.event.EventHandler; import org.bukkit.event.EventPriority; import org.bukkit.event.entity.PlayerDeathEvent; import org.bukkit.event.player.PlayerJoinEvent; import org.bukkit.inventory.ItemStack; import org.jetbrains.annotations.NotNull; import java.util.*; public final class ListenerHuskSync extends ExpansionListener { private final Set punishedPlayers; private final Set alreadyDied; private final Map dataMap; private final HuskSyncAPI huskSyncAPI; public ListenerHuskSync(@NotNull HuskSyncExpansion expansion) { super(expansion); this.punishedPlayers = new HashSet<>(); this.alreadyDied = new HashSet<>(); this.dataMap = new HashMap<>(); this.huskSyncAPI = BukkitHuskSyncAPI.getInstance(); } @EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true) public void onPunish(PlayerPunishEvent event) { printDebug("Detected PlayerPunishEvent..."); ICombatLogX combatLogX = getCombatLogX(); PunishConfiguration punishConfiguration = combatLogX.getPunishConfiguration(); KillTime killTime = punishConfiguration.getKillTime(); if (killTime != KillTime.QUIT) { printDebug("Kill time is not QUIT, ignoring."); return; } UUID playerId = event.getPlayer().getUniqueId(); this.punishedPlayers.add(playerId); printDebug("Added player '" + playerId + "' to punishments map."); } @EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true) public void onDeath(PlayerDeathEvent e) { if(alreadyDied.remove(e.getEntity().getUniqueId())) { e.setDeathMessage(null); return; } printDebug("Detected PlayerDeathEvent..."); Player player = e.getEntity(); UUID playerId = player.getUniqueId(); if (!this.punishedPlayers.remove(playerId)) { printDebug("Punishments map did not contain player '" + playerId + "'. Ignoring."); return; } PlayerData playerData = new PlayerData(player, player.getLocation()); playerData.setKeepInventory(e.getKeepInventory()); playerData.setKeepLevel(e.getKeepLevel()); playerData.setTotalExperience(e.getNewTotalExp()); playerData.setNewLevel(e.getNewLevel()); playerData.setNewExperience(e.getNewExp()); playerData.setOldInventory(player.getInventory().getContents().clone()); this.dataMap.put(playerId, playerData); printDebug("Stored player data for later syncing."); } @EventHandler public void onJoin(PlayerJoinEvent e) { if(alreadyDied.contains(e.getPlayer().getUniqueId())) { // this may or may not cause a race condition, but it's less annoying than showing the death message twice getJavaPlugin().getServer().getScheduler().runTaskLater(getJavaPlugin(), () -> { alreadyDied.remove(e.getPlayer().getUniqueId()); }, 20L*5); } } @EventHandler(priority = EventPriority.NORMAL, ignoreCancelled = true) public void onBukkitDataSave(@NotNull BukkitDataSaveEvent e) { printDebug("Detected BukkitDataSaveEvent..."); DataSnapshot.SaveCause saveCause = e.getSaveCause(); if (!saveCause.getDisplayName().equalsIgnoreCase("DISCONNECT")) { printDebug("DataSaveCause is not 'DISCONNECT', ignoring event."); return; } User user = e.getUser(); PlayerData playerData = this.dataMap.remove(user.getUuid()); if (playerData == null) { printDebug("User does not have death punishment data from CombatLogX, ignoring event."); return; } printDebug("User Name: " + user.getName()); DataSnapshot.Packed userData = e.getData(); checkData(playerData, userData); printDebug("Set modified data in BukkitDataSaveEvent."); } private @NotNull HuskSyncAPI getHuskSyncAPI() { return this.huskSyncAPI; } private void checkData(@NotNull PlayerData playerData, @NotNull DataSnapshot.Packed userData) { Player player = playerData.getPlayer(); printDebug("Checking player data for player '" + player.getUniqueId() + "'."); HuskSyncAPI api = getHuskSyncAPI(); HuskSync huskSync = api.getPlugin(); userData.edit(huskSync, unpacked -> edit(playerData, unpacked)); } private void edit(@NotNull PlayerData playerData, @NotNull DataSnapshot.Unpacked unpacked) { Optional optionalExperience = unpacked.getExperience(); if (optionalExperience.isPresent()) { Data.Experience experience = optionalExperience.get(); if (!playerData.isKeepLevel()) { experience.setTotalExperience(playerData.getTotalExperience()); experience.setExpLevel(playerData.getNewLevel()); experience.setExpProgress(playerData.getNewExperience()); unpacked.setExperience(experience); printDebug("Set experience data in HuskSync."); } } Optional optionalHealth = unpacked.getHealth(); if (optionalHealth.isPresent()) { Data.Health health = optionalHealth.get(); health.setHealth(0.0D); unpacked.setHealth(health); alreadyDied.add(playerData.getPlayer().getUniqueId()); printDebug("Set player health to 0.0 in HuskSync."); } if (!playerData.isKeepInventory()) { printDebug("Death event had keepInventory = false, fetching items..."); ItemStack[] oldInventory = playerData.getOldInventory(); List drops = new ArrayList<>(); for (ItemStack stack : oldInventory) { if (!ItemUtility.isAir(stack)) { drops.add(stack); } } Location location = playerData.getLocation(); ConfigurablePlugin plugin = getJavaPlugin(); DropItemsTask task = new DropItemsTask(plugin, location, drops); plugin.getFoliaHelper().getScheduler().scheduleLocationTask(task); printDebug("Scheduled task to drop items."); Optional optionalInventory = unpacked.getInventory(); Data.Items.Inventory inventory = optionalInventory.orElse(BukkitData.Items.Inventory.empty()); inventory.setContents(BukkitData.Items.Inventory.empty()); unpacked.setInventory(inventory); printDebug("Set HuskSync inventory to empty."); } printDebug("Finished modifying HuskSync save data."); } } ================================================ FILE: expansion/compatibility/HuskSync/src/main/java/combatlogx/expansion/compatibility/husksync/PlayerData.java ================================================ package combatlogx.expansion.compatibility.husksync; import org.jetbrains.annotations.NotNull; import org.bukkit.Location; import org.bukkit.entity.Player; import org.bukkit.inventory.ItemStack; public final class PlayerData { private final Player player; private final Location location; private ItemStack[] oldInventory; private boolean keepInventory; private boolean keepLevel; private int totalExperience; private int newLevel; private float newExperience; public PlayerData(@NotNull Player player, @NotNull Location location) { this.player = player; this.location = location; this.oldInventory = new ItemStack[0]; this.keepInventory = false; this.keepLevel = false; this.totalExperience = 0; this.newLevel = 0; this.newExperience = 0.0F; } public @NotNull Player getPlayer() { return this.player; } public @NotNull Location getLocation() { return this.location; } public boolean isKeepInventory() { return this.keepInventory; } public void setKeepInventory(boolean keepInventory) { this.keepInventory = keepInventory; } public boolean isKeepLevel() { return this.keepLevel; } public void setKeepLevel(boolean keepLevel) { this.keepLevel = keepLevel; } public int getTotalExperience() { return this.totalExperience; } public void setTotalExperience(int totalExperience) { this.totalExperience = totalExperience; } public int getNewLevel() { return this.newLevel; } public void setNewLevel(int newLevel) { this.newLevel = newLevel; } public float getNewExperience() { return this.newExperience; } public void setNewExperience(float newExperience) { this.newExperience = newExperience; } public void setOldInventory(ItemStack @NotNull [] clone) { this.oldInventory = clone; } public ItemStack @NotNull [] getOldInventory() { return this.oldInventory; } } ================================================ FILE: expansion/compatibility/HuskSync/src/main/resources/expansion.yml ================================================ name: "${expansionName}" prefix: "${expansionPrefix}" description: "${expansionDescription}" main: "combatlogx.expansion.compatibility.husksync.HuskSyncExpansion" version: "17.8" author: "olivolja3" plugin-depend: - "HuskSync" ================================================ FILE: expansion/compatibility/HuskTowns/README.MD ================================================ # CombatLogX Expansion: HuskTowns Compatibility The HuskTowns compatibility expansion adds support for HuskTowns claims ## Requirements - [HuskTowns](https://github.com/WiIIiam278/HuskTowns) ## How to use? This expansion can prevent players from entering claimed areas. If a player is fighting another player, set the PVP flag to deny. If a player is fighting mobs, set the PVE flag to deny. ================================================ FILE: expansion/compatibility/HuskTowns/build.gradle.kts ================================================ repositories { maven("https://repo.william278.net/releases/") } dependencies { compileOnly("net.william278:husktowns:2.6.1") } ================================================ FILE: expansion/compatibility/HuskTowns/gradle.properties ================================================ expansion.name=CompatHuskTowns ================================================ FILE: expansion/compatibility/HuskTowns/src/main/java/combatlogx/expansion/compatibility/region/husktowns/HuskTownsExpansion.java ================================================ package combatlogx.expansion.compatibility.region.husktowns; import org.jetbrains.annotations.NotNull; import com.github.sirblobman.combatlogx.api.ICombatLogX; import com.github.sirblobman.combatlogx.api.expansion.region.RegionExpansion; import com.github.sirblobman.combatlogx.api.expansion.region.RegionHandler; public final class HuskTownsExpansion extends RegionExpansion { private RegionHandler regionHandler; public HuskTownsExpansion(@NotNull ICombatLogX plugin) { super(plugin); this.regionHandler = null; } @Override public boolean checkDependencies() { return checkDependency("HuskTowns", true, "2.6"); } @Override public @NotNull RegionHandler getRegionHandler() { if (this.regionHandler == null) { this.regionHandler = new RegionHandlerHuskTowns(this); } return this.regionHandler; } } ================================================ FILE: expansion/compatibility/HuskTowns/src/main/java/combatlogx/expansion/compatibility/region/husktowns/RegionHandlerHuskTowns.java ================================================ package combatlogx.expansion.compatibility.region.husktowns; import org.jetbrains.annotations.NotNull; import org.bukkit.Location; import org.bukkit.entity.Player; import com.github.sirblobman.combatlogx.api.expansion.region.RegionHandler; import com.github.sirblobman.combatlogx.api.object.TagInformation; import com.github.sirblobman.combatlogx.api.object.TagType; import net.william278.husktowns.api.HuskTownsAPI; import net.william278.husktowns.claim.Position; import net.william278.husktowns.listener.Operation; import net.william278.husktowns.listener.Operation.Type; import net.william278.husktowns.user.OnlineUser; public final class RegionHandlerHuskTowns extends RegionHandler { public RegionHandlerHuskTowns(@NotNull HuskTownsExpansion expansion) { super(expansion); } @Override public @NotNull String getEntryDeniedMessagePath(@NotNull TagType tagType) { return "expansion.region-protection.husktowns-no-entry"; } @Override public boolean isSafeZone(@NotNull Player player, @NotNull Location location, @NotNull TagInformation tag) { TagType tagType = tag.getCurrentTagType(); HuskTownsAPI api = HuskTownsAPI.getInstance(); OnlineUser user = api.getOnlineUser(player); if (user == null) { return false; } Position position = api.getPosition(location); if (position == null) { return false; } if (tagType == TagType.PLAYER) { Operation operation = Operation.of(user, Type.PLAYER_DAMAGE_PLAYER, position, true); return !api.isOperationAllowed(operation); } else if (tagType == TagType.MOB) { Operation operation = Operation.of(user, Type.PLAYER_DAMAGE_ENTITY, position, true); return !api.isOperationAllowed(operation); } return false; } } ================================================ FILE: expansion/compatibility/HuskTowns/src/main/resources/config.yml ================================================ # How should CombatLogX prevent players from entering non-pvp areas? # Valid Modes: # DISABLED - Don't do anything, just let them in # KNOCKBACK_PLAYER - Add some opposite velocity to the player so they are pushed backwards # CANCEL_EVENT - Cancel the player's move event # VULNERABLE - Let the player in, but remove their pvp protection # KILL_PLAYER - Set the player's health to 0 # TELEPORT_TO_ENEMY - Teleport the player to their enemy if they have one, or CANCEL if they don't have one. # Default: KNOCKBACK_PLAYER no-entry-mode: "KNOCKBACK_PLAYER" # This value is only used if 'no-entry-mode' is KNOCKBACK_PLAYER # How much should the backwards velocity be multiplied by? # Default: 1.5 knockback-strength: 1.5 # How much time (in seconds) should the plugin wait before sending another 'no-entry' message? # Default: 30 message-cooldown: 30 ================================================ FILE: expansion/compatibility/HuskTowns/src/main/resources/expansion.yml ================================================ name: "${expansionName}" prefix: "${expansionPrefix}" description: "${expansionDescription}" main: "combatlogx.expansion.compatibility.region.husktowns.HuskTownsExpansion" version: "17.2" author: "SirBlobman" plugin-depend: - "HuskTowns" ================================================ FILE: expansion/compatibility/IridiumSkyblock/build.gradle.kts ================================================ dependencies { compileOnly("net.iridiumdevelopment:IridiumSkyblock:4.1.0") } ================================================ FILE: expansion/compatibility/IridiumSkyblock/gradle.properties ================================================ expansion.name=CompatIridiumSkyblock expansion.prefix=IridiumSkyblock Compatibility ================================================ FILE: expansion/compatibility/IridiumSkyblock/src/main/java/combatlogx/expansion/compatibility/iridium/skyblock/IridiumSkyblockExpansion.java ================================================ package combatlogx.expansion.compatibility.iridium.skyblock; import org.jetbrains.annotations.NotNull; import com.github.sirblobman.combatlogx.api.ICombatLogX; import com.github.sirblobman.combatlogx.api.expansion.skyblock.SkyBlockExpansion; import com.github.sirblobman.combatlogx.api.expansion.skyblock.SkyBlockHandler; public final class IridiumSkyblockExpansion extends SkyBlockExpansion { private SkyBlockHandler skyBlockHandler; public IridiumSkyblockExpansion(ICombatLogX plugin) { super(plugin); this.skyBlockHandler = null; } @Override public boolean checkDependencies() { return checkDependency("IridiumSkyblock", true, "4"); } @Override public @NotNull SkyBlockHandler getSkyBlockHandler() { if (this.skyBlockHandler == null) { this.skyBlockHandler = new SkyBlockHandlerIridium(this); } return this.skyBlockHandler; } } ================================================ FILE: expansion/compatibility/IridiumSkyblock/src/main/java/combatlogx/expansion/compatibility/iridium/skyblock/IslandWrapperIridium.java ================================================ package combatlogx.expansion.compatibility.iridium.skyblock; import java.util.Collections; import java.util.HashSet; import java.util.List; import java.util.Set; import java.util.UUID; import org.jetbrains.annotations.NotNull; import com.github.sirblobman.combatlogx.api.expansion.skyblock.IslandWrapper; import com.iridium.iridiumskyblock.IridiumSkyblock; import com.iridium.iridiumskyblock.database.Island; import com.iridium.iridiumskyblock.database.User; import com.iridium.iridiumskyblock.managers.IslandManager; public class IslandWrapperIridium extends IslandWrapper { private Island island; public IslandWrapperIridium(@NotNull Island island) { this.island = island; } private @NotNull Island getIsland() { return this.island; } @Override public @NotNull Set getMembers() { Island island = getIsland(); IslandManager islandManager = getIslandManager(); List userList = islandManager.getMembersOnIsland(island); Set memberSet = new HashSet<>(); for (User user : userList) { UUID userId = user.getUuid(); memberSet.add(userId); } return Collections.unmodifiableSet(memberSet); } private @NotNull IridiumSkyblock getSkyBlock() { return IridiumSkyblock.getInstance(); } private @NotNull IslandManager getIslandManager() { IridiumSkyblock iridiumSkyblock = getSkyBlock(); return iridiumSkyblock.getIslandManager(); } } ================================================ FILE: expansion/compatibility/IridiumSkyblock/src/main/java/combatlogx/expansion/compatibility/iridium/skyblock/SkyBlockHandlerIridium.java ================================================ package combatlogx.expansion.compatibility.iridium.skyblock; import java.util.Optional; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import org.bukkit.Location; import org.bukkit.OfflinePlayer; import com.github.sirblobman.combatlogx.api.expansion.skyblock.IslandWrapper; import com.github.sirblobman.combatlogx.api.expansion.skyblock.SkyBlockHandler; import com.iridium.iridiumskyblock.IridiumSkyblock; import com.iridium.iridiumskyblock.database.Island; import com.iridium.iridiumskyblock.database.User; import com.iridium.iridiumskyblock.managers.IslandManager; import com.iridium.iridiumskyblock.managers.UserManager; public final class SkyBlockHandlerIridium extends SkyBlockHandler { public SkyBlockHandlerIridium(@NotNull IridiumSkyblockExpansion expansion) { super(expansion); } @Override public @Nullable IslandWrapper getIsland(@NotNull Location location) { IslandManager islandManager = getIslandManager(); Optional optionalIsland = islandManager.getTeamViaLocation(location); if (optionalIsland.isPresent()) { Island island = optionalIsland.get(); return wrap(island); } return null; } @Override public @Nullable IslandWrapper getIsland(@NotNull OfflinePlayer player) { User user = getUser(player); Optional optionalIsland = user.getIsland(); if (optionalIsland.isPresent()) { Island island = optionalIsland.get(); return wrap(island); } return null; } @Override public boolean doesIslandMatch(@NotNull OfflinePlayer player1, @NotNull OfflinePlayer player2) { User user1 = getUser(player1); User user2 = getUser(player2); Optional optionalIsland1 = user1.getIsland(); Optional optionalIsland2 = user2.getIsland(); if (!optionalIsland1.isPresent() || !optionalIsland2.isPresent()) { return false; } Island island1 = optionalIsland1.get(); Island island2 = optionalIsland2.get(); int islandId1 = island1.getId(); int islandId2 = island2.getId(); return (islandId1 == islandId2); } private @NotNull IridiumSkyblock getAPI() { return IridiumSkyblock.getInstance(); } private @NotNull IslandManager getIslandManager() { IridiumSkyblock api = getAPI(); return api.getIslandManager(); } private @NotNull UserManager getUserManager() { IridiumSkyblock api = getAPI(); return api.getUserManager(); } private @NotNull User getUser(@NotNull OfflinePlayer player) { UserManager userManager = getUserManager(); return userManager.getUser(player); } private @NotNull IslandWrapper wrap(@NotNull Island island) { return new IslandWrapperIridium(island); } } ================================================ FILE: expansion/compatibility/IridiumSkyblock/src/main/resources/expansion.yml ================================================ name: "${expansionName}" prefix: "${expansionPrefix}" description: "${expansionDescription}" main: "combatlogx.expansion.compatibility.iridium.skyblock.IridiumSkyblockExpansion" version: "17.2" author: "SirBlobman" plugin-depend: - "IridiumSkyblock" ================================================ FILE: expansion/compatibility/KingdomsX/build.gradle.kts ================================================ dependencies { compileOnly("com.github.cryptomorin:kingdoms:1.16.20.5") } ================================================ FILE: expansion/compatibility/KingdomsX/gradle.properties ================================================ expansion.name=CompatKingdomsX expansion.prefix=KingdomsX Compatibility ================================================ FILE: expansion/compatibility/KingdomsX/src/main/java/combatlogx/expansion/compatibility/region/kingdomsx/ExpansionKingdomsX.java ================================================ package combatlogx.expansion.compatibility.region.kingdomsx; import org.jetbrains.annotations.NotNull; import com.github.sirblobman.combatlogx.api.ICombatLogX; import com.github.sirblobman.combatlogx.api.expansion.region.RegionExpansion; import com.github.sirblobman.combatlogx.api.expansion.region.RegionHandler; public final class ExpansionKingdomsX extends RegionExpansion { private RegionHandler regionHandler; public ExpansionKingdomsX(@NotNull ICombatLogX plugin) { super(plugin); this.regionHandler = null; } @Override public boolean checkDependencies() { return checkDependency("Kingdoms", true, "1."); } @Override public @NotNull RegionHandler getRegionHandler() { if (this.regionHandler == null) { this.regionHandler = new RegionHandlerKingdomsX(this); } return this.regionHandler; } } ================================================ FILE: expansion/compatibility/KingdomsX/src/main/java/combatlogx/expansion/compatibility/region/kingdomsx/RegionHandlerKingdomsX.java ================================================ package combatlogx.expansion.compatibility.region.kingdomsx; import java.util.Set; import java.util.UUID; import org.jetbrains.annotations.NotNull; import org.bukkit.Location; import org.bukkit.entity.Player; import com.github.sirblobman.combatlogx.api.expansion.region.RegionHandler; import com.github.sirblobman.combatlogx.api.object.TagInformation; import com.github.sirblobman.combatlogx.api.object.TagType; import org.kingdoms.constants.group.Kingdom; import org.kingdoms.constants.land.Land; public final class RegionHandlerKingdomsX extends RegionHandler { public RegionHandlerKingdomsX(@NotNull ExpansionKingdomsX expansion) { super(expansion); } @Override public @NotNull String getEntryDeniedMessagePath(@NotNull TagType tagType) { return "expansion.region-protection.kingdomsx-no-entry"; } @Override public boolean isSafeZone(@NotNull Player player, @NotNull Location location, @NotNull TagInformation tag) { TagType tagType = tag.getCurrentTagType(); if (tagType != TagType.PLAYER) { return false; } Land land = Land.getLand(location); if (land == null || !land.isClaimed() || land.isBeingInvaded()) { return false; } Kingdom kingdom = land.getKingdom(); if (kingdom == null) { return false; } UUID playerId = player.getUniqueId(); Set memberSet = kingdom.getMembers(); return !memberSet.contains(playerId); } } ================================================ FILE: expansion/compatibility/KingdomsX/src/main/resources/expansion.yml ================================================ name: "${expansionName}" prefix: "${expansionPrefix}" description: "${expansionDescription}" main: "combatlogx.expansion.compatibility.region.kingdomsx.ExpansionKingdomsX" version: "17.1" author: "SirBlobman" plugin-depend: - "Kingdoms" ================================================ FILE: expansion/compatibility/Konquest/build.gradle.kts ================================================ dependencies { compileOnly("com.github.rumsfield:Konquest:1.9.0") } ================================================ FILE: expansion/compatibility/Konquest/gradle.properties ================================================ expansion.name=CompatKonquest expansion.prefix=Konquest Compatibility ================================================ FILE: expansion/compatibility/Konquest/src/main/java/combatlogx/expansion/compatibility/region/konquest/KonquestExpansion.java ================================================ package combatlogx.expansion.compatibility.region.konquest; import org.jetbrains.annotations.NotNull; import com.github.sirblobman.combatlogx.api.ICombatLogX; import com.github.sirblobman.combatlogx.api.expansion.region.RegionExpansion; import com.github.sirblobman.combatlogx.api.expansion.region.RegionHandler; public final class KonquestExpansion extends RegionExpansion { private RegionHandler regionHandler; public KonquestExpansion(@NotNull ICombatLogX plugin) { super(plugin); this.regionHandler = null; } @Override public boolean checkDependencies() { return checkDependency("Konquest", true, "1"); } @Override public @NotNull RegionHandler getRegionHandler() { if (this.regionHandler == null) { this.regionHandler = new RegionHandlerKonquest(this); } return this.regionHandler; } } ================================================ FILE: expansion/compatibility/Konquest/src/main/java/combatlogx/expansion/compatibility/region/konquest/RegionHandlerKonquest.java ================================================ package combatlogx.expansion.compatibility.region.konquest; import org.jetbrains.annotations.NotNull; import org.bukkit.Location; import org.bukkit.entity.Player; import com.github.sirblobman.combatlogx.api.expansion.region.RegionHandler; import com.github.sirblobman.combatlogx.api.object.TagInformation; import com.github.sirblobman.combatlogx.api.object.TagType; import com.github.rumsfield.konquest.Konquest; import com.github.rumsfield.konquest.api.KonquestAPI; import com.github.rumsfield.konquest.api.manager.KonquestTerritoryManager; import com.github.rumsfield.konquest.api.model.KonquestKingdom; import com.github.rumsfield.konquest.api.model.KonquestTerritory; public class RegionHandlerKonquest extends RegionHandler { public RegionHandlerKonquest(@NotNull KonquestExpansion expansion) { super(expansion); } @Override public @NotNull String getEntryDeniedMessagePath(@NotNull TagType tagType) { return "expansion.region-protection.konquest-no-entry"; } @Override public boolean isSafeZone(@NotNull Player player, @NotNull Location location, @NotNull TagInformation tag) { KonquestAPI api = getAPI(); KonquestTerritoryManager territoryManager = api.getTerritoryManager(); KonquestTerritory territory = territoryManager.getChunkTerritory(location); if (territory == null) { return false; } KonquestKingdom kingdom = territory.getKingdom(); return (kingdom != null); } private @NotNull KonquestAPI getAPI() { return Konquest.getInstance(); } } ================================================ FILE: expansion/compatibility/Konquest/src/main/resources/expansion.yml ================================================ name: "${expansionName}" prefix: "${expansionPrefix}" description: "${expansionDescription}" main: "combatlogx.expansion.compatibility.region.konquest.KonquestExpansion" version: "17.5" author: "SirBlobman" plugin-depend: - "Konquest" ================================================ FILE: expansion/compatibility/Lands/build.gradle.kts ================================================ repositories { maven("https://nexus.sirblobman.xyz/proxy-public") } dependencies { compileOnly(project(":expansion:newbie-helper")) compileOnly("com.github.angeschossen:LandsAPI:7.15.4") } ================================================ FILE: expansion/compatibility/Lands/gradle.properties ================================================ expansion.name=CompatLands expansion.prefix=Lands Compatibility ================================================ FILE: expansion/compatibility/Lands/src/main/java/combatlogx/expansion/compatibility/region/lands/LandsConfiguration.java ================================================ package combatlogx.expansion.compatibility.region.lands; import org.jetbrains.annotations.NotNull; import org.bukkit.configuration.ConfigurationSection; import com.github.sirblobman.api.configuration.IConfigurable; public final class LandsConfiguration implements IConfigurable { private boolean preventAllLandEntries; public LandsConfiguration() { this.preventAllLandEntries = false; } @Override public void load(@NotNull ConfigurationSection section) { setPreventAllLandEntries(section.getBoolean("prevent-all-land-entries", false)); } public boolean isPreventAllLandEntries() { return this.preventAllLandEntries; } public void setPreventAllLandEntries(boolean preventAllLandEntries) { this.preventAllLandEntries = preventAllLandEntries; } } ================================================ FILE: expansion/compatibility/Lands/src/main/java/combatlogx/expansion/compatibility/region/lands/LandsExpansion.java ================================================ package combatlogx.expansion.compatibility.region.lands; import com.github.sirblobman.api.configuration.ConfigurationManager; import com.github.sirblobman.combatlogx.api.ICombatLogX; import com.github.sirblobman.combatlogx.api.expansion.Expansion; import com.github.sirblobman.combatlogx.api.expansion.ExpansionManager; import com.github.sirblobman.combatlogx.api.expansion.region.RegionExpansion; import com.github.sirblobman.combatlogx.api.expansion.region.RegionHandler; import combatlogx.expansion.compatibility.region.lands.listener.ListenerLands; import org.jetbrains.annotations.NotNull; import java.util.Optional; public final class LandsExpansion extends RegionExpansion { private final LandsConfiguration configuration; private RegionHandler regionHandler; public LandsExpansion(@NotNull ICombatLogX plugin) { super(plugin); this.configuration = new LandsConfiguration(); this.regionHandler = null; } @Override public boolean checkDependencies() { return checkDependency("Lands", true, "7"); } @Override public void onLoad() { super.onLoad(); ConfigurationManager configurationManager = getConfigurationManager(); configurationManager.saveDefault("lands.yml"); } @Override public void afterEnable() { ICombatLogX plugin = getPlugin(); ExpansionManager expansionManager = plugin.getExpansionManager(); Optional optionalNewbieHelper = expansionManager.getExpansion("NewbieHelper"); if (optionalNewbieHelper.isPresent()) { new ListenerLands(this).register(); } } @Override public @NotNull RegionHandler getRegionHandler() { if (this.regionHandler == null) { this.regionHandler = new RegionHandlerLands(this); } return this.regionHandler; } @Override public void reloadConfig() { super.reloadConfig(); ConfigurationManager configurationManager = getConfigurationManager(); configurationManager.reload("lands.yml"); getLandsConfiguration().load(configurationManager.get("lands.yml")); } public @NotNull LandsConfiguration getLandsConfiguration() { return this.configuration; } } ================================================ FILE: expansion/compatibility/Lands/src/main/java/combatlogx/expansion/compatibility/region/lands/RegionHandlerLands.java ================================================ package combatlogx.expansion.compatibility.region.lands; import java.util.UUID; import me.angeschossen.lands.api.player.LandPlayer; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import org.bukkit.Location; import org.bukkit.entity.Animals; import org.bukkit.entity.Entity; import org.bukkit.entity.Monster; import org.bukkit.entity.Player; import org.bukkit.plugin.java.JavaPlugin; import com.github.sirblobman.combatlogx.api.ICombatLogX; import com.github.sirblobman.combatlogx.api.expansion.region.RegionHandler; import com.github.sirblobman.combatlogx.api.object.TagInformation; import com.github.sirblobman.combatlogx.api.object.TagType; import me.angeschossen.lands.api.LandsIntegration; import me.angeschossen.lands.api.flags.type.Flags; import me.angeschossen.lands.api.flags.type.RoleFlag; import me.angeschossen.lands.api.land.Area; public final class RegionHandlerLands extends RegionHandler { private LandsIntegration landsIntegration; public RegionHandlerLands(@NotNull LandsExpansion expansion) { super(expansion); this.landsIntegration = null; } @Override public @NotNull String getEntryDeniedMessagePath(@NotNull TagType tagType) { return "expansion.region-protection.lands.no-entry"; } @Override public boolean isSafeZone(@NotNull Player player, @NotNull Location location, @NotNull TagInformation tag) { Area area = getArea(location); if (area == null) { return false; } LandsConfiguration landsConfiguration = getExpansion().getLandsConfiguration(); if (landsConfiguration.isPreventAllLandEntries()) { return true; } Entity enemy = tag.getCurrentEnemy(); if (enemy instanceof Player) { // if target is player, check for attack flag and wars. this makes sure that BOTH players are allowed to fight, not just the attacker, since attackers can only attack players that are allowed to fight back LandPlayer attacker = landsIntegration.getLandPlayer(player.getUniqueId()), target = landsIntegration.getLandPlayer(enemy.getUniqueId()); return !area.canPvP(attacker, target, false) // if one of them can't fight, consider as safe zone, since it results in both of them not being able to fight in area || area.canEnter(attacker, false) != area.canEnter(target, false); // if both of them can't enter: ignore, their entry will be denied by Lands anyway. Otherwise, make sure both of them can enter } TagType tagType = tag.getCurrentTagType(); RoleFlag roleFlag = getRoleFlag(tagType, enemy); if (roleFlag == null) { return false; } UUID playerId = player.getUniqueId(); if (tagType == TagType.DAMAGE) { return area.hasRoleFlag(playerId, roleFlag); } else { return !area.hasRoleFlag(playerId, roleFlag); } } private @NotNull LandsIntegration getLandsIntegration() { if (this.landsIntegration == null) { LandsExpansion expansion = getExpansion(); ICombatLogX plugin = expansion.getPlugin(); JavaPlugin javaPlugin = plugin.getPlugin(); this.landsIntegration = LandsIntegration.of(javaPlugin); } return this.landsIntegration; } private @Nullable Area getArea(@NotNull Location location) { LandsIntegration lands = getLandsIntegration(); return lands.getArea(location); } private @Nullable RoleFlag getRoleFlag(@NotNull TagType tagType, @Nullable Entity enemy) { return switch (tagType) { case MOB, PLAYER, MYTHIC_MOB -> getRoleFlag(enemy); case DAMAGE -> Flags.NO_DAMAGE; default -> null; }; } private @Nullable RoleFlag getRoleFlag(@Nullable Entity enemy) { if (enemy instanceof Player) { return Flags.ATTACK_PLAYER; } if (enemy instanceof Animals) { return Flags.ATTACK_ANIMAL; } if (enemy instanceof Monster) { return Flags.ATTACK_MONSTER; } return null; } } ================================================ FILE: expansion/compatibility/Lands/src/main/java/combatlogx/expansion/compatibility/region/lands/listener/ListenerLands.java ================================================ package combatlogx.expansion.compatibility.region.lands.listener; import java.util.Collection; import java.util.Optional; import org.jetbrains.annotations.NotNull; import org.bukkit.entity.Player; import org.bukkit.event.EventHandler; import org.bukkit.event.EventPriority; import com.github.sirblobman.api.language.LanguageManager; import com.github.sirblobman.combatlogx.api.ICombatLogX; import com.github.sirblobman.combatlogx.api.expansion.Expansion; import com.github.sirblobman.combatlogx.api.expansion.ExpansionListener; import com.github.sirblobman.combatlogx.api.expansion.ExpansionManager; import combatlogx.expansion.compatibility.region.lands.LandsExpansion; import combatlogx.expansion.newbie.helper.NewbieHelperExpansion; import combatlogx.expansion.newbie.helper.manager.PVPManager; import combatlogx.expansion.newbie.helper.manager.ProtectionManager; import me.angeschossen.lands.api.events.war.WarDeclareEvent; import me.angeschossen.lands.api.memberholder.MemberHolder; public final class ListenerLands extends ExpansionListener { public ListenerLands(LandsExpansion expansion) { super(expansion); } @EventHandler(priority = EventPriority.NORMAL, ignoreCancelled = true) public void onWarDeclare(WarDeclareEvent e) { MemberHolder attacker = e.getAttacker(); disableNewbieProtection(attacker); MemberHolder defender = e.getDefender(); disableNewbieProtection(defender); } private void disableNewbieProtection(MemberHolder memberHolder) { Collection onlinePlayerCollection = memberHolder.getOnlinePlayers(); for (Player player : onlinePlayerCollection) { disableNewbieProtection(player); } } private void disableNewbieProtection(Player player) { NewbieHelperExpansion newbieHelperExpansion = getNewbieHelperExpansion(); ProtectionManager protectionManager = newbieHelperExpansion.getProtectionManager(); PVPManager pvpManager = newbieHelperExpansion.getPVPManager(); if (protectionManager.isProtected(player) || pvpManager.isDisabled(player)) { protectionManager.setProtected(player, false); pvpManager.setPVP(player, true); String path = ("expansion.region-protection.lands.war-disable-newbie-protection"); LanguageManager languageManager = getLanguageManager(); languageManager.sendMessageWithPrefix(player, path); } } private @NotNull NewbieHelperExpansion getNewbieHelperExpansion() { ICombatLogX combatLogX = getCombatLogX(); ExpansionManager expansionManager = combatLogX.getExpansionManager(); Optional optionalExpansion = expansionManager.getExpansion("NewbieHelper"); if (optionalExpansion.isEmpty()) { throw new IllegalArgumentException("NewbieHelper expansion is missing."); } Expansion expansion = optionalExpansion.get(); if (!(expansion instanceof NewbieHelperExpansion)) { throw new IllegalArgumentException("NewbieHelper expansion is not a proper instance."); } return (NewbieHelperExpansion) expansion; } } ================================================ FILE: expansion/compatibility/Lands/src/main/resources/expansion.yml ================================================ name: "${expansionName}" prefix: "${expansionPrefix}" description: "${expansionDescription}" main: "combatlogx.expansion.compatibility.region.lands.LandsExpansion" version: "17.6" author: "SirBlobman" plugin-depend: - "Lands" expansion-soft-depend: - "NewbieHelper" ================================================ FILE: expansion/compatibility/Lands/src/main/resources/lands.yml ================================================ # This option will prevent entry to ANY lands location owned by the player, regardless of PVP status # Default: false prevent-all-land-entries: false ================================================ FILE: expansion/compatibility/LibsDisguises/build.gradle.kts ================================================ repositories { maven("https://nexus.sirblobman.xyz/proxy-public") } dependencies { compileOnly("me.libraryaddict.disguises:libsdisguises:11.0.13-SNAPSHOT") } ================================================ FILE: expansion/compatibility/LibsDisguises/gradle.properties ================================================ expansion.name=CompatLibsDisguises expansion.prefix=LibsDisguises Compatibility ================================================ FILE: expansion/compatibility/LibsDisguises/src/main/java/combatlogx/expansion/compatibility/libsdisguises/DisguiseHandlerLibsDisguises.java ================================================ package combatlogx.expansion.compatibility.libsdisguises; import org.jetbrains.annotations.NotNull; import org.bukkit.entity.Player; import com.github.sirblobman.combatlogx.api.expansion.disguise.DisguiseHandler; import me.libraryaddict.disguise.DisguiseAPI; public class DisguiseHandlerLibsDisguises extends DisguiseHandler { public DisguiseHandlerLibsDisguises(@NotNull LibsDisguisesExpansion expansion) { super(expansion); } @Override public boolean hasDisguise(@NotNull Player player) { return DisguiseAPI.isDisguised(player); } @Override public void removeDisguise(@NotNull Player player) { DisguiseAPI.undisguiseToAll(player); } } ================================================ FILE: expansion/compatibility/LibsDisguises/src/main/java/combatlogx/expansion/compatibility/libsdisguises/LibsDisguisesExpansion.java ================================================ package combatlogx.expansion.compatibility.libsdisguises; import org.jetbrains.annotations.NotNull; import com.github.sirblobman.combatlogx.api.ICombatLogX; import com.github.sirblobman.combatlogx.api.expansion.disguise.DisguiseExpansion; import com.github.sirblobman.combatlogx.api.expansion.disguise.DisguiseHandler; public final class LibsDisguisesExpansion extends DisguiseExpansion { private DisguiseHandler disguiseHandler; public LibsDisguisesExpansion(@NotNull ICombatLogX plugin) { super(plugin); this.disguiseHandler = null; } @Override public boolean checkDependencies() { return checkDependency("LibsDisguises", true, "11"); } @Override public @NotNull DisguiseHandler getDisguiseHandler() { if (this.disguiseHandler == null) { this.disguiseHandler = new DisguiseHandlerLibsDisguises(this); } return this.disguiseHandler; } } ================================================ FILE: expansion/compatibility/LibsDisguises/src/main/resources/expansion.yml ================================================ name: "${expansionName}" prefix: "${expansionPrefix}" description: "${expansionDescription}" main: "combatlogx.expansion.compatibility.libsdisguises.LibsDisguisesExpansion" version: "17.2" author: "SirBlobman" plugin-depend: - "LibsDisguises" ================================================ FILE: expansion/compatibility/LuckPerms/README.MD ================================================ # LuckPerms Compatibility Expansion This expansion adds custom contexts to LuckPerms. ## Contexts | Name | Type | Description | |-----------------------------|---------|--------------------------------------------------| | combatlogx-in-combat | boolean | true if the player is in combat. | | newbie-helper-pvp-protected | boolean | true if the player is protected as a new player. | | newbie-helper-pvp-status | boolean | true if the player has pvp enabled. | ================================================ FILE: expansion/compatibility/LuckPerms/build.gradle.kts ================================================ dependencies { compileOnly("net.luckperms:api:5.5"); compileOnly(project(":expansion:newbie-helper")) } ================================================ FILE: expansion/compatibility/LuckPerms/gradle.properties ================================================ expansion.name=CompatLuckPerms expansion.prefix=LuckPerms Compatibility ================================================ FILE: expansion/compatibility/LuckPerms/src/main/java/combatlogx/expansion/compatibility/luckperms/LuckPermsExpansion.java ================================================ package combatlogx.expansion.compatibility.luckperms; import com.github.sirblobman.combatlogx.api.ICombatLogX; import com.github.sirblobman.combatlogx.api.expansion.Expansion; import combatlogx.expansion.compatibility.luckperms.context.ContextInCombat; import combatlogx.expansion.compatibility.luckperms.hook.HookNewbieHelper; public final class LuckPermsExpansion extends Expansion { public LuckPermsExpansion(ICombatLogX plugin) { super(plugin); } @Override public void onLoad() { // Do Nothing } @Override public void onEnable() { if (!checkDependency("LuckPerms", true, "5.5")) { selfDisable(); return; } registerContexts(); } @Override public void onDisable() { // Do Nothing } @Override public void reloadConfig() { // Do Nothing } private void registerContexts() { new ContextInCombat(this).register(); HookNewbieHelper.registerContexts(this); } } ================================================ FILE: expansion/compatibility/LuckPerms/src/main/java/combatlogx/expansion/compatibility/luckperms/context/AbstractContext.java ================================================ package combatlogx.expansion.compatibility.luckperms.context; import com.github.sirblobman.api.utility.Validate; import com.github.sirblobman.combatlogx.api.ICombatLogX; import combatlogx.expansion.compatibility.luckperms.LuckPermsExpansion; import net.luckperms.api.LuckPerms; import net.luckperms.api.LuckPermsProvider; import net.luckperms.api.context.ContextCalculator; import net.luckperms.api.context.ContextManager; public abstract class AbstractContext implements ContextCalculator { private final LuckPermsExpansion expansion; public AbstractContext(LuckPermsExpansion expansion) { this.expansion = Validate.notNull(expansion, "expansion must not be null!"); } protected final LuckPermsExpansion getExpansion() { return this.expansion; } protected final ICombatLogX getCombatLogX() { LuckPermsExpansion expansion = getExpansion(); return expansion.getPlugin(); } public final void register() { LuckPerms luckPerms = LuckPermsProvider.get(); ContextManager contextManager = luckPerms.getContextManager(); contextManager.registerCalculator(this); } } ================================================ FILE: expansion/compatibility/LuckPerms/src/main/java/combatlogx/expansion/compatibility/luckperms/context/ContextInCombat.java ================================================ package combatlogx.expansion.compatibility.luckperms.context; import org.jetbrains.annotations.NotNull; import org.bukkit.entity.Player; import com.github.sirblobman.combatlogx.api.ICombatLogX; import com.github.sirblobman.combatlogx.api.manager.ICombatManager; import combatlogx.expansion.compatibility.luckperms.LuckPermsExpansion; import net.luckperms.api.context.ContextConsumer; public final class ContextInCombat extends AbstractContext { public ContextInCombat(LuckPermsExpansion expansion) { super(expansion); } @Override public void calculate(@NotNull Player target, ContextConsumer consumer) { ICombatLogX combatLogX = getCombatLogX(); ICombatManager combatManager = combatLogX.getCombatManager(); boolean combat = combatManager.isInCombat(target); consumer.accept("combatlogx-in-combat", Boolean.toString(combat)); } } ================================================ FILE: expansion/compatibility/LuckPerms/src/main/java/combatlogx/expansion/compatibility/luckperms/context/ContextNewbieHelperProtected.java ================================================ package combatlogx.expansion.compatibility.luckperms.context; import org.jetbrains.annotations.NotNull; import org.bukkit.entity.Player; import com.github.sirblobman.api.utility.Validate; import combatlogx.expansion.compatibility.luckperms.LuckPermsExpansion; import combatlogx.expansion.newbie.helper.NewbieHelperExpansion; import combatlogx.expansion.newbie.helper.manager.ProtectionManager; import net.luckperms.api.context.ContextConsumer; public final class ContextNewbieHelperProtected extends AbstractContext { private final NewbieHelperExpansion newbieHelper; public ContextNewbieHelperProtected(LuckPermsExpansion expansion, NewbieHelperExpansion newbieHelper) { super(expansion); this.newbieHelper = Validate.notNull(newbieHelper, "newbieHelper must not be null!"); } private NewbieHelperExpansion getNewbieHelper() { return this.newbieHelper; } @Override public void calculate(@NotNull Player target, ContextConsumer consumer) { NewbieHelperExpansion newbieHelper = getNewbieHelper(); ProtectionManager protectionManager = newbieHelper.getProtectionManager(); boolean isProtected = protectionManager.isProtected(target); consumer.accept("newbie-helper-pvp-protected", Boolean.toString(isProtected)); } } ================================================ FILE: expansion/compatibility/LuckPerms/src/main/java/combatlogx/expansion/compatibility/luckperms/context/ContextNewbieHelperPvpStatus.java ================================================ package combatlogx.expansion.compatibility.luckperms.context; import org.jetbrains.annotations.NotNull; import org.bukkit.entity.Player; import com.github.sirblobman.api.utility.Validate; import combatlogx.expansion.compatibility.luckperms.LuckPermsExpansion; import combatlogx.expansion.newbie.helper.NewbieHelperExpansion; import combatlogx.expansion.newbie.helper.manager.PVPManager; import net.luckperms.api.context.ContextConsumer; public final class ContextNewbieHelperPvpStatus extends AbstractContext { private final NewbieHelperExpansion newbieHelper; public ContextNewbieHelperPvpStatus(LuckPermsExpansion expansion, NewbieHelperExpansion newbieHelper) { super(expansion); this.newbieHelper = Validate.notNull(newbieHelper, "newbieHelper must not be null!"); } private NewbieHelperExpansion getNewbieHelper() { return this.newbieHelper; } @Override public void calculate(@NotNull Player target, ContextConsumer consumer) { NewbieHelperExpansion newbieHelper = getNewbieHelper(); PVPManager pvpManager = newbieHelper.getPVPManager(); boolean status = !pvpManager.isDisabled(target); consumer.accept("newbie-helper-pvp-status", Boolean.toString(status)); } } ================================================ FILE: expansion/compatibility/LuckPerms/src/main/java/combatlogx/expansion/compatibility/luckperms/hook/HookNewbieHelper.java ================================================ package combatlogx.expansion.compatibility.luckperms.hook; import java.util.Optional; import com.github.sirblobman.combatlogx.api.ICombatLogX; import com.github.sirblobman.combatlogx.api.expansion.Expansion; import com.github.sirblobman.combatlogx.api.expansion.ExpansionManager; import combatlogx.expansion.compatibility.luckperms.LuckPermsExpansion; import combatlogx.expansion.compatibility.luckperms.context.ContextNewbieHelperProtected; import combatlogx.expansion.compatibility.luckperms.context.ContextNewbieHelperPvpStatus; import combatlogx.expansion.newbie.helper.NewbieHelperExpansion; public final class HookNewbieHelper { public static void registerContexts(LuckPermsExpansion instance) { ICombatLogX plugin = instance.getPlugin(); ExpansionManager expansionManager = plugin.getExpansionManager(); Optional optionalExpansion = expansionManager.getExpansion("NewbieHelper"); if (!optionalExpansion.isPresent()) { return; } Expansion expansion = optionalExpansion.get(); if (!(expansion instanceof NewbieHelperExpansion)) { return; } NewbieHelperExpansion newbieHelper = (NewbieHelperExpansion) expansion; new ContextNewbieHelperProtected(instance, newbieHelper).register(); new ContextNewbieHelperPvpStatus(instance, newbieHelper).register(); } } ================================================ FILE: expansion/compatibility/LuckPerms/src/main/resources/expansion.yml ================================================ name: "${expansionName}" prefix: "${expansionPrefix}" description: "${expansionDescription}" main: "combatlogx.expansion.compatibility.luckperms.LuckPermsExpansion" version: "17.2" author: "SirBlobman" plugin-depend: - "LuckPerms" expansion-soft-depend: - "NewbieHelper" ================================================ FILE: expansion/compatibility/MCPets/README.md ================================================ # CombatLogX Compatibility Expansion: MCPets ## Requirements - [MythicMobs](https://www.spigotmc.org/resources/5702/) - [MCPets](https://www.spigotmc.org/resources/97628/) ## Features - Prevent players from spawning pets during combat. - Triggers active pet to despawn when a player is tagged. ================================================ FILE: expansion/compatibility/MCPets/build.gradle.kts ================================================ dependencies { compileOnly("fr.nocsy:mcpets:4.1.4") } ================================================ FILE: expansion/compatibility/MCPets/gradle.properties ================================================ expansion.name=CompatMCPets expansion.prefix=MCPets Compatibility ================================================ FILE: expansion/compatibility/MCPets/src/main/java/combatlogx/expansion/compatibility/mcpets/ListenerMcPets.java ================================================ package combatlogx.expansion.compatibility.mcpets; import java.util.UUID; import org.jetbrains.annotations.NotNull; import org.bukkit.Bukkit; import org.bukkit.entity.Player; import org.bukkit.event.EventHandler; import org.bukkit.event.EventPriority; import com.github.sirblobman.combatlogx.api.event.PlayerTagEvent; import com.github.sirblobman.combatlogx.api.expansion.ExpansionListener; import fr.nocsy.mcpets.api.MCPetsAPI; import fr.nocsy.mcpets.data.Pet; import fr.nocsy.mcpets.data.PetDespawnReason; import fr.nocsy.mcpets.events.PetSpawnEvent; public final class ListenerMcPets extends ExpansionListener { public ListenerMcPets(@NotNull McPetsExpansion expansion) { super(expansion); } @EventHandler(priority = EventPriority.NORMAL, ignoreCancelled = true) public void onPetSpawn(PetSpawnEvent e) { Pet pet = e.getPet(); UUID ownerId = pet.getOwner(); Player owner = Bukkit.getPlayer(ownerId); if (owner == null || !isInCombat(owner)) { return; } e.setCancelled(true); } @EventHandler(priority = EventPriority.NORMAL, ignoreCancelled = true) public void onTag(PlayerTagEvent e) { Player player = e.getPlayer(); UUID playerId = player.getUniqueId(); Pet activePet = MCPetsAPI.getActivePet(playerId); if (activePet != null) { activePet.despawn(PetDespawnReason.DONT_HAVE_PERM); } } } ================================================ FILE: expansion/compatibility/MCPets/src/main/java/combatlogx/expansion/compatibility/mcpets/McPetsExpansion.java ================================================ package combatlogx.expansion.compatibility.mcpets; import org.jetbrains.annotations.NotNull; import com.github.sirblobman.combatlogx.api.ICombatLogX; import com.github.sirblobman.combatlogx.api.expansion.Expansion; public final class McPetsExpansion extends Expansion { public McPetsExpansion(@NotNull ICombatLogX plugin) { super(plugin); } @Override public void onLoad() { // Do Nothing } @Override public void onEnable() { if (!checkDependency("MCPets", true)) { selfDisable(); return; } new ListenerMcPets(this).register(); } @Override public void onDisable() { // Do Nothing } @Override public void reloadConfig() { // Do Nothing } } ================================================ FILE: expansion/compatibility/MCPets/src/main/resources/expansion.yml ================================================ name: "${expansionName}" prefix: "${expansionPrefix}" description: "${expansionDescription}" main: "combatlogx.expansion.compatibility.mcpets.McPetsExpansion" version: "17.1" author: "SirBlobman" plugin-depend: - "MCPets" ================================================ FILE: expansion/compatibility/MarriageMaster/build.gradle.kts ================================================ dependencies { compileOnly("at.pcgamingfreaks:MarriageMaster:2.7.9") } ================================================ FILE: expansion/compatibility/MarriageMaster/gradle.properties ================================================ expansion.name=CompatMarriageMaster expansion.prefix=MarriageMaster Compatibility ================================================ FILE: expansion/compatibility/MarriageMaster/src/main/java/combatlogx/expansion/compatibility/marriagemaster/MarriageMasterExpansion.java ================================================ package combatlogx.expansion.compatibility.marriagemaster; import org.jetbrains.annotations.NotNull; import com.github.sirblobman.combatlogx.api.ICombatLogX; import com.github.sirblobman.combatlogx.api.expansion.Expansion; import combatlogx.expansion.compatibility.marriagemaster.listener.ListenerMarriageMaster; public final class MarriageMasterExpansion extends Expansion { public MarriageMasterExpansion(@NotNull ICombatLogX plugin) { super(plugin); } @Override public void onLoad() { // Do Nothing } @Override public void onEnable() { if (!checkDependency("MarriageMaster", true)) { selfDisable(); return; } new ListenerMarriageMaster(this).register(); } @Override public void onDisable() { // Do Nothing } @Override public void reloadConfig() { // Do Nothing } } ================================================ FILE: expansion/compatibility/MarriageMaster/src/main/java/combatlogx/expansion/compatibility/marriagemaster/listener/ListenerMarriageMaster.java ================================================ package combatlogx.expansion.compatibility.marriagemaster.listener; import org.bukkit.entity.Player; import org.bukkit.event.EventHandler; import org.bukkit.event.EventPriority; import com.github.sirblobman.api.language.LanguageManager; import com.github.sirblobman.combatlogx.api.expansion.Expansion; import com.github.sirblobman.combatlogx.api.expansion.ExpansionListener; import at.pcgamingfreaks.MarriageMaster.Bukkit.API.Events.TPEvent; import at.pcgamingfreaks.MarriageMaster.Bukkit.API.Marriage; import at.pcgamingfreaks.MarriageMaster.Bukkit.API.MarriagePlayer; public final class ListenerMarriageMaster extends ExpansionListener { public ListenerMarriageMaster(Expansion expansion) { super(expansion); } @EventHandler(priority = EventPriority.NORMAL, ignoreCancelled = true) public void onTeleport(TPEvent e) { printDebug("Detected MarriageMaster TPEvent..."); MarriagePlayer teleporter = e.getPlayer(); Player bukkitTeleporter = teleporter.getPlayerOnline(); if (bukkitTeleporter == null) { printDebug("Teleporter is null, ignoring."); return; } printDebug("Checking partner...."); Marriage marriageData = e.getMarriageData(); MarriagePlayer partner = marriageData.getPartner(teleporter); LanguageManager languageManager = getLanguageManager(); if (partner != null) { Player bukkitPartner = partner.getPlayerOnline(); if (bukkitPartner != null && isInCombat(bukkitPartner)) { printDebug("Partner is in combat, preventing teleport."); e.setCancelled(true); String messagePath = ("expansion.marriagemaster-compatibility.prevent-teleport-partner"); languageManager.sendMessageWithPrefix(bukkitTeleporter, messagePath); return; } } printDebug("Partner was not in combat, checking teleporter..."); if (isInCombat(bukkitTeleporter)) { printDebug("Teleporter is in combat, preventing teleport."); e.setCancelled(true); String messagePath = ("expansion.marriagemaster-compatibility.prevent-teleport-self"); languageManager.sendMessageWithPrefix(bukkitTeleporter, messagePath); } } } ================================================ FILE: expansion/compatibility/MarriageMaster/src/main/resources/expansion.yml ================================================ name: "${expansionName}" prefix: "${expansionPrefix}" description: "${expansionDescription}" main: "combatlogx.expansion.compatibility.marriagemaster.MarriageMasterExpansion" version: "17.4" author: "SirBlobman" plugin-depend: - "MarriageMaster" ================================================ FILE: expansion/compatibility/MythicMobs/build.gradle.kts ================================================ repositories { maven("https://nexus.sirblobman.xyz/proxy-public") } dependencies { compileOnly("io.lumine:Mythic-Dist:5.8.2") } ================================================ FILE: expansion/compatibility/MythicMobs/gradle.properties ================================================ expansion.name=CompatMythicMobs expansion.prefix=MythicMobs Compatibility ================================================ FILE: expansion/compatibility/MythicMobs/src/main/java/combatlogx/expansion/compatibility/mythicmobs/ListenerMythicMobs.java ================================================ package combatlogx.expansion.compatibility.mythicmobs; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import org.bukkit.entity.Entity; import org.bukkit.entity.Player; import org.bukkit.event.EventHandler; import org.bukkit.event.EventPriority; import org.bukkit.event.entity.EntityDamageByEntityEvent; import com.github.sirblobman.combatlogx.api.event.PlayerPreTagEvent; import com.github.sirblobman.combatlogx.api.expansion.ExpansionListener; import com.github.sirblobman.combatlogx.api.manager.ICombatManager; import com.github.sirblobman.combatlogx.api.object.TagReason; import com.github.sirblobman.combatlogx.api.object.TagType; import io.lumine.mythic.api.adapters.AbstractEntity; import io.lumine.mythic.bukkit.BukkitAPIHelper; import io.lumine.mythic.bukkit.MythicBukkit; import io.lumine.mythic.core.mobs.ActiveMob; public final class ListenerMythicMobs extends ExpansionListener { private final MythicMobsExpansion expansion; public ListenerMythicMobs(MythicMobsExpansion expansion) { super(expansion); this.expansion = expansion; } @EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true) public void onDamage(EntityDamageByEntityEvent e) { Entity damaged = e.getEntity(); Entity damager = e.getDamager(); ICombatManager combatManager = getCombatManager(); if (damaged instanceof Player playerDamaged && isMythicMob(damager)) { damager = linkMainMythicMob(damager); String mobName = getMythicMobName(damager); if (mobName != null && isForceTag(mobName)) { combatManager.tag(playerDamaged, damager, TagType.MYTHIC_MOB, TagReason.ATTACKED); } } if (damager instanceof Player playerDamager && isMythicMob(damaged)) { damaged = linkMainMythicMob(damaged); String mobName = getMythicMobName(damaged); if (mobName != null && isForceTag(mobName)) { combatManager.tag(playerDamager, damaged, TagType.MYTHIC_MOB, TagReason.ATTACKER); } } } @EventHandler(priority = EventPriority.LOWEST, ignoreCancelled = true) public void beforeTag(PlayerPreTagEvent e) { TagType tagType = e.getTagType(); if (tagType != TagType.MYTHIC_MOB) { return; } Entity enemy = e.getEnemy(); if (enemy == null || !isMythicMob(enemy)) { return; } String mobName = getMythicMobName(enemy); if (mobName != null && isNoTag(mobName)) { e.setCancelled(true); } } private @NotNull BukkitAPIHelper getAPI() { MythicBukkit mythicBukkit = MythicBukkit.inst(); return mythicBukkit.getAPIHelper(); } private boolean isMythicMob(@NotNull Entity entity) { BukkitAPIHelper api = getAPI(); return api.isMythicMob(entity); } private @Nullable ActiveMob getActiveMob(@NotNull Entity entity) { BukkitAPIHelper api = getAPI(); return api.getMythicMobInstance(entity); } private @Nullable String getMythicMobName(@NotNull Entity entity) { if (isMythicMob(entity)) { ActiveMob activeMob = getActiveMob(entity); return (activeMob == null ? null : activeMob.getMobType()); } return null; } private @NotNull Entity linkMainMythicMob(@NotNull Entity original) { ActiveMob activeMob = getActiveMob(original); if (activeMob == null) { return original; } AbstractEntity entity = activeMob.getEntity(); if (entity == null) { return original; } return entity.getBukkitEntity(); } private @NotNull MythicMobsExpansion getMythicMobsExpansion() { return this.expansion; } private @NotNull MythicMobsConfiguration getConfiguration() { MythicMobsExpansion expansion = getMythicMobsExpansion(); return expansion.getConfiguration(); } private boolean isForceTag(@NotNull String mobName) { MythicMobsConfiguration configuration = getConfiguration(); return configuration.isForceTag(mobName); } private boolean isNoTag(@NotNull String mobName) { MythicMobsConfiguration configuration = getConfiguration(); return configuration.isNoTag(mobName); } } ================================================ FILE: expansion/compatibility/MythicMobs/src/main/java/combatlogx/expansion/compatibility/mythicmobs/MythicMobsConfiguration.java ================================================ package combatlogx.expansion.compatibility.mythicmobs; import java.util.Collection; import java.util.Collections; import java.util.HashSet; import java.util.Set; import org.jetbrains.annotations.NotNull; import org.bukkit.configuration.ConfigurationSection; import com.github.sirblobman.api.configuration.IConfigurable; public final class MythicMobsConfiguration implements IConfigurable { private final Set noTagTypeSet; private final Set forceTagTypeSet; public MythicMobsConfiguration() { this.noTagTypeSet = new HashSet<>(); this.forceTagTypeSet = new HashSet<>(); } @Override public void load(@NotNull ConfigurationSection config) { setNoTagTypes(config.getStringList("no-tag-mob-type-list")); setForceTagTypes(config.getStringList("force-tag-mob-type-list")); } public @NotNull Set getNoTagTypes() { return Collections.unmodifiableSet(this.noTagTypeSet); } public void setNoTagTypes(@NotNull Collection types) { this.noTagTypeSet.clear(); this.noTagTypeSet.addAll(types); } public @NotNull Set getForceTagTypes() { return Collections.unmodifiableSet(this.forceTagTypeSet); } public void setForceTagTypes(@NotNull Collection types) { this.forceTagTypeSet.clear(); this.forceTagTypeSet.addAll(types); } public boolean isForceTag(@NotNull String mobName) { Set typeSet = getForceTagTypes(); return typeSet.contains(mobName); } public boolean isNoTag(@NotNull String mobName) { Set typeSet = getNoTagTypes(); return typeSet.contains(mobName); } } ================================================ FILE: expansion/compatibility/MythicMobs/src/main/java/combatlogx/expansion/compatibility/mythicmobs/MythicMobsExpansion.java ================================================ package combatlogx.expansion.compatibility.mythicmobs; import org.jetbrains.annotations.NotNull; import com.github.sirblobman.api.configuration.ConfigurationManager; import com.github.sirblobman.combatlogx.api.ICombatLogX; import com.github.sirblobman.combatlogx.api.expansion.Expansion; public final class MythicMobsExpansion extends Expansion { private final MythicMobsConfiguration configuration; public MythicMobsExpansion(ICombatLogX plugin) { super(plugin); this.configuration = new MythicMobsConfiguration(); } @Override public void onLoad() { ConfigurationManager configurationManager = getConfigurationManager(); configurationManager.saveDefault("config.yml"); } @Override public void onEnable() { if (!checkDependency("MythicMobs", true, "5.8")) { selfDisable(); return; } reloadConfig(); new ListenerMythicMobs(this).register(); } @Override public void onDisable() { // Do Nothing } @Override public void reloadConfig() { ConfigurationManager configurationManager = getConfigurationManager(); configurationManager.reload("config.yml"); getConfiguration().load(configurationManager.get("config.yml")); } public @NotNull MythicMobsConfiguration getConfiguration() { return this.configuration; } } ================================================ FILE: expansion/compatibility/MythicMobs/src/main/resources/config.yml ================================================ # This uses the internal name of the MythicMob # Add mobs to this list to prevent them from tagging players no-tag-mob-type-list: - "Example1" # This uses the internal name of the MythicMob # Add mobs to this list to force them to tag players. force-tag-mob-type-list: - "Example2" ================================================ FILE: expansion/compatibility/MythicMobs/src/main/resources/expansion.yml ================================================ name: "${expansionName}" prefix: "${expansionPrefix}" description: "${expansionDescription}" main: "combatlogx.expansion.compatibility.mythicmobs.MythicMobsExpansion" version: "17.6" author: "SirBlobman" plugin-depend: - "MythicMobs" ================================================ FILE: expansion/compatibility/PlaceholderAPI/README.MD ================================================ # CombatLogX Expansion: PlaceholderAPI Compatibility The PlaceholderAPI Compatibility expansion for CombatLogX adds placeholders to plugins that use PlaceholderAPI. ## Basic Placeholders These placeholders don't require anything special to be used. | PlaceholderAPI Placeholder | Description | |--------------------------------|---------------------------------------------------------------------------------------| | %combatlogx_enemy_count% | The amount of player/entity enemies the player has. | | %combatlogx_in_combat% | Configurable placeholder to show if the player is in combat or not. | | %combatlogx_player% | The name of the player. | | %combatlogx_punishment_count% | The amount of times the player has been punished for logging out during combat. | | %combatlogx_status% | Second configurable placeholder to show if the player is in combat or not. | | %combatlogx_tag_count% | The amount of combat tags the player has. | | %combatlogx_time_left% | The total amount of seconds the player has left in combat with all enemies. (Integer) | | %combatlogx_time_left_decimal% | The total amount of seconds the player has left in combat with all enemies. (Decimal) | ## Enemy Placeholders Players can have multiple enemies. These placeholders can have an index to view information about a specific enemy. Example: %combatlogx_time_left_1% to get the time left with the first enemy. | PlaceholderAPI Placeholder | Description | |------------------------------------------------------------|-------------------------------------------------------------------------------------------------------------| | %combatlogx_time_left_<index>% | Get the total amount of seconds left in combat with a specific enemy. (Integer) | | %combatlogx_time_left_decimal_<index>% | Get the total amount of seconds left in combat with a specific enemy. (Decimal) | | %combatlogx_current_enemy_<placeholder>% | Get a placeholder for the current enemy. If the player doesn't have an enemy, it will show N/A | | %combatlogx_specific_enemy_<index>_<placeholder>% | Get a placeholder for a specific enemy number. If a player doesn't have that many enemies, it will show N/A | | Enemy Placeholder | Description | Example | |------------------------|--------------------------------------------------------------------------------------------------|----------------------------------| | name | The name of the enemy. | SirBlobman | | type | The entity type of the enemy. | PLAYER | | display_name | The display name of the enemy. | &a&oBlobman | | health | The current health of the enemy. | 8.46 | | health_rounded | The current health of the enemy, but rounded. | 9 | | hearts | The current hearts of the enemy (Symbol) | ❤❤❤❤ | | hearts_count | The current hearts of the enemy (Integer) | 4 | | world | The name of the world that the enemy is in. | world_the_end | | x | The current x position of the enemy. | -257 | | y | The current y position of the enemy. | 11 | | z | The current z position of the enemy. | 500 | | <placeholderapi> | Any other valid PlaceholderAPI placeholder without the % symbols. Only works for player enemies. | <varies> | ## Newbie Helper Placeholders These placeholders require the `Newbie Helper` expansion. | Placeholder | Description | |-------------------------------------------------|-------------------------------------------------------------------------------| | %combatlogx_newbie_helper_pvp_status% | Shows if the player has pvp enabled or disabled via the `/togglepvp` command. | | %combatlogx_newbie_helper_protected% | Shows whether or not the player is protected. | | %combatlogx_newbie_helper_protection_time_left% | Shows the amount of protection time remaining on a player. | ================================================ FILE: expansion/compatibility/PlaceholderAPI/build.gradle.kts ================================================ repositories { maven("https://repo.helpch.at/releases/") } dependencies { compileOnly("me.clip:placeholderapi:2.11.6") } ================================================ FILE: expansion/compatibility/PlaceholderAPI/gradle.properties ================================================ expansion.name=CompatPlaceholderAPI expansion.prefix=PlaceholderAPI Compatibility ================================================ FILE: expansion/compatibility/PlaceholderAPI/src/main/java/combatlogx/expansion/compatibility/placeholderapi/HookPlaceholderAPI.java ================================================ package combatlogx.expansion.compatibility.placeholderapi; import java.util.Collections; import java.util.List; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import org.bukkit.entity.Entity; import org.bukkit.entity.Player; import org.bukkit.plugin.PluginDescriptionFile; import org.bukkit.plugin.java.JavaPlugin; import com.github.sirblobman.combatlogx.api.ICombatLogX; import com.github.sirblobman.combatlogx.api.expansion.ExpansionDescription; import com.github.sirblobman.combatlogx.api.manager.ICombatManager; import com.github.sirblobman.combatlogx.api.manager.IPlaceholderManager; import com.github.sirblobman.combatlogx.api.object.TagInformation; import me.clip.placeholderapi.expansion.PlaceholderExpansion; public final class HookPlaceholderAPI extends PlaceholderExpansion { private final PlaceholderAPIExpansion expansion; public HookPlaceholderAPI(@NotNull PlaceholderAPIExpansion expansion) { this.expansion = expansion; } @Override public boolean canRegister() { return true; } @Override public boolean persist() { return true; } @Override public @NotNull String getIdentifier() { PluginDescriptionFile descriptionFile = getDescriptionFile(); String pluginName = descriptionFile.getName(); return pluginName.toLowerCase(); } @Override public @NotNull String getAuthor() { PluginDescriptionFile descriptionFile = getDescriptionFile(); List authorList = descriptionFile.getAuthors(); return String.join(", ", authorList); } @Override public @NotNull String getVersion() { PlaceholderAPIExpansion expansion = getExpansion(); ExpansionDescription description = expansion.getDescription(); return description.getVersion(); } @Override public @Nullable String onPlaceholderRequest(@Nullable Player player, @NotNull String placeholder) { if (player == null) { return null; } ICombatLogX plugin = getCombatLogX(); IPlaceholderManager placeholderManager = plugin.getPlaceholderManager(); if (!placeholder.startsWith("newbie_helper_")) { placeholder = ("combatlogx_" + placeholder); } ICombatManager combatManager = plugin.getCombatManager(); TagInformation tagInformation = combatManager.getTagInformation(player); List enemyList = (tagInformation == null ? Collections.emptyList() : tagInformation.getEnemies()); return placeholderManager.getPlaceholderReplacement(player, enemyList, placeholder); } private @NotNull PlaceholderAPIExpansion getExpansion() { return this.expansion; } private @NotNull ICombatLogX getCombatLogX() { PlaceholderAPIExpansion expansion = getExpansion(); return expansion.getPlugin(); } private @NotNull PluginDescriptionFile getDescriptionFile() { ICombatLogX combatLogX = getCombatLogX(); JavaPlugin plugin = combatLogX.getPlugin(); return plugin.getDescription(); } } ================================================ FILE: expansion/compatibility/PlaceholderAPI/src/main/java/combatlogx/expansion/compatibility/placeholderapi/PlaceholderAPIExpansion.java ================================================ package combatlogx.expansion.compatibility.placeholderapi; import org.jetbrains.annotations.NotNull; import com.github.sirblobman.combatlogx.api.ICombatLogX; import com.github.sirblobman.combatlogx.api.expansion.Expansion; public final class PlaceholderAPIExpansion extends Expansion { public PlaceholderAPIExpansion(@NotNull ICombatLogX plugin) { super(plugin); } @Override public void onLoad() { // Do Nothing } @Override public void onEnable() { if (!checkDependency("PlaceholderAPI", true)) { selfDisable(); return; } new HookPlaceholderAPI(this).register(); } @Override public void onDisable() { // Do Nothing } @Override public void reloadConfig() { // Do Nothing } } ================================================ FILE: expansion/compatibility/PlaceholderAPI/src/main/resources/expansion.yml ================================================ name: "${expansionName}" prefix: "${expansionPrefix}" description: "${expansionDescription}" main: "combatlogx.expansion.compatibility.placeholderapi.PlaceholderAPIExpansion" version: "17.2" author: "SirBlobman" plugin-depend: - "PlaceholderAPI" ================================================ FILE: expansion/compatibility/PlayerParticles/build.gradle.kts ================================================ repositories { maven("https://repo.rosewooddev.io/repository/public-releases/") } dependencies { compileOnly("dev.esophose:playerparticles:8.9") } ================================================ FILE: expansion/compatibility/PlayerParticles/gradle.properties ================================================ expansion.name=CompatPlayerParticles expansion.prefix=PlayerParticles Compatibility ================================================ FILE: expansion/compatibility/PlayerParticles/src/main/java/combatlogx/expansion/compatibility/player/particles/ListenerPlayerParticles.java ================================================ package combatlogx.expansion.compatibility.player.particles; import org.jetbrains.annotations.NotNull; import org.bukkit.entity.Player; import org.bukkit.event.EventHandler; import org.bukkit.event.EventPriority; import com.github.sirblobman.combatlogx.api.event.PlayerTagEvent; import com.github.sirblobman.combatlogx.api.event.PlayerUntagEvent; import com.github.sirblobman.combatlogx.api.expansion.ExpansionListener; import dev.esophose.playerparticles.api.PlayerParticlesAPI; public final class ListenerPlayerParticles extends ExpansionListener { private PlayerParticlesExpansion expansion; public ListenerPlayerParticles(@NotNull PlayerParticlesExpansion expansion) { super(expansion); this.expansion = expansion; } @EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true) public void onTag(PlayerTagEvent e) { if (isTagDisablesParticles()) { Player player = e.getPlayer(); PlayerParticlesAPI api = PlayerParticlesAPI.getInstance(); api.togglePlayerParticleVisibility(player, true); } } @EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true) public void onUntag(PlayerUntagEvent e) { if (isUntagEnablesParticles()) { Player player = e.getPlayer(); PlayerParticlesAPI api = PlayerParticlesAPI.getInstance(); api.togglePlayerParticleVisibility(player, false); } } private @NotNull PlayerParticlesExpansion getPlayerParticlesExpansion() { return this.expansion; } private @NotNull PlayerParticlesConfiguration getConfiguration() { PlayerParticlesExpansion expansion = getPlayerParticlesExpansion(); return expansion.getConfiguration(); } private boolean isTagDisablesParticles() { PlayerParticlesConfiguration configuration = getConfiguration(); return configuration.isTagDisablesParticles(); } private boolean isUntagEnablesParticles() { PlayerParticlesConfiguration configuration = getConfiguration(); return configuration.isUntagEnablesParticles(); } } ================================================ FILE: expansion/compatibility/PlayerParticles/src/main/java/combatlogx/expansion/compatibility/player/particles/PlayerParticlesConfiguration.java ================================================ package combatlogx.expansion.compatibility.player.particles; import org.jetbrains.annotations.NotNull; import org.bukkit.configuration.ConfigurationSection; import com.github.sirblobman.api.configuration.IConfigurable; public final class PlayerParticlesConfiguration implements IConfigurable { private boolean tagDisablesParticles; private boolean untagEnablesParticles; public PlayerParticlesConfiguration() { this.tagDisablesParticles = true; this.untagEnablesParticles = false; } @Override public void load(@NotNull ConfigurationSection config) { setTagDisablesParticles(config.getBoolean("tag-disables-particles", true)); setUntagEnablesParticles(config.getBoolean("untag-enables-particles", false)); } public boolean isTagDisablesParticles() { return this.tagDisablesParticles; } public void setTagDisablesParticles(boolean tagDisablesParticles) { this.tagDisablesParticles = tagDisablesParticles; } public boolean isUntagEnablesParticles() { return this.untagEnablesParticles; } public void setUntagEnablesParticles(boolean untagEnablesParticles) { this.untagEnablesParticles = untagEnablesParticles; } } ================================================ FILE: expansion/compatibility/PlayerParticles/src/main/java/combatlogx/expansion/compatibility/player/particles/PlayerParticlesExpansion.java ================================================ package combatlogx.expansion.compatibility.player.particles; import org.jetbrains.annotations.NotNull; import com.github.sirblobman.api.configuration.ConfigurationManager; import com.github.sirblobman.combatlogx.api.ICombatLogX; import com.github.sirblobman.combatlogx.api.expansion.Expansion; public final class PlayerParticlesExpansion extends Expansion { private final PlayerParticlesConfiguration configuration; public PlayerParticlesExpansion(@NotNull ICombatLogX plugin) { super(plugin); this.configuration = new PlayerParticlesConfiguration(); } @Override public void onLoad() { ConfigurationManager configurationManager = getConfigurationManager(); configurationManager.saveDefault("config.yml"); } @Override public void onEnable() { if (!checkDependency("PlayerParticles", true, "8")) { selfDisable(); return; } new ListenerPlayerParticles(this).register(); } @Override public void reloadConfig() { ConfigurationManager configurationManager = getConfigurationManager(); configurationManager.reload("config.yml"); getConfiguration().load(configurationManager.get("config.yml")); } @Override public void onDisable() { // Do Nothing } public @NotNull PlayerParticlesConfiguration getConfiguration() { return this.configuration; } } ================================================ FILE: expansion/compatibility/PlayerParticles/src/main/resources/config.yml ================================================ # Should CombatLogX disable player particles when a player is tagged? tag-disables-particles: true # Should CombatLogX enable player particles once combat is over? untag-enables-particles: false ================================================ FILE: expansion/compatibility/PlayerParticles/src/main/resources/expansion.yml ================================================ name: "${expansionName}" prefix: "${expansionPrefix}" description: "${expansionDescription}" main: "combatlogx.expansion.compatibility.player.particles.PlayerParticlesExpansion" version: "17.1" author: "SirBlobman" plugin-depend: - "PlayerParticles" ================================================ FILE: expansion/compatibility/PreciousStones/build.gradle.kts ================================================ repositories { maven("https://maven.elmakers.com/repository/") } dependencies { compileOnly("net.sacredlabyrinth.Phaed:PreciousStones:15.0") } ================================================ FILE: expansion/compatibility/PreciousStones/gradle.properties ================================================ expansion.name=CompatPreciousStones expansion.prefix=PreciousStones Compatibility ================================================ FILE: expansion/compatibility/PreciousStones/src/main/java/combatlogx/expansion/compatibility/region/preciousstones/ListenerPreciousStones.java ================================================ package combatlogx.expansion.compatibility.region.preciousstones; import org.jetbrains.annotations.NotNull; import org.bukkit.entity.Player; import org.bukkit.event.EventHandler; import org.bukkit.event.EventPriority; import com.github.sirblobman.api.language.LanguageManager; import com.github.sirblobman.combatlogx.api.expansion.ExpansionListener; import net.sacredlabyrinth.Phaed.PreciousStones.api.events.FieldPreCreationEvent; public final class ListenerPreciousStones extends ExpansionListener { private final PreciousStonesExpansion expansion; public ListenerPreciousStones(@NotNull PreciousStonesExpansion expansion) { super(expansion); this.expansion = expansion; } @EventHandler(priority = EventPriority.NORMAL, ignoreCancelled = true) public void beforeFieldCreation(FieldPreCreationEvent e) { Player player = e.getPlayer(); if (isPreventFieldCreation() && isInCombat(player)) { e.setCancelled(true); String path = "expansion.region-protection.preciousstones.prevent-field-creation"; LanguageManager languageManager = getLanguageManager(); languageManager.sendMessageWithPrefix(player, path); } } private @NotNull PreciousStonesExpansion getPreciousStonesExpansion() { return this.expansion; } private @NotNull PreciousStonesConfiguration getConfiguration() { PreciousStonesExpansion expansion = getPreciousStonesExpansion(); return expansion.getPreciousStonesConfiguration(); } private boolean isPreventFieldCreation() { PreciousStonesConfiguration configuration = getConfiguration(); return configuration.isPreventFieldCreation(); } } ================================================ FILE: expansion/compatibility/PreciousStones/src/main/java/combatlogx/expansion/compatibility/region/preciousstones/PreciousStonesConfiguration.java ================================================ package combatlogx.expansion.compatibility.region.preciousstones; import org.jetbrains.annotations.NotNull; import org.bukkit.configuration.ConfigurationSection; import com.github.sirblobman.api.configuration.IConfigurable; public final class PreciousStonesConfiguration implements IConfigurable { private boolean preventFieldCreation; public PreciousStonesConfiguration() { this.preventFieldCreation = true; } @Override public void load(@NotNull ConfigurationSection config) { setPreventFieldCreation(config.getBoolean("prevent-field-creation", true)); } public boolean isPreventFieldCreation() { return this.preventFieldCreation; } public void setPreventFieldCreation(boolean preventFieldCreation) { this.preventFieldCreation = preventFieldCreation; } } ================================================ FILE: expansion/compatibility/PreciousStones/src/main/java/combatlogx/expansion/compatibility/region/preciousstones/PreciousStonesExpansion.java ================================================ package combatlogx.expansion.compatibility.region.preciousstones; import org.jetbrains.annotations.NotNull; import com.github.sirblobman.api.configuration.ConfigurationManager; import com.github.sirblobman.combatlogx.api.ICombatLogX; import com.github.sirblobman.combatlogx.api.expansion.region.RegionExpansion; import com.github.sirblobman.combatlogx.api.expansion.region.RegionHandler; public final class PreciousStonesExpansion extends RegionExpansion { private final PreciousStonesConfiguration configuration; private RegionHandler regionHandler; public PreciousStonesExpansion(@NotNull ICombatLogX plugin) { super(plugin); this.configuration = new PreciousStonesConfiguration(); this.regionHandler = null; } @Override public boolean checkDependencies() { return checkDependency("PreciousStones", true, "15"); } @Override public @NotNull RegionHandler getRegionHandler() { if (this.regionHandler == null) { this.regionHandler = new RegionHandlerPreciousStones(this); } return this.regionHandler; } @Override public void reloadConfig() { super.reloadConfig(); ConfigurationManager configurationManager = getConfigurationManager(); getPreciousStonesConfiguration().load(configurationManager.get("config.yml")); } @Override public void afterEnable() { new ListenerPreciousStones(this).register(); } public @NotNull PreciousStonesConfiguration getPreciousStonesConfiguration() { return this.configuration; } } ================================================ FILE: expansion/compatibility/PreciousStones/src/main/java/combatlogx/expansion/compatibility/region/preciousstones/RegionHandlerPreciousStones.java ================================================ package combatlogx.expansion.compatibility.region.preciousstones; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import org.bukkit.Location; import org.bukkit.entity.Player; import com.github.sirblobman.combatlogx.api.expansion.region.RegionHandler; import com.github.sirblobman.combatlogx.api.object.TagInformation; import com.github.sirblobman.combatlogx.api.object.TagType; import net.sacredlabyrinth.Phaed.PreciousStones.PreciousStones; import net.sacredlabyrinth.Phaed.PreciousStones.api.IApi; import net.sacredlabyrinth.Phaed.PreciousStones.field.FieldFlag; public final class RegionHandlerPreciousStones extends RegionHandler { public RegionHandlerPreciousStones(@NotNull PreciousStonesExpansion expansion) { super(expansion); } @Override public @NotNull String getEntryDeniedMessagePath(@NotNull TagType tagType) { return "expansion.region-protection.preciousstones.no-entry"; } @Override public boolean isSafeZone(@NotNull Player player, @NotNull Location location, @NotNull TagInformation tag) { IApi api = getAPI(); TagType tagType = tag.getCurrentTagType(); FieldFlag fieldFlag = getFieldFlag(tagType); if (fieldFlag == null) { return false; } return api.isFieldProtectingArea(fieldFlag, location); } private @NotNull IApi getAPI() { return PreciousStones.API(); } private @Nullable FieldFlag getFieldFlag(@NotNull TagType tagType) { switch (tagType) { case PLAYER: return FieldFlag.PREVENT_PVP; case MOB: case MYTHIC_MOB: return FieldFlag.PREVENT_MOB_DAMAGE; default: break; } return null; } } ================================================ FILE: expansion/compatibility/PreciousStones/src/main/resources/expansion.yml ================================================ name: "${expansionName}" prefix: "${expansionPrefix}" description: "${expansionDescription}" main: "combatlogx.expansion.compatibility.region.preciousstones.PreciousStonesExpansion" version: "17.2" author: "SirBlobman" plugin-depend: - "PreciousStones" ================================================ FILE: expansion/compatibility/ProtectionStones/build.gradle.kts ================================================ dependencies { compileOnly("dev.espi:protectionstones:2.10.5") compileOnly("com.sk89q.worldguard:worldguard-bukkit:7.0.14") } ================================================ FILE: expansion/compatibility/ProtectionStones/gradle.properties ================================================ expansion.name=CompatProtectionStones expansion.prefix=ProtectionStones Compatibility ================================================ FILE: expansion/compatibility/ProtectionStones/src/main/java/combatlogx/expansion/compatibility/region/protectionstones/ProtectionStonesConfiguration.java ================================================ package combatlogx.expansion.compatibility.region.protectionstones; import org.jetbrains.annotations.NotNull; import org.bukkit.configuration.ConfigurationSection; import com.github.sirblobman.api.configuration.IConfigurable; public final class ProtectionStonesConfiguration implements IConfigurable { private boolean preventAreaCreation; public ProtectionStonesConfiguration() { this.preventAreaCreation = true; } @Override public void load(@NotNull ConfigurationSection config) { setPreventAreaCreation(config.getBoolean("prevent-area-creation", true)); } public boolean isPreventAreaCreation() { return this.preventAreaCreation; } public void setPreventAreaCreation(boolean preventAreaCreation) { this.preventAreaCreation = preventAreaCreation; } } ================================================ FILE: expansion/compatibility/ProtectionStones/src/main/java/combatlogx/expansion/compatibility/region/protectionstones/ProtectionStonesExpansion.java ================================================ package combatlogx.expansion.compatibility.region.protectionstones; import org.jetbrains.annotations.NotNull; import com.github.sirblobman.api.configuration.ConfigurationManager; import com.github.sirblobman.combatlogx.api.ICombatLogX; import com.github.sirblobman.combatlogx.api.expansion.region.RegionExpansion; import com.github.sirblobman.combatlogx.api.expansion.region.RegionHandler; public final class ProtectionStonesExpansion extends RegionExpansion { private final ProtectionStonesConfiguration configuration; private RegionHandler regionHandler; public ProtectionStonesExpansion(@NotNull ICombatLogX plugin) { super(plugin); this.configuration = new ProtectionStonesConfiguration(); this.regionHandler = null; } @Override public boolean checkDependencies() { boolean checkProtectionStones = checkDependency("ProtectionStones", true); boolean checkWorldGuard = checkDependency("WorldGuard", true, "7"); return (checkProtectionStones && checkWorldGuard); } @Override public @NotNull RegionHandler getRegionHandler() { if (this.regionHandler == null) { this.regionHandler = new RegionHandlerProtectionStones(this); } return this.regionHandler; } @Override public void afterEnable() { new ProtectionStonesListener(this).register(); } @Override public void reloadConfig() { super.reloadConfig(); ConfigurationManager configurationManager = getConfigurationManager(); getProtectionStonesConfiguration().load(configurationManager.get("config.yml")); } public @NotNull ProtectionStonesConfiguration getProtectionStonesConfiguration() { return this.configuration; } } ================================================ FILE: expansion/compatibility/ProtectionStones/src/main/java/combatlogx/expansion/compatibility/region/protectionstones/ProtectionStonesListener.java ================================================ package combatlogx.expansion.compatibility.region.protectionstones; import org.jetbrains.annotations.NotNull; import org.bukkit.entity.Player; import org.bukkit.event.EventHandler; import org.bukkit.event.EventPriority; import com.github.sirblobman.api.language.LanguageManager; import com.github.sirblobman.combatlogx.api.expansion.ExpansionListener; import dev.espi.protectionstones.event.PSCreateEvent; public final class ProtectionStonesListener extends ExpansionListener { private final ProtectionStonesExpansion expansion; public ProtectionStonesListener(@NotNull ProtectionStonesExpansion expansion) { super(expansion); this.expansion = expansion; } @EventHandler(priority = EventPriority.NORMAL, ignoreCancelled = true) public void onCreateRegion(PSCreateEvent e) { Player player = e.getPlayer(); if (isInCombat(player) && isPreventAreaCreation()) { e.setCancelled(true); String path = ("expansion.region-protection.protectionstones.prevent-area-creation"); LanguageManager languageManager = getLanguageManager(); languageManager.sendMessageWithPrefix(player, path); } } private @NotNull ProtectionStonesExpansion getProtectionStonesExpansion() { return this.expansion; } private @NotNull ProtectionStonesConfiguration getConfiguration() { ProtectionStonesExpansion expansion = getProtectionStonesExpansion(); return expansion.getProtectionStonesConfiguration(); } private boolean isPreventAreaCreation() { ProtectionStonesConfiguration configuration = getConfiguration(); return configuration.isPreventAreaCreation(); } } ================================================ FILE: expansion/compatibility/ProtectionStones/src/main/java/combatlogx/expansion/compatibility/region/protectionstones/RegionHandlerProtectionStones.java ================================================ package combatlogx.expansion.compatibility.region.protectionstones; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import org.bukkit.Location; import org.bukkit.entity.Player; import com.github.sirblobman.combatlogx.api.expansion.region.RegionHandler; import com.github.sirblobman.combatlogx.api.object.TagInformation; import com.github.sirblobman.combatlogx.api.object.TagType; import com.sk89q.worldguard.protection.flags.Flags; import com.sk89q.worldguard.protection.flags.StateFlag.State; import com.sk89q.worldguard.protection.regions.ProtectedRegion; import dev.espi.protectionstones.PSRegion; public final class RegionHandlerProtectionStones extends RegionHandler { public RegionHandlerProtectionStones(@NotNull ProtectionStonesExpansion expansion) { super(expansion); } @Override public @NotNull String getEntryDeniedMessagePath(@NotNull TagType tagType) { return "expansion.region-protection.protectionstones.no-entry"; } @Override public boolean isSafeZone(@NotNull Player player, @NotNull Location location, @NotNull TagInformation tag) { TagType tagType = tag.getCurrentTagType(); if (tagType != TagType.PLAYER) { return false; } ProtectedRegion region = getWorldGuardRegion(location); if (region == null) { return false; } State pvpState = region.getFlag(Flags.PVP); return (pvpState == State.DENY); } private @Nullable PSRegion getRegion(@NotNull Location location) { return PSRegion.fromLocation(location); } private @Nullable ProtectedRegion getWorldGuardRegion(@NotNull Location location) { PSRegion region = getRegion(location); if (region == null) { return null; } return region.getWGRegion(); } } ================================================ FILE: expansion/compatibility/ProtectionStones/src/main/resources/expansion.yml ================================================ name: "${expansionName}" prefix: "${expansionPrefix}" description: "${expansionDescription}" main: "combatlogx.expansion.compatibility.region.protectionstones.ProtectionStonesExpansion" version: "17.3" author: "olivolja3 (Olivo#3313)" plugin-depend: - "ProtectionStones" - "WorldGuard" ================================================ FILE: expansion/compatibility/README.MD ================================================ # CombatLogX Compatibility Expansions Compatibility expansions add features to CombatLogX based on the plugin that they add compatibility for. ## Compatibility Table
Plugin Compatibility Type
  • ASkyBlock
  • BSkyBlock
  • FabledSkyBlock
  • IridiumSkyblock
  • SuperiorSkyblock
  • uSkyBlock
Island team members cannot tag each other into combat.
  • Factions
  • FactionsX
  • FactionsUUID
  • FactionsUUID-Legacy
  • LegacyFactions
  • KingdomsX
  • Lands
  • GriefDefender
  • GriefPrevention
  • PreciousStones
  • ProtectionStones
  • RedProtect
  • Residence
  • Towny
  • UltimateClaims
  • WorldGuard
Safe Zone and non-pvp region force-field / no-entry compatibility.
  • PlaceholderAPI
  • MVdWPlaceholderAPI
Placeholders will be registered to these plugins.
  • iDisguise
  • LibsDisguises
  • Essentials
Players in vanish cannot tag players and cannot be tagged.
CrackShot Weapons will be linked to the player that activates them.
Citizens An NPC will be spawned when a player leaves during combat.
LuckPerms Add custom contexts for combat-related permissions.
================================================ FILE: expansion/compatibility/RedProtect/build.gradle.kts ================================================ dependencies { compileOnly("br.net.fabiozumbi12.RedProtect:RedProtect-Spigot:8.1.2") } ================================================ FILE: expansion/compatibility/RedProtect/gradle.properties ================================================ expansion.name=CompatRedProtection expansion.prefix=RedProtect Compatibility ================================================ FILE: expansion/compatibility/RedProtect/src/main/java/combatlogx/expansion/compatibility/region/redprotect/RedProtectExpansion.java ================================================ package combatlogx.expansion.compatibility.region.redprotect; import org.jetbrains.annotations.NotNull; import com.github.sirblobman.combatlogx.api.ICombatLogX; import com.github.sirblobman.combatlogx.api.expansion.region.RegionExpansion; import com.github.sirblobman.combatlogx.api.expansion.region.RegionHandler; public final class RedProtectExpansion extends RegionExpansion { private RegionHandler regionHandler; public RedProtectExpansion(@NotNull ICombatLogX plugin) { super(plugin); this.regionHandler = null; } @Override public boolean checkDependencies() { return checkDependency("RedProtect", true); } @Override public @NotNull RegionHandler getRegionHandler() { if (this.regionHandler == null) { this.regionHandler = new RegionHandlerRedProtect(this); } return this.regionHandler; } } ================================================ FILE: expansion/compatibility/RedProtect/src/main/java/combatlogx/expansion/compatibility/region/redprotect/RegionHandlerRedProtect.java ================================================ package combatlogx.expansion.compatibility.region.redprotect; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import org.bukkit.Location; import org.bukkit.entity.Player; import com.github.sirblobman.combatlogx.api.expansion.region.RegionHandler; import com.github.sirblobman.combatlogx.api.object.TagInformation; import com.github.sirblobman.combatlogx.api.object.TagType; import br.net.fabiozumbi12.RedProtect.Bukkit.API.RedProtectAPI; import br.net.fabiozumbi12.RedProtect.Bukkit.RedProtect; import br.net.fabiozumbi12.RedProtect.Bukkit.Region; public class RegionHandlerRedProtect extends RegionHandler { public RegionHandlerRedProtect(@NotNull RedProtectExpansion expansion) { super(expansion); } @Override public @NotNull String getEntryDeniedMessagePath(@NotNull TagType tagType) { return "expansion.region-protection.redprotect-no-entry"; } @Override public boolean isSafeZone(@NotNull Player player, @NotNull Location location, @NotNull TagInformation tag) { TagType tagType = tag.getCurrentTagType(); if (tagType != TagType.PLAYER) { return false; } Region region = getRegion(location); if (region == null) { return false; } return !region.getFlagBool("pvp"); } private @NotNull RedProtect getRedProtection() { return RedProtect.get(); } private @NotNull RedProtectAPI getAPI() { RedProtect redProtect = getRedProtection(); return redProtect.getAPI(); } private @Nullable Region getRegion(@NotNull Location location) { RedProtectAPI api = getAPI(); return api.getRegion(location); } } ================================================ FILE: expansion/compatibility/RedProtect/src/main/resources/expansion.yml ================================================ name: "${expansionName}" prefix: "${expansionPrefix}" description: "${expansionDescription}" main: "combatlogx.expansion.compatibility.region.redprotect.RedProtectExpansion" version: "17.3" author: "SirBlobman" plugin-depend: - "RedProtect" ================================================ FILE: expansion/compatibility/Residence/build.gradle.kts ================================================ dependencies { compileOnly("net.zrips:Residence:6.0.1.8") } ================================================ FILE: expansion/compatibility/Residence/gradle.properties ================================================ expansion.name=CompatResidence expansion.prefix=Residence Compatibility ================================================ FILE: expansion/compatibility/Residence/src/main/java/combatlogx/expansion/compatibility/region/residence/RegionHandlerResidence.java ================================================ package combatlogx.expansion.compatibility.region.residence; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import org.bukkit.Location; import org.bukkit.entity.Player; import com.github.sirblobman.combatlogx.api.expansion.region.RegionHandler; import com.github.sirblobman.combatlogx.api.object.TagInformation; import com.github.sirblobman.combatlogx.api.object.TagType; import com.bekvon.bukkit.residence.api.ResidenceApi; import com.bekvon.bukkit.residence.api.ResidenceInterface; import com.bekvon.bukkit.residence.containers.Flags; import com.bekvon.bukkit.residence.protection.ClaimedResidence; import com.bekvon.bukkit.residence.protection.ResidencePermissions; public final class RegionHandlerResidence extends RegionHandler { public RegionHandlerResidence(@NotNull ResidenceExpansion expansion) { super(expansion); } @Override public @NotNull String getEntryDeniedMessagePath(@NotNull TagType tagType) { return "expansion.region-protection.residence-no-entry"; } @Override public boolean isSafeZone(@NotNull Player player, @NotNull Location location, @NotNull TagInformation tag) { TagType tagType = tag.getCurrentTagType(); Flags flag = getFlag(tagType); if (flag == null) { return false; } ResidencePermissions permissions = getPermissions(location); if (permissions == null) { return false; } return !permissions.has(flag, true); } private @NotNull ResidenceInterface getInterface() { return ResidenceApi.getResidenceManager(); } private @Nullable ClaimedResidence getResidence(@NotNull Location location) { ResidenceInterface manager = getInterface(); return manager.getByLoc(location); } private @Nullable ResidencePermissions getPermissions(@NotNull Location location) { ClaimedResidence residence = getResidence(location); if (residence == null) { return null; } return residence.getPermissions(); } private @Nullable Flags getFlag(@NotNull TagType tagType) { switch (tagType) { case PLAYER: return Flags.pvp; case MOB: case MYTHIC_MOB: return Flags.mobkilling; case DAMAGE: return Flags.damage; default: break; } return null; } } ================================================ FILE: expansion/compatibility/Residence/src/main/java/combatlogx/expansion/compatibility/region/residence/ResidenceExpansion.java ================================================ package combatlogx.expansion.compatibility.region.residence; import org.jetbrains.annotations.NotNull; import com.github.sirblobman.combatlogx.api.ICombatLogX; import com.github.sirblobman.combatlogx.api.expansion.region.RegionExpansion; import com.github.sirblobman.combatlogx.api.expansion.region.RegionHandler; public final class ResidenceExpansion extends RegionExpansion { private RegionHandler regionHandler; public ResidenceExpansion(ICombatLogX plugin) { super(plugin); this.regionHandler = null; } @Override public boolean checkDependencies() { return checkDependency("Residence", false, "6.0"); } @Override public @NotNull RegionHandler getRegionHandler() { if (this.regionHandler == null) { this.regionHandler = new RegionHandlerResidence(this); } return this.regionHandler; } } ================================================ FILE: expansion/compatibility/Residence/src/main/resources/expansion.yml ================================================ name: "${expansionName}" prefix: "${expansionPrefix}" description: "${expansionDescription}" main: "combatlogx.expansion.compatibility.region.residence.ResidenceExpansion" version: "17.4" author: "SirBlobman" plugin-depend: - "Residence" ================================================ FILE: expansion/compatibility/SuperVanish/build.gradle.kts ================================================ repositories { maven("https://nexus.sirblobman.xyz/proxy-public") } dependencies { compileOnly("com.github.LeonMangler:SuperVanish:6.2.19") { exclude("*", "*") } } ================================================ FILE: expansion/compatibility/SuperVanish/gradle.properties ================================================ expansion.name=CompatSuperVanish expansion.prefix=SuperVanish Compatibility ================================================ FILE: expansion/compatibility/SuperVanish/src/main/java/combatlogx/expansion/compatibility/supervanish/SuperVanishExpansion.java ================================================ package combatlogx.expansion.compatibility.supervanish; import org.jetbrains.annotations.NotNull; import com.github.sirblobman.combatlogx.api.ICombatLogX; import com.github.sirblobman.combatlogx.api.expansion.vanish.VanishExpansion; import com.github.sirblobman.combatlogx.api.expansion.vanish.VanishHandler; public final class SuperVanishExpansion extends VanishExpansion { private VanishHandler vanishHandler; public SuperVanishExpansion(ICombatLogX plugin) { super(plugin); this.vanishHandler = null; } @Override public boolean checkDependencies() { if (checkDependency("PremiumVanish", true)) { return true; } getLogger().info("Missing PremiumVanish, checking for regular SuperVanish..."); return checkDependency("SuperVanish", true); } @Override public @NotNull VanishHandler getVanishHandler() { if (this.vanishHandler == null) { this.vanishHandler = new VanishHandlerSuper(this); } return this.vanishHandler; } } ================================================ FILE: expansion/compatibility/SuperVanish/src/main/java/combatlogx/expansion/compatibility/supervanish/VanishHandlerSuper.java ================================================ package combatlogx.expansion.compatibility.supervanish; import org.jetbrains.annotations.NotNull; import org.bukkit.entity.Player; import com.github.sirblobman.combatlogx.api.expansion.vanish.VanishHandler; import de.myzelyam.api.vanish.VanishAPI; public final class VanishHandlerSuper extends VanishHandler { public VanishHandlerSuper(@NotNull SuperVanishExpansion expansion) { super(expansion); } @Override public boolean isVanished(@NotNull Player player) { return VanishAPI.isInvisible(player); } } ================================================ FILE: expansion/compatibility/SuperVanish/src/main/resources/config.yml ================================================ # Should players in vanish be preventing from going into combat? prevent-vanish-tagging-self: true # Should players in vanish be unable to tag other players? prevent-vanish-tagging-other: true ================================================ FILE: expansion/compatibility/SuperVanish/src/main/resources/expansion.yml ================================================ name: "${expansionName}" prefix: "${expansionPrefix}" description: "${expansionDescription}" main: "combatlogx.expansion.compatibility.supervanish.SuperVanishExpansion" version: "17.2" author: "SirBlobman" plugin-soft-depend: - "PremiumVanish" - "SuperVanish" ================================================ FILE: expansion/compatibility/SuperiorSkyblock/build.gradle.kts ================================================ repositories { maven("https://repo.bg-software.com/repository/api/") } dependencies { compileOnly("com.bgsoftware:SuperiorSkyblockAPI:2025.1") } ================================================ FILE: expansion/compatibility/SuperiorSkyblock/gradle.properties ================================================ expansion.name=CompatSuperiorSkyblock expansion.prefix=SuperiorSkyblock Compatibility ================================================ FILE: expansion/compatibility/SuperiorSkyblock/src/main/java/combatlogx/expansion/compatibility/superior/skyblock/IslandWrapperSuperior.java ================================================ package combatlogx.expansion.compatibility.superior.skyblock; import java.util.Collections; import java.util.HashSet; import java.util.List; import java.util.Set; import java.util.UUID; import org.jetbrains.annotations.NotNull; import com.github.sirblobman.combatlogx.api.expansion.skyblock.IslandWrapper; import com.bgsoftware.superiorskyblock.api.island.Island; import com.bgsoftware.superiorskyblock.api.wrappers.SuperiorPlayer; public class IslandWrapperSuperior extends IslandWrapper { private final Island island; public IslandWrapperSuperior(@NotNull Island island) { this.island = island; } private @NotNull Island getIsland() { return this.island; } @Override public @NotNull Set getMembers() { Island island = getIsland(); List islandMemberList = island.getIslandMembers(true); Set memberSet = new HashSet<>(); for (SuperiorPlayer member : islandMemberList) { UUID memberId = member.getUniqueId(); memberSet.add(memberId); } return Collections.unmodifiableSet(memberSet); } } ================================================ FILE: expansion/compatibility/SuperiorSkyblock/src/main/java/combatlogx/expansion/compatibility/superior/skyblock/SkyBlockHandlerSuperior.java ================================================ package combatlogx.expansion.compatibility.superior.skyblock; import java.util.UUID; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import org.bukkit.Location; import org.bukkit.OfflinePlayer; import com.github.sirblobman.combatlogx.api.expansion.skyblock.IslandWrapper; import com.github.sirblobman.combatlogx.api.expansion.skyblock.SkyBlockHandler; import com.bgsoftware.superiorskyblock.api.SuperiorSkyblockAPI; import com.bgsoftware.superiorskyblock.api.island.Island; import com.bgsoftware.superiorskyblock.api.wrappers.SuperiorPlayer; public final class SkyBlockHandlerSuperior extends SkyBlockHandler { public SkyBlockHandlerSuperior(@NotNull SuperiorSkyblockExpansion expansion) { super(expansion); } @Override public @Nullable IslandWrapper getIsland(@NotNull Location location) { return wrap(SuperiorSkyblockAPI.getIslandAt(location)); } @Override public @Nullable IslandWrapper getIsland(@NotNull OfflinePlayer player) { return wrap(getUnwrappedIsland(player)); } @Override public boolean doesIslandMatch(@NotNull OfflinePlayer player1, @NotNull OfflinePlayer player2) { Island island1 = getUnwrappedIsland(player1); Island island2 = getUnwrappedIsland(player2); if (island1 == null || island2 == null) { return false; } UUID islandId1 = island1.getUniqueId(); UUID islandId2 = island2.getUniqueId(); return islandId1.equals(islandId2); } private @Nullable SuperiorPlayer getUser(@NotNull OfflinePlayer player) { UUID playerId = player.getUniqueId(); return SuperiorSkyblockAPI.getPlayer(playerId); } private @Nullable Island getUnwrappedIsland(@NotNull OfflinePlayer player) { SuperiorPlayer user = getUser(player); if (user == null) { return null; } return user.getIsland(); } private @Nullable IslandWrapper wrap(@Nullable Island island) { if (island == null) { return null; } return new IslandWrapperSuperior(island); } } ================================================ FILE: expansion/compatibility/SuperiorSkyblock/src/main/java/combatlogx/expansion/compatibility/superior/skyblock/SuperiorSkyblockExpansion.java ================================================ package combatlogx.expansion.compatibility.superior.skyblock; import org.jetbrains.annotations.NotNull; import com.github.sirblobman.combatlogx.api.ICombatLogX; import com.github.sirblobman.combatlogx.api.expansion.skyblock.SkyBlockExpansion; import com.github.sirblobman.combatlogx.api.expansion.skyblock.SkyBlockHandler; public final class SuperiorSkyblockExpansion extends SkyBlockExpansion { private SkyBlockHandler skyBlockHandler; public SuperiorSkyblockExpansion(ICombatLogX plugin) { super(plugin); this.skyBlockHandler = null; } @Override public boolean checkDependencies() { return checkDependency("SuperiorSkyblock2", true); } @Override public @NotNull SkyBlockHandler getSkyBlockHandler() { if (this.skyBlockHandler == null) { this.skyBlockHandler = new SkyBlockHandlerSuperior(this); } return this.skyBlockHandler; } } ================================================ FILE: expansion/compatibility/SuperiorSkyblock/src/main/resources/expansion.yml ================================================ name: "${expansionName}" prefix: "${expansionPrefix}" description: "${expansionDescription}" main: "combatlogx.expansion.compatibility.superior.skyblock.SuperiorSkyblockExpansion" version: "17.2" author: "SirBlobman" plugin-depend: - "SuperiorSkyblock2" ================================================ FILE: expansion/compatibility/Towny/build.gradle.kts ================================================ repositories { maven("https://repo.glaremasters.me/repository/towny/") maven("https://nexus.sirblobman.xyz/proxy-public") } dependencies { compileOnly("com.palmergames.bukkit.towny:towny:0.101.1.0") compileOnly("com.github.TownyAdvanced:FlagWar:0.7.0") } ================================================ FILE: expansion/compatibility/Towny/gradle.properties ================================================ expansion.name=CompatTowny expansion.prefix=Towny Compatibility ================================================ FILE: expansion/compatibility/Towny/src/main/java/combatlogx/expansion/compatibility/region/towny/RegionHandlerTowny.java ================================================ package combatlogx.expansion.compatibility.region.towny; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import org.bukkit.Bukkit; import org.bukkit.Location; import org.bukkit.entity.Player; import org.bukkit.plugin.PluginManager; import com.github.sirblobman.combatlogx.api.expansion.region.RegionHandler; import com.github.sirblobman.combatlogx.api.object.TagInformation; import com.github.sirblobman.combatlogx.api.object.TagType; import com.palmergames.bukkit.towny.TownyAPI; import com.palmergames.bukkit.towny.object.Town; import com.palmergames.bukkit.towny.object.TownBlock; import com.palmergames.bukkit.towny.object.TownyPermission; import com.palmergames.bukkit.towny.object.TownyWorld; import io.github.townyadvanced.flagwar.FlagWarAPI; public final class RegionHandlerTowny extends RegionHandler { public RegionHandlerTowny(@NotNull TownyExpansion expansion) { super(expansion); } @Override public @NotNull String getEntryDeniedMessagePath(@NotNull TagType tagType) { return "expansion.region-protection.towny-no-entry"; } @Override public boolean isSafeZone(@NotNull Player player, @NotNull Location location, @NotNull TagInformation tag) { TagType tagType = tag.getCurrentTagType(); if (tagType != TagType.PLAYER) { return false; } if (isPreventAllTownEntries() && isOwnTown(player, location)) { return true; } TownyWorld world = getTownyWorld(location); if (world != null && world.isForcePVP()) { return false; } Town town = getTown(location); if (town == null || town.isPVP() || town.isAdminEnabledPVP() || town.hasActiveWar()) { return false; } if (isUnderAttack(town)) { return false; } TownBlock townBlock = getTownBlock(location); if (townBlock == null) { return false; } TownyPermission permissions = townBlock.getPermissions(); return !permissions.pvp; } private @NotNull TownyConfiguration getConfiguration() { TownyExpansion expansion = getExpansion(); return expansion.getTownyConfiguration(); } private boolean isPreventAllTownEntries() { TownyConfiguration configuration = getConfiguration(); return configuration.isPreventAllTownEntries(); } private @NotNull TownyAPI getAPI() { return TownyAPI.getInstance(); } private @Nullable TownBlock getTownBlock(@NotNull Location location) { TownyAPI api = getAPI(); return api.getTownBlock(location); } private @Nullable Town getTown(@NotNull Location location) { TownBlock townBlock = getTownBlock(location); if (townBlock == null) { return null; } return townBlock.getTownOrNull(); } private @Nullable TownyWorld getTownyWorld(@NotNull Location location) { TownBlock townBlock = getTownBlock(location); if (townBlock == null) { return null; } return townBlock.getWorld(); } private boolean isOwnTown(@NotNull Player player, @NotNull Location location) { Town town = getTown(location); if (town == null) { return false; } return town.hasResident(player); } private boolean isUnderAttack(@NotNull Town town) { PluginManager pluginManager = Bukkit.getPluginManager(); if (!pluginManager.isPluginEnabled("FlagWar")) { return false; } return FlagWarAPI.isUnderAttack(town); } } ================================================ FILE: expansion/compatibility/Towny/src/main/java/combatlogx/expansion/compatibility/region/towny/TownyConfiguration.java ================================================ package combatlogx.expansion.compatibility.region.towny; import org.jetbrains.annotations.NotNull; import org.bukkit.configuration.ConfigurationSection; import com.github.sirblobman.api.configuration.IConfigurable; public final class TownyConfiguration implements IConfigurable { private boolean preventAllTownEntries; private boolean preventJailDuringCombat; public TownyConfiguration() { this.preventAllTownEntries = false; this.preventJailDuringCombat = true; } @Override public void load(@NotNull ConfigurationSection section) { setPreventAllTownEntries(section.getBoolean("prevent-all-town-entries", false)); setPreventJailDuringCombat(section.getBoolean("prevent-jail-during-combat", true)); } public boolean isPreventAllTownEntries() { return this.preventAllTownEntries; } public void setPreventAllTownEntries(boolean preventAllTownEntries) { this.preventAllTownEntries = preventAllTownEntries; } public boolean isPreventJailDuringCombat() { return this.preventJailDuringCombat; } public void setPreventJailDuringCombat(boolean preventJailDuringCombat) { this.preventJailDuringCombat = preventJailDuringCombat; } } ================================================ FILE: expansion/compatibility/Towny/src/main/java/combatlogx/expansion/compatibility/region/towny/TownyExpansion.java ================================================ package combatlogx.expansion.compatibility.region.towny; import java.util.logging.Logger; import java.util.regex.Matcher; import java.util.regex.Pattern; import org.jetbrains.annotations.NotNull; import org.bukkit.Bukkit; import org.bukkit.plugin.Plugin; import org.bukkit.plugin.PluginDescriptionFile; import org.bukkit.plugin.PluginManager; import com.github.sirblobman.api.configuration.ConfigurationManager; import com.github.sirblobman.api.utility.VersionUtility; import com.github.sirblobman.combatlogx.api.ICombatLogX; import com.github.sirblobman.combatlogx.api.expansion.region.RegionExpansion; import com.github.sirblobman.combatlogx.api.expansion.region.RegionHandler; import combatlogx.expansion.compatibility.region.towny.listener.ListenerPrison; public final class TownyExpansion extends RegionExpansion { private final TownyConfiguration configuration; private RegionHandler regionHandler; public TownyExpansion(@NotNull ICombatLogX plugin) { super(plugin); this.configuration = new TownyConfiguration(); this.regionHandler = null; } @Override public void onLoad() { super.onLoad(); ConfigurationManager configurationManager = getConfigurationManager(); configurationManager.saveDefault("towny.yml"); } @Override public boolean checkDependencies() { if (!checkDependency("Towny", true)) { return false; } Logger logger = getLogger(); PluginManager pluginManager = Bukkit.getPluginManager(); Plugin plugin = pluginManager.getPlugin("Towny"); if (plugin == null) { return false; } PluginDescriptionFile description = plugin.getDescription(); String version = description.getVersion(); int minorVersion = parseTownyMinorVersion(version); if (minorVersion >= 100) { return true; } logger.info("Dependency 'Towny' is not the correct version!"); logger.info("Expected version > 100 but found '" + minorVersion + "'."); return false; } private int parseTownyMinorVersion(@NotNull String version) { Pattern pattern = Pattern.compile("^\\D*(\\d+)\\.(\\d+)"); Matcher matcher = pattern.matcher(version); Logger logger = getLogger(); if (!matcher.find()) { logger.info("Failed to find expected Towny version pattern."); logger.info("Expected a version with at least two numeric segments such as '0.100' but got '" + version + "'."); return 0; } String minorString = matcher.group(2); try { return Integer.parseInt(minorString); } catch (NumberFormatException ex) { getLogger().info("Failed to parse towny version: Expected number but got '" + minorString + "'"); return 0; } } @Override public void afterEnable() { checkDependency("FlagWar", true); new ListenerPrison(this).register(); } @Override public void reloadConfig() { super.reloadConfig(); ConfigurationManager configurationManager = getConfigurationManager(); configurationManager.reload("towny.yml"); getTownyConfiguration().load(configurationManager.get("towny.yml")); } @Override public @NotNull RegionHandler getRegionHandler() { if (this.regionHandler == null) { this.regionHandler = new RegionHandlerTowny(this); } return this.regionHandler; } public @NotNull TownyConfiguration getTownyConfiguration() { return this.configuration; } } ================================================ FILE: expansion/compatibility/Towny/src/main/java/combatlogx/expansion/compatibility/region/towny/listener/ListenerPrison.java ================================================ package combatlogx.expansion.compatibility.region.towny.listener; import org.jetbrains.annotations.NotNull; import org.bukkit.entity.Player; import org.bukkit.event.EventHandler; import org.bukkit.event.EventPriority; import com.github.sirblobman.combatlogx.api.expansion.ExpansionListener; import com.palmergames.bukkit.towny.event.resident.ResidentPreJailEvent; import com.palmergames.bukkit.towny.object.Resident; import com.palmergames.bukkit.towny.object.jail.JailReason; import combatlogx.expansion.compatibility.region.towny.TownyConfiguration; import combatlogx.expansion.compatibility.region.towny.TownyExpansion; public final class ListenerPrison extends ExpansionListener { private final TownyExpansion expansion; public ListenerPrison(@NotNull TownyExpansion expansion) { super(expansion); this.expansion = expansion; } @EventHandler(priority = EventPriority.NORMAL, ignoreCancelled = true) public void onPrison(ResidentPreJailEvent e) { if (!isPreventJailDuringCombat()) { return; } JailReason reason = e.getReason(); if (reason != JailReason.MAYOR) { return; } Resident resident = e.getResident(); Player player = resident.getPlayer(); if (player == null) { return; } if (isInCombat(player)) { e.setCancelled(true); } } private boolean isPreventJailDuringCombat() { TownyConfiguration configuration = this.expansion.getTownyConfiguration(); return configuration.isPreventJailDuringCombat(); } } ================================================ FILE: expansion/compatibility/Towny/src/main/resources/expansion.yml ================================================ name: "${expansionName}" prefix: "${expansionPrefix}" description: "${expansionDescription}" main: "combatlogx.expansion.compatibility.region.towny.TownyExpansion" version: "17.9" author: "SirBlobman" plugin-depend: - "Towny" plugin-soft-depend: - "FlagWar" ================================================ FILE: expansion/compatibility/Towny/src/main/resources/towny.yml ================================================ # This option will prevent entry to ANY town location owned by the player, regardless of PVP status # Default: false prevent-all-town-entries: false # This option will prevent mayors from jailing players during combat to save them. # Default: true prevent-jail-during-combat: true ================================================ FILE: expansion/compatibility/UltimateClaims/build.gradle.kts ================================================ dependencies { compileOnly("com.songoda:UltimateClaims:3.3.0") } ================================================ FILE: expansion/compatibility/UltimateClaims/gradle.properties ================================================ expansion.name=CompatUltimateClaims expansion.prefix=UltimateClaims Compatibility ================================================ FILE: expansion/compatibility/UltimateClaims/src/main/java/combatlogx/expansion/compatibility/region/ultimateclaims/RegionHandlerUltimateClaims.java ================================================ package combatlogx.expansion.compatibility.region.ultimateclaims; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import org.bukkit.Chunk; import org.bukkit.Location; import org.bukkit.entity.Player; import org.bukkit.plugin.java.JavaPlugin; import com.github.sirblobman.combatlogx.api.expansion.region.RegionHandler; import com.github.sirblobman.combatlogx.api.object.TagInformation; import com.github.sirblobman.combatlogx.api.object.TagType; import com.songoda.ultimateclaims.UltimateClaims; import com.songoda.ultimateclaims.claim.Claim; import com.songoda.ultimateclaims.claim.ClaimManager; import com.songoda.ultimateclaims.claim.ClaimSetting; import com.songoda.ultimateclaims.claim.ClaimSettings; public final class RegionHandlerUltimateClaims extends RegionHandler { public RegionHandlerUltimateClaims(@NotNull UltimateClaimsExpansion expansion) { super(expansion); } @Override public @NotNull String getEntryDeniedMessagePath(@NotNull TagType tagType) { return "expansion.region-protection.ultimateclaims-no-entry"; } @Override public boolean isSafeZone(@NotNull Player player, @NotNull Location location, @NotNull TagInformation tag) { TagType tagType = tag.getCurrentTagType(); if (tagType != TagType.PLAYER) { return false; } ClaimSettings claimSettings = getClaimSettings(location); if (claimSettings == null) { return false; } return !claimSettings.isEnabled(ClaimSetting.PVP); } private @NotNull UltimateClaims getUltimateClaims() { return JavaPlugin.getPlugin(UltimateClaims.class); } private @NotNull ClaimManager getClaimManager() { UltimateClaims ultimateClaims = getUltimateClaims(); return ultimateClaims.getClaimManager(); } private @Nullable Claim getClaim(@NotNull Location location) { Chunk chunk = location.getChunk(); ClaimManager claimManager = getClaimManager(); return claimManager.getClaim(chunk); } private @Nullable ClaimSettings getClaimSettings(@NotNull Location location) { Claim claim = getClaim(location); if (claim == null) { return null; } return claim.getClaimSettings(); } } ================================================ FILE: expansion/compatibility/UltimateClaims/src/main/java/combatlogx/expansion/compatibility/region/ultimateclaims/UltimateClaimsExpansion.java ================================================ package combatlogx.expansion.compatibility.region.ultimateclaims; import org.jetbrains.annotations.NotNull; import com.github.sirblobman.combatlogx.api.ICombatLogX; import com.github.sirblobman.combatlogx.api.expansion.region.RegionExpansion; import com.github.sirblobman.combatlogx.api.expansion.region.RegionHandler; public final class UltimateClaimsExpansion extends RegionExpansion { private RegionHandler regionHandler; public UltimateClaimsExpansion(@NotNull ICombatLogX plugin) { super(plugin); this.regionHandler = null; } @Override public boolean checkDependencies() { return checkDependency("UltimateClaims", true, "3"); } @Override public @NotNull RegionHandler getRegionHandler() { if (this.regionHandler == null) { this.regionHandler = new RegionHandlerUltimateClaims(this); } return this.regionHandler; } } ================================================ FILE: expansion/compatibility/UltimateClaims/src/main/resources/expansion.yml ================================================ name: "${expansionName}" prefix: "${expansionPrefix}" description: "${expansionDescription}" main: "combatlogx.expansion.compatibility.region.ultimateclaims.UltimateClaimsExpansion" version: "17.2" author: "SirBlobman" plugin-depend: - "UltimateClaims" ================================================ FILE: expansion/compatibility/VanishNoPacket/build.gradle.kts ================================================ repositories { maven("https://nexus.sirblobman.xyz/proxy-public") } dependencies { compileOnly("com.github.mbax:VanishNoPacket:3.22") } ================================================ FILE: expansion/compatibility/VanishNoPacket/gradle.properties ================================================ expansion.name=CompatVanishNoPacket expansion.prefix=VanishNoPacket Compatibility ================================================ FILE: expansion/compatibility/VanishNoPacket/src/main/java/combatlogx/expansion/compatibility/vnp/VanishHandlerNoPacket.java ================================================ package combatlogx.expansion.compatibility.vnp; import org.jetbrains.annotations.NotNull; import org.bukkit.entity.Player; import org.bukkit.plugin.java.JavaPlugin; import com.github.sirblobman.combatlogx.api.expansion.vanish.VanishHandler; import org.kitteh.vanish.VanishManager; import org.kitteh.vanish.VanishPlugin; public final class VanishHandlerNoPacket extends VanishHandler { public VanishHandlerNoPacket(@NotNull VanishNoPacketExpansion expansion) { super(expansion); } @Override public boolean isVanished(@NotNull Player player) { VanishManager vanishManager = getVanishManager(); return vanishManager.isVanished(player); } private @NotNull VanishPlugin getVanish() { return JavaPlugin.getPlugin(VanishPlugin.class); } private @NotNull VanishManager getVanishManager() { VanishPlugin plugin = getVanish(); return plugin.getManager(); } } ================================================ FILE: expansion/compatibility/VanishNoPacket/src/main/java/combatlogx/expansion/compatibility/vnp/VanishNoPacketExpansion.java ================================================ package combatlogx.expansion.compatibility.vnp; import org.jetbrains.annotations.NotNull; import com.github.sirblobman.combatlogx.api.ICombatLogX; import com.github.sirblobman.combatlogx.api.expansion.vanish.VanishExpansion; import com.github.sirblobman.combatlogx.api.expansion.vanish.VanishHandler; public final class VanishNoPacketExpansion extends VanishExpansion { private VanishHandler vanishHandler; public VanishNoPacketExpansion(ICombatLogX plugin) { super(plugin); this.vanishHandler = null; } @Override public boolean checkDependencies() { return checkDependency("VanishNoPacket", true, "3"); } @Override public @NotNull VanishHandler getVanishHandler() { if (this.vanishHandler == null) { this.vanishHandler = new VanishHandlerNoPacket(this); } return this.vanishHandler; } } ================================================ FILE: expansion/compatibility/VanishNoPacket/src/main/resources/config.yml ================================================ # Should players in vanish be preventing from going into combat? prevent-vanish-tagging-self: true # Should players in vanish be unable to tag other players? prevent-vanish-tagging-other: true ================================================ FILE: expansion/compatibility/VanishNoPacket/src/main/resources/expansion.yml ================================================ name: "${expansionName}" prefix: "${expansionPrefix}" description: "${expansionDescription}" main: "combatlogx.expansion.compatibility.vnp.VanishNoPacketExpansion" version: "17.0" author: "SirBlobman" plugin-depend: - "VanishNoPacket" ================================================ FILE: expansion/compatibility/WorldGuard/build.gradle.kts ================================================ import com.github.jengelman.gradle.plugins.shadow.tasks.ShadowJar plugins { id("com.gradleup.shadow") version "9.2.2" } repositories { maven("https://repo.codemc.io/repository/maven-public/") } dependencies { // https://github.com/CodeMC/WorldGuardWrapper implementation("org.codemc.worldguardwrapper:worldguardwrapper:1.2.1-SNAPSHOT") } tasks { named("jar") { enabled = false } named("shadowJar") { val expansionName = findProperty("expansion.name") ?: "invalid" val expansionPrefix = findProperty("expansion.prefix") ?: expansionName archiveFileName.set("$expansionPrefix.jar") archiveClassifier.set(null as String?) val basePath = "combatlogx.expansion.compatibility.region.world.guard" relocate("org.codemc.worldguardwrapper", "$basePath.wrapper") } named("build") { dependsOn("shadowJar") } } ================================================ FILE: expansion/compatibility/WorldGuard/gradle.properties ================================================ expansion.name=CompatWorldGuard expansion.prefix=WorldGuard Compatibility ================================================ FILE: expansion/compatibility/WorldGuard/src/main/java/combatlogx/expansion/compatibility/region/world/guard/WorldGuardConfiguration.java ================================================ package combatlogx.expansion.compatibility.region.world.guard; import org.jetbrains.annotations.NotNull; import org.bukkit.configuration.ConfigurationSection; import com.github.sirblobman.api.configuration.IConfigurable; public final class WorldGuardConfiguration implements IConfigurable { private boolean usePvpFlag; public WorldGuardConfiguration() { this.usePvpFlag = false; } @Override public void load(@NotNull ConfigurationSection section) { setUsePvpFlag(section.getBoolean("use-pvp-flag", true)); } public boolean isUsePvpFlag() { return usePvpFlag; } public void setUsePvpFlag(boolean usePvpFlag) { this.usePvpFlag = usePvpFlag; } } ================================================ FILE: expansion/compatibility/WorldGuard/src/main/java/combatlogx/expansion/compatibility/region/world/guard/WorldGuardExpansion.java ================================================ package combatlogx.expansion.compatibility.region.world.guard; import org.jetbrains.annotations.NotNull; import com.github.sirblobman.api.configuration.ConfigurationManager; import com.github.sirblobman.combatlogx.api.ICombatLogX; import com.github.sirblobman.combatlogx.api.expansion.region.RegionExpansion; import com.github.sirblobman.combatlogx.api.expansion.region.RegionHandler; import combatlogx.expansion.compatibility.region.world.guard.handler.WorldGuardRegionHandler; import combatlogx.expansion.compatibility.region.world.guard.hook.HookWorldGuard; import combatlogx.expansion.compatibility.region.world.guard.listener.ListenerPreventLeaving; import combatlogx.expansion.compatibility.region.world.guard.listener.ListenerWorldGuard; public final class WorldGuardExpansion extends RegionExpansion { private final WorldGuardConfiguration worldGuardConfiguration; private final HookWorldGuard hookWorldGuard; private RegionHandler regionHandler; public WorldGuardExpansion(@NotNull ICombatLogX plugin) { super(plugin); this.worldGuardConfiguration = new WorldGuardConfiguration(); this.hookWorldGuard = new HookWorldGuard(this); this.regionHandler = null; } @Override public void onLoad() { super.onLoad(); if (!checkDependency("WorldGuard", false)) { return; } HookWorldGuard hook = getHookWorldGuard(); hook.registerFlags(); ConfigurationManager configurationManager = getConfigurationManager(); configurationManager.saveDefault("worldguard.yml"); } @Override public boolean checkDependencies() { return checkDependency("WorldGuard", true); } @Override public void afterEnable() { new ListenerWorldGuard(this).register(); new ListenerPreventLeaving(this).register(); } @Override public @NotNull RegionHandler getRegionHandler() { if (this.regionHandler == null) { this.regionHandler = new WorldGuardRegionHandler(this); } return this.regionHandler; } @Override public void reloadConfig() { super.reloadConfig(); ConfigurationManager configurationManager = getConfigurationManager(); configurationManager.reload("worldguard.yml"); getWorldGuardConfiguration().load(configurationManager.get("worldguard.yml")); } public @NotNull HookWorldGuard getHookWorldGuard() { return this.hookWorldGuard; } public @NotNull WorldGuardConfiguration getWorldGuardConfiguration() { return this.worldGuardConfiguration; } } ================================================ FILE: expansion/compatibility/WorldGuard/src/main/java/combatlogx/expansion/compatibility/region/world/guard/handler/WorldGuardRegionHandler.java ================================================ package combatlogx.expansion.compatibility.region.world.guard.handler; import java.util.Locale; import java.util.Optional; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import org.bukkit.Location; import org.bukkit.entity.Entity; import org.bukkit.entity.Player; import org.bukkit.event.Cancellable; import com.github.sirblobman.combatlogx.api.ICombatLogX; import com.github.sirblobman.combatlogx.api.expansion.region.RegionHandler; import com.github.sirblobman.combatlogx.api.manager.ICombatManager; import com.github.sirblobman.combatlogx.api.object.TagInformation; import com.github.sirblobman.combatlogx.api.object.TagReason; import com.github.sirblobman.combatlogx.api.object.TagType; import combatlogx.expansion.compatibility.region.world.guard.WorldGuardConfiguration; import combatlogx.expansion.compatibility.region.world.guard.WorldGuardExpansion; import combatlogx.expansion.compatibility.region.world.guard.hook.HookWorldGuard; import org.codemc.worldguardwrapper.WorldGuardWrapper; import org.codemc.worldguardwrapper.flag.IWrappedFlag; import org.codemc.worldguardwrapper.flag.WrappedState; public final class WorldGuardRegionHandler extends RegionHandler { public WorldGuardRegionHandler(@NotNull WorldGuardExpansion expansion) { super(expansion); } @Override public @NotNull String getEntryDeniedMessagePath(@NotNull TagType tagType) { String tagTypeName = tagType.name(); String tagTypeLower = tagTypeName.toLowerCase(Locale.US); String nameFormat = "expansion.region-protection.worldguard.no-entry-%s-combat"; return String.format(Locale.US, nameFormat, tagTypeLower); } @Override public boolean isSafeZone(@NotNull Player player, @NotNull Location location, @NotNull TagInformation tag) { TagType tagType = tag.getCurrentTagType(); WorldGuardWrapper wrappedWorldGuard = WorldGuardWrapper.getInstance(); IWrappedFlag wrappedFlag = getFlag(tagType); if (wrappedFlag == null) { return false; } // First check for custom CombatLogX flag. Optional optionalWrappedState = wrappedWorldGuard.queryFlag(player, location, wrappedFlag); if (optionalWrappedState.isPresent()) { WrappedState wrappedState = optionalWrappedState.get(); return (wrappedState == WrappedState.DENY); } WorldGuardExpansion expansion = getExpansion(); WorldGuardConfiguration configuration = expansion.getWorldGuardConfiguration(); if (!configuration.isUsePvpFlag()) { // 'use-pvp-flag' option is disabled in configuration. return false; } WrappedState pvpState = getPvpState(player, location); return (pvpState == WrappedState.DENY); } /** * @param player The player being checked (might bypass or ignore certain flags) * @param location The coordinates to check. * @return {@code null} if the 'pvp' flag doesn't exist. {@code null} if the location doesn't have the flag. * Otherwise, a {@link WrappedState} depending on the region flags of the location. */ private @Nullable WrappedState getPvpState(@NotNull Player player, @NotNull Location location) { WorldGuardWrapper wrappedWorldGuard = WorldGuardWrapper.getInstance(); Optional> optionalPvpFlag = wrappedWorldGuard.getFlag("pvp", WrappedState.class); if (!optionalPvpFlag.isPresent()) { // 'pvp' flag does not exist in the WorldGuard plugin (nearly impossible). return null; } IWrappedFlag pvpFlag = optionalPvpFlag.get(); Optional optionalPvpState = wrappedWorldGuard.queryFlag(player, location, pvpFlag); return optionalPvpState.orElse(null); // Missing 'pvp' flag state from location will be ignored. } private IWrappedFlag getFlag(TagType tagType) { WorldGuardExpansion expansion = getExpansion(); HookWorldGuard hook = expansion.getHookWorldGuard(); switch (tagType) { case PLAYER: return hook.getPlayerCombatFlag(); case MOB: return hook.getMobCombatFlag(); case MYTHIC_MOB: return hook.getMythicMobCombatFlag(); case DAMAGE: return hook.getDamageCombatFlag(); case UNKNOWN: return hook.getUnknownCombatFlag(); default: break; } return null; } @Override protected void customPreventEntry(@NotNull Cancellable e, @NotNull Player player, @NotNull TagInformation tagInformation, @NotNull Location fromLocation, @NotNull Location toLocation) { WorldGuardExpansion expansion = getExpansion(); HookWorldGuard hook = expansion.getHookWorldGuard(); IWrappedFlag retagFlag = hook.getRetagFlag(); WorldGuardWrapper wrappedWorldGuard = WorldGuardWrapper.getInstance(); Optional optionalFlag = wrappedWorldGuard.queryFlag(player, toLocation, retagFlag); if (!optionalFlag.isPresent() || !optionalFlag.get()) { return; } ICombatLogX combatLogX = getExpansion().getPlugin(); ICombatManager combatManager = combatLogX.getCombatManager(); Entity currentEnemy = tagInformation.getCurrentEnemy(); TagType currentTagType = tagInformation.getCurrentTagType(); combatManager.tag(player, currentEnemy, currentTagType, TagReason.UNKNOWN); } } ================================================ FILE: expansion/compatibility/WorldGuard/src/main/java/combatlogx/expansion/compatibility/region/world/guard/hook/HookWorldGuard.java ================================================ package combatlogx.expansion.compatibility.region.world.guard.hook; import java.util.logging.Level; import java.util.logging.Logger; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import combatlogx.expansion.compatibility.region.world.guard.WorldGuardExpansion; import org.codemc.worldguardwrapper.WorldGuardWrapper; import org.codemc.worldguardwrapper.flag.IWrappedFlag; import org.codemc.worldguardwrapper.flag.WrappedState; public final class HookWorldGuard { private final WorldGuardExpansion expansion; private IWrappedFlag mythicMobCombatFlag; private IWrappedFlag unknownCombatFlag; private IWrappedFlag playerCombatFlag; private IWrappedFlag damageCombatFlag; private IWrappedFlag mobCombatFlag; private IWrappedFlag noTaggingFlag; private IWrappedFlag retagFlag; private IWrappedFlag preventLeavingFlag; public HookWorldGuard(@NotNull WorldGuardExpansion expansion) { this.expansion = expansion; this.mythicMobCombatFlag = null; this.unknownCombatFlag = null; this.playerCombatFlag = null; this.damageCombatFlag = null; this.mobCombatFlag = null; this.noTaggingFlag = null; this.retagFlag = null; this.preventLeavingFlag = null; } private @NotNull WorldGuardExpansion getExpansion() { return this.expansion; } private @NotNull Logger getLogger() { WorldGuardExpansion expansion = getExpansion(); return expansion.getLogger(); } public void registerFlags() { try { WorldGuardWrapper wrapper = WorldGuardWrapper.getInstance(); Class booleanClass = Boolean.TYPE; Class stateClass = WrappedState.class; WrappedState state = WrappedState.ALLOW; this.mythicMobCombatFlag = wrapper.registerFlag("mythic-mob-combat", stateClass, state).orElse(null); this.unknownCombatFlag = wrapper.registerFlag("unknown-combat", stateClass, state).orElse(null); this.playerCombatFlag = wrapper.registerFlag("player-combat", stateClass, state).orElse(null); this.damageCombatFlag = wrapper.registerFlag("damage-combat", stateClass, state).orElse(null); this.mobCombatFlag = wrapper.registerFlag("mob-combat", stateClass, state).orElse(null); this.noTaggingFlag = wrapper.registerFlag("no-tagging", booleanClass, false).orElse(null); this.retagFlag = wrapper.registerFlag("retag-player", booleanClass, false).orElse(null); this.preventLeavingFlag = wrapper.registerFlag("prevent-leaving", String.class, null).orElse(null); } catch (Exception ex) { Logger logger = getLogger(); logger.log(Level.WARNING, "An error occurred while registering custom WorldGuard flags:", ex); } } public @Nullable IWrappedFlag getMythicMobCombatFlag() { return this.mythicMobCombatFlag; } public @Nullable IWrappedFlag getUnknownCombatFlag() { return this.unknownCombatFlag; } public @Nullable IWrappedFlag getPlayerCombatFlag() { return this.playerCombatFlag; } public @Nullable IWrappedFlag getDamageCombatFlag() { return this.damageCombatFlag; } public @Nullable IWrappedFlag getMobCombatFlag() { return this.mobCombatFlag; } public @Nullable IWrappedFlag getNoTaggingFlag() { return this.noTaggingFlag; } public @Nullable IWrappedFlag getRetagFlag() { return this.retagFlag; } public @Nullable IWrappedFlag getPreventLeavingFlag() { return this.preventLeavingFlag; } } ================================================ FILE: expansion/compatibility/WorldGuard/src/main/java/combatlogx/expansion/compatibility/region/world/guard/listener/ListenerPreventLeaving.java ================================================ package combatlogx.expansion.compatibility.region.world.guard.listener; import java.util.Optional; import org.jetbrains.annotations.NotNull; import org.bukkit.Location; import org.bukkit.entity.Player; import org.bukkit.event.EventHandler; import org.bukkit.event.EventPriority; import org.bukkit.event.player.PlayerMoveEvent; import com.github.sirblobman.combatlogx.api.expansion.region.listener.RegionExpansionListener; import combatlogx.expansion.compatibility.region.world.guard.WorldGuardExpansion; import combatlogx.expansion.compatibility.region.world.guard.hook.HookWorldGuard; import org.codemc.worldguardwrapper.WorldGuardWrapper; import org.codemc.worldguardwrapper.flag.IWrappedFlag; public final class ListenerPreventLeaving extends RegionExpansionListener { private final WorldGuardExpansion expansion; public ListenerPreventLeaving(@NotNull WorldGuardExpansion expansion) { super(expansion); this.expansion = expansion; } @EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true) public void onPlayerMove(PlayerMoveEvent e) { Player player = e.getPlayer(); if (!isInCombat(player)) { return; } Location from = e.getFrom(); Location to = e.getTo(); if (isPreventLeaving(player, from, to)) { e.setCancelled(true); } } private @NotNull WorldGuardExpansion getWorldGuardExpansion() { return this.expansion; } private @NotNull Optional getPreventLeavingId(@NotNull Player player, @NotNull Location location) { WorldGuardExpansion worldGuardExpansion = getWorldGuardExpansion(); HookWorldGuard hookWorldGuard = worldGuardExpansion.getHookWorldGuard(); IWrappedFlag preventLeavingFlag = hookWorldGuard.getPreventLeavingFlag(); if (preventLeavingFlag == null) { return Optional.empty(); } WorldGuardWrapper wrappedWorldGuard = WorldGuardWrapper.getInstance(); return wrappedWorldGuard.queryFlag(player, location, preventLeavingFlag); } private boolean isPreventLeaving(@NotNull Player player, @NotNull Location from, @NotNull Location to) { Optional fromId = getPreventLeavingId(player, from); if (fromId.isEmpty()) { return false; } Optional toId = getPreventLeavingId(player, to); return toId.map(s -> !fromId.get().equals(s)).orElse(true); } } ================================================ FILE: expansion/compatibility/WorldGuard/src/main/java/combatlogx/expansion/compatibility/region/world/guard/listener/ListenerWorldGuard.java ================================================ package combatlogx.expansion.compatibility.region.world.guard.listener; import java.util.HashSet; import java.util.Optional; import java.util.Set; import java.util.UUID; import org.jetbrains.annotations.NotNull; import org.bukkit.Location; import org.bukkit.entity.Player; import org.bukkit.event.EventHandler; import org.bukkit.event.EventPriority; import org.bukkit.event.player.PlayerQuitEvent; import org.bukkit.event.player.PlayerTeleportEvent; import com.github.sirblobman.api.folia.FoliaHelper; import com.github.sirblobman.api.folia.teleport.TeleportHandler; import com.github.sirblobman.combatlogx.api.event.PlayerPreTagEvent; import com.github.sirblobman.combatlogx.api.expansion.ExpansionListener; import combatlogx.expansion.compatibility.region.world.guard.WorldGuardExpansion; import combatlogx.expansion.compatibility.region.world.guard.hook.HookWorldGuard; import org.codemc.worldguardwrapper.WorldGuardWrapper; import org.codemc.worldguardwrapper.flag.IWrappedFlag; public final class ListenerWorldGuard extends ExpansionListener { private final WorldGuardExpansion expansion; private final Set preventTeleportLoop; public ListenerWorldGuard(@NotNull WorldGuardExpansion expansion) { super(expansion); this.expansion = expansion; this.preventTeleportLoop = new HashSet<>(); } @EventHandler(priority = EventPriority.NORMAL, ignoreCancelled = true) public void beforeCombat(PlayerPreTagEvent e) { Player player = e.getPlayer(); Location location = player.getLocation(); if (isNoTaggingRegion(player, location)) { e.setCancelled(true); } } // Bug Fix: WorldGuard Invulnerability when teleport is cancelled during combat. // Bug Reported and Patched by PhoenixZT#0278 on Discord. @EventHandler(priority = EventPriority.HIGHEST) public void onTeleport(PlayerTeleportEvent e) { Player player = e.getPlayer(); UUID playerId = player.getUniqueId(); if (!this.preventTeleportLoop.remove(playerId) && e.isCancelled() && isInCombat(player)) { this.preventTeleportLoop.add(playerId); Location location = player.getLocation(); FoliaHelper foliaHelper = getExpansion().getPlugin().getFoliaHelper(); TeleportHandler teleporter = foliaHelper.getTeleporter(); teleporter.teleport(player, location).join(); } } @EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true) public void onQuit(PlayerQuitEvent e) { Player player = e.getPlayer(); UUID playerId = player.getUniqueId(); this.preventTeleportLoop.remove(playerId); } private @NotNull WorldGuardExpansion getWorldGuardExpansion() { return this.expansion; } private boolean isNoTaggingRegion(@NotNull Player player, @NotNull Location location) { WorldGuardExpansion expansion = getWorldGuardExpansion(); HookWorldGuard hook = expansion.getHookWorldGuard(); IWrappedFlag noTaggingFlag = hook.getNoTaggingFlag(); if (noTaggingFlag == null) { return false; } WorldGuardWrapper instance = WorldGuardWrapper.getInstance(); Optional optionalFlag = instance.queryFlag(player, location, noTaggingFlag); return optionalFlag.orElse(false); } } ================================================ FILE: expansion/compatibility/WorldGuard/src/main/resources/expansion.yml ================================================ name: "${expansionName}" prefix: "${expansionPrefix}" description: "${expansionDescription}" main: "combatlogx.expansion.compatibility.region.world.guard.WorldGuardExpansion" version: "17.4" author: "SirBlobman" plugin-depend: - "WorldGuard" ================================================ FILE: expansion/compatibility/WorldGuard/src/main/resources/worldguard.yml ================================================ # CombatLogX adds its own flag to prevent entry (player-combat: DENY) # Set this option to true if 'pvp: DENY` flag should also prevent entry. use-pvp-flag: true ================================================ FILE: expansion/compatibility/ZNPCsPlus/build.gradle.kts ================================================ repositories { maven("https://repo.pyr.lol/snapshots") } dependencies { compileOnly("lol.pyr:znpcsplus-api:2.0.0-SNAPSHOT") } ================================================ FILE: expansion/compatibility/ZNPCsPlus/gradle.properties ================================================ version.spigot=1.8.8-R0.1-SNAPSHOT expansion.name=CompatZNPCsPlus expansion.prefix=ZNPCsPlus Compatibility ================================================ FILE: expansion/compatibility/ZNPCsPlus/src/main/java/combatlogx/expansion/compatibility/znpc/CombatNpc.java ================================================ package combatlogx.expansion.compatibility.znpc; import java.util.UUID; import org.jetbrains.annotations.NotNull; import org.bukkit.Bukkit; import org.bukkit.OfflinePlayer; import org.bukkit.entity.Player; import com.github.sirblobman.api.folia.details.TaskDetails; import com.github.sirblobman.api.folia.scheduler.TaskScheduler; import com.github.sirblobman.combatlogx.api.manager.ICombatManager; import com.github.sirblobman.combatlogx.api.object.TagInformation; import combatlogx.expansion.compatibility.znpc.configuration.NpcConfiguration; import lol.pyr.znpcsplus.api.npc.Npc; public final class CombatNpc extends TaskDetails { private final ZNPCExpansion expansion; private final Npc originalNpc; private final UUID ownerId; private UUID enemyId; private long survivalTicks; public CombatNpc(@NotNull ZNPCExpansion expansion, @NotNull Npc originalNpc, @NotNull OfflinePlayer owner) { super(expansion.getPlugin().getPlugin()); this.expansion = expansion; this.originalNpc = originalNpc; this.ownerId = owner.getUniqueId(); } @Override public void run() { this.survivalTicks--; if (this.survivalTicks > 0) { return; } ZNPCExpansion expansion = getExpansion(); NpcConfiguration npcConfiguration = expansion.getNpcConfiguration(); if(npcConfiguration.isStayUntilEnemyEscape() && this.enemyId != null) { if(updateEnemySurvivalTicks()) { return; } } CombatNpcManager combatNpcManager = expansion.getCombatNpcManager(); combatNpcManager.remove(this); } public void start() { setDelay(1L); setPeriod(1L); resetSurvivalTime(); TaskScheduler scheduler = getExpansion().getPlugin().getFoliaHelper().getScheduler(); scheduler.scheduleTask(this); } public @NotNull Npc getOriginalNpc() { return this.originalNpc; } public @NotNull UUID getOwnerId() { return this.ownerId; } public @NotNull OfflinePlayer getOfflineOwner() { return Bukkit.getOfflinePlayer(getOwnerId()); } public void resetSurvivalTime() { NpcConfiguration npcConfiguration = getExpansion().getNpcConfiguration(); long survivalSeconds = npcConfiguration.getSurvivalTime(); this.survivalTicks = (survivalSeconds * 20L); } public void setEnemy(@NotNull Player enemy) { this.enemyId = enemy.getUniqueId(); } private @NotNull ZNPCExpansion getExpansion() { return this.expansion; } private boolean updateEnemySurvivalTicks() { Player enemyPlayer = Bukkit.getPlayer(this.enemyId); if (enemyPlayer == null) { return false; } ICombatManager combatManager = getExpansion().getPlugin().getCombatManager(); TagInformation tagInformation = combatManager.getTagInformation(enemyPlayer); if (tagInformation == null) { return false; } long timeLeftMillis = tagInformation.getMillisLeftCombined(); this.survivalTicks = ((timeLeftMillis / 50L) + 1L); return true; } } ================================================ FILE: expansion/compatibility/ZNPCsPlus/src/main/java/combatlogx/expansion/compatibility/znpc/CombatNpcManager.java ================================================ package combatlogx.expansion.compatibility.znpc; import java.util.Collection; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.UUID; import java.util.concurrent.ConcurrentHashMap; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import org.bukkit.Location; import org.bukkit.OfflinePlayer; import org.bukkit.World; import org.bukkit.configuration.file.YamlConfiguration; import org.bukkit.entity.Entity; import org.bukkit.entity.EntityType; import org.bukkit.entity.NPC; import org.bukkit.entity.Player; import com.github.sirblobman.api.configuration.PlayerDataManager; import com.github.sirblobman.api.folia.scheduler.TaskScheduler; import com.github.sirblobman.combatlogx.api.ICombatLogX; import combatlogx.expansion.compatibility.znpc.configuration.NpcConfiguration; import combatlogx.expansion.compatibility.znpc.task.NpcRemoveTask; import lol.pyr.znpcsplus.api.NpcApi; import lol.pyr.znpcsplus.api.NpcApiProvider; import lol.pyr.znpcsplus.api.entity.EntityProperty; import lol.pyr.znpcsplus.api.entity.EntityPropertyRegistry; import lol.pyr.znpcsplus.api.hologram.Hologram; import lol.pyr.znpcsplus.api.npc.Npc; import lol.pyr.znpcsplus.api.npc.NpcEntry; import lol.pyr.znpcsplus.api.npc.NpcRegistry; import lol.pyr.znpcsplus.api.npc.NpcType; import lol.pyr.znpcsplus.util.NpcLocation; public final class CombatNpcManager { private final ZNPCExpansion expansion; private final Map playerNpcMap; private final Map npcCombatMap; public CombatNpcManager(@NotNull ZNPCExpansion expansion) { this.expansion = expansion; this.playerNpcMap = new ConcurrentHashMap<>(); this.npcCombatMap = new ConcurrentHashMap<>(); } private @NotNull ZNPCExpansion getExpansion() { return this.expansion; } private @NotNull ICombatLogX getCombatLogX() { return getExpansion().getPlugin(); } public @NotNull YamlConfiguration getData(@NotNull OfflinePlayer player) { PlayerDataManager playerDataManager = getCombatLogX().getPlayerDataManager(); return playerDataManager.get(player); } public void saveData(@NotNull OfflinePlayer player) { PlayerDataManager playerDataManager = getCombatLogX().getPlayerDataManager(); playerDataManager.save(player); } public @NotNull CombatNpc createCombatNpc(@NotNull Player player, @NotNull List enemyList) { if (player.hasMetadata("NPC")) { throw new IllegalArgumentException("Attempted to create NPC for an existing NPC."); } UUID playerId = player.getUniqueId(); String playerName = player.getName(); World playerWorld = player.getWorld(); Location playerLocation = player.getLocation(); NpcConfiguration npcConfiguration = getExpansion().getNpcConfiguration(); EntityType entityType = npcConfiguration.getMobType(); NpcApi npcApi = NpcApiProvider.get(); NpcRegistry npcRegistry = npcApi.getNpcRegistry(); NpcType npcType = npcApi.getNpcTypeRegistry().getByName(entityType.name()); NpcLocation npcLocation = new NpcLocation(playerLocation); NpcEntry npcEntry = npcRegistry.create("combatnpc-" + playerId, playerWorld, npcType, npcLocation); npcEntry.setAllowCommandModification(false); npcEntry.setSave(false); String npcNameFormat = npcConfiguration.getCustomNpcNameFormat(); String npcName = npcNameFormat.replace("{player_name}", playerName); Npc npc = npcEntry.getNpc(); Hologram hologram = npc.getHologram(); hologram.clearLines(); hologram.addLine(npcName); npc.setEnabled(true); CombatNpc combatNpc = new CombatNpc(getExpansion(), npc, player); this.playerNpcMap.put(playerId, combatNpc); this.npcCombatMap.put(npc.getUuid(), combatNpc); if (!enemyList.isEmpty()) { Entity mainEnemy = enemyList.get(0); if (mainEnemy instanceof Player) { combatNpc.setEnemy((Player) mainEnemy); } } saveLocation(player, npc); saveInventory(player); equipNpc(player, npc); combatNpc.start(); return combatNpc; } public @Nullable CombatNpc getCombatNpc(@Nullable NPC npc) { if (npc == null) { return null; } UUID npcId = npc.getUniqueId(); return this.npcCombatMap.get(npcId); } public @Nullable CombatNpc getCombatNpc(@NotNull OfflinePlayer player) { UUID playerId = player.getUniqueId(); return this.playerNpcMap.get(playerId); } public void remove(@NotNull CombatNpc combatNpc) { try { combatNpc.cancel(); } catch(IllegalStateException ignored) { // Do Nothing } UUID ownerId = combatNpc.getOwnerId(); OfflinePlayer owner = combatNpc.getOfflineOwner(); Npc originalNpc = combatNpc.getOriginalNpc(); saveNpc(owner, originalNpc); this.playerNpcMap.remove(ownerId); this.npcCombatMap.remove(originalNpc.getUuid()); TaskScheduler scheduler = getCombatLogX().getFoliaHelper().getScheduler(); scheduler.scheduleTask(new NpcRemoveTask(getExpansion(), originalNpc)); } public void removeAll() { Map copyMap = new HashMap<>(this.playerNpcMap); this.playerNpcMap.clear(); Collection combatNpcCollection = copyMap.values(); for (CombatNpc combatNpc : combatNpcCollection) { remove(combatNpc); } } private void saveNpc(@NotNull OfflinePlayer player, @NotNull Npc npc) { saveHealth(player, npc); saveLocation(player, npc); YamlConfiguration data = getData(player); data.set("znpcs-compatibility.punish", true); saveData(player); } private void saveHealth(@NotNull OfflinePlayer player, @NotNull Npc npc) { // ZNPCs don't have health. } private void saveLocation(@NotNull OfflinePlayer player, @NotNull Npc npc) { World world = npc.getWorld(); NpcLocation npcLocation = npc.getLocation(); Location location = npcLocation.toBukkitLocation(world); YamlConfiguration data = getData(player); data.set("znpcs-compatibility.location", location); saveData(player); } } ================================================ FILE: expansion/compatibility/ZNPCsPlus/src/main/java/combatlogx/expansion/compatibility/znpc/ZNPCExpansion.java ================================================ package combatlogx.expansion.compatibility.znpc; import org.jetbrains.annotations.NotNull; import com.github.sirblobman.api.configuration.ConfigurationManager; import com.github.sirblobman.api.utility.VersionUtility; import com.github.sirblobman.combatlogx.api.ICombatLogX; import com.github.sirblobman.combatlogx.api.expansion.Expansion; import combatlogx.expansion.compatibility.znpc.configuration.Configuration; import combatlogx.expansion.compatibility.znpc.configuration.NpcConfiguration; public final class ZNPCExpansion extends Expansion { private final Configuration configuration; private final NpcConfiguration npcConfiguration; private final CombatNpcManager combatNpcManager; private final InventoryManager inventoryManager; public ZNPCExpansion(@NotNull ICombatLogX plugin) { super(plugin); this.configuration = new Configuration(); this.npcConfiguration = new NpcConfiguration(this); this.combatNpcManager = new CombatNpcManager(this); this.inventoryManager = new InventoryManager(this); } @Override public void onLoad() { ConfigurationManager configurationManager = getConfigurationManager(); configurationManager.saveDefault("config.yml"); configurationManager.saveDefault("npcs.yml"); } @Override public void onEnable() { // Only ZNPCsPlus v2.0.0 is supported at this time. if(!checkDependency("ZNPCsPlus", true, "2")) { selfDisable(); return; } reloadConfig(); registerListeners(); } @Override public void onDisable() { CombatNpcManager combatNpcManager = getCombatNpcManager(); combatNpcManager.removeAll(); } @Override public void reloadConfig() { ConfigurationManager configurationManager = getConfigurationManager(); configurationManager.reload("config.yml"); configurationManager.reload("npcs.yml"); getConfiguration().load(configurationManager.get("config.yml")); getNpcConfiguration().load(configurationManager.get("npcs.yml")); } public @NotNull Configuration getConfiguration() { return this.configuration; } public @NotNull NpcConfiguration getNpcConfiguration() { return this.npcConfiguration; } public @NotNull CombatNpcManager getCombatNpcManager() { return this.combatNpcManager; } public @NotNull InventoryManager getInventoryManager() { return this.inventoryManager; } private void registerListeners() { new ListenerCombat(this).register(); new ListenerDeath(this).register(); new ListenerJoin(this).register(); new ListenerPunish(this).register(); new ListenerQuit(this).register(); // Totem of Undying was added in 1.11. int minorVersion = VersionUtility.getMinorVersion(); if (minorVersion >= 11) { new ListenerResurrect(this).register(); } // EntityTransformEvent was added in 1.13 if (minorVersion >= 13) { new ListenerConvert(this).register(); } } } ================================================ FILE: expansion/compatibility/ZNPCsPlus/src/main/java/combatlogx/expansion/compatibility/znpc/configuration/Configuration.java ================================================ package combatlogx.expansion.compatibility.znpc.configuration; import org.jetbrains.annotations.NotNull; import org.bukkit.configuration.ConfigurationSection; import com.github.sirblobman.api.configuration.IConfigurable; public final class Configuration implements IConfigurable { private boolean npcTagging; public Configuration() { this.npcTagging = false; } @Override public void load(@NotNull ConfigurationSection config) { setNpcTagging(config.getBoolean("npc-tagging", false)); } public boolean isNpcTagging() { return npcTagging; } public void setNpcTagging(boolean npcTagging) { this.npcTagging = npcTagging; } } ================================================ FILE: expansion/compatibility/ZNPCsPlus/src/main/java/combatlogx/expansion/compatibility/znpc/configuration/NpcConfiguration.java ================================================ package combatlogx.expansion.compatibility.znpc.configuration; import java.util.logging.Logger; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import org.bukkit.configuration.ConfigurationSection; import org.bukkit.entity.EntityType; import com.github.sirblobman.api.configuration.IConfigurable; import com.github.sirblobman.api.utility.Validate; import combatlogx.expansion.compatibility.znpc.ZNPCExpansion; public final class NpcConfiguration implements IConfigurable { private final ZNPCExpansion expansion; private boolean preventPunishments; private boolean preventLogin; private boolean storeInventory; private boolean storeLocation; private boolean mobTarget; private double mobTargetRadius; private int survivalTime; private boolean stayUntilEnemyEscape; private boolean stayUntilNoDamage; private boolean preventResurrect; private boolean tagPlayer; private boolean alwaysSpawnNpcOnQuit; private String customNpcNameFormat; private transient EntityType mobType; public NpcConfiguration(@NotNull ZNPCExpansion expansion) { this.expansion = expansion; this.preventPunishments = true; this.preventLogin = false; this.storeInventory = true; this.storeLocation = true; this.mobTarget = true; this.mobTargetRadius = 10.0D; this.survivalTime = 30; this.stayUntilEnemyEscape = false; this.stayUntilNoDamage = false; this.preventResurrect = true; this.tagPlayer = true; this.alwaysSpawnNpcOnQuit = false; this.customNpcNameFormat = "{player_name}"; this.mobType = EntityType.PLAYER; } private @NotNull ZNPCExpansion getExpansion() { return this.expansion; } private @NotNull Logger getLogger() { return getExpansion().getLogger(); } @Override public void load(@NotNull ConfigurationSection config) { setPreventPunishments(config.getBoolean("prevent-punishments", true)); setPreventLogin(config.getBoolean("prevent-login", false)); setMobType(config.getString("mob-type", "PLAYER")); setStoreInventory(config.getBoolean("store-inventory", true)); setStoreLocation(config.getBoolean("store-location", true)); setMobTarget(config.getBoolean("mob-target", true)); setMobTargetRadius(config.getDouble("mob-target-radius", 10.0D)); setSurvivalTime(config.getInt("survival-time", 30)); setStayUntilEnemyEscape(config.getBoolean("stay-until-enemy-escapes", false)); setStayUntilNoDamage(config.getBoolean("stay-until-no-damage", false)); setPreventResurrect(config.getBoolean("prevent-resurrect", true)); setTagPlayer(config.getBoolean("tag-player", true)); setAlwaysSpawnNpcOnQuit(config.getBoolean("always-spawn-npc-on-quit", false)); setCustomNpcNameFormat(config.getString("custom-npc-name", "{player_name}")); } public boolean isPreventPunishments() { return preventPunishments; } public void setPreventPunishments(boolean preventPunishments) { this.preventPunishments = preventPunishments; } public boolean isPreventLogin() { return preventLogin; } public void setPreventLogin(boolean preventLogin) { this.preventLogin = preventLogin; } public @NotNull EntityType getMobType() { return mobType; } public void setMobType(@NotNull EntityType mobType) { this.mobType = mobType; } private void setMobType(@Nullable String mobTypeName) { if (mobTypeName == null) { mobTypeName = "PLAYER"; } EntityType mobType; try { mobType = EntityType.valueOf(mobTypeName); if (!mobType.isAlive()) { Logger logger = getLogger(); logger.warning("'" + mobType + "' is a non-living value, defaulting to PLAYER."); mobType = EntityType.PLAYER; } } catch (IllegalArgumentException ex) { Logger logger = getLogger(); logger.warning("'" + mobTypeName + "' is not a valid EntityType."); logger.warning("Defaulting to PLAYER."); mobType = EntityType.PLAYER; } setMobType(mobType); } public boolean isStoreInventory() { return storeInventory; } public void setStoreInventory(boolean storeInventory) { this.storeInventory = storeInventory; } public boolean isStoreLocation() { return storeLocation; } public void setStoreLocation(boolean storeLocation) { this.storeLocation = storeLocation; } public boolean isMobTarget() { return mobTarget; } public void setMobTarget(boolean mobTarget) { this.mobTarget = mobTarget; } public double getMobTargetRadius() { return mobTargetRadius; } public void setMobTargetRadius(double mobTargetRadius) { this.mobTargetRadius = mobTargetRadius; } public int getSurvivalTime() { return survivalTime; } public void setSurvivalTime(int survivalTime) { this.survivalTime = survivalTime; } public boolean isStayUntilEnemyEscape() { return stayUntilEnemyEscape; } public void setStayUntilEnemyEscape(boolean stayUntilEnemyEscape) { this.stayUntilEnemyEscape = stayUntilEnemyEscape; } public boolean isStayUntilNoDamage() { return stayUntilNoDamage; } public void setStayUntilNoDamage(boolean stayUntilNoDamage) { this.stayUntilNoDamage = stayUntilNoDamage; } public boolean isPreventResurrect() { return preventResurrect; } public void setPreventResurrect(boolean preventResurrect) { this.preventResurrect = preventResurrect; } public boolean isTagPlayer() { return tagPlayer; } public void setTagPlayer(boolean tagPlayer) { this.tagPlayer = tagPlayer; } public boolean isAlwaysSpawnNpcOnQuit() { return alwaysSpawnNpcOnQuit; } public void setAlwaysSpawnNpcOnQuit(boolean alwaysSpawnNpcOnQuit) { this.alwaysSpawnNpcOnQuit = alwaysSpawnNpcOnQuit; } public @NotNull String getCustomNpcNameFormat() { return customNpcNameFormat; } public void setCustomNpcNameFormat(String customNpcNameFormat) { Validate.notEmpty(customNpcNameFormat, "'custom-npc-name' must not be an empty string."); this.customNpcNameFormat = customNpcNameFormat; } } ================================================ FILE: expansion/compatibility/ZNPCsPlus/src/main/java/combatlogx/expansion/compatibility/znpc/listener/NpcExpansionListener.java ================================================ package combatlogx.expansion.compatibility.znpc.listener; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import org.bukkit.entity.Entity; import com.github.sirblobman.combatlogx.api.expansion.ExpansionListener; import combatlogx.expansion.compatibility.znpc.ZNPCExpansion; import combatlogx.expansion.compatibility.znpc.configuration.Configuration; import combatlogx.expansion.compatibility.znpc.configuration.NpcConfiguration; import lol.pyr.znpcsplus.api.NpcApiProvider; import lol.pyr.znpcsplus.api.npc.Npc; import lol.pyr.znpcsplus.api.npc.NpcEntry; import lol.pyr.znpcsplus.api.npc.NpcRegistry; public abstract class NpcExpansionListener extends ExpansionListener { private final ZNPCExpansion expansion; public NpcExpansionListener(@NotNull ZNPCExpansion expansion) { super(expansion); this.expansion = expansion; } protected final @NotNull ZNPCExpansion getNpcExpansion() { return this.expansion; } protected final @NotNull Configuration getConfiguration() { return getNpcExpansion().getConfiguration(); } protected final @NotNull NpcConfiguration getNpcConfiguration() { return getNpcExpansion().getNpcConfiguration(); } protected final @NotNull CombatNpcManager getCombatNpcManager() { return getNpcExpansion().getCombatNpcManager(); } protected final @NotNull InventoryManager getInventoryManager() { return getNpcExpansion().getInventoryManager(); } protected final @Nullable CombatNPC getCombatNpc(@NotNull NPC npc) { return getCombatNpcManager().getCombatNpc(npc); } protected final @Nullable Npc getNpc(@NotNull Entity entity) { NpcRegistry registry = NpcApiProvider.get().getNpcRegistry(); NpcEntry entry = registry.getByUuid(entity.getUniqueId()); return entry.getNpc(); } } ================================================ FILE: expansion/compatibility/ZNPCsPlus/src/main/java/combatlogx/expansion/compatibility/znpc/task/NpcRemoveTask.java ================================================ package combatlogx.expansion.compatibility.znpc.task; import org.jetbrains.annotations.NotNull; import com.github.sirblobman.api.folia.details.TaskDetails; import combatlogx.expansion.compatibility.znpc.ZNPCExpansion; import lol.pyr.znpcsplus.api.NpcApiProvider; import lol.pyr.znpcsplus.api.npc.Npc; import lol.pyr.znpcsplus.api.npc.NpcRegistry; public final class NpcRemoveTask extends TaskDetails { private final Npc npc; public NpcRemoveTask(@NotNull ZNPCExpansion expansion, @NotNull Npc npc) { super(expansion.getPlugin().getPlugin()); this.npc = npc; } @Override public void run() { this.npc.setEnabled(false); NpcRegistry npcRegistry = NpcApiProvider.get().getNpcRegistry(); String npcId = npcRegistry.getByUuid(this.npc.getUuid()).getId(); npcRegistry.delete(npcId); } } ================================================ FILE: expansion/compatibility/ZNPCsPlus/src/main/resources/config.yml ================================================ # Should players be tagged by NPCs? # Default: false npc-tagging: false ================================================ FILE: expansion/compatibility/ZNPCsPlus/src/main/resources/expansion.yml ================================================ name: "${expansionName}" prefix: "${expansionPrefix}" description: "${expansionDescription}" main: "combatlogx.expansion.compatibility.znpc.ZNPCExpansion" version: "17.0.alpha.test" author: "SirBlobman" plugin-depend: - "ZNPCsPlus" ================================================ FILE: expansion/compatibility/ZNPCsPlus/src/main/resources/npcs.yml ================================================ # Should this expansion prevent other punishments from executing? (e.g. kill, commands, etc...) # This prevents issues such as killing AND spawning an NPC # Default: true prevent-punishments: true # Should this expansion prevent a player from logging in if they have an NPC active? # This means they will have to wait until it is killed or despawned. # Default: false prevent-login: false # Which entity type should be used to create NPCs? # You can find a list of valid EntityTypes in the link below: # https://hub.spigotmc.org/javadocs/spigot/org/bukkit/entity/EntityType.html # Default: PLAYER mob-type: PLAYER # Should we take the player's inventory and put it into the NPC? # This will prevent items from being dropped unless the NPC is killed. # Items will be taken when the NPC is spawned and restored to the player once they log back in. # Armor and held items will be placed in the correct slots. # Default: true store-inventory: true # Should we store the NPC's last location? # The player will be teleported to that location once they log bck in. # Default: true store-location: true # Should nearby mobs target combat NPCs? # Default: true mob-target: true # How close do mobs need to be to force-target an NPC? # Set this to 0 to disable this feature. # Default: 10 mob-target-radius: 10 # How long do combat NPCs last if they are not attacked by mobs or players? # NPC survival time is in seconds. # Default: 30 survival-time: 30 # Should an NPC stay alive until their last known enemy is out of combat? # Default: false stay-until-enemy-escape: false # Should the survival time on an NPC reset every time they are hit? # Default: false stay-until-no-damage: false # Should combat NPCs be prevented from using totems of undying? # Default: true prevent-resurrect: true # Should players receive a combat tag when they log back in? # This only applies if their NPC still had health when it respawned. tag-player: true # Should CombatLogX always spawn an NPC, even if the player is not tagged? always-spawn-npc-on-quit: false # Custom NPC name # May be character limited to 16 on some versions. # Available Placeholders: {player_name} # DO NOT set this to null or empty. custom-npc-name: "{player_name}" ================================================ FILE: expansion/compatibility/build.gradle.kts ================================================ tasks.named("jar") { enabled = false } ================================================ FILE: expansion/compatibility/iDisguise/build.gradle.kts ================================================ repositories { maven("https://www.luisagrether.de/mc/repo/") } dependencies { compileOnly("de.luisagrether.idisguise:idisguise:6.0.1-SNAPSHOT") } ================================================ FILE: expansion/compatibility/iDisguise/gradle.properties ================================================ expansion.name=Compat_iDisguise expansion.prefix=iDisguise Compatibility ================================================ FILE: expansion/compatibility/iDisguise/src/main/java/combatlogx/expansion/compatibility/idisguise/DisguiseHandler_iDisguise.java ================================================ package combatlogx.expansion.compatibility.idisguise; import org.jetbrains.annotations.NotNull; import org.bukkit.entity.Player; import com.github.sirblobman.combatlogx.api.expansion.disguise.DisguiseHandler; import de.luisagrether.idisguise.iDisguise; public final class DisguiseHandler_iDisguise extends DisguiseHandler { public DisguiseHandler_iDisguise(@NotNull Expansion_iDisguise expansion) { super(expansion); } @Override public boolean hasDisguise(@NotNull Player player) { iDisguise plugin = iDisguise.getInstance(); return plugin.isDisguised(player); } @Override public void removeDisguise(@NotNull Player player) { iDisguise plugin = iDisguise.getInstance(); plugin.undisguise(player); } } ================================================ FILE: expansion/compatibility/iDisguise/src/main/java/combatlogx/expansion/compatibility/idisguise/Expansion_iDisguise.java ================================================ package combatlogx.expansion.compatibility.idisguise; import org.jetbrains.annotations.NotNull; import com.github.sirblobman.combatlogx.api.ICombatLogX; import com.github.sirblobman.combatlogx.api.expansion.disguise.DisguiseExpansion; import com.github.sirblobman.combatlogx.api.expansion.disguise.DisguiseHandler; public final class Expansion_iDisguise extends DisguiseExpansion { private DisguiseHandler disguiseHandler; public Expansion_iDisguise(@NotNull ICombatLogX plugin) { super(plugin); this.disguiseHandler = null; } @Override public boolean checkDependencies() { return checkDependency("iDisguise", true, "6"); } @Override public @NotNull DisguiseHandler getDisguiseHandler() { if (this.disguiseHandler == null) { this.disguiseHandler = new DisguiseHandler_iDisguise(this); } return this.disguiseHandler; } } ================================================ FILE: expansion/compatibility/iDisguise/src/main/resources/expansion.yml ================================================ name: "${expansionName}" prefix: "${expansionPrefix}" description: "${expansionDescription}" main: "combatlogx.expansion.compatibility.idisguise.Expansion_iDisguise" version: "17.2" author: "SirBlobman" plugin-depend: - "iDisguise" ================================================ FILE: expansion/compatibility/uSkyBlock/build.gradle.kts ================================================ repositories { maven("https://nexus.sirblobman.xyz/proxy-public") } dependencies { compileOnly("com.github.rlf:uSkyBlock-API:3.1.0") } ================================================ FILE: expansion/compatibility/uSkyBlock/gradle.properties ================================================ expansion.name=Compat_uSkyBlock expansion.prefix=uSkyBlock Compatibility ================================================ FILE: expansion/compatibility/uSkyBlock/src/main/java/combatlogx/expansion/compatibility/uskyblock/IslandWrapper_uSkyBlock.java ================================================ package combatlogx.expansion.compatibility.uskyblock; import java.util.Collections; import java.util.HashMap; import java.util.HashSet; import java.util.Map; import java.util.Set; import java.util.UUID; import org.jetbrains.annotations.NotNull; import org.bukkit.Bukkit; import org.bukkit.OfflinePlayer; import com.github.sirblobman.combatlogx.api.expansion.skyblock.IslandWrapper; import us.talabrek.ultimateskyblock.api.IslandInfo; public class IslandWrapper_uSkyBlock extends IslandWrapper { private final IslandInfo island; private final Map nameCache; public IslandWrapper_uSkyBlock(@NotNull IslandInfo island) { this.island = island; this.nameCache = new HashMap<>(); } private @NotNull IslandInfo getIsland() { return this.island; } @Override public @NotNull Set getMembers() { IslandInfo island = getIsland(); Set memberNameSet = island.getMembers(); Set memberSet = new HashSet<>(); for (String memberName : memberNameSet) { UUID memberId = getPlayerId(memberName); memberSet.add(memberId); } return Collections.unmodifiableSet(memberSet); } private @NotNull UUID getPlayerId(@NotNull String playerName) { return this.nameCache.computeIfAbsent(playerName, this::fetchPlayerId); } @SuppressWarnings("deprecation") private @NotNull UUID fetchPlayerId(@NotNull String playerName) { OfflinePlayer offlinePlayer = Bukkit.getOfflinePlayer(playerName); return offlinePlayer.getUniqueId(); } } ================================================ FILE: expansion/compatibility/uSkyBlock/src/main/java/combatlogx/expansion/compatibility/uskyblock/SkyBlockHandler_uSkyBlock.java ================================================ package combatlogx.expansion.compatibility.uskyblock; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import org.bukkit.Bukkit; import org.bukkit.Location; import org.bukkit.OfflinePlayer; import org.bukkit.entity.Player; import org.bukkit.plugin.Plugin; import org.bukkit.plugin.PluginManager; import com.github.sirblobman.combatlogx.api.expansion.skyblock.IslandWrapper; import com.github.sirblobman.combatlogx.api.expansion.skyblock.SkyBlockHandler; import us.talabrek.ultimateskyblock.api.IslandInfo; import us.talabrek.ultimateskyblock.api.uSkyBlockAPI; public final class SkyBlockHandler_uSkyBlock extends SkyBlockHandler { public SkyBlockHandler_uSkyBlock(@NotNull uSkyBlockExpansion expansion) { super(expansion); } @Override public @Nullable IslandWrapper getIsland(@NotNull Location location) { return wrap(getIslandInfo(location)); } @Override public @Nullable IslandWrapper getIsland(@NotNull OfflinePlayer player) { return wrap(getIslandInfo(player)); } @Override public boolean doesIslandMatch(@NotNull OfflinePlayer player1, @NotNull OfflinePlayer player2) { IslandInfo island1 = getIslandInfo(player1); IslandInfo island2 = getIslandInfo(player2); if (island1 == null || island2 == null) { return false; } String islandName1 = island1.getName(); String islandName2 = island2.getName(); return islandName1.equals(islandName2); } private @NotNull uSkyBlockAPI getAPI() { PluginManager pluginManager = Bukkit.getPluginManager(); Plugin plugin = pluginManager.getPlugin("uSkyBlock"); return (uSkyBlockAPI) plugin; } private @Nullable IslandInfo getIslandInfo(@NotNull OfflinePlayer player) { if (!player.isOnline()) { return null; } Player onlinePlayer = player.getPlayer(); if (onlinePlayer == null) { return null; } uSkyBlockAPI api = getAPI(); return api.getIslandInfo(onlinePlayer); } private @Nullable IslandInfo getIslandInfo(@NotNull Location location) { uSkyBlockAPI api = getAPI(); return api.getIslandInfo(location); } private @Nullable IslandWrapper wrap(@Nullable IslandInfo islandInfo) { if (islandInfo == null) { return null; } return new IslandWrapper_uSkyBlock(islandInfo); } } ================================================ FILE: expansion/compatibility/uSkyBlock/src/main/java/combatlogx/expansion/compatibility/uskyblock/uSkyBlockExpansion.java ================================================ package combatlogx.expansion.compatibility.uskyblock; import org.jetbrains.annotations.NotNull; import com.github.sirblobman.combatlogx.api.ICombatLogX; import com.github.sirblobman.combatlogx.api.expansion.skyblock.SkyBlockExpansion; import com.github.sirblobman.combatlogx.api.expansion.skyblock.SkyBlockHandler; public final class uSkyBlockExpansion extends SkyBlockExpansion { private SkyBlockHandler skyBlockHandler; public uSkyBlockExpansion(ICombatLogX plugin) { super(plugin); this.skyBlockHandler = null; } @Override public boolean checkDependencies() { return checkDependency("uSkyBlock", true, "3"); } @Override public @NotNull SkyBlockHandler getSkyBlockHandler() { if (this.skyBlockHandler == null) { this.skyBlockHandler = new SkyBlockHandler_uSkyBlock(this); } return this.skyBlockHandler; } } ================================================ FILE: expansion/compatibility/uSkyBlock/src/main/resources/expansion.yml ================================================ name: "${expansionName}" prefix: "${expansionPrefix}" description: "${expansionDescription}" main: "combatlogx.expansion.compatibility.uskyblock.uSkyBlockExpansion" version: "17.1" author: "SirBlobman" plugin-depend: - "uSkyBlock" ================================================ FILE: expansion/damage-effects/README.MD ================================================ # CombatLogX Expansion: Damage Effects The damage effects expansion creates particles every time a player is damaged. ================================================ FILE: expansion/damage-effects/gradle.properties ================================================ version.spigot=1.13.2-R0.1-SNAPSHOT expansion.name=DamageEffects expansion.prefix=Damage Effects ================================================ FILE: expansion/damage-effects/src/main/java/combatlogx/expansion/damage/effects/DamageEffectsConfiguration.java ================================================ package combatlogx.expansion.damage.effects; import org.jetbrains.annotations.NotNull; import org.bukkit.configuration.ConfigurationSection; import com.github.sirblobman.api.configuration.IConfigurable; import combatlogx.expansion.damage.effects.effect.Blood; public final class DamageEffectsConfiguration implements IConfigurable { private final Blood blood; private boolean allDamage; public DamageEffectsConfiguration() { this.allDamage = false; this.blood = new Blood(); } @Override public void load(@NotNull ConfigurationSection config) { setAllDamage(config.getBoolean("all-damage", false)); getBlood().load(getOrCreateSection(config, "blood")); } public boolean isAllDamage() { return this.allDamage; } public void setAllDamage(boolean allDamage) { this.allDamage = allDamage; } public @NotNull Blood getBlood() { return this.blood; } } ================================================ FILE: expansion/damage-effects/src/main/java/combatlogx/expansion/damage/effects/DamageEffectsExpansion.java ================================================ package combatlogx.expansion.damage.effects; import com.github.sirblobman.api.utility.VersionUtility; import org.jetbrains.annotations.NotNull; import com.github.sirblobman.api.configuration.ConfigurationManager; import com.github.sirblobman.combatlogx.api.ICombatLogX; import com.github.sirblobman.combatlogx.api.expansion.Expansion; import java.util.logging.Logger; public final class DamageEffectsExpansion extends Expansion { private final DamageEffectsConfiguration configuration; public DamageEffectsExpansion(@NotNull ICombatLogX plugin) { super(plugin); this.configuration = new DamageEffectsConfiguration(); } @Override public void onLoad() { ConfigurationManager configurationManager = getConfigurationManager(); configurationManager.saveDefault("effects.yml"); } @Override public void onEnable() { int majorVersion = VersionUtility.getMajorVersion(); int minorVersion = VersionUtility.getMinorVersion(); if (majorVersion == 1 && minorVersion < 13) { Logger logger = getLogger(); logger.warning("This expansion requires Spigot 1.13 or higher."); selfDisable(); return; } reloadConfig(); new ListenerDamageEffects(this).register(); } @Override public void onDisable() { // Do Nothing } @Override public void reloadConfig() { ConfigurationManager configurationManager = getConfigurationManager(); configurationManager.reload("effects.yml"); getConfiguration().load(configurationManager.get("effects.yml")); } public @NotNull DamageEffectsConfiguration getConfiguration() { return this.configuration; } } ================================================ FILE: expansion/damage-effects/src/main/java/combatlogx/expansion/damage/effects/ListenerDamageEffects.java ================================================ package combatlogx.expansion.damage.effects; import org.jetbrains.annotations.NotNull; import org.bukkit.entity.Entity; import org.bukkit.entity.Player; import org.bukkit.event.EventHandler; import org.bukkit.event.EventPriority; import org.bukkit.event.entity.EntityDamageByEntityEvent; import com.github.sirblobman.combatlogx.api.ICombatLogX; import com.github.sirblobman.combatlogx.api.expansion.ExpansionListener; import com.github.sirblobman.combatlogx.api.utility.EntityHelper; import combatlogx.expansion.damage.effects.effect.Blood; public final class ListenerDamageEffects extends ExpansionListener { private final DamageEffectsExpansion expansion; public ListenerDamageEffects(@NotNull DamageEffectsExpansion expansion) { super(expansion); this.expansion = expansion; } @EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true) public void onEntityDamageByEntity(EntityDamageByEntityEvent e) { Entity damaged = e.getEntity(); if (!(damaged instanceof Player)) { return; } ICombatLogX combatLogX = getCombatLogX(); Entity damager = EntityHelper.linkProjectile(combatLogX, e.getDamager()); DamageEffectsConfiguration configuration = getConfiguration(); if (configuration.isAllDamage() || damager instanceof Player) { playBlood((Player) damaged); } } private @NotNull DamageEffectsExpansion getDamageEffectsExpansion() { return this.expansion; } private @NotNull DamageEffectsConfiguration getConfiguration() { DamageEffectsExpansion expansion = getDamageEffectsExpansion(); return expansion.getConfiguration(); } private void playBlood(@NotNull Player player) { DamageEffectsConfiguration configuration = getConfiguration(); Blood blood = configuration.getBlood(); if (blood.isEnabled()) { blood.play(player); } } } ================================================ FILE: expansion/damage-effects/src/main/java/combatlogx/expansion/damage/effects/effect/Blood.java ================================================ package combatlogx.expansion.damage.effects.effect; import java.awt.Color; import com.github.sirblobman.api.shaded.xseries.particles.Particles; import org.jetbrains.annotations.NotNull; import org.bukkit.Location; import org.bukkit.Particle; import org.bukkit.configuration.ConfigurationSection; import org.bukkit.entity.Player; import com.github.sirblobman.api.configuration.IConfigurable; import com.github.sirblobman.api.shaded.xseries.particles.ParticleDisplay; import com.github.sirblobman.api.shaded.xseries.particles.XParticle; public final class Blood implements DamageEffect, IConfigurable { private final Offset offset; private boolean enabled; private Color color; private float size; private double ringRate; private double ringRadius; private double ringTubeRadius; public Blood() { this.enabled = true; this.offset = new Offset(); this.color = Color.RED; this.size = 1.0F; this.ringRate = 2.0D; this.ringRadius = 2.0D; this.ringTubeRadius = 0.5D; } @Override public boolean isEnabled() { return this.enabled; } public void setEnabled(boolean enabled) { this.enabled = enabled; } @Override public void load(@NotNull ConfigurationSection section) { setEnabled(section.getBoolean("enabled", true)); getOffset().load(getOrCreateSection(section, "offset")); int red = section.getInt("color.red", 255); int green = section.getInt("color.green", 0); int blue = section.getInt("color.blue", 0); setColor(red, green, blue); setSize((float) section.getDouble("size", 1.0D)); setRingRate(section.getDouble("ring-rate", 2.0D)); setRingRadius(section.getDouble("ring-radius", 2.0D)); setRingTubeRadius(section.getDouble("ring-tube-radius", 0.5D)); } @Override public void play(@NotNull Player player) { Color color = getColor(); float size = getSize(); double rate = getRingRate(); double radius = getRingRadius(); double tubeRadius = getRingTubeRadius(); Offset offset = getOffset(); double offsetX = offset.getX(); double offsetY = offset.getY(); double offsetZ = offset.getZ(); Location location = player.getLocation().add(offsetX, offsetY, offsetZ); ParticleDisplay display = ParticleDisplay.of(XParticle.DUST); display.withColor(color, size); display.withLocation(location); Particles.ring(rate, radius, tubeRadius, display); } public @NotNull Offset getOffset() { return this.offset; } public @NotNull Color getColor() { return color; } public void setColor(@NotNull Color color) { this.color = color; } public void setColor(int red, int green, int blue) { Color color = new Color(red, green, blue); setColor(color); } public float getSize() { return this.size; } public void setSize(float size) { this.size = size; } public double getRingRate() { return this.ringRate; } public void setRingRate(double ringRate) { this.ringRate = ringRate; } public double getRingRadius() { return this.ringRadius; } public void setRingRadius(double ringRadius) { this.ringRadius = ringRadius; } public double getRingTubeRadius() { return this.ringTubeRadius; } public void setRingTubeRadius(double ringTubeRadius) { this.ringTubeRadius = ringTubeRadius; } } ================================================ FILE: expansion/damage-effects/src/main/java/combatlogx/expansion/damage/effects/effect/DamageEffect.java ================================================ package combatlogx.expansion.damage.effects.effect; import org.jetbrains.annotations.NotNull; import org.bukkit.entity.Player; public interface DamageEffect { boolean isEnabled(); void play(@NotNull Player player); } ================================================ FILE: expansion/damage-effects/src/main/java/combatlogx/expansion/damage/effects/effect/Offset.java ================================================ package combatlogx.expansion.damage.effects.effect; import org.jetbrains.annotations.NotNull; import org.bukkit.configuration.ConfigurationSection; import com.github.sirblobman.api.configuration.IConfigurable; public final class Offset implements IConfigurable { private double x; private double y; private double z; public Offset() { this.x = 0.0D; this.y = 0.0D; this.z = 0.0D; } @Override public void load(@NotNull ConfigurationSection section) { setX(section.getDouble("x", 0.0D)); setY(section.getDouble("y", 0.0D)); setZ(section.getDouble("z", 0.0D)); } public double getX() { return this.x; } public void setX(double x) { this.x = x; } public double getY() { return this.y; } public void setY(double y) { this.y = y; } public double getZ() { return this.z; } public void setZ(double z) { this.z = z; } } ================================================ FILE: expansion/damage-effects/src/main/resources/effects.yml ================================================ # Set this to 'false' to only show for pvp damage. # Set this to 'true' to show particles for all entity damage. # Default: false all-damage: false blood: # Set this to 'true' to show the blood particles. # Default: true enabled: true # This is the location offset from the player's feet # Default: 0,0,0 offset: x: 0 y: 1.5 z: 0 # This is the color of the blood particles # Default: Full red (255, 0, 0) / #FF0000 color: red: 255 green: 0 blue: 0 # Particle size # Default: 1.0 size: 1.0 # Blood ring rate. # Default: 1.0 ring-rate: 1.0 # Blood ring radius. # Default: 1.0 ring-radius: 1.0 # Blood ring tube radius. # Default: 0.5 ring-tube-radius: 0.5 ================================================ FILE: expansion/damage-effects/src/main/resources/expansion.yml ================================================ name: "${expansionName}" prefix: "${expansionPrefix}" description: "${expansionDescription}" main: "combatlogx.expansion.damage.effects.DamageEffectsExpansion" version: "17.3" author: "SirBlobman" ================================================ FILE: expansion/damage-tagger/README.MD ================================================ # CombatLogX Expansion: Damage Tagger The damage tagger expansion allows you to tag players for non-combat damage types. ## Available Damage Types: | Damage Type | Description | |---------------------|--------------------------------------------------------------| | **CONTACT** | Touching a cactus or a berry bush. | | **SUFFOCATION** | Buried in sand or teleported into a wall. | | **FALL** | Falling from a high place. | | **FIRE** | Touching a fire block. | | **FIRE_TICK** | Being on fire after touching a source of heat. | | **LAVA** | Touching or swimming in lava. | | **DROWNING** | Staying under water for too long. | | **BLOCK_EXPLOSION** | Explosions created by plugins. | | **STARVATION** | Running out of food. | | **POISON** | Damage from a Poison potion due to witches or plugins. | | **MAGIC** | Damage from the Instant Damage potion | **WITHER** | Wither effect caused by wither skeletons, roses, and bosses. | | **FALLING_BLOCK** | Damage from a falling block, such as an anvil. | | **CUSTOM** | Custom damage created by plugins. | | **FLY_INTO_WALL** | Damage caused by lack of elytra training. | | **HOT_FLOOR** | Standing on magma blocks. | | **CRAMMING** | Standing in an enclosed space with too many other mobs. |" ================================================ FILE: expansion/damage-tagger/gradle.properties ================================================ expansion.name=DamageTagger expansion.prefix=Damage Tagger ================================================ FILE: expansion/damage-tagger/src/main/java/combatlogx/expansion/damage/tagger/DamageTaggerExpansion.java ================================================ package combatlogx.expansion.damage.tagger; import com.github.sirblobman.api.configuration.ConfigurationManager; import com.github.sirblobman.combatlogx.api.ICombatLogX; import com.github.sirblobman.combatlogx.api.expansion.Expansion; import combatlogx.expansion.damage.tagger.configuration.DamageTaggerConfiguration; import combatlogx.expansion.damage.tagger.listener.ListenerDamage; public final class DamageTaggerExpansion extends Expansion { private final DamageTaggerConfiguration configuration; public DamageTaggerExpansion(ICombatLogX plugin) { super(plugin); this.configuration = new DamageTaggerConfiguration(); } @Override public void onLoad() { ConfigurationManager configurationManager = getConfigurationManager(); configurationManager.saveDefault("config.yml"); } @Override public void onEnable() { reloadConfig(); new ListenerDamage(this).register(); } @Override public void onDisable() { // Do Nothing } @Override public void reloadConfig() { ConfigurationManager configurationManager = getConfigurationManager(); configurationManager.reload("config.yml"); getConfiguration().load(configurationManager.get("config.yml")); } public DamageTaggerConfiguration getConfiguration() { return this.configuration; } } ================================================ FILE: expansion/damage-tagger/src/main/java/combatlogx/expansion/damage/tagger/configuration/DamageTaggerConfiguration.java ================================================ package combatlogx.expansion.damage.tagger.configuration; import java.util.Collections; import java.util.EnumSet; import java.util.Locale; import java.util.Set; import org.jetbrains.annotations.NotNull; import org.bukkit.configuration.ConfigurationSection; import org.bukkit.event.entity.EntityDamageEvent.DamageCause; import com.github.sirblobman.api.configuration.IConfigurable; public final class DamageTaggerConfiguration implements IConfigurable { private final Set enabledDamageTypes; private boolean allDamage; private boolean endCrystals; private boolean retagOnly; public DamageTaggerConfiguration() { this.allDamage = false; this.endCrystals = true; this.retagOnly = false; this.enabledDamageTypes = EnumSet.noneOf(DamageCause.class); } @Override public void load(ConfigurationSection config) { setAllDamage(config.getBoolean("all-damage", false)); setEndCrystals(config.getBoolean("end-crystals", true)); setRetagOnly(config.getBoolean("retag-only", false)); ConfigurationSection sectionDamageType = getOrCreateSection(config, "damage-type"); DamageCause[] damageCauses = DamageCause.values(); disableAllDamageTypes(); for (DamageCause damageCause : damageCauses) { String damageCauseName = damageCause.name().toLowerCase(Locale.US).replace('_', '-'); if (sectionDamageType.getBoolean(damageCauseName, false)) { enableDamageType(damageCause); } } } public boolean isAllDamage() { return this.allDamage; } public void setAllDamage(boolean allDamage) { this.allDamage = allDamage; } public boolean isEndCrystals() { return this.endCrystals; } public void setEndCrystals(boolean endCrystals) { this.endCrystals = endCrystals; } public boolean isRetagOnly() { return this.retagOnly; } public void setRetagOnly(boolean retagOnly) { this.retagOnly = retagOnly; } public @NotNull Set getEnabledDamageTypes() { return Collections.unmodifiableSet(this.enabledDamageTypes); } public void disableAllDamageTypes() { this.enabledDamageTypes.clear(); } public void enableDamageType(@NotNull DamageCause cause) { this.enabledDamageTypes.add(cause); } public boolean isEnabled(@NotNull DamageCause cause) { Set damageTypes = getEnabledDamageTypes(); return damageTypes.contains(cause); } } ================================================ FILE: expansion/damage-tagger/src/main/java/combatlogx/expansion/damage/tagger/listener/ListenerDamage.java ================================================ package combatlogx.expansion.damage.tagger.listener; import java.util.Locale; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import org.bukkit.entity.EnderCrystal; import org.bukkit.entity.Entity; import org.bukkit.entity.Player; import org.bukkit.event.EventHandler; import org.bukkit.event.EventPriority; import org.bukkit.event.entity.EntityDamageByEntityEvent; import org.bukkit.event.entity.EntityDamageEvent; import org.bukkit.event.entity.EntityDamageEvent.DamageCause; import com.github.sirblobman.api.language.LanguageManager; import com.github.sirblobman.combatlogx.api.ICombatLogX; import com.github.sirblobman.combatlogx.api.expansion.ExpansionListener; import com.github.sirblobman.combatlogx.api.manager.ICombatManager; import com.github.sirblobman.combatlogx.api.object.TagReason; import com.github.sirblobman.combatlogx.api.object.TagType; import combatlogx.expansion.damage.tagger.DamageTaggerExpansion; import combatlogx.expansion.damage.tagger.configuration.DamageTaggerConfiguration; public final class ListenerDamage extends ExpansionListener { private final DamageTaggerExpansion expansion; public ListenerDamage(@NotNull DamageTaggerExpansion expansion) { super(expansion); this.expansion = expansion; } @EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true) public void onDamage(EntityDamageEvent e) { Entity entity = e.getEntity(); if (!(entity instanceof Player)) { return; } Player player = (Player) entity; DamageCause damageCause = e.getCause(); if (e instanceof EntityDamageByEntityEvent) { EntityDamageByEntityEvent ee = (EntityDamageByEntityEvent) e; Entity damager = ee.getDamager(); if (damageCause == DamageCause.ENTITY_EXPLOSION) { if (damager instanceof EnderCrystal && isCrystalDamageEnabled()) { tag(player, damageCause); } } if (damageCause == DamageCause.FALLING_BLOCK) { tag(player, damageCause); } return; } if (isAllDamageEnabled()) { tag(player, null); return; } if (isEnabled(damageCause)) { tag(player, damageCause); } } private @NotNull DamageTaggerExpansion getDamageTagger() { return this.expansion; } private DamageTaggerConfiguration getConfiguration() { DamageTaggerExpansion expansion = getDamageTagger(); return expansion.getConfiguration(); } private boolean isAllDamageEnabled() { DamageTaggerConfiguration configuration = getConfiguration(); return configuration.isAllDamage(); } private boolean isCrystalDamageEnabled() { if (isAllDamageEnabled()) { return true; } DamageTaggerConfiguration configuration = getConfiguration(); return configuration.isEndCrystals(); } private boolean isEnabled(@NotNull DamageCause cause) { if (isAllDamageEnabled()) { return true; } DamageTaggerConfiguration configuration = getConfiguration(); return configuration.isEnabled(cause); } private void tag(@NotNull Player player, @Nullable DamageCause damageCause) { ICombatManager combatManager = getCombatManager(); DamageTaggerConfiguration configuration = getConfiguration(); boolean alreadyInCombat = combatManager.isInCombat(player); boolean retagOnly = configuration.isRetagOnly(); if (retagOnly && !alreadyInCombat) { return; } boolean tagged = combatManager.tag(player, null, TagType.DAMAGE, TagReason.UNKNOWN); if (tagged && !alreadyInCombat) { sendMessage(player, damageCause); } } private void sendMessage(@NotNull Player player, @Nullable DamageCause damageCause) { ICombatLogX combatLogX = getCombatLogX(); LanguageManager languageManager = combatLogX.getLanguageManager(); if (damageCause == null || isAllDamageEnabled()) { languageManager.sendMessageWithPrefix(player, "expansion.damage-tagger.unknown-damage"); return; } String damageCauseName = damageCause.name(); String damageCauseNameLowerCase = damageCauseName.toLowerCase(Locale.US); String damageCauseNameReplaced = damageCauseNameLowerCase.replace('_', '-'); String messagePath = ("expansion.damage-tagger.damage-type." + damageCauseNameReplaced); languageManager.sendMessageWithPrefix(player, messagePath); } } ================================================ FILE: expansion/damage-tagger/src/main/resources/config.yml ================================================ # Set this to true if players should be tagged by all types of damage. # If this is true, damage-type settings will be ignored. # Default: true all-damage: true # Should CombatLogX tag players when they are blown up by end crystals? end-crystals: true # Should CombatLogX only use Damage Tagger when a player is already tagged by something else? retag-only: false # See the SpigotMC Documentation for descriptions. # https://hub.spigotmc.org/javadocs/spigot/org/bukkit/event/entity/EntityDamageEvent.DamageCause.html damage-type: block-explosion: false contact: false cramming: false custom: false drowning: false dryout: false entity-explosion: false # Only triggered by end crystals. fall: false falling-block: false fire: false fire-tick: false fly-into-wall: false freeze: false hot-floor: false lava: false lightning: false magic: false melting: false poison: false starvation: false suffocation: false void: false wither: false world-border: false ================================================ FILE: expansion/damage-tagger/src/main/resources/expansion.yml ================================================ name: "${expansionName}" prefix: "${expansionPrefix}" description: "${expansionDescription}" main: "combatlogx.expansion.damage.tagger.DamageTaggerExpansion" version: "17.1" author: "SirBlobman" ================================================ FILE: expansion/death-effects/README.MD ================================================ # CombatLogX Expansion: Death Effects The death effects expansion creates different effects when players die. You can configure these effects to trigger for combat-log deaths or for all deaths. ## Available Death Effects: | Effect | Description | |-----------------|----------------------------------------------------------------------------| | **LIGHTNING** | Spawn a lightning bolt. Configurable silence and effect-only values. | | **BLOOD** | Spawn redstone particles and a fake redstone dust block. Not configurable. | | **BLOOD_ITEMS** | Spawn items that can't be picked up. Configurable type and amount. | ================================================ FILE: expansion/death-effects/gradle.properties ================================================ version.spigot=1.13.2-R0.1-SNAPSHOT expansion.name=DeathEffects expansion.prefix=Death Effects ================================================ FILE: expansion/death-effects/src/main/java/combatlogx/expansion/death/effects/DeathEffectsConfiguration.java ================================================ package combatlogx.expansion.death.effects; import java.util.ArrayList; import java.util.Collection; import java.util.Collections; import java.util.List; import java.util.Optional; import org.jetbrains.annotations.NotNull; import org.bukkit.configuration.ConfigurationSection; import com.github.sirblobman.api.configuration.IConfigurable; import com.github.sirblobman.api.shaded.xseries.XMaterial; public final class DeathEffectsConfiguration implements IConfigurable { private final List deathEffectList; private boolean requireCombatDeath; private boolean lightningEffectOnly; private boolean lightningSilent; private XMaterial bloodItemsMaterial; private int bloodItemsAmount; private long bloodItemsStayTicks; public DeathEffectsConfiguration() { this.requireCombatDeath = true; this.deathEffectList = new ArrayList<>(); this.lightningEffectOnly = true; this.lightningSilent = true; this.bloodItemsMaterial = XMaterial.RED_DYE; this.bloodItemsAmount = 10; this.bloodItemsStayTicks = 100L; } @Override public void load(@NotNull ConfigurationSection section) { setRequireCombatDeath(section.getBoolean("combat-death-only", true)); setDeathEffectList(section.getStringList("death-effect-list")); ConfigurationSection sectionLightning = getOrCreateSection(section, "lightning"); setLightningEffectOnly(sectionLightning.getBoolean("effect-only", true)); setLightningSilent(sectionLightning.getBoolean("silent", true)); ConfigurationSection sectionBloodItems = getOrCreateSection(section, "blood-items"); setBloodItemsAmount(sectionBloodItems.getInt("amount", 10)); setBloodItemsStayTicks(sectionBloodItems.getLong("stay-ticks", 100L)); loadBloodItemsMaterial(sectionBloodItems); } private void loadBloodItemsMaterial(ConfigurationSection section) { String bloodItemsMaterialName = section.getString("material", "RED_DYE"); if (bloodItemsMaterialName == null) { bloodItemsMaterialName = "RED_DYE"; } Optional optionalBloodItemsMaterial = XMaterial.matchXMaterial(bloodItemsMaterialName); XMaterial bloodItemsMaterial = optionalBloodItemsMaterial.orElse(XMaterial.RED_DYE); setBloodItemsMaterial(bloodItemsMaterial); } public boolean isRequireCombatDeath() { return requireCombatDeath; } public void setRequireCombatDeath(boolean requireCombatDeath) { this.requireCombatDeath = requireCombatDeath; } public List getDeathEffectList() { return Collections.unmodifiableList(this.deathEffectList); } public void setDeathEffectList(Collection deathEffectList) { this.deathEffectList.clear(); this.deathEffectList.addAll(deathEffectList); } public boolean hasEffect(String deathEffect) { List deathEffectList = getDeathEffectList(); return deathEffectList.contains(deathEffect); } public boolean isLightningEffectOnly() { return lightningEffectOnly; } public void setLightningEffectOnly(boolean lightningEffectOnly) { this.lightningEffectOnly = lightningEffectOnly; } public boolean isLightningSilent() { return lightningSilent; } public void setLightningSilent(boolean lightningSilent) { this.lightningSilent = lightningSilent; } public XMaterial getBloodItemsMaterial() { return bloodItemsMaterial; } public void setBloodItemsMaterial(XMaterial bloodItemsMaterial) { this.bloodItemsMaterial = bloodItemsMaterial; } public int getBloodItemsAmount() { return bloodItemsAmount; } public void setBloodItemsAmount(int bloodItemsAmount) { this.bloodItemsAmount = bloodItemsAmount; } public long getBloodItemsStayTicks() { return bloodItemsStayTicks; } public void setBloodItemsStayTicks(long bloodItemsStayTicks) { this.bloodItemsStayTicks = bloodItemsStayTicks; } } ================================================ FILE: expansion/death-effects/src/main/java/combatlogx/expansion/death/effects/DeathEffectsExpansion.java ================================================ package combatlogx.expansion.death.effects; import org.bukkit.configuration.file.YamlConfiguration; import com.github.sirblobman.api.configuration.ConfigurationManager; import com.github.sirblobman.combatlogx.api.ICombatLogX; import com.github.sirblobman.combatlogx.api.expansion.Expansion; public final class DeathEffectsExpansion extends Expansion { private final DeathEffectsConfiguration configuration; public DeathEffectsExpansion(ICombatLogX plugin) { super(plugin); this.configuration = new DeathEffectsConfiguration(); } @Override public void onLoad() { ConfigurationManager configurationManager = getConfigurationManager(); configurationManager.saveDefault("config.yml"); } @Override public void onEnable() { reloadConfig(); new ListenerDeathEffects(this).register(); } @Override public void onDisable() { // Do Nothing } @Override public void reloadConfig() { ConfigurationManager configurationManager = getConfigurationManager(); configurationManager.reload("config.yml"); YamlConfiguration configuration = configurationManager.get("config.yml"); DeathEffectsConfiguration deathEffectsConfiguration = getConfiguration(); deathEffectsConfiguration.load(configuration); } public DeathEffectsConfiguration getConfiguration() { return this.configuration; } } ================================================ FILE: expansion/death-effects/src/main/java/combatlogx/expansion/death/effects/ListenerDeathEffects.java ================================================ package combatlogx.expansion.death.effects; import java.util.List; import org.bukkit.Effect; import org.bukkit.Location; import org.bukkit.Material; import org.bukkit.World; import org.bukkit.World.Spigot; import org.bukkit.block.data.BlockData; import org.bukkit.entity.Entity; import org.bukkit.entity.Item; import org.bukkit.entity.Player; import org.bukkit.event.EventHandler; import org.bukkit.event.EventPriority; import org.bukkit.event.entity.EntityPickupItemEvent; import org.bukkit.event.entity.PlayerDeathEvent; import org.bukkit.event.inventory.InventoryPickupItemEvent; import org.bukkit.inventory.ItemStack; import org.bukkit.metadata.FixedMetadataValue; import org.bukkit.metadata.MetadataValue; import org.bukkit.plugin.java.JavaPlugin; import com.github.sirblobman.api.folia.scheduler.TaskScheduler; import com.github.sirblobman.api.item.ItemBuilder; import com.github.sirblobman.api.nms.EntityHandler; import com.github.sirblobman.api.nms.MultiVersionHandler; import com.github.sirblobman.api.utility.VersionUtility; import com.github.sirblobman.combatlogx.api.ICombatLogX; import com.github.sirblobman.combatlogx.api.expansion.ExpansionListener; import com.github.sirblobman.combatlogx.api.manager.IDeathManager; import com.github.sirblobman.api.shaded.xseries.XMaterial; import combatlogx.expansion.death.effects.task.ItemRemoveTask; public final class ListenerDeathEffects extends ExpansionListener { private final DeathEffectsExpansion expansion; public ListenerDeathEffects(DeathEffectsExpansion expansion) { super(expansion); this.expansion = expansion; } @EventHandler(priority = EventPriority.LOW, ignoreCancelled = true) public void onDeath(PlayerDeathEvent e) { Player player = e.getEntity(); DeathEffectsConfiguration configuration = getConfiguration(); if (configuration.isRequireCombatDeath()) { ICombatLogX combatLogX = getCombatLogX(); IDeathManager deathManager = combatLogX.getDeathManager(); if (!deathManager.wasPunishKilled(player)) { return; } } if (configuration.hasEffect("BLOOD")) { playBloodEffect(player); } if (configuration.hasEffect("LIGHTNING")) { playLightningEffect(player); } if (configuration.hasEffect("BLOOD_ITEMS")) { playBloodItemsEffect(player); } } @EventHandler(priority = EventPriority.NORMAL, ignoreCancelled = true) public void onPickup(InventoryPickupItemEvent e) { Item itemEntity = e.getItem(); if (itemEntity.hasMetadata("fake-item")) { e.setCancelled(true); } } @EventHandler(priority = EventPriority.NORMAL, ignoreCancelled = true) public void onPickup(EntityPickupItemEvent e) { Item itemEntity = e.getItem(); if (itemEntity.hasMetadata("fake-item")) { e.setCancelled(true); } } private DeathEffectsExpansion getDeathEffectsExpansion() { return this.expansion; } private DeathEffectsConfiguration getConfiguration() { DeathEffectsExpansion expansion = getDeathEffectsExpansion(); return expansion.getConfiguration(); } private void playLightningEffect(Player player) { DeathEffectsConfiguration configuration = getConfiguration(); boolean effectOnly = configuration.isLightningEffectOnly(); boolean silent = configuration.isLightningSilent(); Location location = player.getLocation(); World world = player.getWorld(); Spigot spigot = world.spigot(); if (effectOnly) { spigot.strikeLightningEffect(location, silent); } else { spigot.strikeLightning(location, silent); } } private void playBloodEffect(Player player) { Material bukkitMaterial = XMaterial.REDSTONE_BLOCK.get(); if (bukkitMaterial != null) { World world = player.getWorld(); Location location = player.getLocation(); world.playEffect(location, Effect.STEP_SOUND, bukkitMaterial); } Location location = player.getLocation(); List nearbyEntityList = player.getNearbyEntities(200D, 20.0D, 20.0D); for (Entity entity : nearbyEntityList) { if (entity instanceof Player other) { sendFakeRedstoneDust(other, location); } } } @SuppressWarnings("deprecation") private void sendFakeRedstoneDust(Player player, Location location) { Material bukkitMaterial = XMaterial.REDSTONE_WIRE.parseMaterial(); if (bukkitMaterial == null) { return; } int minorVersion = VersionUtility.getMinorVersion(); if (minorVersion < 13) { player.sendBlockChange(location, bukkitMaterial, (byte) 0); return; } BlockData blockData = bukkitMaterial.createBlockData(); player.sendBlockChange(location, blockData); } private void playBloodItemsEffect(Player player) { ICombatLogX combatLogX = getCombatLogX(); MultiVersionHandler multiVersionHandler = combatLogX.getMultiVersionHandler(); EntityHandler entityHandler = multiVersionHandler.getEntityHandler(); Location location = player.getLocation(); DeathEffectsConfiguration configuration = getConfiguration(); int amount = configuration.getBloodItemsAmount(); for (int i = 0; i < amount; i++) { spawnFakeItem(location, entityHandler); } } private void spawnFakeItem(Location location, EntityHandler entityHandler) { DeathEffectsConfiguration configuration = getConfiguration(); XMaterial material = configuration.getBloodItemsMaterial(); ItemStack item = new ItemBuilder(material).build(); Item itemEntity = entityHandler.spawnEntity(location, Item.class, preItem -> { preItem.setItemStack(item); preItem.setPickupDelay(Integer.MAX_VALUE); JavaPlugin plugin = getJavaPlugin(); MetadataValue value = new FixedMetadataValue(plugin, true); preItem.setMetadata("fake-item", value); }); long delay = configuration.getBloodItemsStayTicks(); ItemRemoveTask removeTask = new ItemRemoveTask(getJavaPlugin(), itemEntity); removeTask.setDelay(delay); TaskScheduler scheduler = getCombatLogX().getFoliaHelper().getScheduler(); scheduler.scheduleEntityTask(removeTask); } } ================================================ FILE: expansion/death-effects/src/main/java/combatlogx/expansion/death/effects/task/ItemRemoveTask.java ================================================ package combatlogx.expansion.death.effects.task; import org.jetbrains.annotations.NotNull; import org.bukkit.entity.Item; import com.github.sirblobman.api.folia.details.EntityTaskDetails; import com.github.sirblobman.api.plugin.ConfigurablePlugin; public final class ItemRemoveTask extends EntityTaskDetails { public ItemRemoveTask(@NotNull ConfigurablePlugin plugin, @NotNull Item entity) { super(plugin, entity); } @Override public void run() { Item entity = getEntity(); if (entity != null) { entity.removeMetadata("fake-item", getPlugin()); entity.remove(); } } } ================================================ FILE: expansion/death-effects/src/main/resources/config.yml ================================================ # Should these effects apply only to logging out during combat, or to all deaths? # Default: true combat-death-only: true # Which death effects are enabled? # Available Effects can be found on the README page. # https://github.com/SirBlobman/CombatLogX/blob/main/expansion/death-effects/README.MD # Default: ALL death-effect-list: - BLOOD - LIGHTNING - BLOOD_ITEMS lightning: # Should the lightning only be a visual effect (no damage to nearby players or blocks)? # Default: true effect-only: true # Should the lightning be silent? # Lightning can be annoying to some players. # Default: true silent: true blood-items: # This is the type of item that will be dropped on the ground. # Use XMaterial names. # Default: RED_DYE material: RED_DYE # This is the amount of items that will be dropped on the ground. # Default: 10 amount: 10 # This is the amount of ticks that the items will exist. # Default: 100 (5 seconds) stay-ticks: 100 ================================================ FILE: expansion/death-effects/src/main/resources/expansion.yml ================================================ name: "${expansionName}" prefix: "${expansionPrefix}" description: "${expansionDescription}" main: "combatlogx.expansion.death.effects.DeathEffectsExpansion" version: "17.0" author: "SirBlobman" ================================================ FILE: expansion/end-crystal/build.gradle.kts ================================================ import com.github.jengelman.gradle.plugins.shadow.tasks.ShadowJar plugins { id("com.gradleup.shadow") version "9.2.2" } dependencies { implementation(project(":expansion:end-crystal:legacy")) implementation(project(":expansion:end-crystal:modern")) } tasks { named("jar") { enabled = false } named("shadowJar") { val expansionName = findProperty("expansion.name") ?: "invalid" val expansionPrefix = findProperty("expansion.prefix") ?: expansionName archiveFileName.set("$expansionPrefix.jar") archiveClassifier.set(null as String?) } named("build") { dependsOn("shadowJar") } } ================================================ FILE: expansion/end-crystal/gradle.properties ================================================ expansion.name=EndCrystalHelper expansion.prefix=End Crystal Helper version.spigot=1.8.8-R0.1-SNAPSHOT ================================================ FILE: expansion/end-crystal/legacy/gradle.properties ================================================ version.spigot=1.9.4-R0.1-SNAPSHOT ================================================ FILE: expansion/end-crystal/legacy/src/main/java/combatlogx/expansion/endcrystals/CheckEndCrystalTask.java ================================================ package combatlogx.expansion.endcrystals; import java.util.Collection; import org.jetbrains.annotations.NotNull; import org.bukkit.Location; import org.bukkit.World; import org.bukkit.entity.Entity; import org.bukkit.entity.EntityType; import org.bukkit.entity.Player; import com.github.sirblobman.api.folia.details.LocationTaskDetails; import com.github.sirblobman.combatlogx.api.ICombatLogX; import com.github.sirblobman.combatlogx.api.manager.ICrystalManager; import com.github.sirblobman.api.shaded.xseries.XEntityType; public final class CheckEndCrystalTask extends LocationTaskDetails { private final ICombatLogX plugin; private final Player player; public CheckEndCrystalTask(@NotNull ICombatLogX plugin, @NotNull Location location, @NotNull Player player) { super(plugin.getPlugin(), location); this.plugin = plugin; this.player = player; } @Override public void run() { Location location = getLocation(); World world = location.getWorld(); if (world == null) { return; } Collection nearbyEntityCollection = world.getNearbyEntities(location, 4.0D, 4.0D, 4.0D); for (Entity entity : nearbyEntityCollection) { XEntityType entityType = XEntityType.of(entity); if (entityType != XEntityType.END_CRYSTAL) { continue; } ICombatLogX combatLogX = getCombatLogX(); ICrystalManager crystalManager = combatLogX.getCrystalManager(); crystalManager.setPlacer(entity, getPlayer()); break; } } private @NotNull ICombatLogX getCombatLogX() { return this.plugin; } private @NotNull Player getPlayer() { return this.player; } } ================================================ FILE: expansion/end-crystal/legacy/src/main/java/combatlogx/expansion/endcrystals/ListenerCrystals_Legacy.java ================================================ package combatlogx.expansion.endcrystals; import org.jetbrains.annotations.NotNull; import org.bukkit.Material; import org.bukkit.block.Block; import org.bukkit.entity.Player; import org.bukkit.event.EventHandler; import org.bukkit.event.EventPriority; import org.bukkit.event.block.Action; import org.bukkit.event.player.PlayerInteractEvent; import org.bukkit.inventory.ItemStack; import com.github.sirblobman.api.folia.scheduler.TaskScheduler; import com.github.sirblobman.api.utility.ItemUtility; import com.github.sirblobman.combatlogx.api.expansion.Expansion; import com.github.sirblobman.combatlogx.api.expansion.ExpansionListener; public final class ListenerCrystals_Legacy extends ExpansionListener { public ListenerCrystals_Legacy(@NotNull Expansion expansion) { super(expansion); } @EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true) public void onPlayerInteract(PlayerInteractEvent e) { Action action = e.getAction(); if (action != Action.RIGHT_CLICK_BLOCK) { return; } Block block = e.getClickedBlock(); if (block == null) { return; } // End Crystals can only be placed on obsidian/bedrock. // If there is another way, this check may be changed. Material blockType = block.getType(); if (blockType != Material.OBSIDIAN && blockType != Material.BEDROCK) { return; } ItemStack item = e.getItem(); if (ItemUtility.isAir(item)) { return; } Material itemType = item.getType(); if (itemType != Material.END_CRYSTAL) { return; } Player player = e.getPlayer(); CheckEndCrystalTask task = new CheckEndCrystalTask(getCombatLogX(), block.getLocation(), player); task.setDelay(1L); TaskScheduler scheduler = getCombatLogX().getFoliaHelper().getScheduler(); scheduler.scheduleLocationTask(task); } } ================================================ FILE: expansion/end-crystal/modern/gradle.properties ================================================ version.spigot=1.13.2-R0.1-SNAPSHOT ================================================ FILE: expansion/end-crystal/modern/src/main/java/combatlogx/expansion/endcrystals/ListenerCrystals_Modern.java ================================================ package combatlogx.expansion.endcrystals; import org.jetbrains.annotations.NotNull; import org.bukkit.entity.Entity; import org.bukkit.entity.EntityType; import org.bukkit.entity.Player; import org.bukkit.event.EventHandler; import org.bukkit.event.EventPriority; import com.github.sirblobman.combatlogx.api.ICombatLogX; import com.github.sirblobman.combatlogx.api.configuration.MainConfiguration; import com.github.sirblobman.combatlogx.api.expansion.Expansion; import com.github.sirblobman.combatlogx.api.expansion.ExpansionListener; import com.github.sirblobman.combatlogx.api.manager.ICrystalManager; import com.github.sirblobman.api.shaded.xseries.XEntityType; public final class ListenerCrystals_Modern extends ExpansionListener { public ListenerCrystals_Modern(@NotNull Expansion expansion) { super(expansion); } @EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true) public void onPlace(org.bukkit.event.entity.EntityPlaceEvent e) { ICombatLogX plugin = getCombatLogX(); MainConfiguration configuration = plugin.getConfiguration(); if (!configuration.isLinkEndCrystals()) { return; } EntityType bukkitEntityType = e.getEntityType(); XEntityType entityType = XEntityType.of(bukkitEntityType); if (entityType != XEntityType.END_CRYSTAL) { return; } Player player = e.getPlayer(); if (player == null) { return; } Entity crystal = e.getEntity(); ICrystalManager crystalManager = plugin.getCrystalManager(); crystalManager.setPlacer(crystal, player); } } ================================================ FILE: expansion/end-crystal/src/main/java/combatlogx/expansion/endcrystals/EndCrystalExpansion.java ================================================ package combatlogx.expansion.endcrystals; import java.util.logging.Logger; import org.jetbrains.annotations.NotNull; import com.github.sirblobman.api.utility.VersionUtility; import com.github.sirblobman.combatlogx.api.ICombatLogX; import com.github.sirblobman.combatlogx.api.expansion.Expansion; import com.github.sirblobman.combatlogx.api.expansion.ExpansionListener; public final class EndCrystalExpansion extends Expansion { public EndCrystalExpansion(@NotNull ICombatLogX plugin) { super(plugin); } @Override public void onLoad() { // Empty Method } @Override public void onEnable() { int majorVersion = VersionUtility.getMajorVersion(); int minorVersion = VersionUtility.getMinorVersion(); if (majorVersion == 1 && minorVersion < 9) { Logger logger = getLogger(); logger.warning("This expansion requires Spigot 1.9.4 or higher."); selfDisable(); return; } reloadConfig(); getPreferredListener().register(); } @Override public void onDisable() { // Empty Method } @Override public void reloadConfig() { // Empty Method } private @NotNull ExpansionListener getPreferredListener() { int minorVersion = VersionUtility.getMinorVersion(); if (minorVersion < 13) { return new ListenerCrystals_Legacy(this); } return new ListenerCrystals_Modern(this); } } ================================================ FILE: expansion/end-crystal/src/main/resources/expansion.yml ================================================ name: "${expansionName}" prefix: "${expansionPrefix}" description: "${expansionDescription}" main: "combatlogx.expansion.endcrystals.EndCrystalExpansion" version: "17.5" author: "SirBlobman" ================================================ FILE: expansion/force-field/README.MD ================================================ # CombatLogX Expansion: Force Field The force field expansion shows a border around protected non-pvp areas. You must have at least one compatibility expansion to use the force field. ## Disclaimers: - The force field is a nice visual effect that shows players areas they cannot enter. - The force field should not be used as entry prevention, as players can just ignore the fake block packets that are sent to them. - For the actual entry prevention options, please check the configuration for your region expansion (e.g. WorldGuard Compatibility). - If your server has weak hardware, or you have a lot of players online, we recommend disabling the force field effect. - You can try unsafe mode and see if performance improves, but the most recommended option is to disable the force field. ================================================ FILE: expansion/force-field/build.gradle.kts ================================================ repositories { maven("https://nexus.sirblobman.xyz/proxy-public") } dependencies { compileOnly("com.comphenix.protocol:ProtocolLib:5.4.0-SNAPSHOT") } ================================================ FILE: expansion/force-field/gradle.properties ================================================ version.spigot=1.13.2-R0.1-SNAPSHOT expansion.name=ForceField expansion.prefix=Force Field ================================================ FILE: expansion/force-field/src/main/java/combatlogx/expansion/force/field/ForceFieldExpansion.java ================================================ package combatlogx.expansion.force.field; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import com.github.sirblobman.api.configuration.ConfigurationManager; import com.github.sirblobman.combatlogx.api.ICombatLogX; import com.github.sirblobman.combatlogx.api.expansion.Expansion; import combatlogx.expansion.force.field.configuration.ForceFieldConfiguration; import combatlogx.expansion.force.field.task.ForceFieldTask; public final class ForceFieldExpansion extends Expansion { private final ForceFieldConfiguration configuration; private ForceFieldTask task; public ForceFieldExpansion(@NotNull ICombatLogX plugin) { super(plugin); this.configuration = new ForceFieldConfiguration(); this.task = null; } @Override public void onLoad() { ConfigurationManager configurationManager = getConfigurationManager(); configurationManager.saveDefault("config.yml"); } @Override public void onEnable() { if (!checkDependency("ProtocolLib", true, "5")) { selfDisable(); return; } reloadConfig(); registerTask(); } @Override public void onDisable() { ForceFieldTask task = getTask(); if (task == null) { return; } task.cancel(); task.removeProtocol(); this.task = null; } @Override public void reloadConfig() { ConfigurationManager configurationManager = getConfigurationManager(); configurationManager.reload("config.yml"); getConfiguration().load(configurationManager.get("config.yml")); } public @Nullable ForceFieldTask getTask() { return this.task; } public @NotNull ForceFieldConfiguration getConfiguration() { return this.configuration; } private void registerTask() { this.task = new ForceFieldTask(this); this.task.register(); this.task.registerTask(); this.task.registerProtocol(); } } ================================================ FILE: expansion/force-field/src/main/java/combatlogx/expansion/force/field/configuration/ForceFieldConfiguration.java ================================================ package combatlogx.expansion.force.field.configuration; import java.util.Optional; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import org.bukkit.configuration.ConfigurationSection; import org.bukkit.permissions.Permission; import org.bukkit.permissions.PermissionDefault; import com.github.sirblobman.api.configuration.IConfigurable; import com.github.sirblobman.api.shaded.xseries.XMaterial; public final class ForceFieldConfiguration implements IConfigurable { private boolean enabled; private XMaterial material; private int radius; private String bypassPermissionName; private transient Permission bypassPermission; public ForceFieldConfiguration() { this.enabled = true; this.material = XMaterial.RED_STAINED_GLASS; this.radius = 8; this.bypassPermissionName = "combatlogx.bypass.force.field"; } @Override public void load(@NotNull ConfigurationSection section) { setEnabled(section.getBoolean("enabled", true)); setMaterial(section.getString("material", "RED_STAINED_GLASS")); setRadius(section.getInt("radius", 8)); setBypassPermissionName(section.getString("bypass-permission")); } public boolean isEnabled() { return this.enabled; } public void setEnabled(boolean enabled) { this.enabled = enabled; } public @NotNull XMaterial getMaterial() { return this.material; } public void setMaterial(@NotNull XMaterial material) { this.material = material; } public void setMaterial(@Nullable String materialName) { if (materialName == null) { setMaterial(XMaterial.RED_STAINED_GLASS); return; } Optional optionalMaterial = XMaterial.matchXMaterial(materialName); setMaterial(optionalMaterial.orElse(XMaterial.RED_STAINED_GLASS)); } public int getRadius() { return this.radius; } public void setRadius(int radius) { if (radius < 1) { throw new IllegalArgumentException("radius must be at least one."); } this.radius = radius; } public @Nullable String getBypassPermissionName() { return bypassPermissionName; } public void setBypassPermissionName(@Nullable String bypassPermissionName) { this.bypassPermissionName = bypassPermissionName; this.bypassPermission = null; } public @Nullable Permission getBypassPermission() { if (this.bypassPermission != null) { return this.bypassPermission; } String permissionName = getBypassPermissionName(); if (permissionName == null || permissionName.isEmpty()) { return null; } String description = "CombatLogX Force Field Bypass"; this.bypassPermission = new Permission(permissionName, description, PermissionDefault.FALSE); return this.bypassPermission; } } ================================================ FILE: expansion/force-field/src/main/java/combatlogx/expansion/force/field/task/ForceFieldAdapter.java ================================================ package combatlogx.expansion.force.field.task; import java.util.Map; import java.util.Set; import java.util.UUID; import com.github.sirblobman.api.folia.details.LocationTaskDetails; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import org.bukkit.GameMode; import org.bukkit.Location; import org.bukkit.Material; import org.bukkit.World; import org.bukkit.entity.Player; import org.bukkit.plugin.java.JavaPlugin; import com.github.sirblobman.api.location.BlockLocation; import com.github.sirblobman.api.utility.VersionUtility; import com.github.sirblobman.combatlogx.api.ICombatLogX; import com.github.sirblobman.combatlogx.api.manager.ICombatManager; import com.github.sirblobman.combatlogx.api.object.TagInformation; import com.github.sirblobman.api.shaded.xseries.XMaterial; import com.comphenix.protocol.PacketType; import com.comphenix.protocol.PacketType.Play.Client; import com.comphenix.protocol.PacketType.Play.Server; import com.comphenix.protocol.events.ListenerPriority; import com.comphenix.protocol.events.PacketAdapter; import com.comphenix.protocol.events.PacketContainer; import com.comphenix.protocol.events.PacketEvent; import com.comphenix.protocol.reflect.FieldAccessException; import com.comphenix.protocol.reflect.StructureModifier; import com.comphenix.protocol.wrappers.BlockPosition; import com.comphenix.protocol.wrappers.EnumWrappers.PlayerDigType; import com.comphenix.protocol.wrappers.MovingObjectPositionBlock; import com.comphenix.protocol.wrappers.WrappedBlockData; import combatlogx.expansion.force.field.ForceFieldExpansion; import combatlogx.expansion.force.field.configuration.ForceFieldConfiguration; /** * @author olivolja3 */ public final class ForceFieldAdapter extends PacketAdapter { private final ForceFieldExpansion expansion; public ForceFieldAdapter(@NotNull ForceFieldExpansion expansion) { this(expansion, expansion.getPlugin()); } private ForceFieldAdapter(@NotNull ForceFieldExpansion expansion, @NotNull ICombatLogX combatLogX) { this(expansion, combatLogX.getPlugin()); } private ForceFieldAdapter(@NotNull ForceFieldExpansion expansion, @NotNull JavaPlugin plugin) { super(plugin, ListenerPriority.NORMAL, Client.USE_ITEM, Client.BLOCK_DIG, Server.BLOCK_CHANGE); this.expansion = expansion; } @Override public void onPacketReceiving(@NotNull PacketEvent e) { if (e.isCancelled()) { return; } ForceFieldTask task = getTask(); if (task == null) { return; } Player player = e.getPlayer(); ICombatManager combatManager = getCombatManager(); if (!combatManager.isInCombat(player)) { return; } TagInformation tag = combatManager.getTagInformation(player); if (tag == null) { return; } World world = player.getWorld(); PacketContainer packet = e.getPacket(); Location location = getLocation0(world, packet); if (location == null) { return; } getCombatLogX().getFoliaHelper().getScheduler().scheduleLocationTask(new LocationTaskDetails(plugin, location) { @Override public void run() { if (isForceFieldBlock(task, player, location, tag)) { sendForceField(task, player, location, packet); } } }); } @Override public void onPacketSending(PacketEvent e) { if (e.isCancelled()) { return; } ForceFieldTask task = getTask(); if (task == null) { return; } Player player = e.getPlayer(); ICombatManager combatManager = getCombatManager(); if (!combatManager.isInCombat(player)) { return; } TagInformation tagInformation = combatManager.getTagInformation(player); if (tagInformation == null) { return; } World world = player.getWorld(); PacketContainer packetContainer = e.getPacket(); Location location = getLocation0(world, packetContainer); if (location == null) { return; } if (isForceFieldBlock(task, player, location, tagInformation)) { WrappedBlockData wrappedBlockData = getWrappedBlockData(); StructureModifier blockData = packetContainer.getBlockData(); blockData.writeSafely(0, wrappedBlockData); } } private @NotNull ForceFieldExpansion getExpansion() { return this.expansion; } private @Nullable ForceFieldTask getTask() { ForceFieldExpansion expansion = getExpansion(); return expansion.getTask(); } private @NotNull ForceFieldConfiguration getConfiguration() { ForceFieldExpansion expansion = getExpansion(); return expansion.getConfiguration(); } private @NotNull ICombatLogX getCombatLogX() { ForceFieldExpansion expansion = getExpansion(); return expansion.getPlugin(); } private @NotNull ICombatManager getCombatManager() { ICombatLogX combatLogX = getCombatLogX(); return combatLogX.getCombatManager(); } private boolean isForceFieldBlock(@NotNull ForceFieldTask task, @NotNull Player player, @NotNull Location location, @NotNull TagInformation tag) { UUID playerId = player.getUniqueId(); Map> fakeBlockMap = task.getFakeBlockMap(); if (fakeBlockMap.containsKey(playerId)) { boolean isSafe = task.isSafe(player, location); boolean isSafeSurround = task.isSafeSurround(player, location, tag); boolean canPlace = task.canPlace(BlockLocation.from(location)); if (isSafe && isSafeSurround && canPlace) { BlockLocation worldXYZ = BlockLocation.from(location); return fakeBlockMap.get(playerId).contains(worldXYZ); } } return false; } private @NotNull WrappedBlockData getWrappedBlockData() { ForceFieldConfiguration configuration = getConfiguration(); XMaterial material = configuration.getMaterial(); Material bukkitMaterial = material.get(); if (bukkitMaterial == null) { throw new IllegalStateException("Invalid material configuration!"); } int minorVersion = VersionUtility.getMinorVersion(); if (minorVersion < 13) { byte data = material.getData(); return WrappedBlockData.createData(bukkitMaterial, data); } return WrappedBlockData.createData(bukkitMaterial); } private @Nullable Location getLocation0(@NotNull World world, @NotNull PacketContainer packet) { try { StructureModifier blockPositionModifier = packet.getBlockPositionModifier(); BlockPosition blockPosition = blockPositionModifier.readSafely(0); if (blockPosition == null) { return getLocation1(world, packet); } return blockPosition.toLocation(world); } catch (FieldAccessException ex) { return getLocation1(world, packet); } } private @Nullable Location getLocation1(@NotNull World world, @NotNull PacketContainer packet) { try { StructureModifier modifier = packet.getMovingBlockPositions(); MovingObjectPositionBlock movingBlock = modifier.readSafely(0); if (movingBlock == null) { return null; } BlockPosition blockPosition = movingBlock.getBlockPosition(); if (blockPosition == null) { return null; } return blockPosition.toLocation(world); } catch (FieldAccessException ex) { return null; } } private void sendForceField(@NotNull ForceFieldTask task, @NotNull Player player, @NotNull Location location, @NotNull PacketContainer packet) { PacketType packetType = packet.getType(); if (packetType == Client.BLOCK_DIG) { sendForceFieldBlockDig(task, player, location, packet); } if (packetType == Client.USE_ITEM) { task.sendForceField(player, location); } } private void sendForceFieldBlockDig(@NotNull ForceFieldTask task, @NotNull Player player, @NotNull Location location, @NotNull PacketContainer packet) { StructureModifier playerDigTypeModifier = packet.getPlayerDigTypes(); PlayerDigType digType = playerDigTypeModifier.readSafely(0); GameMode gameMode = player.getGameMode(); if (digType == PlayerDigType.STOP_DESTROY_BLOCK || (digType == PlayerDigType.START_DESTROY_BLOCK && gameMode == GameMode.CREATIVE)) { task.sendForceField(player, location); } } } ================================================ FILE: expansion/force-field/src/main/java/combatlogx/expansion/force/field/task/ForceFieldTask.java ================================================ package combatlogx.expansion.force.field.task; import java.util.ConcurrentModificationException; import java.util.HashSet; import java.util.List; import java.util.Map; import java.util.Set; import java.util.UUID; import java.util.concurrent.ConcurrentHashMap; import com.github.sirblobman.api.folia.details.LocationTaskDetails; import org.jetbrains.annotations.NotNull; import org.bukkit.Bukkit; import org.bukkit.Location; import org.bukkit.Material; import org.bukkit.World; import org.bukkit.block.Block; import org.bukkit.block.BlockFace; import org.bukkit.block.data.BlockData; import org.bukkit.entity.Player; import org.bukkit.event.EventHandler; import org.bukkit.event.EventPriority; import org.bukkit.event.player.PlayerQuitEvent; import org.bukkit.permissions.Permission; import org.bukkit.plugin.java.JavaPlugin; import com.github.sirblobman.api.folia.details.RunnableTask; import com.github.sirblobman.api.folia.scheduler.TaskScheduler; import com.github.sirblobman.api.folia.task.WrappedTask; import com.github.sirblobman.api.location.BlockLocation; import com.github.sirblobman.api.utility.VersionUtility; import com.github.sirblobman.combatlogx.api.ICombatLogX; import com.github.sirblobman.combatlogx.api.event.PlayerUntagEvent; import com.github.sirblobman.combatlogx.api.expansion.Expansion; import com.github.sirblobman.combatlogx.api.expansion.ExpansionListener; import com.github.sirblobman.combatlogx.api.expansion.ExpansionManager; import com.github.sirblobman.combatlogx.api.expansion.region.RegionExpansion; import com.github.sirblobman.combatlogx.api.expansion.region.RegionHandler; import com.github.sirblobman.combatlogx.api.manager.ICombatManager; import com.github.sirblobman.combatlogx.api.object.TagInformation; import com.github.sirblobman.api.shaded.xseries.XMaterial; import com.comphenix.protocol.ProtocolLibrary; import com.comphenix.protocol.ProtocolManager; import combatlogx.expansion.force.field.ForceFieldExpansion; import combatlogx.expansion.force.field.configuration.ForceFieldConfiguration; public final class ForceFieldTask extends ExpansionListener implements Runnable { private final ForceFieldExpansion expansion; private final Map> fakeBlockMap; private WrappedTask wrappedTask; public ForceFieldTask(@NotNull ForceFieldExpansion expansion) { super(expansion); this.expansion = expansion; this.fakeBlockMap = new ConcurrentHashMap<>(); this.wrappedTask = null; } @Override public void run() { ForceFieldConfiguration configuration = getConfiguration(); if (!configuration.isEnabled()) { return; } ICombatManager combatManager = getCombatManager(); List combatPlayerList = combatManager.getPlayersInCombat(); for (Player player : combatPlayerList) { checkForceField(player); } } @EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true) public void onQuit(PlayerQuitEvent e) { Player player = e.getPlayer(); UUID playerId = player.getUniqueId(); this.fakeBlockMap.remove(playerId); } @EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true) public void onUntag(PlayerUntagEvent e) { Player player = e.getPlayer(); removeForceField(player); } public void registerProtocol() { ForceFieldExpansion forceFieldExpansion = getForceFieldExpansion(); ProtocolManager protocolManager = ProtocolLibrary.getProtocolManager(); ForceFieldAdapter forceFieldAdapter = new ForceFieldAdapter(forceFieldExpansion); protocolManager.addPacketListener(forceFieldAdapter); } public void removeProtocol() { JavaPlugin plugin = getJavaPlugin(); ProtocolManager protocolManager = ProtocolLibrary.getProtocolManager(); protocolManager.removePacketListeners(plugin); for (Player player : Bukkit.getOnlinePlayers()) { removeForceField(player); } } public void registerTask() { RunnableTask thisTask = new RunnableTask(getJavaPlugin(), this); thisTask.setDelay(1L); thisTask.setPeriod(1L); TaskScheduler scheduler = getCombatLogX().getFoliaHelper().getScheduler(); this.wrappedTask = scheduler.scheduleAsyncTask(thisTask); } public void cancel() { if (this.wrappedTask != null) { this.wrappedTask.cancel(); this.wrappedTask = null; } } public @NotNull Map> getFakeBlockMap() { return this.fakeBlockMap; } boolean isSafe(@NotNull Player player, @NotNull Location location) { ICombatManager combatManager = getCombatManager(); TagInformation tag = combatManager.getTagInformation(player); if (tag == null) { return false; } return isSafe(player, location, tag); } boolean isSafeSurround(@NotNull Player player, @NotNull Location location, @NotNull TagInformation tag) { Block blockLocation = location.getBlock(); BlockFace[] faces = {BlockFace.UP, BlockFace.DOWN, BlockFace.NORTH, BlockFace.SOUTH, BlockFace.EAST, BlockFace.WEST}; for (BlockFace blockFace : faces) { Location relativeLocation = blockLocation.getRelative(blockFace).getLocation(); if (!isSafe(player, relativeLocation, tag)) { return true; } } return false; } void sendForceField(Player player, Location location) { ForceFieldConfiguration configuration = getConfiguration(); XMaterial material = configuration.getMaterial(); int minorVersion = VersionUtility.getMinorVersion(); if (minorVersion < 13) { sendFakeBlockLegacy(player, location, material); } else { sendFakeBlockModern(player, location, material); } } boolean canPlace(@NotNull BlockLocation blockLocation) { World world = blockLocation.getWorld(); if (world == null) { return false; } int maxY = world.getMaxHeight(); int locationY = blockLocation.getY(); if (locationY > maxY) { return false; } Location location = blockLocation.asLocation(); if (location == null) { return false; } Block block = location.getBlock(); Material material = block.getType(); return (material == Material.AIR || !material.isSolid()); } private @NotNull ForceFieldExpansion getForceFieldExpansion() { return this.expansion; } private @NotNull ForceFieldConfiguration getConfiguration() { ForceFieldExpansion expansion = getForceFieldExpansion(); return expansion.getConfiguration(); } private void checkForceField(@NotNull Player player) { Location location = player.getLocation(); getCombatLogX().getFoliaHelper().getScheduler().scheduleLocationTask(new LocationTaskDetails(expansion.getPlugin().getPlugin(), location) { @Override public void run() { if (hasBypass(player)) { removeForceField(player); return; } if (isSafe(player, location)) { return; } updateForceField(player); } }); } private boolean hasBypass(@NotNull Player player) { ForceFieldConfiguration configuration = getConfiguration(); Permission bypassPermission = configuration.getBypassPermission(); if (bypassPermission == null) { return false; } return player.hasPermission(bypassPermission); } private boolean isSafe(@NotNull Player player, @NotNull Location location, @NotNull TagInformation tag) { ICombatLogX plugin = getCombatLogX(); ExpansionManager expansionManager = plugin.getExpansionManager(); List enabledExpansionList = expansionManager.getEnabledExpansions(); for (Expansion expansion : enabledExpansionList) { if (!(expansion instanceof RegionExpansion)) { continue; } RegionExpansion regionExpansion = (RegionExpansion) expansion; RegionHandler regionHandler = regionExpansion.getRegionHandler(); if (regionHandler.isSafeZone(player, location, tag)) { return true; } } return false; } private void updateForceField(@NotNull Player player) { ICombatManager combatManager = getCombatManager(); if (!combatManager.isInCombat(player)) { removeForceField(player); return; } TagInformation tagInformation = combatManager.getTagInformation(player); if (tagInformation == null) { removeForceField(player); return; } updateForceField(player, tagInformation); } private void updateForceField(@NotNull Player player, @NotNull TagInformation tag) { Set oldArea = new HashSet<>(); Set newArea = getForceFieldArea(player, tag); Set fullArea = new HashSet<>(newArea); UUID playerId = player.getUniqueId(); if (this.fakeBlockMap.containsKey(playerId)) { oldArea = this.fakeBlockMap.get(playerId); newArea.removeAll(oldArea); try { oldArea.removeAll(fullArea); // Sometimes causes ConcurrentModificationException? } catch (ConcurrentModificationException ex) { printDebug("Detected ForceField concurrent modification:"); if (!isDebugModeDisabled()) { ex.printStackTrace(); } } } this.fakeBlockMap.put(playerId, fullArea); for (BlockLocation blockLocation : newArea) { Location location = blockLocation.asLocation(); if (location != null) { sendForceField(player, location); } } for (BlockLocation blockLocation : oldArea) { Location location = blockLocation.asLocation(); if (location != null) { resetBlock(player, location); } } } private @NotNull Set getForceFieldArea(@NotNull Player player, @NotNull TagInformation tagInformation) { World world = player.getWorld(); BlockLocation playerBlockLocation = BlockLocation.from(player); Set area = new HashSet<>(); ForceFieldConfiguration configuration = getConfiguration(); int radius = configuration.getRadius(); int playerX = playerBlockLocation.getX(); int playerY = playerBlockLocation.getY(); int playerZ = playerBlockLocation.getZ(); int minX = (playerX - radius); int maxX = (playerX + radius); int minZ = (playerZ - radius); int maxZ = (playerZ + radius); for (int x = minX; x <= maxX; x++) { for (int z = minZ; z <= maxZ; z++) { BlockLocation blockLocation = BlockLocation.from(world, x, playerY, z); Location location = blockLocation.asLocation(); if (location == null) { continue; } if (!isSafe(player, location, tagInformation)) { continue; } if (!isSafeSurround(player, location, tagInformation)) { continue; } for (int y = -radius; y < radius; y++) { BlockLocation blockLocation2 = BlockLocation.from(world, x, playerY + y, z); if (!canPlace(blockLocation2)) { continue; } area.add(blockLocation2); } } } return area; } private void resetBlock(Player player, Location location) { Block block = location.getBlock(); int minorVersion = VersionUtility.getMinorVersion(); if (minorVersion < 13) { resetBlockLegacy(player, block); } else { resetBlockModern(player, block); } } @SuppressWarnings("deprecation") private void resetBlockLegacy(@NotNull Player player, @NotNull Block block) { Location location = block.getLocation(); Material material = block.getType(); byte data = block.getData(); player.sendBlockChange(location, material, data); } private void resetBlockModern(@NotNull Player player, @NotNull Block block) { Location location = block.getLocation(); BlockData blockData = block.getBlockData(); player.sendBlockChange(location, blockData); } @SuppressWarnings("deprecation") private void sendFakeBlockLegacy(@NotNull Player player, @NotNull Location location, @NotNull XMaterial material) { Material bukkitMaterial = material.parseMaterial(); if (bukkitMaterial == null || !bukkitMaterial.isBlock()) { return; } byte data = material.getData(); player.sendBlockChange(location, bukkitMaterial, data); } private void sendFakeBlockModern(@NotNull Player player, @NotNull Location location, @NotNull XMaterial material) { Material bukkitMaterial = material.get(); if (bukkitMaterial == null || !bukkitMaterial.isBlock()) { return; } BlockData blockData = bukkitMaterial.createBlockData(); player.sendBlockChange(location, blockData); } private void removeForceField(@NotNull Player player) { UUID playerId = player.getUniqueId(); if (!this.fakeBlockMap.containsKey(playerId)) { return; } Set oldArea = new HashSet<>(this.fakeBlockMap.remove(playerId)); for (BlockLocation blockLocation : oldArea) { Location location = blockLocation.asLocation(); if (location != null) { getCombatLogX().getFoliaHelper().getScheduler().scheduleLocationTask(new LocationTaskDetails(expansion.getPlugin().getPlugin(), location) { @Override public void run() { resetBlock(player, location); } }); } } } } ================================================ FILE: expansion/force-field/src/main/resources/config.yml ================================================ ### Disclaimers: ## The force field is a nice visual effect that shows players areas they cannot enter. ## ## The force field should not be used as entry prevention, as players can just ignore the fake block packets that are sent to them. ## ## For the actual entry prevention options, please check the configuration for your region expansion (e.g. WorldGuard Compatibility). ## ## If your server has weak hardware, or you have a lot of players online, we recommend disabling the force field effect. ## ## You can try unsafe mode and see if performance improves, but the most recommended option is to disable the force field. # Credits: # The force field code was contributed by olivolja3 (Olivo#3313) # Should force fields be enabled around non-pvp areas? # This does require at least one region compatibility expansion. # Default: true enabled: true # What material will the force field be made out of? # This uses the XMaterial naming system to support multiple Spigot versions. # Default: RED_STAINED_GLASS material: RED_STAINED_GLASS # Radius is the distance that a player has to be from a region to display the force field. # A higher radius may cause your server to lag. # Default: 8 radius: 8 # The bypass permission to not show a force field to a player # Set it to "" to prevent all players from bypassing # Default: "combatlogx.bypass.force.field" bypass-permission: "combatlogx.bypass.force.field" ================================================ FILE: expansion/force-field/src/main/resources/expansion.yml ================================================ name: "${expansionName}" prefix: "${expansionPrefix}" description: "${expansionDescription}" main: "combatlogx.expansion.force.field.ForceFieldExpansion" version: "17.6" authors: - "olivolja3 (Olivo#3313)" - "SirBlobman" plugin-depend: - "ProtocolLib" ================================================ FILE: expansion/glowing/README.MD ================================================ # CombatLogX Expansion: Glowing The glowing expansion makes players glow while they are in combat. ## Requirements - Spigot 1.9 and above. ## Features - Players will have a glowing effect during combat. - The glow effect will be removed once the player escapes. ================================================ FILE: expansion/glowing/gradle.properties ================================================ version.spigot=1.9.4-R0.1-SNAPSHOT expansion.name=Glowing ================================================ FILE: expansion/glowing/src/main/java/combatlogx/expansion/glowing/GlowingExpansion.java ================================================ package combatlogx.expansion.glowing; import java.util.Collection; import java.util.logging.Logger; import org.bukkit.Bukkit; import org.bukkit.entity.Player; import com.github.sirblobman.api.utility.VersionUtility; import com.github.sirblobman.combatlogx.api.ICombatLogX; import com.github.sirblobman.combatlogx.api.expansion.Expansion; import com.github.sirblobman.combatlogx.api.expansion.ExpansionManager; import combatlogx.expansion.glowing.listener.ListenerGlow; public class GlowingExpansion extends Expansion { public GlowingExpansion(ICombatLogX plugin) { super(plugin); } @Override public void onLoad() { // Do Nothing } @Override public void onEnable() { int majorVersion = VersionUtility.getMajorVersion(); int minorVersion = VersionUtility.getMinorVersion(); if (majorVersion == 1 && minorVersion < 9) { Logger logger = getLogger(); logger.warning("This expansion requires Spigot 1.9 or higher."); selfDisable(); return; } new ListenerGlow(this).register(); } @Override public void onDisable() { int minorVersion = VersionUtility.getMinorVersion(); if (minorVersion < 9) { return; } // Remove glowing for all online players. Collection onlinePlayerCollection = Bukkit.getOnlinePlayers(); for (Player player : onlinePlayerCollection) { player.setGlowing(false); } } @Override public void reloadConfig() { // Do Nothing } } ================================================ FILE: expansion/glowing/src/main/java/combatlogx/expansion/glowing/listener/ListenerGlow.java ================================================ package combatlogx.expansion.glowing.listener; import org.bukkit.entity.Player; import org.bukkit.event.EventHandler; import org.bukkit.event.EventPriority; import org.bukkit.event.entity.PlayerDeathEvent; import org.bukkit.event.player.PlayerJoinEvent; import org.bukkit.event.player.PlayerKickEvent; import org.bukkit.event.player.PlayerQuitEvent; import org.bukkit.event.player.PlayerRespawnEvent; import com.github.sirblobman.combatlogx.api.event.PlayerTagEvent; import com.github.sirblobman.combatlogx.api.event.PlayerUntagEvent; import com.github.sirblobman.combatlogx.api.expansion.Expansion; import com.github.sirblobman.combatlogx.api.expansion.ExpansionListener; public final class ListenerGlow extends ExpansionListener { public ListenerGlow(Expansion expansion) { super(expansion); } // Add glow effect when a player is tagged @EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true) public void onTag(PlayerTagEvent e) { Player player = e.getPlayer(); player.setGlowing(true); } // Remove glow when a player is untagged. @EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true) public void onUntag(PlayerUntagEvent e) { Player player = e.getPlayer(); player.setGlowing(false); } // Remove glow when a player joins the server. @EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true) public void onJoin(PlayerJoinEvent e) { Player player = e.getPlayer(); player.setGlowing(false); } // Remove glow when a player leaves the server @EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true) public void onQuit(PlayerQuitEvent e) { Player player = e.getPlayer(); player.setGlowing(false); } // Remove glow when a player is kicked from the server @EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true) public void onKick(PlayerKickEvent e) { Player player = e.getPlayer(); player.setGlowing(false); } // Remove glow when a player is killed. @EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true) public void onDeath(PlayerDeathEvent e) { Player player = e.getEntity(); player.setGlowing(false); } // Remove glow when a player respawns @EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true) public void onDeath(PlayerRespawnEvent e) { Player player = e.getPlayer(); player.setGlowing(false); } } ================================================ FILE: expansion/glowing/src/main/resources/expansion.yml ================================================ name: "${expansionName}" prefix: "${expansionPrefix}" description: "${expansionDescription}" main: "combatlogx.expansion.glowing.GlowingExpansion" version: "17.1" author: "SirBlobman" ================================================ FILE: expansion/logger/README.MD ================================================ # CombatLogX Expansion: Logger The logger expansion saves details about different combat events to files. ## Features - Change the name and format of the log files. - Configurable log message and date format. - Option to log every CombatLogX event and the EntityDamageByEntityEvent. ================================================ FILE: expansion/logger/gradle.properties ================================================ expansion.name=Logger ================================================ FILE: expansion/logger/src/main/java/combatlogx/expansion/logger/LoggerExpansion.java ================================================ package combatlogx.expansion.logger; import org.jetbrains.annotations.NotNull; import com.github.sirblobman.api.configuration.ConfigurationManager; import com.github.sirblobman.combatlogx.api.ICombatLogX; import com.github.sirblobman.combatlogx.api.expansion.Expansion; import combatlogx.expansion.logger.configuration.LoggerConfiguration; import combatlogx.expansion.logger.listener.ListenerLogger; public final class LoggerExpansion extends Expansion { private final LoggerConfiguration configuration; public LoggerExpansion(ICombatLogX plugin) { super(plugin); this.configuration = new LoggerConfiguration(); } @Override public void onLoad() { ConfigurationManager configurationManager = getConfigurationManager(); configurationManager.saveDefault("config.yml"); } @Override public void onEnable() { reloadConfig(); new ListenerLogger(this).register(); } @Override public void onDisable() { // Do Nothing } @Override public void reloadConfig() { ConfigurationManager configurationManager = getConfigurationManager(); configurationManager.reload("config.yml"); getConfiguration().load(configurationManager.get("config.yml")); } public @NotNull LoggerConfiguration getConfiguration() { return this.configuration; } } ================================================ FILE: expansion/logger/src/main/java/combatlogx/expansion/logger/configuration/LogEntryOptions.java ================================================ package combatlogx.expansion.logger.configuration; import java.text.DateFormat; import java.text.SimpleDateFormat; import java.time.Instant; import java.util.Date; import org.jetbrains.annotations.NotNull; import org.bukkit.configuration.ConfigurationSection; import com.github.sirblobman.api.configuration.IConfigurable; public final class LogEntryOptions implements IConfigurable { private String prefixFormat; private String entityDamageEventFormat; private String pretagFormat; private String tagFormat; private String retagFormat; private String untagFormat; private String punishFormat; private transient DateFormat dateFormat; public LogEntryOptions() { this.prefixFormat = ""; this.entityDamageEventFormat = ""; this.pretagFormat = ""; this.tagFormat = ""; this.retagFormat = ""; this.untagFormat = ""; this.punishFormat = ""; this.dateFormat = null; } @Override public void load(@NotNull ConfigurationSection section) { setPrefixFormat(section.getString("prefix-format", "")); setEntityDamageEventFormat(section.getString("entity-damage-event-format", "")); setPretagFormat(section.getString("pretag-format", "")); setTagFormat(section.getString("tag-format", "")); setRetagFormat(section.getString("retag-format", "")); setUntagFormat(section.getString("untag-format", "")); setPunishFormat(section.getString("punish-format", "")); } public @NotNull String getPrefixFormat() { return this.prefixFormat; } public void setPrefixFormat(@NotNull String prefixFormat) { this.prefixFormat = prefixFormat; } public @NotNull String getEntityDamageEventFormat() { return this.entityDamageEventFormat; } public void setEntityDamageEventFormat(@NotNull String entityDamageEventFormat) { this.entityDamageEventFormat = entityDamageEventFormat; } public @NotNull String getPretagFormat() { return this.pretagFormat; } public void setPretagFormat(@NotNull String pretagFormat) { this.pretagFormat = pretagFormat; } public @NotNull String getTagFormat() { return this.tagFormat; } public void setTagFormat(@NotNull String tagFormat) { this.tagFormat = tagFormat; } public @NotNull String getRetagFormat() { return this.retagFormat; } public void setRetagFormat(@NotNull String retagFormat) { this.retagFormat = retagFormat; } public @NotNull String getUntagFormat() { return this.untagFormat; } public void setUntagFormat(@NotNull String untagFormat) { this.untagFormat = untagFormat; } public @NotNull String getPunishFormat() { return this.punishFormat; } public void setPunishFormat(@NotNull String punishFormat) { this.punishFormat = punishFormat; } public @NotNull DateFormat getDateFormat() { if (this.dateFormat != null) { return this.dateFormat; } String prefixFormat = getPrefixFormat(); this.dateFormat = new SimpleDateFormat(prefixFormat); return this.dateFormat; } public @NotNull String getCurrentPrefix() { Instant now = Instant.now(); Date date = Date.from(now); DateFormat dateFormat = getDateFormat(); return dateFormat.format(date); } } ================================================ FILE: expansion/logger/src/main/java/combatlogx/expansion/logger/configuration/LogFileInfo.java ================================================ package combatlogx.expansion.logger.configuration; import java.io.File; import java.text.DateFormat; import java.text.SimpleDateFormat; import java.time.Instant; import java.util.Date; import java.util.regex.Matcher; import java.util.regex.Pattern; import org.jetbrains.annotations.NotNull; import org.bukkit.configuration.ConfigurationSection; import com.github.sirblobman.api.configuration.IConfigurable; public final class LogFileInfo implements IConfigurable { private final Pattern fileNameFixerPattern; private String fileName; private String fileExtraFormat; private String fileExtension; private transient DateFormat dateFormat; public LogFileInfo() { this.fileName = "logger"; this.fileExtraFormat = "yyyy.MM.dd"; this.fileExtension = "log"; this.dateFormat = null; this.fileNameFixerPattern = Pattern.compile("[^\\w.\\-]"); } @Override public void load(@NotNull ConfigurationSection section) { setFileName(section.getString("file-name", "logger")); setFileExtraFormat(section.getString("file-extra-format", "yyyy.MM.dd")); setFileExtension(section.getString("file-extension", "log")); } public @NotNull String getFileName() { return this.fileName; } public void setFileName(@NotNull String fileName) { this.fileName = fileName; } public @NotNull String getFileExtraFormat() { return this.fileExtraFormat; } public void setFileExtraFormat(@NotNull String fileExtraFormat) { this.fileExtraFormat = fileExtraFormat; this.dateFormat = null; } public @NotNull String getFileExtension() { return this.fileExtension; } public void setFileExtension(@NotNull String fileExtension) { this.fileExtension = fileExtension; } public DateFormat getDateFormat() { if (this.dateFormat != null) { return this.dateFormat; } String fileExtraFormat = getFileExtraFormat(); this.dateFormat = new SimpleDateFormat(fileExtraFormat); return this.dateFormat; } public @NotNull File getCurrentLogFile(@NotNull File baseFolder) { String fileName = getFileName(); DateFormat dateFormat = getDateFormat(); String extension = getFileExtension(); Instant now = Instant.now(); Date date = Date.from(now); String extra = dateFormat.format(date); String preFile = (fileName + "-" + extra + "." + extension); Matcher matcher = this.fileNameFixerPattern.matcher(preFile); String finalFileName = matcher.replaceAll("_"); return new File(baseFolder, finalFileName); } } ================================================ FILE: expansion/logger/src/main/java/combatlogx/expansion/logger/configuration/LogOptions.java ================================================ package combatlogx.expansion.logger.configuration; import org.jetbrains.annotations.NotNull; import org.bukkit.configuration.ConfigurationSection; import com.github.sirblobman.api.configuration.IConfigurable; public final class LogOptions implements IConfigurable { private boolean logEntityDamageEvent; private boolean logPreTag; private boolean logTag; private boolean logRetag; private boolean logUntag; private boolean logPunish; public LogOptions() { this.logEntityDamageEvent = true; this.logPreTag = true; this.logTag = true; this.logRetag = true; this.logUntag = true; this.logPunish = true; } @Override public void load(@NotNull ConfigurationSection section) { setLogEntityDamageEvent(section.getBoolean("log-entity-damage-event", true)); setLogPreTag(section.getBoolean("log-pretag", true)); setLogTag(section.getBoolean("log-tag", true)); setLogRetag(section.getBoolean("log-retag", true)); setLogUntag(section.getBoolean("log-untag", true)); setLogPunish(section.getBoolean("log-punish", true)); } public boolean isLogEntityDamageEvent() { return this.logEntityDamageEvent; } public void setLogEntityDamageEvent(boolean logEntityDamageEvent) { this.logEntityDamageEvent = logEntityDamageEvent; } public boolean isLogPreTag() { return this.logPreTag; } public void setLogPreTag(boolean logPreTag) { this.logPreTag = logPreTag; } public boolean isLogTag() { return this.logTag; } public void setLogTag(boolean logTag) { this.logTag = logTag; } public boolean isLogRetag() { return this.logRetag; } public void setLogRetag(boolean logRetag) { this.logRetag = logRetag; } public boolean isLogUntag() { return this.logUntag; } public void setLogUntag(boolean logUntag) { this.logUntag = logUntag; } public boolean isLogPunish() { return this.logPunish; } public void setLogPunish(boolean logPunish) { this.logPunish = logPunish; } } ================================================ FILE: expansion/logger/src/main/java/combatlogx/expansion/logger/configuration/LogType.java ================================================ package combatlogx.expansion.logger.configuration; import java.util.function.Function; import org.jetbrains.annotations.NotNull; public enum LogType { ENTITY_DAMAGE_EVENT(LogOptions::isLogEntityDamageEvent, LogEntryOptions::getEntityDamageEventFormat), PRE_TAG(LogOptions::isLogPreTag, LogEntryOptions::getPretagFormat), TAG(LogOptions::isLogTag, LogEntryOptions::getTagFormat), RE_TAG(LogOptions::isLogRetag, LogEntryOptions::getRetagFormat), UNTAG(LogOptions::isLogUntag, LogEntryOptions::getUntagFormat), PUNISH(LogOptions::isLogPunish, LogEntryOptions::getPunishFormat); private final Function enabledFunction; private final Function formatFunction; LogType(@NotNull Function enabledFunction, @NotNull Function formatFunction) { this.enabledFunction = enabledFunction; this.formatFunction = formatFunction; } private @NotNull Function getEnabledFunction() { return this.enabledFunction; } private @NotNull Function getFormatFunction() { return this.formatFunction; } public boolean isEnabled(LogOptions options) { Function function = getEnabledFunction(); return function.apply(options); } public String getFormat(LogEntryOptions options) { Function formatFunction = getFormatFunction(); return formatFunction.apply(options); } } ================================================ FILE: expansion/logger/src/main/java/combatlogx/expansion/logger/configuration/LoggerConfiguration.java ================================================ package combatlogx.expansion.logger.configuration; import org.jetbrains.annotations.NotNull; import org.bukkit.configuration.ConfigurationSection; import com.github.sirblobman.api.configuration.IConfigurable; public final class LoggerConfiguration implements IConfigurable { private final LogFileInfo logFileInfo; private final LogOptions logOptions; private final LogEntryOptions logEntryOptions; public LoggerConfiguration() { this.logFileInfo = new LogFileInfo(); this.logOptions = new LogOptions(); this.logEntryOptions = new LogEntryOptions(); } @Override public void load(@NotNull ConfigurationSection config) { getLogFileInfo().load(getOrCreateSection(config, "log-file-info")); getLogOptions().load(getOrCreateSection(config, "log-options")); getLogEntryOptions().load(getOrCreateSection(config, "log-entry-options")); } public LogFileInfo getLogFileInfo() { return this.logFileInfo; } public LogOptions getLogOptions() { return this.logOptions; } public LogEntryOptions getLogEntryOptions() { return this.logEntryOptions; } } ================================================ FILE: expansion/logger/src/main/java/combatlogx/expansion/logger/listener/ListenerLogger.java ================================================ package combatlogx.expansion.logger.listener; import java.io.File; import java.io.IOException; import java.nio.charset.StandardCharsets; import java.nio.file.Files; import java.nio.file.Path; import java.nio.file.StandardOpenOption; import java.util.ArrayList; import java.util.Collections; import java.util.List; import java.util.logging.Level; import java.util.logging.Logger; import java.util.stream.Collectors; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import org.bukkit.Bukkit; import org.bukkit.command.CommandSender; import org.bukkit.entity.Entity; import org.bukkit.entity.Player; import org.bukkit.event.EventHandler; import org.bukkit.event.EventPriority; import org.bukkit.event.entity.EntityDamageByEntityEvent; import com.github.sirblobman.api.language.ComponentHelper; import com.github.sirblobman.api.language.LanguageManager; import com.github.sirblobman.api.nms.EntityHandler; import com.github.sirblobman.api.nms.MultiVersionHandler; import com.github.sirblobman.combatlogx.api.ICombatLogX; import com.github.sirblobman.combatlogx.api.event.PlayerPreTagEvent; import com.github.sirblobman.combatlogx.api.event.PlayerPunishEvent; import com.github.sirblobman.combatlogx.api.event.PlayerReTagEvent; import com.github.sirblobman.combatlogx.api.event.PlayerTagEvent; import com.github.sirblobman.combatlogx.api.event.PlayerUntagEvent; import com.github.sirblobman.combatlogx.api.expansion.ExpansionListener; import com.github.sirblobman.combatlogx.api.object.TagReason; import com.github.sirblobman.combatlogx.api.object.TagType; import com.github.sirblobman.combatlogx.api.object.UntagReason; import com.github.sirblobman.api.shaded.adventure.text.Component; import combatlogx.expansion.logger.LoggerExpansion; import combatlogx.expansion.logger.configuration.LogEntryOptions; import combatlogx.expansion.logger.configuration.LogFileInfo; import combatlogx.expansion.logger.configuration.LogOptions; import combatlogx.expansion.logger.configuration.LogType; import combatlogx.expansion.logger.configuration.LoggerConfiguration; public final class ListenerLogger extends ExpansionListener { private final LoggerExpansion expansion; public ListenerLogger(@NotNull LoggerExpansion expansion) { super(expansion); this.expansion = expansion; } private @NotNull LoggerExpansion getLoggerExpansion() { return this.expansion; } @EventHandler(priority = EventPriority.MONITOR) public void beforeTag(PlayerPreTagEvent e) { if (isDisabled(LogType.PRE_TAG)) { return; } Player player = e.getPlayer(); Entity enemy = e.getEnemy(); TagReason tagReason = e.getTagReason(); TagType tagType = e.getTagType(); String format = getFormat(LogType.PRE_TAG); String playerName = player.getName(); String enemyName = getEntityName(enemy); String tagReasonName = tagReason.name(); String tagTypeName = tagType.name(); String cancelledString = Boolean.toString(e.isCancelled()); String message = format.replace("{player_name}", playerName).replace("{enemy_name}", enemyName) .replace("{tag_reason}", tagReasonName).replace("{tag_type}", tagTypeName) .replace("{was_cancelled}", cancelledString); appendLog(message); } @EventHandler(priority = EventPriority.MONITOR) public void onTag(PlayerTagEvent e) { if (isDisabled(LogType.TAG)) { return; } Player player = e.getPlayer(); Entity enemy = e.getEnemy(); TagReason tagReason = e.getTagReason(); TagType tagType = e.getTagType(); String format = getFormat(LogType.TAG); String playerName = player.getName(); String enemyName = getEntityName(enemy); String tagReasonName = tagReason.name(); String tagTypeName = tagType.name(); String message = format.replace("{player_name}", playerName).replace("{enemy_name}", enemyName) .replace("{tag_reason}", tagReasonName).replace("{tag_type}", tagTypeName); appendLog(message); } @EventHandler(priority = EventPriority.MONITOR) public void onReTag(PlayerReTagEvent e) { if (isDisabled(LogType.RE_TAG)) { return; } Player player = e.getPlayer(); Entity enemy = e.getEnemy(); TagReason tagReason = e.getTagReason(); TagType tagType = e.getTagType(); String format = getFormat(LogType.RE_TAG); String playerName = player.getName(); String enemyName = getEntityName(enemy); String tagReasonName = tagReason.name(); String tagTypeName = tagType.name(); String cancelledString = Boolean.toString(e.isCancelled()); String message = format.replace("{player_name}", playerName).replace("{enemy_name}", enemyName) .replace("{tag_reason}", tagReasonName).replace("{tag_type}", tagTypeName) .replace("{was_cancelled}", cancelledString); appendLog(message); } @EventHandler(priority = EventPriority.MONITOR) public void onUntag(PlayerUntagEvent e) { if (isDisabled(LogType.UNTAG)) { return; } Player player = e.getPlayer(); UntagReason untagReason = e.getUntagReason(); boolean isExpire = untagReason.isExpire(); String format = getFormat(LogType.UNTAG); String playerName = player.getName(); String untagReasonName = untagReason.name(); String expireString = Boolean.toString(isExpire); String message = format.replace("{player_name}", playerName).replace("{untag_reason}", untagReasonName) .replace("{was_expire}", expireString); appendLog(message); } @EventHandler(priority = EventPriority.MONITOR) public void onPunish(PlayerPunishEvent e) { if (isDisabled(LogType.PUNISH)) { return; } Player player = e.getPlayer(); List enemyList = e.getEnemies(); UntagReason untagReason = e.getPunishReason(); String format = getFormat(LogType.PUNISH); String playerName = player.getName(); String enemyNames = enemyList.stream().map(this::getEntityName).collect(Collectors.joining(", ")); String untagReasonName = untagReason.name(); String cancelledString = Boolean.toString(e.isCancelled()); String message = format.replace("{player_name}", playerName).replace("{enemy_name}", enemyNames) .replace("{punish_reason}", untagReasonName).replace("{was_cancelled}", cancelledString); appendLog(message); } @EventHandler(priority = EventPriority.MONITOR) public void onDamage(EntityDamageByEntityEvent e) { if (isDisabled(LogType.ENTITY_DAMAGE_EVENT)) { return; } Entity damaged = e.getEntity(); Entity damager = e.getDamager(); String damagedType = damaged.getType().name(); String damagedName = getEntityName(damaged); String damagerType = damager.getType().name(); String damagerName = getEntityName(damager); String wasCancelled = Boolean.toString(e.isCancelled()); String format = getFormat(LogType.ENTITY_DAMAGE_EVENT); String message = format.replace("{damaged_type}", damagedType) .replace("{damaged_name}", damagedName).replace("{damager_type}", damagerType) .replace("{damager_name}", damagerName).replace("{was_cancelled}", wasCancelled); appendLog(message); } private @NotNull String getEntityName(@Nullable Entity entity) { if (entity == null) { CommandSender console = Bukkit.getConsoleSender(); LanguageManager languageManager = getLanguageManager(); Component message = languageManager.getMessage(console, "placeholder.unknown-enemy"); return ComponentHelper.toPlain(message); } ICombatLogX combatLogX = getCombatLogX(); MultiVersionHandler multiVersionHandler = combatLogX.getMultiVersionHandler(); EntityHandler entityHandler = multiVersionHandler.getEntityHandler(); return entityHandler.getName(entity); } private boolean isDisabled(@NotNull LogType logType) { LoggerExpansion expansion = getLoggerExpansion(); LoggerConfiguration configuration = expansion.getConfiguration(); LogOptions logOptions = configuration.getLogOptions(); return !logType.isEnabled(logOptions); } private @NotNull String getFormat(@NotNull LogType logType) { LoggerExpansion expansion = getLoggerExpansion(); LoggerConfiguration configuration = expansion.getConfiguration(); LogEntryOptions logEntryOptions = configuration.getLogEntryOptions(); String baseFormat = logType.getFormat(logEntryOptions); String prefix = logEntryOptions.getCurrentPrefix(); return (prefix + " " + baseFormat); } private @NotNull File getLogFile() { LoggerExpansion expansion = getLoggerExpansion(); LoggerConfiguration configuration = expansion.getConfiguration(); LogFileInfo logFileInfo = configuration.getLogFileInfo(); File dataFolder = expansion.getDataFolder(); return logFileInfo.getCurrentLogFile(dataFolder); } private void appendLog(String @NotNull ... messageArray) { try { Path logPath = getLogPath(); List messageList = new ArrayList<>(); Collections.addAll(messageList, messageArray); Files.write(logPath, messageList, StandardCharsets.UTF_8, StandardOpenOption.APPEND); } catch (IOException ex) { Logger logger = getExpansionLogger(); logger.log(Level.WARNING, "Failed to write to a custom log file:", ex); } } private @NotNull Path getLogPath() throws IOException { LoggerExpansion expansion = getLoggerExpansion(); File dataFolder = expansion.getDataFolder(); if (!dataFolder.exists() && !dataFolder.mkdirs()) { throw new IOException("Failed to create expansion folder."); } File logFile = getLogFile(); if (!logFile.exists() && !logFile.createNewFile()) { throw new IOException("Failed to create custom log file."); } return logFile.toPath(); } } ================================================ FILE: expansion/logger/src/main/resources/config.yml ================================================ # Default Configuration for the Logger Expansion # Made by SirBlobman log-file-info: # The log file will be placed in "/plugins/CombatLogX/expansion/Logger/-." # Any characters that don't match the following regex will be replaced by _ # [\w.\-] file-name: "logger" # This is the date format for the part of the file name # Check here for formatting details: https://docs.oracle.com/javase/8/docs/api/java/text/SimpleDateFormat.html file-extra-format: "yyyy.MM.dd" # The file will always be in the UTF-8 TXT format, this is just the file name extension file-extension: "log" log-options: log-entity-damage-event: true log-pretag: true log-tag: true log-retag: true log-untag: true log-punish: true log-entry-options: # Default Format Example: [January 04, 2019 01:08:29.232PM EST] prefix-format: "[MMMM dd, YYYY HH:mm:ss.SSSa zzz] " # All valid placeholders are written in the default examples for each event type # Only those placeholders can be used entity-damage-event-format: "EntityDamageByEntityEvent was triggered by damaged {damaged_type} {damaged_name}, damager {damager_type} {damager_name} and cancelled {was_cancelled}." pretag-format: "PlayerPreTagEvent was triggered on {player_name} by {enemy_name} with type {tag_type}, reason {tag_reason}, and cancelled {was_cancelled}." tag-format: "PlayerTagEvent was triggered on {player_name} by {enemy_name} with type {tag_type} and reason {tag_reason}." retag-format: "PlayerReTagEvent was triggered on {player_name} by {enemy_name} with type {tag_type} and reason {tag_reason}." untag-format: "PlayerUntagEvent was triggered on {player_name} with reason {untag_reason} and expire set to {was_expire}." punish-format: "PlayerPunishEvent was triggered on {player_name} with reason {punish_reason} and cancelled {was_cancelled}." ================================================ FILE: expansion/logger/src/main/resources/expansion.yml ================================================ name: "${expansionName}" prefix: "${expansionPrefix}" description: "${expansionDescription}" main: "combatlogx.expansion.logger.LoggerExpansion" version: "17.3" author: "SirBlobman" ================================================ FILE: expansion/loot-protection/build.gradle.kts ================================================ import com.github.jengelman.gradle.plugins.shadow.tasks.ShadowJar plugins { id("com.gradleup.shadow") version "9.2.2" } dependencies { implementation("net.jodah:expiringmap:0.5.11") } tasks { named("jar") { enabled = false } named("shadowJar") { val expansionName = findProperty("expansion.name") ?: project.name archiveFileName.set("$expansionName.jar") archiveClassifier.set(null as String?) relocate("net.jodah.expiringmap", "combatlogx.expansion.loot.protection.expiringmap") } named("build") { dependsOn("shadowJar") } } ================================================ FILE: expansion/loot-protection/gradle.properties ================================================ version.spigot=1.16.5-R0.1-SNAPSHOT expansion.name=LootProtection expansion.prefix=Loot Protection ================================================ FILE: expansion/loot-protection/src/main/java/combatlogx/expansion/loot/protection/LootProtectionExpansion.java ================================================ package combatlogx.expansion.loot.protection; import java.util.logging.Logger; import org.jetbrains.annotations.NotNull; import com.github.sirblobman.api.configuration.ConfigurationManager; import com.github.sirblobman.api.utility.VersionUtility; import com.github.sirblobman.combatlogx.api.ICombatLogX; import com.github.sirblobman.combatlogx.api.expansion.Expansion; import combatlogx.expansion.loot.protection.configuration.LootProtectionConfiguration; import combatlogx.expansion.loot.protection.listener.ListenerLootProtection; public final class LootProtectionExpansion extends Expansion { private final LootProtectionConfiguration configuration; public LootProtectionExpansion(ICombatLogX plugin) { super(plugin); this.configuration = new LootProtectionConfiguration(); } @Override public void onLoad() { ConfigurationManager configurationManager = getConfigurationManager(); configurationManager.saveDefault("config.yml"); } @Override public void onEnable() { int minorVersion = VersionUtility.getMinorVersion(); if (minorVersion < 16) { Logger logger = getLogger(); logger.info("The loot protection expansion requires Spigot 1.16.5 or higher."); selfDisable(); return; } reloadConfig(); new ListenerLootProtection(this).register(); } @Override public void onDisable() { // Do Nothing } @Override public void reloadConfig() { ConfigurationManager configurationManager = getConfigurationManager(); configurationManager.reload("config.yml"); getConfiguration().load(configurationManager.get("config.yml")); } public @NotNull LootProtectionConfiguration getConfiguration() { return this.configuration; } } ================================================ FILE: expansion/loot-protection/src/main/java/combatlogx/expansion/loot/protection/configuration/LootProtectionConfiguration.java ================================================ package combatlogx.expansion.loot.protection.configuration; import org.jetbrains.annotations.NotNull; import org.bukkit.configuration.ConfigurationSection; import com.github.sirblobman.api.configuration.IConfigurable; public final class LootProtectionConfiguration implements IConfigurable { private int lootProtectionTime; private int messageCooldown; private boolean onlyProtectAfterLog; private boolean returnVoidItems; public LootProtectionConfiguration() { this.lootProtectionTime = 30; this.messageCooldown = 30; this.onlyProtectAfterLog = false; this.returnVoidItems = true; } @Override public void load(@NotNull ConfigurationSection config) { setLootProtectionTime(config.getInt("loot-protection-time", 30)); setMessageCooldown(config.getInt("message-cooldown", 30)); setOnlyProtectAfterLog(config.getBoolean("only-protect-after-log", false)); setReturnVoidItems(config.getBoolean("return-void-items", true)); } public int getLootProtectionTime() { return this.lootProtectionTime; } public void setLootProtectionTime(int lootProtectionTime) { this.lootProtectionTime = lootProtectionTime; } public int getMessageCooldown() { return this.messageCooldown; } public void setMessageCooldown(int messageCooldown) { this.messageCooldown = messageCooldown; } public boolean isOnlyProtectAfterLog() { return this.onlyProtectAfterLog; } public void setOnlyProtectAfterLog(boolean onlyProtectAfterLog) { this.onlyProtectAfterLog = onlyProtectAfterLog; } public boolean isReturnVoidItems() { return this.returnVoidItems; } public void setReturnVoidItems(boolean returnVoidItems) { this.returnVoidItems = returnVoidItems; } } ================================================ FILE: expansion/loot-protection/src/main/java/combatlogx/expansion/loot/protection/event/QueryPickupEvent.java ================================================ package combatlogx.expansion.loot.protection.event; import org.jetbrains.annotations.NotNull; import org.bukkit.entity.Player; import org.bukkit.event.HandlerList; import com.github.sirblobman.combatlogx.api.event.CustomPlayerEventCancellable; import combatlogx.expansion.loot.protection.object.ProtectedItem; public final class QueryPickupEvent extends CustomPlayerEventCancellable { private static final HandlerList HANDLER_LIST; static { HANDLER_LIST = new HandlerList(); } private final ProtectedItem protectedItem; public QueryPickupEvent(@NotNull Player player, @NotNull ProtectedItem protectedItem) { super(player); this.protectedItem = protectedItem; } public static @NotNull HandlerList getHandlerList() { return HANDLER_LIST; } @Override public @NotNull HandlerList getHandlers() { return getHandlerList(); } public @NotNull ProtectedItem getProtectedItem() { return protectedItem; } } ================================================ FILE: expansion/loot-protection/src/main/java/combatlogx/expansion/loot/protection/listener/ListenerLootProtection.java ================================================ package combatlogx.expansion.loot.protection.listener; import java.util.Collections; import java.util.List; import java.util.Map; import java.util.Set; import java.util.UUID; import java.util.concurrent.ConcurrentLinkedQueue; import java.util.concurrent.TimeUnit; import org.jetbrains.annotations.NotNull; import org.bukkit.Bukkit; import org.bukkit.Location; import org.bukkit.World; import org.bukkit.configuration.file.YamlConfiguration; import org.bukkit.entity.Entity; import org.bukkit.entity.Item; import org.bukkit.entity.LivingEntity; import org.bukkit.entity.Player; import org.bukkit.event.EventHandler; import org.bukkit.event.EventPriority; import org.bukkit.event.entity.EntityDamageEvent; import org.bukkit.event.entity.EntityDamageEvent.DamageCause; import org.bukkit.event.entity.EntityDeathEvent; import org.bukkit.event.entity.EntityPickupItemEvent; import org.bukkit.event.entity.ItemSpawnEvent; import org.bukkit.event.inventory.InventoryPickupItemEvent; import org.bukkit.inventory.ItemStack; import org.bukkit.inventory.PlayerInventory; import org.bukkit.plugin.PluginManager; import com.github.sirblobman.api.configuration.PlayerDataManager; import com.github.sirblobman.api.language.LanguageManager; import com.github.sirblobman.api.language.replacer.LongReplacer; import com.github.sirblobman.api.language.replacer.Replacer; import com.github.sirblobman.api.language.replacer.StringReplacer; import com.github.sirblobman.api.location.BlockLocation; import com.github.sirblobman.api.utility.VersionUtility; import com.github.sirblobman.combatlogx.api.ICombatLogX; import com.github.sirblobman.combatlogx.api.configuration.PunishConfiguration; import com.github.sirblobman.combatlogx.api.event.PlayerPunishEvent; import com.github.sirblobman.combatlogx.api.event.PlayerUntagEvent; import com.github.sirblobman.combatlogx.api.expansion.ExpansionListener; import com.github.sirblobman.combatlogx.api.manager.IDeathManager; import com.github.sirblobman.combatlogx.api.object.KillTime; import com.github.sirblobman.combatlogx.api.object.UntagReason; import combatlogx.expansion.loot.protection.LootProtectionExpansion; import combatlogx.expansion.loot.protection.configuration.LootProtectionConfiguration; import combatlogx.expansion.loot.protection.event.QueryPickupEvent; import combatlogx.expansion.loot.protection.object.ProtectedItem; import net.jodah.expiringmap.ExpiringMap; public class ListenerLootProtection extends ExpansionListener { private final LootProtectionExpansion expansion; private final Set messageCooldownSet; private final ExpiringMap protectedItemMap; private final Map> pendingProtectionMap; private final Map enemyMap; public ListenerLootProtection(@NotNull LootProtectionExpansion expansion) { super(expansion); this.expansion = expansion; LootProtectionConfiguration configuration = getConfiguration(); int messageCooldown = configuration.getMessageCooldown(); int lootProtectionTime = configuration.getLootProtectionTime(); this.messageCooldownSet = Collections.newSetFromMap(ExpiringMap.builder() .expiration(messageCooldown, TimeUnit.SECONDS).build()); this.pendingProtectionMap = ExpiringMap.builder().expiration(lootProtectionTime, TimeUnit.SECONDS).build(); this.protectedItemMap = ExpiringMap.builder().expiration(lootProtectionTime, TimeUnit.SECONDS).build(); this.enemyMap = ExpiringMap.builder().expiration(lootProtectionTime, TimeUnit.SECONDS).build(); } @EventHandler(priority = EventPriority.NORMAL, ignoreCancelled = true) public void onEntityItemPickup(EntityPickupItemEvent e) { printDebug("Detected EntityPickupItemEvent..."); Item itemEntity = e.getItem(); if (!contains(itemEntity)) { printDebug("Item was not protected, ignoring."); return; } Entity entity = e.getEntity(); if (!(entity instanceof Player player)) { printDebug("Entity was not player, preventing pickup."); e.setCancelled(true); return; } UUID itemEntityId = itemEntity.getUniqueId(); printDebug("Item Entity ID: " + itemEntityId); ProtectedItem protectedItem = this.protectedItemMap.get(itemEntityId); UUID playerId = player.getUniqueId(); printDebug("Player ID: " + playerId); QueryPickupEvent queryPickupEvent = new QueryPickupEvent(player, protectedItem); PluginManager pluginManager = Bukkit.getPluginManager(); pluginManager.callEvent(queryPickupEvent); printDebug("Sent out custom QueryPickupEvent..."); if (!protectedItem.getOwnerUUID().equals(playerId) && !queryPickupEvent.isCancelled()) { printDebug("Owner does not match and custom event is not cancelled, preventing pickup..."); e.setCancelled(true); if (!this.messageCooldownSet.contains(playerId)) { long expireMillisLeft = this.protectedItemMap.getExpectedExpiration(itemEntityId); long expireSecondsLeft = TimeUnit.MILLISECONDS.toSeconds(expireMillisLeft); Replacer replacer = new LongReplacer("{time}", expireSecondsLeft); LanguageManager languageManager = getLanguageManager(); languageManager.sendMessageWithPrefix(player, "expansion.loot-protection.protected", replacer); this.messageCooldownSet.add(playerId); printDebug("Sent pickup prevention message to player."); } } else { printDebug("Item matches owner or pickup event was cancelled. Allowing pickup."); } } @EventHandler(priority = EventPriority.NORMAL, ignoreCancelled = true) public void onHopperItemPickup(InventoryPickupItemEvent e) { printDebug("Detected InventoryPickupItemEvent..."); Item itemEntity = e.getItem(); if (contains(itemEntity)) { printDebug("Item is protected, cancelled event."); e.setCancelled(true); } } @EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true) public void onPunish(PlayerPunishEvent e) { List enemyList = e.getEnemies(); if (enemyList.isEmpty()) { return; } Entity previousEnemy = enemyList.getFirst(); if (previousEnemy == null) { return; } Player player = e.getPlayer(); PlayerDataManager playerDataManager = getPlayerDataManager(); YamlConfiguration playerData = playerDataManager.get(player); ICombatLogX plugin = getCombatLogX(); PunishConfiguration punishConfiguration = plugin.getPunishConfiguration(); KillTime killTime = punishConfiguration.getKillTime(); UUID previousEnemyId = previousEnemy.getUniqueId(); if (killTime == KillTime.JOIN) { playerData.set("loot-protection-enemy", previousEnemyId.toString()); playerDataManager.save(player); return; } UUID playerId = player.getUniqueId(); this.enemyMap.put(playerId, previousEnemyId); } @EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true) public void onUntag(PlayerUntagEvent e) { List enemyList = e.getPreviousEnemies(); if (enemyList.isEmpty()) { return; } Entity previousEnemy = enemyList.getFirst(); if (previousEnemy == null) { return; } Player player = e.getPlayer(); UUID playerId = player.getUniqueId(); UUID previousEnemyId = previousEnemy.getUniqueId(); UntagReason untagReason = e.getUntagReason(); if (untagReason == UntagReason.SELF_DEATH) { this.enemyMap.put(playerId, previousEnemyId); } if (untagReason == UntagReason.ENEMY_DEATH) { this.enemyMap.put(previousEnemyId, playerId); } } @EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true) public void onDeath(EntityDeathEvent e) { printDebug("Detected EntityDeathEvent..."); LivingEntity entity = e.getEntity(); ICombatLogX combatLogX = getCombatLogX(); IDeathManager deathManager = combatLogX.getDeathManager(); if (entity instanceof Player player) { if (isOnlyProtectAfterLog() && !deathManager.wasPunishKilled(player)) { printDebug("option 'only-protect-after-log' is 'true' and the player did not combat log. Ignoring."); return; } } UUID entityId = entity.getUniqueId(); UUID enemyId = this.enemyMap.get(entityId); if (!checkVoidKill(e) && entity instanceof Player player) { printDebug("Cause of death was not void and entity is player."); PlayerDataManager playerDataManager = getPlayerDataManager(); YamlConfiguration playerData = playerDataManager.get(player); String enemyIdString = playerData.getString("loot-protection-enemy"); if (enemyIdString != null) { playerData.set("loot-protection-enemy", null); playerDataManager.save(player); enemyId = UUID.fromString(enemyIdString); printDebug("Removed previously saved loot-protection-enemy for player '" + player.getName() + "'."); } } if (enemyId == null) { printDebug("Previous enemy is null, ignoring event."); return; } Entity enemy = Bukkit.getEntity(enemyId); if (enemy == null) { printDebug("Enemy entity with id '" + enemyId + "' does not exist, ignoring event."); return; } enemyId = enemy.getUniqueId(); BlockLocation entityLocation = BlockLocation.from(entity); ConcurrentLinkedQueue protectedItemQueue = new ConcurrentLinkedQueue<>(); List dropList = e.getDrops(); for (ItemStack drop : dropList) { ProtectedItem protectedItem = new ProtectedItem(entityLocation, drop); protectedItem.setOwnerUUID(enemyId); protectedItemQueue.add(protectedItem); } printDebug("Added all event drops to protection queue."); this.pendingProtectionMap.put(entityLocation, protectedItemQueue); printDebug("Saved pending protection queue to protection map."); String entityName = (entity.getCustomName() == null ? entity.getName() : entity.getCustomName()); long timeLeftMillis = this.protectedItemMap.getExpiration(); long timeLeftSeconds = TimeUnit.MILLISECONDS.toSeconds(timeLeftMillis); Replacer timeReplacer = new LongReplacer("{time}", timeLeftSeconds); Replacer enemyReplacer = new StringReplacer("{enemy}", entityName); LanguageManager languageManager = getLanguageManager(); languageManager.sendMessageWithPrefix(enemy, "expansion.loot-protection.enemy-died", timeReplacer, enemyReplacer); printDebug("Sent 'enemy-died' message to living enemy."); } @EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true) public void onItemSpawn(ItemSpawnEvent e) { printDebug("Detected ItemSpawnEvent..."); if (this.pendingProtectionMap.isEmpty()) { printDebug("Pending protection map is empty, ignoring."); return; } Location location = e.getLocation(); BlockLocation blockLocation = BlockLocation.from(location); int minorVersion = VersionUtility.getMinorVersion(); if (minorVersion >= 21) { // Subtract 1 from block y location. // See CombatLogX GitHub Issue # 929 printDebug("version is 1.21 or higher, subtracting 1 from spawn block Y location."); blockLocation = new BlockLocation(blockLocation.getWorldId(), blockLocation.getX(), blockLocation.getY() - 1, blockLocation.getZ()); } if (!this.pendingProtectionMap.containsKey(blockLocation)) { printDebug("Current Location: " + blockLocation); printDebug("Pending Protection Map Keys: " + this.pendingProtectionMap.keySet()); printDebug("Pending protection map doesn't contain current location, ignoring."); return; } Item itemEntity = e.getEntity(); UUID itemEntityId = itemEntity.getUniqueId(); ConcurrentLinkedQueue protectedItemQueue = this.pendingProtectionMap.get(blockLocation); for (ProtectedItem protectedItem : protectedItemQueue) { ItemStack protectedItemStack = protectedItem.getItemStack(); ItemStack itemEntityStack = itemEntity.getItemStack(); if (protectedItemStack.equals(itemEntityStack)) { printDebug("Detected protecting item spawn, saving entity ID ' " + itemEntityId + "'."); protectedItem.setItemUUID(itemEntityId); this.protectedItemMap.put(itemEntityId, protectedItem); protectedItemQueue.remove(protectedItem); if (protectedItemQueue.isEmpty()) { printDebug("Protected item queue is now empty, removing fro pending protection map."); this.pendingProtectionMap.remove(blockLocation); } return; } } } private @NotNull LootProtectionExpansion getLootProtection() { return this.expansion; } private @NotNull LootProtectionConfiguration getConfiguration() { LootProtectionExpansion expansion = getLootProtection(); return expansion.getConfiguration(); } private boolean isOnlyProtectAfterLog() { LootProtectionConfiguration configuration = getConfiguration(); return configuration.isOnlyProtectAfterLog(); } private boolean isReturnVoidItems() { LootProtectionConfiguration configuration = getConfiguration(); return configuration.isReturnVoidItems(); } private boolean contains(Item item) { UUID uuid = item.getUniqueId(); return this.protectedItemMap.containsKey(uuid); } private boolean checkVoidKill(EntityDeathEvent e) { printDebug("Checking void kill..."); LivingEntity entity = e.getEntity(); EntityDamageEvent lastDamageEvent = entity.getLastDamageCause(); if (lastDamageEvent == null) { printDebug("Player was killed by a mob, not VOID."); return false; } DamageCause lastDamageCause = lastDamageEvent.getCause(); if (lastDamageCause != DamageCause.VOID) { printDebug("Last cause of damage was not VOID."); return false; } if (isReturnVoidItems()) { UUID entityId = entity.getUniqueId(); UUID enemyId = this.enemyMap.get(entityId); if (enemyId == null) { printDebug("Enemy ID is null, VOID = true but can't return items."); return true; } Entity enemy = Bukkit.getEntity(enemyId); if (!(enemy instanceof Player enemyPlayer)) { printDebug("Enemy is not player, VOID = true but can't return items."); return true; } World enemyWorld = enemy.getWorld(); Location enemyLocation = enemy.getLocation(); List dropList = e.getDrops(); ItemStack[] dropArray = dropList.toArray(new ItemStack[0]); PlayerInventory enemyInventory = enemyPlayer.getInventory(); Map leftoverDrops = enemyInventory.addItem(dropArray); leftoverDrops.forEach((slot, drop) -> enemyWorld.dropItem(enemyLocation, drop, itemEntity -> { ProtectedItem protectedItem = new ProtectedItem(enemyLocation, drop); protectedItem.setItemUUID(itemEntity.getUniqueId()); protectedItem.setOwnerUUID(enemyId); this.protectedItemMap.put(protectedItem.getItemUUID(), protectedItem); })); printDebug("Added all void items to protection queue and dropped them at the enemy's location."); dropList.clear(); printDebug("Removed all items from death event."); return true; } printDebug("Void option is not enabled in configuration."); return false; } } ================================================ FILE: expansion/loot-protection/src/main/java/combatlogx/expansion/loot/protection/object/ProtectedItem.java ================================================ package combatlogx.expansion.loot.protection.object; import java.util.UUID; import org.bukkit.Location; import org.bukkit.inventory.ItemStack; import com.github.sirblobman.api.location.BlockLocation; import com.github.sirblobman.api.utility.Validate; public class ProtectedItem { private final BlockLocation location; private final ItemStack item; private UUID ownerUUID; private UUID itemUUID; public ProtectedItem(BlockLocation location, ItemStack item) { this.location = Validate.notNull(location, "location must not be null!"); this.item = Validate.notNull(item, "item must not be null!"); } public ProtectedItem(Location location, ItemStack item) { this(BlockLocation.from(location), item); } public ItemStack getItemStack() { return this.item; } public UUID getItemUUID() { return this.itemUUID; } public void setItemUUID(UUID itemUUID) { this.itemUUID = itemUUID; } public UUID getOwnerUUID() { return this.ownerUUID; } public void setOwnerUUID(UUID ownerUUID) { this.ownerUUID = ownerUUID; } } ================================================ FILE: expansion/loot-protection/src/main/resources/config.yml ================================================ # How long should items be protected after death? # Default: 30 (seconds) loot-protection-time: 30 # How long should the expansion wait before sending the same message again? # Default: 30 (seconds) message-cooldown: 30 # Should the expansion only protect items from people that have logged out during combat? # Default: false only-protect-after-log: false # Should the expansion add items to the killers inventory if the player dies in the void? # Default: true return-void-items: true ================================================ FILE: expansion/loot-protection/src/main/resources/expansion.yml ================================================ name: "${expansionName}" prefix: "${expansionPrefix}" description: "${expansionDescription}" main: "combatlogx.expansion.loot.protection.LootProtectionExpansion" version: "17.2" authors: - "olivolja3 (Olivo#3313)" # Original creator - "SirBlobman" # Code contributor ================================================ FILE: expansion/mob-tagger/README.MD ================================================ # CombatLogX Expansion: Mob Tagger The mob tagger expansion causes players to be tagged when they hit a mob or when a mob attacks them. ## Features - Allow mobs to tag players into combat. - Configurable list of mobs that can tag players. - Prevent certain types of mobs from tagging players. - Prevent mobs spawned for certain reasons from tagging players. (e.g. spawners) ================================================ FILE: expansion/mob-tagger/gradle.properties ================================================ version.spigot=1.14.4-R0.1-SNAPSHOT expansion.name=MobTagger expansion.prefix=Mob Tagger ================================================ FILE: expansion/mob-tagger/src/main/java/combatlogx/expansion/mob/tagger/MobTaggerExpansion.java ================================================ package combatlogx.expansion.mob.tagger; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import org.bukkit.configuration.file.YamlConfiguration; import com.github.sirblobman.api.configuration.ConfigurationManager; import com.github.sirblobman.api.utility.VersionUtility; import com.github.sirblobman.combatlogx.api.ICombatLogX; import com.github.sirblobman.combatlogx.api.expansion.Expansion; import combatlogx.expansion.mob.tagger.configuration.MobTaggerConfiguration; import combatlogx.expansion.mob.tagger.listener.ListenerDamage; import combatlogx.expansion.mob.tagger.manager.ISpawnReasonManager; import combatlogx.expansion.mob.tagger.manager.SpawnReasonManager_Legacy; import combatlogx.expansion.mob.tagger.manager.SpawnReasonManager_New; public final class MobTaggerExpansion extends Expansion { private final MobTaggerConfiguration configuration; private ISpawnReasonManager spawnReasonManager; public MobTaggerExpansion(ICombatLogX plugin) { super(plugin); this.configuration = new MobTaggerConfiguration(); this.spawnReasonManager = null; } @Override public void onLoad() { ConfigurationManager configurationManager = getConfigurationManager(); configurationManager.saveDefault("config.yml"); } @Override public void onEnable() { reloadConfig(); int minorVersion = VersionUtility.getMinorVersion(); if (minorVersion < 14) { this.spawnReasonManager = new SpawnReasonManager_Legacy(this); } else { this.spawnReasonManager = new SpawnReasonManager_New(this); } new ListenerDamage(this).register(); } @Override public void onDisable() { ISpawnReasonManager spawnReasonManager = getSpawnReasonManager(); if (spawnReasonManager != null) { spawnReasonManager.clear(); } } @Override public void reloadConfig() { ConfigurationManager configurationManager = getConfigurationManager(); configurationManager.reload("config.yml"); YamlConfiguration yamlConfiguration = configurationManager.get("config.yml"); MobTaggerConfiguration configuration = getConfiguration(); configuration.load(yamlConfiguration); } public @Nullable ISpawnReasonManager getSpawnReasonManager() { return this.spawnReasonManager; } public @NotNull MobTaggerConfiguration getConfiguration() { return this.configuration; } } ================================================ FILE: expansion/mob-tagger/src/main/java/combatlogx/expansion/mob/tagger/configuration/MobTaggerConfiguration.java ================================================ package combatlogx.expansion.mob.tagger.configuration; import java.util.Collection; import java.util.Collections; import java.util.EnumSet; import java.util.List; import java.util.Set; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import org.bukkit.configuration.ConfigurationSection; import org.bukkit.entity.EntityType; import org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason; import org.bukkit.permissions.Permission; import org.bukkit.permissions.PermissionDefault; import com.github.sirblobman.api.configuration.IConfigurable; import static com.github.sirblobman.api.utility.ConfigurationHelper.parseEnums; public final class MobTaggerConfiguration implements IConfigurable { private final Set mobTypeSet; private final Set spawnReasonSet; private boolean mobTypeSetInverted; private boolean spawnReasonSetInverted; private String bypassPermissionName; private transient Permission bypassPermission; public MobTaggerConfiguration() { this.mobTypeSet = EnumSet.noneOf(EntityType.class); this.mobTypeSetInverted = false; this.spawnReasonSet = EnumSet.noneOf(SpawnReason.class); this.spawnReasonSetInverted = false; this.bypassPermissionName = null; this.bypassPermission = null; } @Override public void load(ConfigurationSection config) { setMobTypeSetInverted(config.getBoolean("mob-list-inverted", false)); setSpawnReasonSetInverted(config.getBoolean("spawn-reason-list-inverted", false)); setBypassPermissionName(config.getString("bypass-permission")); List mobTypeNameList = config.getStringList("mob-list"); Set mobTypeSet = parseEnums(mobTypeNameList, EntityType.class); setMobTypes(mobTypeSet); List spawnReasonNameList = config.getStringList("spawn-reason-list"); Set spawnReasonSet = parseEnums(spawnReasonNameList, SpawnReason.class); setSpawnReasons(spawnReasonSet); } public @NotNull Set getMobTypes() { return Collections.unmodifiableSet(this.mobTypeSet); } public void setMobTypes(@NotNull Collection typeCollection) { this.mobTypeSet.clear(); this.mobTypeSet.addAll(typeCollection); } public @NotNull Set getSpawnReasons() { return Collections.unmodifiableSet(this.spawnReasonSet); } public void setSpawnReasons(@NotNull Collection reasonCollection) { this.spawnReasonSet.clear(); this.spawnReasonSet.addAll(reasonCollection); } public @Nullable String getBypassPermissionName() { return this.bypassPermissionName; } public void setBypassPermissionName(@Nullable String bypassPermissionName) { this.bypassPermissionName = bypassPermissionName; this.bypassPermission = null; } public @Nullable Permission getBypassPermission() { if (this.bypassPermission != null) { return this.bypassPermission; } String permissionName = getBypassPermissionName(); if (permissionName == null || permissionName.isEmpty()) { return null; } String permissionDescription = "CombatLogX bypass permission for mob combat."; this.bypassPermission = new Permission(permissionName, permissionDescription, PermissionDefault.FALSE); return this.bypassPermission; } public boolean isMobTypeSetInverted() { return mobTypeSetInverted; } public void setMobTypeSetInverted(boolean mobTypeSetInverted) { this.mobTypeSetInverted = mobTypeSetInverted; } public boolean isSpawnReasonSetInverted() { return spawnReasonSetInverted; } public void setSpawnReasonSetInverted(boolean spawnReasonSetInverted) { this.spawnReasonSetInverted = spawnReasonSetInverted; } public boolean shouldNotTag(EntityType mobType) { Set mobTypeSet = getMobTypes(); boolean inverted = isMobTypeSetInverted(); boolean contains = mobTypeSet.contains(mobType); return (inverted == contains); } public boolean shouldNotTag(SpawnReason reason) { Set reasonSet = getSpawnReasons(); boolean inverted = isSpawnReasonSetInverted(); boolean contains = reasonSet.contains(reason); return (inverted != contains); } } ================================================ FILE: expansion/mob-tagger/src/main/java/combatlogx/expansion/mob/tagger/listener/ListenerDamage.java ================================================ package combatlogx.expansion.mob.tagger.listener; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import org.bukkit.entity.Entity; import org.bukkit.entity.EntityType; import org.bukkit.entity.LivingEntity; import org.bukkit.entity.Player; import org.bukkit.event.EventHandler; import org.bukkit.event.EventPriority; import org.bukkit.event.entity.CreatureSpawnEvent; import org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason; import org.bukkit.event.entity.EntityDamageByEntityEvent; import org.bukkit.event.player.PlayerFishEvent; import org.bukkit.event.player.PlayerFishEvent.State; import org.bukkit.permissions.Permission; import com.github.sirblobman.combatlogx.api.ICombatLogX; import com.github.sirblobman.combatlogx.api.configuration.MainConfiguration; import com.github.sirblobman.combatlogx.api.event.PlayerPreTagEvent; import com.github.sirblobman.combatlogx.api.expansion.ExpansionListener; import com.github.sirblobman.combatlogx.api.manager.ICombatManager; import com.github.sirblobman.combatlogx.api.manager.ICrystalManager; import com.github.sirblobman.combatlogx.api.object.TagReason; import com.github.sirblobman.combatlogx.api.object.TagType; import com.github.sirblobman.combatlogx.api.utility.EntityHelper; import combatlogx.expansion.mob.tagger.MobTaggerExpansion; import combatlogx.expansion.mob.tagger.configuration.MobTaggerConfiguration; import combatlogx.expansion.mob.tagger.manager.ISpawnReasonManager; public final class ListenerDamage extends ExpansionListener { private final MobTaggerExpansion expansion; public ListenerDamage(MobTaggerExpansion expansion) { super(expansion); this.expansion = expansion; } @EventHandler(priority = EventPriority.NORMAL, ignoreCancelled = true) public void beforeTag(PlayerPreTagEvent e) { printDebug("Detected PlayerPreTagEvent..."); TagType tagType = e.getTagType(); if (tagType != TagType.MOB) { printDebug("TagType is not MOB, ignoring."); return; } Entity enemy = e.getEnemy(); if (enemy == null || enemy instanceof Player) { printDebug("Enemy is null or player, ignoring."); return; } EntityType entityType = enemy.getType(); MobTaggerConfiguration configuration = getConfiguration(); if (configuration.shouldNotTag(entityType)) { printDebug("EntityType " + entityType + " is disabled, cancelling event."); e.setCancelled(true); return; } SpawnReason spawnReason = getSpawnReason(enemy); if (configuration.shouldNotTag(spawnReason)) { printDebug("SpawnReason " + spawnReason + " is disabled, cancelling event."); e.setCancelled(true); } } @EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true) public void onDamage(EntityDamageByEntityEvent e) { Entity damaged = e.getEntity(); Entity damager = getDamager(e); checkTag(damaged, damager, TagReason.ATTACKED); checkTag(damager, damaged, TagReason.ATTACKER); } @EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true) public void onFish(PlayerFishEvent e) { ICombatLogX combatLogX = getCombatLogX(); MainConfiguration configuration = combatLogX.getConfiguration(); if (!configuration.isLinkFishingRod()) { return; } State state = e.getState(); if (state != State.CAUGHT_ENTITY) { return; } Entity caughtEntity = e.getCaught(); if (caughtEntity == null) { return; } Player player = e.getPlayer(); checkTag(player, caughtEntity, TagReason.ATTACKER); } @EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true) public void onSpawn(CreatureSpawnEvent e) { LivingEntity entity = e.getEntity(); SpawnReason spawnReason = e.getSpawnReason(); ISpawnReasonManager spawnReasonManager = getSpawnReasonManager(); if (spawnReasonManager != null) { spawnReasonManager.setSpawnReason(entity, spawnReason); } } private @NotNull MobTaggerExpansion getMobTaggerExpansion() { return this.expansion; } private @NotNull MobTaggerConfiguration getConfiguration() { MobTaggerExpansion expansion = getMobTaggerExpansion(); return expansion.getConfiguration(); } private @Nullable ISpawnReasonManager getSpawnReasonManager() { MobTaggerExpansion expansion = getMobTaggerExpansion(); return expansion.getSpawnReasonManager(); } private @NotNull Entity getDamager(@NotNull EntityDamageByEntityEvent e) { Entity entity = e.getDamager(); return getDamager(entity); } private @NotNull Entity getDamager(@NotNull Entity entity) { ICombatLogX plugin = getCombatLogX(); MainConfiguration configuration = plugin.getConfiguration(); if (configuration.isLinkProjectiles()) { entity = EntityHelper.linkProjectile(plugin, entity); } if (configuration.isLinkPets()) { entity = EntityHelper.linkPet(entity); } if (configuration.isLinkTnt()) { entity = EntityHelper.linkTNT(entity); } if (configuration.isLinkEndCrystals()) { ICombatLogX combatLogX = getCombatLogX(); ICrystalManager crystalManager = combatLogX.getCrystalManager(); Player player = crystalManager.getPlacer(entity); if (player != null) { entity = player; } } return entity; } private boolean isDisabled(@NotNull SpawnReason spawnReason) { MobTaggerConfiguration configuration = getConfiguration(); return configuration.shouldNotTag(spawnReason); } private void checkTag(Entity entity, Entity enemy, TagReason tagReason) { printDebug("Checking tag between entity " + entity + " and enemy " + enemy + " with reason " + tagReason + "..."); if (!(entity instanceof Player)) { printDebug("entity is not player, ignoring."); return; } if (enemy instanceof Player) { printDebug("enemy is a player, ignoring for mob tagger."); return; } Player player = (Player) entity; if (hasBypassPermission(player)) { printDebug("Player has bypass permission, ignoring."); return; } EntityType enemyType = enemy.getType(); MobTaggerConfiguration configuration = getConfiguration(); if (configuration.shouldNotTag(enemyType)) { printDebug("Enemy type '" + enemyType + "' is disabled, ignoring."); return; } SpawnReason spawnReason = getSpawnReason(enemy); if (isDisabled(spawnReason)) { printDebug("Enemy spawn reason '" + spawnReason + "' is disabled, ignoring."); return; } ICombatLogX plugin = getCombatLogX(); ICombatManager combatManager = plugin.getCombatManager(); combatManager.tag(player, enemy, TagType.MOB, tagReason); printDebug("Tagged player with type MOB."); } private SpawnReason getSpawnReason(Entity entity) { if (entity == null) { return SpawnReason.DEFAULT; } ISpawnReasonManager spawnReasonManager = getSpawnReasonManager(); if (spawnReasonManager == null) { return SpawnReason.DEFAULT; } return spawnReasonManager.getSpawnReason(entity); } private boolean hasBypassPermission(Player player) { MobTaggerConfiguration configuration = getConfiguration(); Permission bypassPermission = configuration.getBypassPermission(); if (bypassPermission == null) { return false; } return player.hasPermission(bypassPermission); } } ================================================ FILE: expansion/mob-tagger/src/main/java/combatlogx/expansion/mob/tagger/manager/ISpawnReasonManager.java ================================================ package combatlogx.expansion.mob.tagger.manager; import org.jetbrains.annotations.NotNull; import org.bukkit.entity.Entity; import org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason; import combatlogx.expansion.mob.tagger.MobTaggerExpansion; public interface ISpawnReasonManager { @NotNull MobTaggerExpansion getExpansion(); @NotNull SpawnReason getSpawnReason(@NotNull Entity entity); void setSpawnReason(@NotNull Entity entity, @NotNull SpawnReason spawnReason); void clear(); } ================================================ FILE: expansion/mob-tagger/src/main/java/combatlogx/expansion/mob/tagger/manager/SpawnReasonManager_Legacy.java ================================================ package combatlogx.expansion.mob.tagger.manager; import java.util.HashMap; import java.util.Map; import java.util.UUID; import org.jetbrains.annotations.NotNull; import org.bukkit.entity.Entity; import org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason; import combatlogx.expansion.mob.tagger.MobTaggerExpansion; public final class SpawnReasonManager_Legacy implements ISpawnReasonManager { private final MobTaggerExpansion expansion; private final Map spawnReasonMap; public SpawnReasonManager_Legacy(@NotNull MobTaggerExpansion expansion) { this.expansion = expansion; this.spawnReasonMap = new HashMap<>(); } @Override public @NotNull MobTaggerExpansion getExpansion() { return this.expansion; } @NotNull @Override public SpawnReason getSpawnReason(@NotNull Entity entity) { UUID entityId = entity.getUniqueId(); return this.spawnReasonMap.getOrDefault(entityId, SpawnReason.DEFAULT); } @Override public void setSpawnReason(@NotNull Entity entity, @NotNull SpawnReason spawnReason) { UUID entityId = entity.getUniqueId(); this.spawnReasonMap.put(entityId, spawnReason); } @Override public void clear() { this.spawnReasonMap.clear(); } } ================================================ FILE: expansion/mob-tagger/src/main/java/combatlogx/expansion/mob/tagger/manager/SpawnReasonManager_New.java ================================================ package combatlogx.expansion.mob.tagger.manager; import org.jetbrains.annotations.NotNull; import org.bukkit.NamespacedKey; import org.bukkit.entity.Entity; import org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason; import org.bukkit.persistence.PersistentDataContainer; import org.bukkit.persistence.PersistentDataType; import org.bukkit.plugin.java.JavaPlugin; import com.github.sirblobman.api.utility.Validate; import com.github.sirblobman.combatlogx.api.ICombatLogX; import combatlogx.expansion.mob.tagger.MobTaggerExpansion; public final class SpawnReasonManager_New implements ISpawnReasonManager { private final MobTaggerExpansion expansion; private final NamespacedKey spawnReasonKey; public SpawnReasonManager_New(MobTaggerExpansion expansion) { this.expansion = Validate.notNull(expansion, "expansion must not be null!"); ICombatLogX combatLogX = expansion.getPlugin(); JavaPlugin plugin = combatLogX.getPlugin(); this.spawnReasonKey = new NamespacedKey(plugin, "mob_tagger_spawn_reason"); } private @NotNull NamespacedKey getSpawnReasonKey() { return this.spawnReasonKey; } @Override public @NotNull MobTaggerExpansion getExpansion() { return this.expansion; } @NotNull @Override public SpawnReason getSpawnReason(@NotNull Entity entity) { NamespacedKey spawnReasonKey = getSpawnReasonKey(); PersistentDataContainer dataContainer = entity.getPersistentDataContainer(); if (!dataContainer.has(spawnReasonKey, PersistentDataType.STRING)) { return SpawnReason.DEFAULT; } String spawnReasonName = dataContainer.get(spawnReasonKey, PersistentDataType.STRING); if (spawnReasonName == null) { return SpawnReason.DEFAULT; } try { return SpawnReason.valueOf(spawnReasonName); } catch (IllegalArgumentException ignored) { return SpawnReason.DEFAULT; } } @Override public void setSpawnReason(@NotNull Entity entity, @NotNull SpawnReason spawnReason) { String spawnReasonName = spawnReason.name(); NamespacedKey spawnReasonKey = getSpawnReasonKey(); PersistentDataContainer dataContainer = entity.getPersistentDataContainer(); dataContainer.set(spawnReasonKey, PersistentDataType.STRING, spawnReasonName); } @Override public void clear() { // Empty Method } } ================================================ FILE: expansion/mob-tagger/src/main/resources/config.yml ================================================ # Information: # If you don't want mobs to tag players, remove this expansion # This is a list of mobs that should tag players. # Use "*" to allow all mob types # You can find a list of valid mob types on the Spigot javadocs: # https://hub.spigotmc.org/javadocs/spigot/org/bukkit/entity/EntityType.html mob-list: - "*" # Which spawn reasons prevent mobs from tagging players? # You can find a list of spawn reasons on the Spigot javadocs: # https://hub.spigotmc.org/javadocs/spigot/org/bukkit/event/entity/CreatureSpawnEvent.SpawnReason.html spawn-reason-list: - SPAWNER # Players with this permission will not be tagged by any mobs. # Other forms of combat will still tag players. # The permission is not given to OPs by default, you must set it manually. bypass-permission: "combatlogx.bypass.mobs" ================================================ FILE: expansion/mob-tagger/src/main/resources/expansion.yml ================================================ name: "${expansionName}" prefix: "${expansionPrefix}" description: "${expansionDescription}" main: "combatlogx.expansion.mob.tagger.MobTaggerExpansion" version: "17.1" author: "SirBlobman" ================================================ FILE: expansion/newbie-helper/README.MD ================================================ # CombatLogX Expansion: Newbie Helper The newbie helper expansion helps new players. ## Features - Prevent new players from being attacked for a configurable amount of time. - Remove protection from newbies when they attack someone. - Toggle your own ability to PVP. - (Admin Only) Force a certain player to have pvp enabled/disabled. ## Commands - **/togglepvp:** - **Aliases:** `pvptoggle`, `pvp` - **/togglepvp check \:** Check the PVP status of a player. - **/togglepvp on/off:** Enable or disable your ability to pvp. - **/togglepvp admin on/off \:** Enable or disable the pvp of another player by force. ## Permissions - **combatlogx.command.togglepvp:** Allows access to the `/togglepvp` command. - **combatlogx.command.togglepvp.admin:** Allows access to the `/togglepvp admin` command. ================================================ FILE: expansion/newbie-helper/build.gradle.kts ================================================ fun getEnvOrProp(variableName: String, propertyName: String): String { val environmentProvider = providers.environmentVariable(variableName) val propertyProvider = providers.gradleProperty(propertyName) return environmentProvider.orElse(propertyProvider).orElse("").get() } fun getProp(propertyName: String): String { val propertyProvider = providers.gradleProperty(propertyName) return propertyProvider.get() } plugins { id("maven-publish") } java { withSourcesJar() withJavadocJar() } publishing { repositories { maven("https://nexus.sirblobman.xyz/public/") { credentials { username = getEnvOrProp("MAVEN_DEPLOY_USR", "maven.username.sirblobman") password = getEnvOrProp("MAVEN_DEPLOY_PSW", "maven.password.sirblobman") } } } publications { create("maven") { groupId = "com.github.sirblobman.combatlogx.expansion" artifactId = "newbie-helper" version = getProp("version.api") from(components["java"]) } } } tasks.withType { val standardOptions = (options as StandardJavadocDocletOptions) standardOptions.addStringOption("Xdoclint:none", "-quiet") } ================================================ FILE: expansion/newbie-helper/gradle.properties ================================================ expansion.name=NewbieHelper expansion.prefix=Newbie Helper ================================================ FILE: expansion/newbie-helper/src/main/java/combatlogx/expansion/newbie/helper/NewbieHelperExpansion.java ================================================ package combatlogx.expansion.newbie.helper; import org.jetbrains.annotations.NotNull; import com.github.sirblobman.api.configuration.ConfigurationManager; import com.github.sirblobman.combatlogx.api.ICombatLogX; import com.github.sirblobman.combatlogx.api.expansion.Expansion; import com.github.sirblobman.combatlogx.api.manager.IPlaceholderManager; import combatlogx.expansion.newbie.helper.command.CommandTogglePVP; import combatlogx.expansion.newbie.helper.configuration.NewbieHelperConfiguration; import combatlogx.expansion.newbie.helper.configuration.WorldsConfiguration; import combatlogx.expansion.newbie.helper.listener.ListenerDamage; import combatlogx.expansion.newbie.helper.listener.ListenerJoin; import combatlogx.expansion.newbie.helper.listener.ListenerLavaFire; import combatlogx.expansion.newbie.helper.manager.CooldownManager; import combatlogx.expansion.newbie.helper.manager.PVPManager; import combatlogx.expansion.newbie.helper.manager.ProtectionManager; import combatlogx.expansion.newbie.helper.placeholder.NewbieHelperPlaceholderExpansion; public final class NewbieHelperExpansion extends Expansion { private final NewbieHelperConfiguration configuration; private final WorldsConfiguration worldsConfiguration; private final PVPManager pvpManager; private final ProtectionManager protectionManager; private final CooldownManager cooldownManager; public NewbieHelperExpansion(ICombatLogX plugin) { super(plugin); this.configuration = new NewbieHelperConfiguration(); this.worldsConfiguration = new WorldsConfiguration(); this.pvpManager = new PVPManager(this); this.protectionManager = new ProtectionManager(this); this.cooldownManager = new CooldownManager(this); } @Override public void onLoad() { ConfigurationManager configurationManager = getConfigurationManager(); configurationManager.saveDefault("config.yml"); configurationManager.saveDefault("worlds.yml"); } @Override public void onEnable() { // Reload Configuration reloadConfig(); // Register Listeners new ListenerJoin(this).register(); new ListenerDamage(this).register(); new ListenerLavaFire(this).register(); // Register command new CommandTogglePVP(this).register(); // Register Placeholder Expansion registerPlaceholderExpansion(); } @Override public void onDisable() { // Do Nothing } @Override public void reloadConfig() { ConfigurationManager configurationManager = getConfigurationManager(); configurationManager.reload("config.yml"); configurationManager.reload("worlds.yml"); getConfiguration().load(configurationManager.get("config.yml")); getWorldsConfiguration().load(configurationManager.get("worlds.yml")); } public @NotNull NewbieHelperConfiguration getConfiguration() { return this.configuration; } public @NotNull WorldsConfiguration getWorldsConfiguration() { return this.worldsConfiguration; } public @NotNull PVPManager getPVPManager() { return this.pvpManager; } public @NotNull ProtectionManager getProtectionManager() { return this.protectionManager; } public @NotNull CooldownManager getCooldownManager() { return this.cooldownManager; } private void registerPlaceholderExpansion() { ICombatLogX plugin = getPlugin(); IPlaceholderManager placeholderManager = plugin.getPlaceholderManager(); NewbieHelperPlaceholderExpansion expansion = new NewbieHelperPlaceholderExpansion(this); placeholderManager.registerPlaceholderExpansion(expansion); } } ================================================ FILE: expansion/newbie-helper/src/main/java/combatlogx/expansion/newbie/helper/command/CommandTogglePVP.java ================================================ package combatlogx.expansion.newbie.helper.command; import org.jetbrains.annotations.NotNull; import org.bukkit.World; import org.bukkit.entity.Player; import com.github.sirblobman.combatlogx.api.command.CombatLogPlayerCommand; import combatlogx.expansion.newbie.helper.NewbieHelperExpansion; import combatlogx.expansion.newbie.helper.command.admin.SubCommandAdmin; import combatlogx.expansion.newbie.helper.configuration.NewbieHelperConfiguration; import combatlogx.expansion.newbie.helper.manager.CooldownManager; import combatlogx.expansion.newbie.helper.manager.PVPManager; public final class CommandTogglePVP extends CombatLogPlayerCommand { private final NewbieHelperExpansion expansion; public CommandTogglePVP(@NotNull NewbieHelperExpansion expansion) { super(expansion.getPlugin(), "togglepvp"); setPermissionName("combatlogx.command.togglepvp"); addSubCommand(new SubCommandAdmin(expansion)); addSubCommand(new SubCommandCheck(expansion)); addSubCommand(new SubCommandOn(expansion)); addSubCommand(new SubCommandOff(expansion)); this.expansion = expansion; } @Override public boolean execute(@NotNull Player player, String @NotNull [] args) { NewbieHelperExpansion expansion = getExpansion(); NewbieHelperConfiguration configuration = expansion.getConfiguration(); World world = player.getWorld(); if (configuration.isPreventPvpToggleInDisabledWorlds() && isWorldDisabled(world)) { sendMessageWithPrefix(player, "error.disabled-world"); return true; } CooldownManager cooldownManager = expansion.getCooldownManager(); if (cooldownManager.hasCooldown(player)) { cooldownManager.sendCooldownMessage(player); return true; } else { cooldownManager.addCooldown(player); } PVPManager pvpManager = expansion.getPVPManager(); boolean pvpDisabled = pvpManager.isDisabled(player); pvpManager.setPVP(player, pvpDisabled); pvpManager.sendToggleMessage(player); return true; } private @NotNull NewbieHelperExpansion getExpansion() { return this.expansion; } } ================================================ FILE: expansion/newbie-helper/src/main/java/combatlogx/expansion/newbie/helper/command/SubCommandCheck.java ================================================ package combatlogx.expansion.newbie.helper.command; import java.util.Collections; import java.util.List; import java.util.Set; import org.jetbrains.annotations.NotNull; import org.bukkit.command.CommandSender; import org.bukkit.entity.Player; import com.github.sirblobman.api.language.LanguageManager; import com.github.sirblobman.api.language.replacer.ComponentReplacer; import com.github.sirblobman.api.language.replacer.Replacer; import com.github.sirblobman.api.language.replacer.StringReplacer; import com.github.sirblobman.combatlogx.api.command.CombatLogCommand; import com.github.sirblobman.api.shaded.adventure.text.Component; import combatlogx.expansion.newbie.helper.NewbieHelperExpansion; import combatlogx.expansion.newbie.helper.manager.PVPManager; import combatlogx.expansion.newbie.helper.manager.ProtectionManager; public final class SubCommandCheck extends CombatLogCommand { private final NewbieHelperExpansion expansion; public SubCommandCheck(@NotNull NewbieHelperExpansion expansion) { super(expansion.getPlugin(), "check"); setPermissionName("combatlogx.command.togglepvp.check"); this.expansion = expansion; } @Override protected @NotNull List onTabComplete(@NotNull CommandSender sender, String @NotNull [] args) { if (args.length == 1) { Set valueSet = getOnlinePlayerNames(); return getMatching(args[0], valueSet); } return Collections.emptyList(); } @Override protected boolean execute(@NotNull CommandSender sender, String @NotNull [] args) { if (args.length < 1) { return false; } Player target = findTarget(sender, args[0]); if (target == null) { return true; } String targetName = target.getName(); LanguageManager languageManager = getLanguageManager(); NewbieHelperExpansion expansion = getExpansion(); ProtectionManager protectionManager = expansion.getProtectionManager(); PVPManager pvpManager = expansion.getPVPManager(); boolean targetProtected = protectionManager.isProtected(target); boolean targetPvpStatus = !pvpManager.isDisabled(target); String placeholderPath0 = ("placeholder.toggle."); String placeholderPath1 = (placeholderPath0 + (targetProtected ? "enabled" : "disabled")); String placeholderPath2 = (placeholderPath0 + (targetPvpStatus ? "enabled" : "disabled")); Component protectedMessage = languageManager.getMessage(sender, placeholderPath1); Component pvpStatusMessage = languageManager.getMessage(sender, placeholderPath2); Replacer targetReplacer = new StringReplacer("{target}", targetName); Replacer protectedReplacer = new ComponentReplacer("{protected}", protectedMessage); Replacer pvpReplacer = new ComponentReplacer("{pvp}", pvpStatusMessage); sendMessageWithPrefix(sender, "expansion.newbie-helper.check-format", targetReplacer, protectedReplacer, pvpReplacer); return true; } private @NotNull NewbieHelperExpansion getExpansion() { return this.expansion; } } ================================================ FILE: expansion/newbie-helper/src/main/java/combatlogx/expansion/newbie/helper/command/SubCommandOff.java ================================================ package combatlogx.expansion.newbie.helper.command; import org.jetbrains.annotations.NotNull; import org.bukkit.World; import org.bukkit.entity.Player; import com.github.sirblobman.combatlogx.api.command.CombatLogPlayerCommand; import combatlogx.expansion.newbie.helper.NewbieHelperExpansion; import combatlogx.expansion.newbie.helper.configuration.NewbieHelperConfiguration; import combatlogx.expansion.newbie.helper.manager.PVPManager; public final class SubCommandOff extends CombatLogPlayerCommand { private final NewbieHelperExpansion expansion; public SubCommandOff(@NotNull NewbieHelperExpansion expansion) { super(expansion.getPlugin(), "off"); setPermissionName("combatlogx.command.togglepvp"); this.expansion = expansion; } @Override protected boolean execute(@NotNull Player player, String @NotNull [] args) { NewbieHelperExpansion expansion = getExpansion(); NewbieHelperConfiguration configuration = expansion.getConfiguration(); World world = player.getWorld(); if (configuration.isPreventPvpToggleInDisabledWorlds() && isWorldDisabled(world)) { sendMessageWithPrefix(player, "error.disabled-world"); return true; } PVPManager pvpManager = expansion.getPVPManager(); pvpManager.setPVP(player, false); pvpManager.sendToggleMessage(player); return true; } private @NotNull NewbieHelperExpansion getExpansion() { return this.expansion; } } ================================================ FILE: expansion/newbie-helper/src/main/java/combatlogx/expansion/newbie/helper/command/SubCommandOn.java ================================================ package combatlogx.expansion.newbie.helper.command; import org.jetbrains.annotations.NotNull; import org.bukkit.World; import org.bukkit.entity.Player; import com.github.sirblobman.combatlogx.api.command.CombatLogPlayerCommand; import combatlogx.expansion.newbie.helper.NewbieHelperExpansion; import combatlogx.expansion.newbie.helper.configuration.NewbieHelperConfiguration; import combatlogx.expansion.newbie.helper.manager.PVPManager; public final class SubCommandOn extends CombatLogPlayerCommand { private final NewbieHelperExpansion expansion; public SubCommandOn(@NotNull NewbieHelperExpansion expansion) { super(expansion.getPlugin(), "on"); setPermissionName("combatlogx.command.togglepvp"); this.expansion = expansion; } @Override protected boolean execute(@NotNull Player player, String @NotNull [] args) { NewbieHelperExpansion expansion = getExpansion(); NewbieHelperConfiguration configuration = expansion.getConfiguration(); World world = player.getWorld(); if (configuration.isPreventPvpToggleInDisabledWorlds() && isWorldDisabled(world)) { sendMessageWithPrefix(player, "error.disabled-world"); return true; } PVPManager pvpManager = expansion.getPVPManager(); pvpManager.setPVP(player, true); pvpManager.sendToggleMessage(player); return true; } private @NotNull NewbieHelperExpansion getExpansion() { return this.expansion; } } ================================================ FILE: expansion/newbie-helper/src/main/java/combatlogx/expansion/newbie/helper/command/admin/SubCommandAdmin.java ================================================ package combatlogx.expansion.newbie.helper.command.admin; import org.jetbrains.annotations.NotNull; import com.github.sirblobman.combatlogx.api.command.CombatLogCommand; import combatlogx.expansion.newbie.helper.NewbieHelperExpansion; public final class SubCommandAdmin extends CombatLogCommand { public SubCommandAdmin(@NotNull NewbieHelperExpansion expansion) { super(expansion.getPlugin(), "admin"); setPermissionName("combatlogx.command.togglepvp.admin"); addSubCommand(new SubCommandAdminOn(expansion)); addSubCommand(new SubCommandAdminOff(expansion)); } } ================================================ FILE: expansion/newbie-helper/src/main/java/combatlogx/expansion/newbie/helper/command/admin/SubCommandAdminOff.java ================================================ package combatlogx.expansion.newbie.helper.command.admin; import java.util.Collections; import java.util.List; import java.util.Set; import org.jetbrains.annotations.NotNull; import org.bukkit.command.CommandSender; import org.bukkit.entity.Player; import com.github.sirblobman.combatlogx.api.command.CombatLogCommand; import combatlogx.expansion.newbie.helper.NewbieHelperExpansion; import combatlogx.expansion.newbie.helper.manager.PVPManager; public final class SubCommandAdminOff extends CombatLogCommand { private final NewbieHelperExpansion expansion; public SubCommandAdminOff(@NotNull NewbieHelperExpansion expansion) { super(expansion.getPlugin(), "off"); setPermissionName("combatlogx.command.togglepvp.admin.off"); this.expansion = expansion; } @Override protected @NotNull List onTabComplete(@NotNull CommandSender sender, String @NotNull [] args) { if (args.length == 1) { Set valueSet = getOnlinePlayerNames(); return getMatching(args[0], valueSet); } return Collections.emptyList(); } @Override protected boolean execute(@NotNull CommandSender sender, String @NotNull [] args) { if (args.length < 1) { return false; } Player target = findTarget(sender, args[0]); if (target == null) { return true; } NewbieHelperExpansion expansion = getExpansion(); PVPManager pvpManager = expansion.getPVPManager(); pvpManager.setPVP(target, false); pvpManager.sendAdminToggleMessage(sender, target); return true; } private NewbieHelperExpansion getExpansion() { return this.expansion; } } ================================================ FILE: expansion/newbie-helper/src/main/java/combatlogx/expansion/newbie/helper/command/admin/SubCommandAdminOn.java ================================================ package combatlogx.expansion.newbie.helper.command.admin; import java.util.Collections; import java.util.List; import java.util.Set; import org.jetbrains.annotations.NotNull; import org.bukkit.command.CommandSender; import org.bukkit.entity.Player; import com.github.sirblobman.combatlogx.api.command.CombatLogCommand; import combatlogx.expansion.newbie.helper.NewbieHelperExpansion; import combatlogx.expansion.newbie.helper.manager.PVPManager; public final class SubCommandAdminOn extends CombatLogCommand { private final NewbieHelperExpansion expansion; public SubCommandAdminOn(@NotNull NewbieHelperExpansion expansion) { super(expansion.getPlugin(), "on"); setPermissionName("combatlogx.command.togglepvp.admin.on"); this.expansion = expansion; } @Override protected @NotNull List onTabComplete(@NotNull CommandSender sender, String @NotNull [] args) { if (args.length == 1) { Set valueSet = getOnlinePlayerNames(); return getMatching(args[0], valueSet); } return Collections.emptyList(); } @Override protected boolean execute(@NotNull CommandSender sender, String @NotNull [] args) { if (args.length < 1) { return false; } Player target = findTarget(sender, args[0]); if (target == null) { return true; } NewbieHelperExpansion expansion = getExpansion(); PVPManager pvpManager = expansion.getPVPManager(); pvpManager.setPVP(target, true); pvpManager.sendAdminToggleMessage(sender, target); return true; } private @NotNull NewbieHelperExpansion getExpansion() { return this.expansion; } } ================================================ FILE: expansion/newbie-helper/src/main/java/combatlogx/expansion/newbie/helper/configuration/NewbieHelperConfiguration.java ================================================ package combatlogx.expansion.newbie.helper.configuration; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import org.bukkit.configuration.ConfigurationSection; import org.bukkit.permissions.Permission; import org.bukkit.permissions.PermissionDefault; import com.github.sirblobman.api.configuration.IConfigurable; public final class NewbieHelperConfiguration implements IConfigurable { private boolean newPlayerProtection; private boolean removeProtectionOnAttack; private long protectionTime; private boolean mobProtection; private boolean blockProtection; private boolean pvpToggleDefaultStatus; private int pvpToggleCooldown; private String permissionName; private boolean preventPvpToggleInDisabledWorlds; private boolean newPlayerCauseDamage; private transient Permission permission; public NewbieHelperConfiguration() { this.newPlayerProtection = true; this.removeProtectionOnAttack = true; this.protectionTime = 30_000L; this.mobProtection = true; this.blockProtection = true; this.pvpToggleDefaultStatus = true; this.pvpToggleCooldown = 0; this.permissionName = null; this.preventPvpToggleInDisabledWorlds = true; this.newPlayerCauseDamage = true; this.permission = null; } @Override public void load(@NotNull ConfigurationSection config) { setNewPlayerProtection(config.getBoolean("new-player-protection", true)); setRemoveProtectionOnAttack(config.getBoolean("remove-protection-on-attack", true)); setProtectionTime(config.getLong("protection-time", 30_000L)); setMobProtection(config.getBoolean("mob-protection", true)); setBlockProtection(config.getBoolean("block-protection", true)); setPvpToggleDefaultStatus(config.getBoolean("pvp-toggle-default-status", true)); setPvpToggleCooldown(config.getInt("pvp-toggle-cooldown", 0)); setPermissionName(config.getString("pvp-toggle-cooldown-bypass-permission")); setPreventPvpToggleInDisabledWorlds(config.getBoolean("prevent-pvp-toggle-in-disabled-worlds", true)); setNewPlayerCauseDamage(config.getBoolean("new-player-cause-damage", true)); } public boolean isNewPlayerProtection() { return this.newPlayerProtection; } public void setNewPlayerProtection(boolean newPlayerProtection) { this.newPlayerProtection = newPlayerProtection; } public boolean isRemoveProtectionOnAttack() { return this.removeProtectionOnAttack; } public void setRemoveProtectionOnAttack(boolean removeProtectionOnAttack) { this.removeProtectionOnAttack = removeProtectionOnAttack; } public long getProtectionTime() { return this.protectionTime; } public void setProtectionTime(long protectionTime) { this.protectionTime = protectionTime; } public boolean isMobProtection() { return this.mobProtection; } public void setMobProtection(boolean mobProtection) { this.mobProtection = mobProtection; } public boolean getPvpToggleDefaultStatus() { return this.pvpToggleDefaultStatus; } public void setPvpToggleDefaultStatus(boolean pvpToggleDefaultStatus) { this.pvpToggleDefaultStatus = pvpToggleDefaultStatus; } public int getPvpToggleCooldown() { return this.pvpToggleCooldown; } public void setPvpToggleCooldown(int pvpToggleCooldown) { this.pvpToggleCooldown = pvpToggleCooldown; } public @Nullable String getPermissionName() { return this.permissionName; } public void setPermissionName(@Nullable String permissionName) { this.permissionName = permissionName; } public @Nullable Permission getPermission() { if (this.permission != null) { return this.permission; } String permissionName = getPermissionName(); if (permissionName == null || permissionName.isEmpty()) { return null; } String description = "CombatLogX Newbie Helper permission to bypass the cooldown for '/toggle-pvp'."; this.permission = new Permission(permissionName, description, PermissionDefault.OP); return this.permission; } public boolean isPreventPvpToggleInDisabledWorlds() { return this.preventPvpToggleInDisabledWorlds; } public void setPreventPvpToggleInDisabledWorlds(boolean preventPvpToggleInDisabledWorlds) { this.preventPvpToggleInDisabledWorlds = preventPvpToggleInDisabledWorlds; } public boolean isNewPlayerCauseDamage() { return this.newPlayerCauseDamage; } public void setNewPlayerCauseDamage(boolean newPlayerCauseDamage) { this.newPlayerCauseDamage = newPlayerCauseDamage; } public boolean isBlockProtection() { return blockProtection; } public void setBlockProtection(boolean blockProtection) { this.blockProtection = blockProtection; } } ================================================ FILE: expansion/newbie-helper/src/main/java/combatlogx/expansion/newbie/helper/configuration/WorldsConfiguration.java ================================================ package combatlogx.expansion.newbie.helper.configuration; import java.util.Collection; import java.util.Collections; import java.util.HashSet; import java.util.Set; import org.jetbrains.annotations.NotNull; import org.bukkit.World; import org.bukkit.configuration.ConfigurationSection; import com.github.sirblobman.api.configuration.IConfigurable; public final class WorldsConfiguration implements IConfigurable { private final Set forcedPvpWorldNameSet; private final Set noPvpWorldNameSet; public WorldsConfiguration() { this.forcedPvpWorldNameSet = new HashSet<>(); this.noPvpWorldNameSet = new HashSet<>(); } @Override public void load(@NotNull ConfigurationSection section) { setForcedPvpWorlds(section.getStringList("forced-pvp-world-list")); setNoPvpWorlds(section.getStringList("no-pvp-world-list")); } public @NotNull Set getForcedPvpWorlds() { return Collections.unmodifiableSet(this.forcedPvpWorldNameSet); } public void setForcedPvpWorlds(@NotNull Collection worlds) { this.forcedPvpWorldNameSet.clear(); this.forcedPvpWorldNameSet.addAll(worlds); } public @NotNull Set getNoPvpWorlds() { return Collections.unmodifiableSet(this.noPvpWorldNameSet); } public void setNoPvpWorlds(@NotNull Collection worlds) { this.noPvpWorldNameSet.clear(); this.noPvpWorldNameSet.addAll(worlds); } public boolean isForcePvp(@NotNull World world) { String worldName = world.getName(); Set worldNameSet = getForcedPvpWorlds(); return worldNameSet.contains(worldName); } public boolean isNoPvp(@NotNull World world) { String worldName = world.getName(); Set worldNameSet = getForcedPvpWorlds(); return worldNameSet.contains(worldName); } } ================================================ FILE: expansion/newbie-helper/src/main/java/combatlogx/expansion/newbie/helper/listener/ListenerDamage.java ================================================ package combatlogx.expansion.newbie.helper.listener; import org.jetbrains.annotations.NotNull; import org.bukkit.World; import org.bukkit.entity.Entity; import org.bukkit.entity.Player; import org.bukkit.event.EventHandler; import org.bukkit.event.EventPriority; import org.bukkit.event.entity.EntityDamageByEntityEvent; import com.github.sirblobman.api.language.LanguageManager; import com.github.sirblobman.combatlogx.api.ICombatLogX; import com.github.sirblobman.combatlogx.api.configuration.MainConfiguration; import com.github.sirblobman.combatlogx.api.expansion.ExpansionListener; import com.github.sirblobman.combatlogx.api.manager.ICrystalManager; import com.github.sirblobman.combatlogx.api.utility.EntityHelper; import combatlogx.expansion.newbie.helper.NewbieHelperExpansion; import combatlogx.expansion.newbie.helper.configuration.NewbieHelperConfiguration; import combatlogx.expansion.newbie.helper.configuration.WorldsConfiguration; import combatlogx.expansion.newbie.helper.manager.PVPManager; import combatlogx.expansion.newbie.helper.manager.ProtectionManager; public final class ListenerDamage extends ExpansionListener { private final NewbieHelperExpansion expansion; public ListenerDamage(@NotNull NewbieHelperExpansion expansion) { super(expansion); this.expansion = expansion; } @EventHandler(priority = EventPriority.NORMAL, ignoreCancelled = true) public void onDamageByMob(EntityDamageByEntityEvent e) { Entity damaged = e.getEntity(); if (!(damaged instanceof Player player)) { return; } if (isWorldDisabled(player)) { return; } Entity damager = getDamager(e); if (damager instanceof Player) { return; } ProtectionManager protectionManager = this.expansion.getProtectionManager(); if (protectionManager.isProtected(player) && isMobProtection()) { e.setCancelled(true); } } @EventHandler(priority = EventPriority.NORMAL, ignoreCancelled = true) public void onDamageMob(EntityDamageByEntityEvent e) { Entity damaged = e.getEntity(); if (damaged instanceof Player) { return; } Entity damager = getDamager(e); if (!(damager instanceof Player player)) { return; } if (isWorldDisabled(player)) { return; } ProtectionManager protectionManager = this.expansion.getProtectionManager(); if (protectionManager.isProtected(player) && isMobProtection()) { if (isRemoveProtectionOnAttack()) { protectionManager.setProtected(player, false); String messagePath = ("expansion.newbie-helper.protection-disabled.attacker"); LanguageManager languageManager = getLanguageManager(); languageManager.sendMessageWithPrefix(player, messagePath); } } } @EventHandler(priority = EventPriority.NORMAL, ignoreCancelled = true) public void onDamageByPlayer(EntityDamageByEntityEvent e) { Entity damaged = e.getEntity(); if (!(damaged instanceof Player attacked)) { return; } if (isWorldDisabled(attacked)) { return; } Entity damager = getDamager(e); if (!(damager instanceof Player attacker)) { return; } if (isWorldDisabled(attacker)) { return; } if (isForcePvpWorld(damager)) { return; } if (isNoPvpWorld(damager)) { e.setCancelled(true); return; } NewbieHelperExpansion expansion = getNewbieHelperExpansion(); ProtectionManager protectionManager = expansion.getProtectionManager(); PVPManager pvpManager = expansion.getPVPManager(); LanguageManager languageManager = getLanguageManager(); if (pvpManager.isDisabled(attacked)) { e.setCancelled(true); languageManager.sendMessageWithPrefix(attacker, "expansion.newbie-helper.no-pvp.other"); return; } if (pvpManager.isDisabled(attacker)) { e.setCancelled(true); languageManager.sendMessageWithPrefix(attacker, "expansion.newbie-helper.no-pvp.self"); return; } if (protectionManager.isProtected(attacked)) { e.setCancelled(true); String messagePath = ("expansion.newbie-helper.no-pvp.protected"); languageManager.sendMessageWithPrefix(attacker, messagePath); return; } if (protectionManager.isProtected(attacker)) { if (isRemoveProtectionOnAttack()) { protectionManager.setProtected(attacker, false); String messagePath = ("expansion.newbie-helper.protection-disabled.attacker"); languageManager.sendMessageWithPrefix(attacker, messagePath); return; } if (!isNewPlayerCauseDamage()) { e.setCancelled(true); String messagePath = ("expansion.newbie-helper.no-pvp.cancel"); languageManager.sendMessageWithPrefix(attacker, messagePath); } } } private @NotNull NewbieHelperExpansion getNewbieHelperExpansion() { return this.expansion; } private @NotNull NewbieHelperConfiguration getConfiguration() { NewbieHelperExpansion expansion = getNewbieHelperExpansion(); return expansion.getConfiguration(); } private @NotNull WorldsConfiguration getWorldsConfiguration() { NewbieHelperExpansion expansion = getNewbieHelperExpansion(); return expansion.getWorldsConfiguration(); } private boolean isForcePvpWorld(@NotNull Entity entity) { World world = entity.getWorld(); return isForcePvpWorld(world); } private boolean isForcePvpWorld(@NotNull World world) { WorldsConfiguration configuration = getWorldsConfiguration(); return configuration.isForcePvp(world); } private boolean isNoPvpWorld(@NotNull Entity entity) { World world = entity.getWorld(); return isNoPvpWorld(world); } private boolean isNoPvpWorld(@NotNull World world) { WorldsConfiguration configuration = getWorldsConfiguration(); return configuration.isNoPvp(world); } private boolean isRemoveProtectionOnAttack() { NewbieHelperConfiguration configuration = getConfiguration(); return configuration.isRemoveProtectionOnAttack(); } private boolean isNewPlayerCauseDamage() { NewbieHelperConfiguration configuration = getConfiguration(); return configuration.isNewPlayerCauseDamage(); } private boolean isMobProtection() { NewbieHelperConfiguration configuration = getConfiguration(); return configuration.isMobProtection(); } private @NotNull Entity getDamager(@NotNull EntityDamageByEntityEvent e) { Entity entity = e.getDamager(); return getDamager(entity); } private @NotNull Entity getDamager(@NotNull Entity entity) { ICombatLogX plugin = getCombatLogX(); MainConfiguration configuration = plugin.getConfiguration(); if (configuration.isLinkProjectiles()) { entity = EntityHelper.linkProjectile(plugin, entity); } if (configuration.isLinkPets()) { entity = EntityHelper.linkPet(entity); } if (configuration.isLinkTnt()) { entity = EntityHelper.linkTNT(entity); } if (configuration.isLinkEndCrystals()) { ICombatLogX combatLogX = getCombatLogX(); ICrystalManager crystalManager = combatLogX.getCrystalManager(); Player player = crystalManager.getPlacer(entity); if (player != null) { entity = player; } } return entity; } } ================================================ FILE: expansion/newbie-helper/src/main/java/combatlogx/expansion/newbie/helper/listener/ListenerJoin.java ================================================ package combatlogx.expansion.newbie.helper.listener; import org.jetbrains.annotations.NotNull; import org.bukkit.entity.Player; import org.bukkit.event.EventHandler; import org.bukkit.event.EventPriority; import org.bukkit.event.player.PlayerJoinEvent; import com.github.sirblobman.combatlogx.api.expansion.ExpansionListener; import combatlogx.expansion.newbie.helper.NewbieHelperExpansion; import combatlogx.expansion.newbie.helper.manager.ProtectionManager; public final class ListenerJoin extends ExpansionListener { private final NewbieHelperExpansion expansion; public ListenerJoin(NewbieHelperExpansion expansion) { super(expansion); this.expansion = expansion; } @EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true) public void onJoin(PlayerJoinEvent e) { Player player = e.getPlayer(); if (player.hasPlayedBefore()) { return; } if (isWorldDisabled(player)) { return; } NewbieHelperExpansion expansion = getNewbieHelper(); ProtectionManager protectionManager = expansion.getProtectionManager(); protectionManager.setProtected(player, true); } private @NotNull NewbieHelperExpansion getNewbieHelper() { return this.expansion; } } ================================================ FILE: expansion/newbie-helper/src/main/java/combatlogx/expansion/newbie/helper/listener/ListenerLavaFire.java ================================================ package combatlogx.expansion.newbie.helper.listener; import java.util.HashMap; import java.util.HashSet; import java.util.Map; import java.util.Set; import java.util.UUID; import org.jetbrains.annotations.NotNull; import org.bukkit.Material; import org.bukkit.block.Block; import org.bukkit.block.BlockFace; import org.bukkit.block.BlockState; import org.bukkit.entity.Entity; import org.bukkit.entity.Player; import org.bukkit.event.EventHandler; import org.bukkit.event.EventPriority; import org.bukkit.event.block.BlockBreakEvent; import org.bukkit.event.block.BlockBurnEvent; import org.bukkit.event.block.BlockFadeEvent; import org.bukkit.event.block.BlockFromToEvent; import org.bukkit.event.block.BlockPlaceEvent; import org.bukkit.event.block.BlockSpreadEvent; import org.bukkit.event.entity.EntityDamageByBlockEvent; import org.bukkit.event.player.PlayerBucketEmptyEvent; import org.bukkit.event.player.PlayerBucketFillEvent; import com.github.sirblobman.api.location.BlockLocation; import com.github.sirblobman.combatlogx.api.expansion.Expansion; import com.github.sirblobman.combatlogx.api.expansion.ExpansionListener; import com.github.sirblobman.api.shaded.xseries.XMaterial; import combatlogx.expansion.newbie.helper.NewbieHelperExpansion; import combatlogx.expansion.newbie.helper.configuration.NewbieHelperConfiguration; import combatlogx.expansion.newbie.helper.manager.ProtectionManager; public final class ListenerLavaFire extends ExpansionListener { private final NewbieHelperExpansion expansion; private final Set playerHazardSet; public ListenerLavaFire(@NotNull NewbieHelperExpansion expansion) { super(expansion); this.expansion = expansion; this.playerHazardSet = new HashSet<>(); } @EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true) public void onBucketEmpty(PlayerBucketEmptyEvent e) { XMaterial bucketType = XMaterial.matchXMaterial(e.getBucket()); if(bucketType != XMaterial.LAVA_BUCKET) { return; } Block clickedBlock = e.getBlockClicked(); BlockFace clickedFace = e.getBlockFace(); Block newLava = clickedBlock.getRelative(clickedFace); BlockLocation lavaLocation = BlockLocation.from(newLava); addPlayerHazard(lavaLocation); } @EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true) public void onBucketFill(PlayerBucketFillEvent e) { Block clickedBlock = e.getBlockClicked(); XMaterial clickedBlockType = XMaterial.matchXMaterial(clickedBlock.getType()); if (clickedBlockType == XMaterial.LAVA) { BlockLocation lavaLocation = BlockLocation.from(clickedBlock); removePlayerHazard(lavaLocation); } } @EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true) public void onPlace(BlockPlaceEvent e) { Block blockPlaced = e.getBlockPlaced(); XMaterial blockPlacedType = XMaterial.matchXMaterial(blockPlaced.getType()); if (blockPlacedType == XMaterial.FIRE) { BlockLocation fireLocation = BlockLocation.from(blockPlaced); addPlayerHazard(fireLocation); } if (blockPlacedType != XMaterial.FIRE && blockPlacedType != XMaterial.LAVA) { BlockLocation blockLocation = BlockLocation.from(blockPlaced); addPlayerHazard(blockLocation); } } @EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true) public void onBreak(BlockBreakEvent e) { Block blockBroken = e.getBlock(); XMaterial blockBrokenType = XMaterial.matchXMaterial(blockBroken.getType()); if (blockBrokenType == XMaterial.FIRE) { BlockLocation fireLocation = BlockLocation.from(blockBroken); removePlayerHazard(fireLocation); } } @EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true) public void onFireFade(@NotNull BlockFadeEvent e) { Block block = e.getBlock(); XMaterial blockType = XMaterial.matchXMaterial(block.getType()); if (blockType == XMaterial.FIRE) { BlockLocation fireLocation = BlockLocation.from(block); removePlayerHazard(fireLocation); } } @EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true) public void onFireSpread(@NotNull BlockSpreadEvent e) { Block source = e.getSource(); BlockLocation sourceLocation = BlockLocation.from(source); if (isPlayerHazard(sourceLocation)) { Block block = e.getBlock(); BlockLocation fireLocation = BlockLocation.from(block); removePlayerHazard(fireLocation); } } @EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true) public void onLavaFlow(@NotNull BlockFromToEvent e) { Block sourceBlock = e.getBlock(); BlockLocation sourceLocation = BlockLocation.from(sourceBlock); if (isPlayerHazard(sourceLocation)) { Block toBlock = e.getToBlock(); BlockLocation toLocation = BlockLocation.from(toBlock); addPlayerHazard(toLocation); } } @EventHandler(priority = EventPriority.NORMAL, ignoreCancelled = true) public void onDamage(EntityDamageByBlockEvent e) { Entity damaged = e.getEntity(); if (!(damaged instanceof Player player)) { return; } if (isBlockProtection()) { NewbieHelperExpansion expansion = getNewbieHelperExpansion(); BlockLocation blockLocation = BlockLocation.from(e.getDamager()); ProtectionManager protectionManager = expansion.getProtectionManager(); if (protectionManager.isProtected(player) && isPlayerHazard(blockLocation)) { printDebug("Detected damage from player-placed hazard, cancelled."); e.setCancelled(true); } } } private void addPlayerHazard(@NotNull BlockLocation location) { printDebug("Detected player-placed lava/fire at " + location); this.playerHazardSet.add(location); } private void removePlayerHazard(@NotNull BlockLocation location) { if (this.playerHazardSet.remove(location)) { printDebug("Detected removal of player lava/fire at " + location); } } private boolean isPlayerHazard(@NotNull BlockLocation location) { return this.playerHazardSet.contains(location); } private @NotNull NewbieHelperExpansion getNewbieHelperExpansion() { return this.expansion; } private @NotNull NewbieHelperConfiguration getConfiguration() { NewbieHelperExpansion expansion = getNewbieHelperExpansion(); return expansion.getConfiguration(); } private boolean isBlockProtection() { NewbieHelperConfiguration configuration = getConfiguration(); return configuration.isBlockProtection(); } } ================================================ FILE: expansion/newbie-helper/src/main/java/combatlogx/expansion/newbie/helper/manager/CooldownManager.java ================================================ package combatlogx.expansion.newbie.helper.manager; import java.util.Map; import java.util.UUID; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.TimeUnit; import org.jetbrains.annotations.NotNull; import org.bukkit.entity.Player; import org.bukkit.permissions.Permission; import com.github.sirblobman.api.language.LanguageManager; import com.github.sirblobman.api.language.replacer.LongReplacer; import com.github.sirblobman.api.language.replacer.Replacer; import com.github.sirblobman.combatlogx.api.ICombatLogX; import combatlogx.expansion.newbie.helper.NewbieHelperExpansion; import combatlogx.expansion.newbie.helper.configuration.NewbieHelperConfiguration; public final class CooldownManager { private final NewbieHelperExpansion expansion; private final Map cooldownMap; public CooldownManager(@NotNull NewbieHelperExpansion expansion) { this.expansion = expansion; this.cooldownMap = new ConcurrentHashMap<>(); } public boolean hasCooldown(@NotNull Player player) { NewbieHelperConfiguration configuration = getConfiguration(); Permission permission = configuration.getPermission(); if (permission != null && player.hasPermission(permission)) { return false; } UUID playerId = player.getUniqueId(); if (!this.cooldownMap.containsKey(playerId)) { return false; } long systemMillis = System.currentTimeMillis(); long expireMillis = this.cooldownMap.get(playerId); if (systemMillis >= expireMillis) { removeCooldown(player); return false; } return true; } public void addCooldown(@NotNull Player player) { NewbieHelperConfiguration configuration = getConfiguration(); Permission permission = configuration.getPermission(); if (permission != null && player.hasPermission(permission)) { return; } long cooldownSeconds = getCooldownSeconds(); if (cooldownSeconds <= 0L) { return; } long systemTimeMillis = System.currentTimeMillis(); long cooldownMillis = TimeUnit.SECONDS.toMillis(cooldownSeconds); long cooldownExpireMillis = (systemTimeMillis + cooldownMillis); setCooldownExpireMillis(player, cooldownExpireMillis); } public void setCooldownExpireMillis(@NotNull Player player, long expireMillis) { UUID playerId = player.getUniqueId(); this.cooldownMap.put(playerId, expireMillis); } public long getCooldownExpireMillis(@NotNull Player player) { UUID playerId = player.getUniqueId(); return this.cooldownMap.getOrDefault(playerId, 0L); } public void removeCooldown(@NotNull Player player) { UUID playerId = player.getUniqueId(); this.cooldownMap.remove(playerId); } public void sendCooldownMessage(@NotNull Player player) { if (!hasCooldown(player)) { return; } long expireMillis = getCooldownExpireMillis(player); long systemTimeMillis = System.currentTimeMillis(); long subtractMillis = (expireMillis - systemTimeMillis); long subtractSeconds = TimeUnit.MILLISECONDS.toSeconds(subtractMillis); Replacer replacer = new LongReplacer("{time_left}", subtractSeconds); LanguageManager languageManager = getLanguageManager(); String messageKey = "expansion.newbie-helper.togglepvp.cooldown"; languageManager.sendMessageWithPrefix(player, messageKey, replacer); } private @NotNull NewbieHelperExpansion getExpansion() { return this.expansion; } private @NotNull NewbieHelperConfiguration getConfiguration() { NewbieHelperExpansion expansion = getExpansion(); return expansion.getConfiguration(); } private @NotNull ICombatLogX getCombatLogX() { NewbieHelperExpansion expansion = getExpansion(); return expansion.getPlugin(); } private @NotNull LanguageManager getLanguageManager() { ICombatLogX combatLogX = getCombatLogX(); return combatLogX.getLanguageManager(); } private long getCooldownSeconds() { NewbieHelperConfiguration configuration = getConfiguration(); return configuration.getPvpToggleCooldown(); } } ================================================ FILE: expansion/newbie-helper/src/main/java/combatlogx/expansion/newbie/helper/manager/PVPManager.java ================================================ package combatlogx.expansion.newbie.helper.manager; import org.jetbrains.annotations.NotNull; import org.bukkit.command.CommandSender; import org.bukkit.configuration.file.YamlConfiguration; import org.bukkit.entity.Player; import com.github.sirblobman.api.configuration.PlayerDataManager; import com.github.sirblobman.api.language.LanguageManager; import com.github.sirblobman.api.language.replacer.ComponentReplacer; import com.github.sirblobman.api.language.replacer.Replacer; import com.github.sirblobman.api.language.replacer.StringReplacer; import com.github.sirblobman.combatlogx.api.ICombatLogX; import com.github.sirblobman.api.shaded.adventure.text.Component; import combatlogx.expansion.newbie.helper.NewbieHelperExpansion; import combatlogx.expansion.newbie.helper.configuration.NewbieHelperConfiguration; public final class PVPManager { private final NewbieHelperExpansion expansion; public PVPManager(@NotNull NewbieHelperExpansion expansion) { this.expansion = expansion; } public void setPVP(@NotNull Player player, boolean pvp) { if (isNPC(player)) { return; } YamlConfiguration playerData = getPlayerData(player); playerData.set("newbie-helper.pvp-toggle", pvp); savePlayerData(player); } public boolean isDisabled(@NotNull Player player) { if (isNPC(player)) { return false; } NewbieHelperConfiguration configuration = getConfiguration(); boolean defaultPvpState = configuration.getPvpToggleDefaultStatus(); YamlConfiguration playerData = getPlayerData(player); return !playerData.getBoolean("newbie-helper.pvp-toggle", defaultPvpState); } public void sendToggleMessage(@NotNull Player player) { boolean pvpDisabled = isDisabled(player); String pvpStatusPath = ("placeholder.toggle." + (pvpDisabled ? "disabled" : "enabled")); LanguageManager languageManager = getLanguageManager(); Component pvpStatus = languageManager.getMessage(player, pvpStatusPath); Replacer replacer = new ComponentReplacer("{status}", pvpStatus); languageManager.sendMessageWithPrefix(player, "expansion.newbie-helper.togglepvp.self", replacer); } public void sendAdminToggleMessage(@NotNull CommandSender sender, @NotNull Player target) { boolean pvpDisabled = isDisabled(target); String pvpStatusPath = ("placeholder.toggle." + (pvpDisabled ? "disabled" : "enabled")); LanguageManager languageManager = getLanguageManager(); Component pvpStatus = languageManager.getMessage(target, pvpStatusPath); Replacer statusReplacer = new ComponentReplacer("{status}", pvpStatus); String targetName = target.getName(); Replacer targetReplacer = new StringReplacer("{target}", targetName); languageManager.sendMessageWithPrefix(sender, "expansion.newbie-helper.togglepvp.admin", statusReplacer, targetReplacer); } private @NotNull NewbieHelperExpansion getExpansion() { return this.expansion; } private @NotNull NewbieHelperConfiguration getConfiguration() { NewbieHelperExpansion expansion = getExpansion(); return expansion.getConfiguration(); } private @NotNull ICombatLogX getCombatLogX() { NewbieHelperExpansion expansion = getExpansion(); return expansion.getPlugin(); } private @NotNull LanguageManager getLanguageManager() { ICombatLogX combatLogX = getCombatLogX(); return combatLogX.getLanguageManager(); } private @NotNull PlayerDataManager getPlayerDataManager() { ICombatLogX combatLogX = getCombatLogX(); return combatLogX.getPlayerDataManager(); } private @NotNull YamlConfiguration getPlayerData(@NotNull Player player) { PlayerDataManager playerDataManager = getPlayerDataManager(); return playerDataManager.get(player); } private void savePlayerData(@NotNull Player player) { PlayerDataManager playerDataManager = getPlayerDataManager(); playerDataManager.save(player); } private boolean isNPC(@NotNull Player player) { return player.hasMetadata("NPC"); } } ================================================ FILE: expansion/newbie-helper/src/main/java/combatlogx/expansion/newbie/helper/manager/ProtectionManager.java ================================================ package combatlogx.expansion.newbie.helper.manager; import org.jetbrains.annotations.NotNull; import org.bukkit.configuration.file.YamlConfiguration; import org.bukkit.entity.Player; import com.github.sirblobman.api.configuration.PlayerDataManager; import com.github.sirblobman.api.language.LanguageManager; import com.github.sirblobman.combatlogx.api.ICombatLogX; import combatlogx.expansion.newbie.helper.NewbieHelperExpansion; import combatlogx.expansion.newbie.helper.configuration.NewbieHelperConfiguration; public final class ProtectionManager { private final NewbieHelperExpansion expansion; public ProtectionManager(@NotNull NewbieHelperExpansion expansion) { this.expansion = expansion; } public void setProtected(@NotNull Player player, boolean protect) { if (isNPC(player)) { return; } YamlConfiguration playerData = getPlayerData(player); if (protect) { long newExpireTime = getProtectionExpireTime(); playerData.set("newbie-helper.protection-expire-time", newExpireTime); } else { playerData.set("newbie-helper.protection-expire-time", null); } playerData.set("newbie-helper.protected", protect); savePlayerData(player); } public boolean isProtected(@NotNull Player player) { if (isNPC(player)) { return false; } YamlConfiguration configuration = getPlayerData(player); if (!configuration.getBoolean("newbie-helper.protected")) { return false; } long expireTime = configuration.getLong("newbie-helper.protection-expire-time", 0L); long systemTime = System.currentTimeMillis(); if (systemTime < expireTime) { return true; } setProtected(player, false); LanguageManager languageManager = getLanguageManager(); languageManager.sendMessage(player, "expansion.newbie-helper.protection-disabled.expired"); return false; } public long getProtectionExpireTime(Player player) { if (isNPC(player)) { return 0L; } YamlConfiguration configuration = getPlayerData(player); if (!configuration.getBoolean("newbie-helper.protected")) { return 0L; } return configuration.getLong("newbie-helper.protection-expire-time", 0L); } private long getProtectionExpireTime() { NewbieHelperConfiguration configuration = getConfiguration(); long protectionMillis = configuration.getProtectionTime(); return (System.currentTimeMillis() + protectionMillis); } private @NotNull NewbieHelperExpansion getExpansion() { return this.expansion; } private @NotNull NewbieHelperConfiguration getConfiguration() { NewbieHelperExpansion expansion = getExpansion(); return expansion.getConfiguration(); } private @NotNull ICombatLogX getCombatLogX() { NewbieHelperExpansion expansion = getExpansion(); return expansion.getPlugin(); } private @NotNull LanguageManager getLanguageManager() { ICombatLogX combatLogX = getCombatLogX(); return combatLogX.getLanguageManager(); } private @NotNull PlayerDataManager getPlayerDataManager() { ICombatLogX combatLogX = getCombatLogX(); return combatLogX.getPlayerDataManager(); } private @NotNull YamlConfiguration getPlayerData(@NotNull Player player) { PlayerDataManager playerDataManager = getPlayerDataManager(); return playerDataManager.get(player); } private void savePlayerData(@NotNull Player player) { PlayerDataManager playerDataManager = getPlayerDataManager(); playerDataManager.save(player); } private boolean isNPC(@NotNull Player player) { return player.hasMetadata("NPC"); } } ================================================ FILE: expansion/newbie-helper/src/main/java/combatlogx/expansion/newbie/helper/placeholder/NewbieHelperPlaceholderExpansion.java ================================================ package combatlogx.expansion.newbie.helper.placeholder; import java.util.List; import java.util.concurrent.TimeUnit; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import org.bukkit.entity.Entity; import org.bukkit.entity.Player; import com.github.sirblobman.api.language.LanguageManager; import com.github.sirblobman.combatlogx.api.ICombatLogX; import com.github.sirblobman.combatlogx.api.placeholder.IPlaceholderExpansion; import com.github.sirblobman.api.shaded.adventure.text.Component; import combatlogx.expansion.newbie.helper.NewbieHelperExpansion; import combatlogx.expansion.newbie.helper.manager.PVPManager; import combatlogx.expansion.newbie.helper.manager.ProtectionManager; public final class NewbieHelperPlaceholderExpansion implements IPlaceholderExpansion { private final NewbieHelperExpansion expansion; public NewbieHelperPlaceholderExpansion(@NotNull NewbieHelperExpansion expansion) { this.expansion = expansion; } @Override public @NotNull ICombatLogX getCombatLogX() { NewbieHelperExpansion expansion = getExpansion(); return expansion.getPlugin(); } @Override public @NotNull String getId() { return "newbie"; } @Override public @Nullable Component getReplacement(@NotNull Player player, @NotNull List enemyList, @NotNull String placeholder) { switch (placeholder) { case "helper_pvp_status": return getPvpStatus(player); case "helper_protected": return getProtected(player); case "helper_protection_time_left": return getProtectionTimeLeft(player); default: break; } return null; } private @NotNull NewbieHelperExpansion getExpansion() { return this.expansion; } private @NotNull Component getPvpStatus(@NotNull Player player) { NewbieHelperExpansion expansion = getExpansion(); PVPManager pvpManager = expansion.getPVPManager(); boolean pvp = !pvpManager.isDisabled(player); ICombatLogX combatLogX = getCombatLogX(); LanguageManager languageManager = combatLogX.getLanguageManager(); String messagePath = ("placeholder.pvp-status." + (pvp ? "enabled" : "disabled")); return languageManager.getMessage(player, messagePath); } private @NotNull Component getProtected(@NotNull Player player) { NewbieHelperExpansion expansion = getExpansion(); ProtectionManager protectionManager = expansion.getProtectionManager(); boolean isProtected = protectionManager.isProtected(player); return Component.text(isProtected); } private @NotNull Component getProtectionTimeLeft(@NotNull Player player) { ICombatLogX combatLogX = getCombatLogX(); LanguageManager languageManager = combatLogX.getLanguageManager(); Component zero = languageManager.getMessage(player, "placeholder.time-left-zero"); NewbieHelperExpansion expansion = getExpansion(); ProtectionManager protectionManager = expansion.getProtectionManager(); if (!protectionManager.isProtected(player)) { return zero; } long expireTime = protectionManager.getProtectionExpireTime(player); long systemTime = System.currentTimeMillis(); long timeLeftMillis = (expireTime - systemTime); if (timeLeftMillis <= 0L) { return zero; } long timeLeftSeconds = TimeUnit.MILLISECONDS.toSeconds(timeLeftMillis); return Component.text(timeLeftSeconds); } } ================================================ FILE: expansion/newbie-helper/src/main/resources/config.yml ================================================ # Should new players be protected from attacks by other players? # Default: true new-player-protection: true # Should new players cause damage to other players? # Default: true new-player-cause-damage: true # Should new player protection be removed from a player if they attack someone? # Default: true remove-protection-on-attack: true # How long does protection last on a player (in milliseconds)? # Default: 30,000 (30 seconds) protection-time: 30000 # Should new players also be protected from mob attacks? # Default: true mob-protection: true # Should new players also be protected from blocks placed by players? # This will prevent damage from lava buckets and fire, but not if it wasn't placed by a player. # Default: true block-protection: true # (This is for the `/togglepvp` command, protection options are above.) # What is the default PVP status for players? # Default: true (PVP allowed) pvp-toggle-default-status: true # How long (in seconds) must players wait before using the pvp toggle command again? # Default: 0 (no cooldown) pvp-toggle-cooldown: 0 # What permission is required to bypass the pvp toggle cooldown? # Set this to "" to disable the bypass permission. # Default: "combatlogx.bypass.pvp-toggle.cooldown" pvp-toggle-cooldown-bypass-permission: "combatlogx.bypass.pvp-toggle.cooldown" # Should the expansion prevent non-admin pvp-toggle from being used # in worlds that are disabled in the main config? # Default: true prevent-pvp-toggle-in-disabled-worlds: true ================================================ FILE: expansion/newbie-helper/src/main/resources/expansion.yml ================================================ name: "${expansionName}" prefix: "${expansionPrefix}" description: "${expansionDescription}" main: "combatlogx.expansion.newbie.helper.NewbieHelperExpansion" version: "17.5" author: "SirBlobman" ================================================ FILE: expansion/newbie-helper/src/main/resources/worlds.yml ================================================ # This is a list of worlds that will ignore the pvp toggle and newbie protection # and allow PVP at all times. forced-pvp-world-list: - "pvp" - "arena" # This is a list of worlds that will ignore the pvp toggle and newbie protection # and deny PVP at all times; no-pvp-world-list: - "no_pvp" - "peaceful" ================================================ FILE: expansion/rewards/README.MD ================================================ # CombatLogX Expansion: Rewards The rewards expansion runs commands whenever a player kills a mob or another player. ## Features - Custom rewards - Enabled/Disabled worlds per reward. - Specific entity types per reward. - Chance based rewards. - Rewards with custom requirements: - Vault Economy Balance - *More coming soon...* ================================================ FILE: expansion/rewards/build.gradle.kts ================================================ repositories { maven("https://nexus.sirblobman.xyz/proxy-public") maven("https://repo.helpch.at/releases/") } dependencies { compileOnly("com.github.MilkBowl:VaultAPI:1.7.1") compileOnly("me.clip:placeholderapi:2.11.6") } ================================================ FILE: expansion/rewards/gradle.properties ================================================ expansion.name=Rewards ================================================ FILE: expansion/rewards/src/main/java/combatlogx/expansion/rewards/RewardExpansion.java ================================================ package combatlogx.expansion.rewards; import org.jetbrains.annotations.NotNull; import com.github.sirblobman.api.configuration.ConfigurationManager; import com.github.sirblobman.combatlogx.api.ICombatLogX; import com.github.sirblobman.combatlogx.api.expansion.Expansion; import com.github.sirblobman.combatlogx.api.expansion.ExpansionManager; import combatlogx.expansion.rewards.configuration.RewardConfiguration; import combatlogx.expansion.rewards.hook.HookVault; import combatlogx.expansion.rewards.listener.ListenerRewards; public final class RewardExpansion extends Expansion { private final RewardConfiguration configuration; private HookVault hookVault; public RewardExpansion(@NotNull ICombatLogX plugin) { super(plugin); this.configuration = new RewardConfiguration(this); this.hookVault = null; } @Override public void onLoad() { ConfigurationManager configurationManager = getConfigurationManager(); configurationManager.saveDefault("config.yml"); } @Override public void onEnable() { ICombatLogX plugin = getPlugin(); ExpansionManager expansionManager = plugin.getExpansionManager(); if (!checkDependency("Vault", true)) { expansionManager.disableExpansion(this); return; } this.hookVault = new HookVault(this); if (!this.hookVault.setupEconomy()) { expansionManager.disableExpansion(this); return; } reloadConfig(); new ListenerRewards(this).register(); } @Override public void onDisable() { // Do Nothing } @Override public void reloadConfig() { ConfigurationManager configurationManager = getConfigurationManager(); configurationManager.reload("config.yml"); getConfiguration().load(configurationManager.get("config.yml")); } public @NotNull RewardConfiguration getConfiguration() { return this.configuration; } public @NotNull HookVault getVaultHook() { return this.hookVault; } } ================================================ FILE: expansion/rewards/src/main/java/combatlogx/expansion/rewards/configuration/Reward.java ================================================ package combatlogx.expansion.rewards.configuration; import java.util.ArrayList; import java.util.Collection; import java.util.Collections; import java.util.EnumSet; import java.util.HashMap; import java.util.HashSet; import java.util.List; import java.util.Map; import java.util.Set; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import org.bukkit.World; import org.bukkit.configuration.ConfigurationSection; import org.bukkit.entity.EntityType; import org.bukkit.permissions.Permission; import org.bukkit.permissions.PermissionDefault; import com.github.sirblobman.api.configuration.IConfigurable; import combatlogx.expansion.rewards.RewardExpansion; import combatlogx.expansion.rewards.configuration.requirement.EconomyRequirement; import combatlogx.expansion.rewards.configuration.requirement.ExperienceRequirement; import combatlogx.expansion.rewards.configuration.requirement.Requirement; import static com.github.sirblobman.api.utility.ConfigurationHelper.parseEnums; public final class Reward implements IConfigurable { private final RewardExpansion expansion; private final String id; private final Set mobTypeList; private final Set worldList; private final List commandList; private final Map requirementMap; private String permissionName; private int chance; private int maxChance; private boolean mobWhiteList; private boolean worldWhiteList; private boolean randomCommand; private transient Permission permission; public Reward(@NotNull RewardExpansion expansion, @NotNull String id) { this.expansion = expansion; this.id = id; this.permissionName = null; this.chance = 1; this.maxChance = 2; this.mobWhiteList = true; this.mobTypeList = EnumSet.noneOf(EntityType.class); this.worldWhiteList = false; this.worldList = new HashSet<>(); this.randomCommand = false; this.commandList = new ArrayList<>(); this.requirementMap = new HashMap<>(); this.permission = null; } @Override public void load(@NotNull ConfigurationSection section) { setPermissionName(section.getString("permission")); setChance(section.getInt("chance", 5)); setMaxChance(section.getInt("max-chance", 1_000)); setWorldWhiteList(section.getBoolean("world-whitelist", false)); setWorldList(section.getStringList("world-list")); setMobWhiteList(section.getBoolean("mob-whitelist", true)); List mobTypeNameList = section.getStringList("mob-list"); setMobTypeList(parseEnums(mobTypeNameList, EntityType.class)); setRandomCommand(section.getBoolean("random-command", false)); setCommandList(section.getStringList("commands")); resetRequirements(); loadRequirements(getOrCreateSection(section, "requirements")); } private void loadRequirements(ConfigurationSection section) { Set requirementIdSet = section.getKeys(false); for (String requirementId : requirementIdSet) { ConfigurationSection sectionRequirement = section.getConfigurationSection(requirementId); if (sectionRequirement == null) { continue; } String type = sectionRequirement.getString("type"); if (type == null) { continue; } Requirement requirement; switch (type) { case "economy": requirement = loadEconomyRequirement(requirementId, sectionRequirement); break; case "experience": requirement = loadExperienceRequirement(requirementId, sectionRequirement); break; default: requirement = null; break; } if (requirement != null) { addRequirement(requirement); } } } private @NotNull EconomyRequirement loadEconomyRequirement(@NotNull String id, @NotNull ConfigurationSection section) { RewardExpansion expansion = getExpansion(); EconomyRequirement requirement = new EconomyRequirement(expansion, id); requirement.load(section); return requirement; } private @NotNull ExperienceRequirement loadExperienceRequirement(@NotNull String id, @NotNull ConfigurationSection section) { RewardExpansion expansion = getExpansion(); ExperienceRequirement requirement = new ExperienceRequirement(expansion, id); requirement.load(section); return requirement; } private @NotNull RewardExpansion getExpansion() { return this.expansion; } public @NotNull String getId() { return this.id; } public @Nullable String getPermissionName() { return permissionName; } public void setPermissionName(@Nullable String permissionName) { this.permissionName = permissionName; this.permission = null; } public @Nullable Permission getPermission() { if (this.permission != null) { return this.permission; } String permissionName = getPermissionName(); if (permissionName == null || permissionName.isEmpty()) { return null; } String description = "CombatLogX Rewards access permission."; this.permission = new Permission(permissionName, description, PermissionDefault.FALSE); return this.permission; } public int getChance() { return chance; } public void setChance(int chance) { this.chance = chance; } public int getMaxChance() { return maxChance; } public void setMaxChance(int maxChance) { this.maxChance = maxChance; } public boolean isMobWhiteList() { return mobWhiteList; } public void setMobWhiteList(boolean mobWhiteList) { this.mobWhiteList = mobWhiteList; } public Set getMobTypeList() { return mobTypeList; } public void setMobTypeList(@NotNull Collection mobTypeList) { this.mobTypeList.clear(); this.mobTypeList.addAll(mobTypeList); } public boolean isWorldWhiteList() { return worldWhiteList; } public void setWorldWhiteList(boolean worldWhiteList) { this.worldWhiteList = worldWhiteList; } public Set getWorldList() { return Collections.unmodifiableSet(this.worldList); } public void setWorldList(@NotNull Collection worldList) { this.worldList.clear(); this.worldList.addAll(worldList); } public boolean isRandomCommand() { return randomCommand; } public void setRandomCommand(boolean randomCommand) { this.randomCommand = randomCommand; } public @NotNull List getCommandList() { return Collections.unmodifiableList(this.commandList); } public void setCommandList(@NotNull Collection commandList) { this.commandList.clear(); this.commandList.addAll(commandList); } public @NotNull Map getRequirementMap() { return Collections.unmodifiableMap(this.requirementMap); } public @NotNull Collection getRequirements() { Map requirementMap = getRequirementMap(); Collection requirements = requirementMap.values(); return Collections.unmodifiableCollection(requirements); } public void addRequirement(Requirement requirement) { String id = requirement.getId(); this.requirementMap.put(id, requirement); } public void resetRequirements() { this.requirementMap.clear(); } public boolean contains(@NotNull World world) { Set worldList = getWorldList(); boolean whitelist = isWorldWhiteList(); String worldName = world.getName(); boolean contains = worldList.contains(worldName); return (whitelist == contains); } public boolean contains(@NotNull EntityType mobType) { Set mobTypeList = getMobTypeList(); boolean whitelist = isMobWhiteList(); boolean contains = mobTypeList.contains(mobType); return (whitelist == contains); } } ================================================ FILE: expansion/rewards/src/main/java/combatlogx/expansion/rewards/configuration/RewardConfiguration.java ================================================ package combatlogx.expansion.rewards.configuration; import java.util.Collection; import java.util.Collections; import java.util.HashMap; import java.util.Map; import java.util.Set; import org.jetbrains.annotations.NotNull; import org.bukkit.Bukkit; import org.bukkit.configuration.ConfigurationSection; import org.bukkit.plugin.PluginManager; import com.github.sirblobman.api.configuration.IConfigurable; import combatlogx.expansion.rewards.RewardExpansion; public final class RewardConfiguration implements IConfigurable { private final RewardExpansion expansion; private final Map rewardMap; private boolean usePlaceholderAPI; private transient Boolean placeholderApiPlugin; public RewardConfiguration(@NotNull RewardExpansion expansion) { this.expansion = expansion; this.rewardMap = new HashMap<>(); this.usePlaceholderAPI = false; this.placeholderApiPlugin = null; } @Override public void load(@NotNull ConfigurationSection config) { ConfigurationSection sectionHooks = getOrCreateSection(config, "hooks"); setUsePlaceholderAPI(sectionHooks.getBoolean("placeholderapi", true)); resetRewards(); ConfigurationSection rewardsSection = getOrCreateSection(config, "rewards"); loadRewards(rewardsSection); } private @NotNull RewardExpansion getExpansion() { return this.expansion; } private void loadRewards(@NotNull ConfigurationSection section) { RewardExpansion expansion = getExpansion(); Set rewardIdSet = section.getKeys(false); for (String rewardId : rewardIdSet) { ConfigurationSection rewardSection = section.getConfigurationSection(rewardId); if (rewardSection == null) { continue; } Reward reward = new Reward(expansion, rewardId); reward.load(rewardSection); addReward(reward); } } public boolean getUsePlaceholderAPI() { return this.usePlaceholderAPI; } public boolean isUsePlaceholderAPI() { if (this.placeholderApiPlugin != null) { return this.placeholderApiPlugin; } if (getUsePlaceholderAPI()) { PluginManager pluginManager = Bukkit.getPluginManager(); this.placeholderApiPlugin = pluginManager.isPluginEnabled("PlaceholderAPI"); } else { this.placeholderApiPlugin = false; } return this.placeholderApiPlugin; } public void setUsePlaceholderAPI(boolean usePlaceholderAPI) { this.usePlaceholderAPI = usePlaceholderAPI; this.placeholderApiPlugin = null; } public @NotNull Map getRewardMap() { return Collections.unmodifiableMap(this.rewardMap); } public @NotNull Collection getRewards() { Map rewardMap = getRewardMap(); Collection rewardCollection = rewardMap.values(); return Collections.unmodifiableCollection(rewardCollection); } public void addReward(@NotNull Reward reward) { String id = reward.getId(); this.rewardMap.put(id, reward); } public void resetRewards() { this.rewardMap.clear(); } } ================================================ FILE: expansion/rewards/src/main/java/combatlogx/expansion/rewards/configuration/requirement/EconomyRequirement.java ================================================ package combatlogx.expansion.rewards.configuration.requirement; import org.jetbrains.annotations.NotNull; import org.bukkit.entity.Player; import combatlogx.expansion.rewards.RewardExpansion; import combatlogx.expansion.rewards.hook.HookVault; import net.milkbowl.vault.economy.Economy; public final class EconomyRequirement extends Requirement { private double amount; public EconomyRequirement(@NotNull RewardExpansion expansion, @NotNull String id) { super(expansion, id); this.amount = 1.0D; } public double getAmount() { return this.amount; } public void setAmount(double amount) { this.amount = amount; } @Override public boolean meetsRequirement(@NotNull Player player) { RewardExpansion expansion = getExpansion(); HookVault vaultHook = expansion.getVaultHook(); Economy economyHandler = vaultHook.getEconomyHandler(); if (economyHandler == null) { return false; } double balance = economyHandler.getBalance(player); double amount = getAmount(); return (balance >= amount); } } ================================================ FILE: expansion/rewards/src/main/java/combatlogx/expansion/rewards/configuration/requirement/ExperienceRequirement.java ================================================ package combatlogx.expansion.rewards.configuration.requirement; import org.jetbrains.annotations.NotNull; import org.bukkit.configuration.ConfigurationSection; import org.bukkit.entity.Player; import com.github.sirblobman.api.utility.ExperienceUtility; import combatlogx.expansion.rewards.RewardExpansion; public final class ExperienceRequirement extends Requirement { private int amount; public ExperienceRequirement(@NotNull RewardExpansion expansion, @NotNull String id) { super(expansion, id); this.amount = 1; } @Override public void load(@NotNull ConfigurationSection section) { super.load(section); setAmount(section.getInt("amount", 1)); } public int getAmount() { return this.amount; } public void setAmount(int amount) { this.amount = amount; } @Override public boolean meetsRequirement(@NotNull Player player) { int amount = getAmount(); int balance = ExperienceUtility.getExp(player); return (balance >= amount); } } ================================================ FILE: expansion/rewards/src/main/java/combatlogx/expansion/rewards/configuration/requirement/Requirement.java ================================================ package combatlogx.expansion.rewards.configuration.requirement; import org.jetbrains.annotations.NotNull; import org.bukkit.configuration.ConfigurationSection; import org.bukkit.entity.LivingEntity; import org.bukkit.entity.Player; import com.github.sirblobman.api.configuration.IConfigurable; import combatlogx.expansion.rewards.RewardExpansion; public abstract class Requirement implements IConfigurable { private final RewardExpansion expansion; private final String id; private boolean checkEnemy; public Requirement(@NotNull RewardExpansion expansion, @NotNull String id) { this.expansion = expansion; this.id = id; } @Override public void load(@NotNull ConfigurationSection section) { setCheckEnemy(section.getBoolean("check-enemy")); } protected final @NotNull RewardExpansion getExpansion() { return this.expansion; } public final @NotNull String getId() { return this.id; } public final boolean isCheckEnemy() { return this.checkEnemy; } public final void setCheckEnemy(boolean checkEnemy) { this.checkEnemy = checkEnemy; } public boolean meetsRequirement(@NotNull LivingEntity entity) { if (entity instanceof Player) { Player player = (Player) entity; return meetsRequirement(player); } return false; } public abstract boolean meetsRequirement(@NotNull Player player); } ================================================ FILE: expansion/rewards/src/main/java/combatlogx/expansion/rewards/hook/HookVault.java ================================================ package combatlogx.expansion.rewards.hook; import java.util.Locale; import java.util.logging.Level; import java.util.logging.Logger; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import org.bukkit.Bukkit; import org.bukkit.plugin.Plugin; import org.bukkit.plugin.PluginDescriptionFile; import org.bukkit.plugin.RegisteredServiceProvider; import org.bukkit.plugin.ServicesManager; import combatlogx.expansion.rewards.RewardExpansion; import net.milkbowl.vault.economy.Economy; public final class HookVault { private final RewardExpansion expansion; private Economy economy; public HookVault(@NotNull RewardExpansion expansion) { this.expansion = expansion; } private @NotNull RewardExpansion getExpansion() { return this.expansion; } private @NotNull Logger getLogger() { RewardExpansion expansion = getExpansion(); return expansion.getLogger(); } public @Nullable Economy getEconomyHandler() { return this.economy; } public void setEconomyHandler(@NotNull Economy economy) { this.economy = economy; } public boolean setupEconomy() { try { ServicesManager servicesManager = Bukkit.getServicesManager(); RegisteredServiceProvider registration = servicesManager.getRegistration(Economy.class); if (registration == null) { Logger logger = getLogger(); logger.warning("An economy plugin is not registered."); return false; } Plugin plugin = registration.getPlugin(); PluginDescriptionFile description = plugin.getDescription(); String fullName = description.getFullName(); Economy economy = registration.getProvider(); String economyName = economy.getName(); Logger logger = getLogger(); String messageFormat = "Successfully hooked into economy handler '%s' from plugin '%s'."; String logMessage = String.format(Locale.US, messageFormat, economyName, fullName); logger.info(logMessage); setEconomyHandler(economy); return true; } catch (Exception ex) { Logger logger = getLogger(); logger.log(Level.WARNING, "Failed to find the economy handler:", ex); return false; } } } ================================================ FILE: expansion/rewards/src/main/java/combatlogx/expansion/rewards/listener/ListenerRewards.java ================================================ package combatlogx.expansion.rewards.listener; import java.util.ArrayList; import java.util.Collection; import java.util.Collections; import java.util.List; import java.util.Locale; import java.util.Random; import java.util.UUID; import java.util.logging.Level; import java.util.logging.Logger; import org.jetbrains.annotations.NotNull; import org.bukkit.Bukkit; import org.bukkit.World; import org.bukkit.command.CommandSender; import org.bukkit.entity.Entity; import org.bukkit.entity.EntityType; import org.bukkit.entity.LivingEntity; import org.bukkit.entity.Player; import org.bukkit.event.EventHandler; import org.bukkit.event.EventPriority; import org.bukkit.event.entity.EntityDeathEvent; import org.bukkit.permissions.Permission; import com.github.sirblobman.api.nms.EntityHandler; import com.github.sirblobman.api.nms.MultiVersionHandler; import com.github.sirblobman.combatlogx.api.ICombatLogX; import com.github.sirblobman.combatlogx.api.expansion.ExpansionListener; import combatlogx.expansion.rewards.RewardExpansion; import combatlogx.expansion.rewards.configuration.Reward; import combatlogx.expansion.rewards.configuration.RewardConfiguration; import combatlogx.expansion.rewards.configuration.requirement.Requirement; import me.clip.placeholderapi.PlaceholderAPI; public final class ListenerRewards extends ExpansionListener { private final RewardExpansion expansion; public ListenerRewards(@NotNull RewardExpansion expansion) { super(expansion); this.expansion = expansion; } @EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true) public void onDeath(EntityDeathEvent e) { LivingEntity entity = e.getEntity(); Player killer = entity.getKiller(); if (killer == null) { return; } checkRewards(killer, entity); } private @NotNull RewardExpansion getRewardsExpansion() { return this.expansion; } private @NotNull RewardConfiguration getConfiguration() { RewardExpansion expansion = getRewardsExpansion(); return expansion.getConfiguration(); } private void checkRewards(@NotNull Player player, @NotNull LivingEntity enemy) { RewardConfiguration configuration = getConfiguration(); Collection rewards = configuration.getRewards(); for (Reward reward : rewards) { checkReward(player, enemy, reward); } } private void checkReward(@NotNull Player player, @NotNull LivingEntity enemy, @NotNull Reward reward) { if (!hasPermission(player, reward)) { return; } if (isSelf(player, enemy)) { return; } World world = player.getWorld(); if (!reward.contains(world)) { return; } EntityType mobType = enemy.getType(); if (!reward.contains(mobType)) { return; } if (!checkChance(reward)) { return; } if (checkRequirements(enemy, reward)) { runCommands(player, enemy, reward); } } private boolean hasPermission(@NotNull Player player, @NotNull Reward reward) { Permission permission = reward.getPermission(); if (permission != null) { return player.hasPermission(permission); } return true; } private boolean isSelf(@NotNull Player player, @NotNull LivingEntity enemy) { if (!(enemy instanceof Player)) { return false; } Player enemyPlayer = (Player) enemy; UUID playerId = player.getUniqueId(); UUID enemyId = enemyPlayer.getUniqueId(); return playerId.equals(enemyId); } private boolean checkChance(@NotNull Reward reward) { int chance = reward.getChance(); int maxChance = reward.getMaxChance(); if (chance >= maxChance) { return true; } Random random = new Random(); int randomValue = 1 + random.nextInt(maxChance); return (randomValue <= chance); } private boolean checkRequirements(@NotNull LivingEntity enemy, @NotNull Reward reward) { Collection requirements = reward.getRequirements(); for (Requirement requirement : requirements) { if (!requirement.meetsRequirement(enemy)) { return false; } } return true; } private void runCommands(@NotNull Player player, @NotNull LivingEntity enemy, @NotNull Reward reward) { List commandList = reward.getCommandList(); if (commandList.isEmpty()) { return; } int commandListSize = commandList.size(); if (reward.isRandomCommand() && commandListSize > 1) { Random random = new Random(); int randomIndex = random.nextInt(commandListSize); commandList = Collections.singletonList(commandList.get(randomIndex)); } List replacedCommandList = new ArrayList<>(); for (String command : commandList) { String replaced = replaceCommand(player, enemy, command); replacedCommandList.add(replaced); } runCommands(replacedCommandList); } private @NotNull String getEntityName(@NotNull Entity entity) { ICombatLogX plugin = getCombatLogX(); MultiVersionHandler multiVersionHandler = plugin.getMultiVersionHandler(); EntityHandler entityHandler = multiVersionHandler.getEntityHandler(); return entityHandler.getName(entity); } private @NotNull String replaceCommand(@NotNull Player player, @NotNull LivingEntity enemy, @NotNull String command) { String playerName = player.getName(); String enemyName = getEntityName(enemy); String enemyType = enemy.getType().name(); String replaceBasic = command.replace("{player}", playerName) .replace("{enemy}", enemyName) .replace("{enemy_type}", enemyType); RewardConfiguration configuration = getConfiguration(); if (configuration.isUsePlaceholderAPI()) { return PlaceholderAPI.setPlaceholders(player, replaceBasic); } return replaceBasic; } private void runCommands(@NotNull List commandList) { CommandSender console = Bukkit.getConsoleSender(); for (String command : commandList) { runCommand(console, command); } } private void runCommand(@NotNull CommandSender sender, @NotNull String command) { try { Bukkit.dispatchCommand(sender, command); } catch (Exception ex) { Logger logger = getExpansionLogger(); String messageFormat = "Failed to execute command '/%s' in the console:"; String logMessage = String.format(Locale.US, messageFormat, command); logger.log(Level.WARNING, logMessage, ex); } } } ================================================ FILE: expansion/rewards/src/main/resources/config.yml ================================================ hooks: # Should placeholders from PlaceholderAPI be replaced in commands? # Recommended Version: 2.11.3 placeholderapi: true rewards: # 'exampleOne' is the ID for this reward. # You can use letters (A-Z and a-z) and numbers (0-9) for the id, but not symbols. # Every ID should be different, but you can have as many as you want. exampleOne: # If the player does not have this permission, the reward will not be triggered. # Defaults to empty (not required) permission: "" # Chance is calculated using RNG (Java ThreadLocalRandom) # The value checked is a percent that comes from the value of (chance / max-chance) # This example will give a (5/1000) or a 0.5% chance of this reward occurring. chance: 5 max-chance: 1000 # If you set this to true, the mobs in the mob-list will activate rewards # If you set this to false, all mobs will activate rewards except the ones in the list mob-whitelist: true # PLAYER is technically a mob mob-list: - PLAYER - CREEPER # If you set this to true, only the worlds in the list will activate this reward # If you set this to false, All worlds will activate this reward except the ones in the list world-whitelist: true # A list of worlds # World names are case sensitive, "wOrLd" is not the same as "world" world-list: - "world" - "world_nether" - "world_the_end" # Set this to true if a single command should be chosen randomly instead of running all commands random-command: false # A list of commands to execute when the reward chance is successful # Valid Placeholders: # - {player} - the player who killed the entity that triggered this reward # - {enemy} - The name of the entity that was killed. (e.g. SirBlobman) # - {enemy_type} - The type of the entity that was killed. (e.g. PLAYER) commands: - "give {player} diamond 1" - "msg {player} You won a diamond for killing {enemy}" - "msg {player} Kill more {enemy_type} for a 0.5% chance of a diamond." exampleTwo: # Some rewards can have requirements. requirements: # This example requirement ensures that the enemy killed has $500 in their Vault economy account # Requirements may exclude mobs if they require a player, even if mobs are included in the list # The only available requirements types at this time are 'economy' and 'experience'. # Economy requires a decimal 'amount'. Experience requires an integer 'amount'. economyExampleOne: type: economy check-enemy: true amount: 500.0 mob-whitelist: false world-whitelist: false chance: 1 max-chance: 2 random-command: false commands: - "eco take {enemy} 500" - "eco give {player} 500" ================================================ FILE: expansion/rewards/src/main/resources/expansion.yml ================================================ name: "${expansionName}" prefix: "${expansionPrefix}" description: "${expansionDescription}" main: "combatlogx.expansion.rewards.RewardExpansion" version: "17.6" author: "SirBlobman" ================================================ FILE: expansion/scoreboard/README.MD ================================================ # CombatLogX Expansion: Scoreboard The scoreboard expansion shows a scoreboard to every player that is in combat. ## Features - Customizable title and lines - Lines update without flickering ## Commands - **/combatlogx toggle:** - **/combatlogx toggle scoreboard:** Enable or disable your scoreboard display. ================================================ FILE: expansion/scoreboard/build.gradle.kts ================================================ repositories { maven("https://repo.papermc.io/repository/maven-public/") } dependencies { val spigotVersion = property("version.spigot") as String compileOnly("com.destroystokyo.paper:paper-api:$spigotVersion") } ================================================ FILE: expansion/scoreboard/gradle.properties ================================================ version.spigot=1.16.5-R0.1-SNAPSHOT expansion.name=Scoreboard ================================================ FILE: expansion/scoreboard/src/main/java/combatlogx/expansion/scoreboard/ScoreboardConfiguration.java ================================================ package combatlogx.expansion.scoreboard; import org.jetbrains.annotations.NotNull; import org.bukkit.configuration.ConfigurationSection; import com.github.sirblobman.api.configuration.IConfigurable; public final class ScoreboardConfiguration implements IConfigurable { private boolean enabled; private boolean savePrevious; public ScoreboardConfiguration() { setEnabled(true); setSavePrevious(true); } @Override public void load(@NotNull ConfigurationSection config) { setEnabled(config.getBoolean("enabled", true)); setSavePrevious(config.getBoolean("save-previous", true)); } public boolean isEnabled() { return enabled; } public void setEnabled(boolean enabled) { this.enabled = enabled; } public boolean isSavePrevious() { return savePrevious; } public void setSavePrevious(boolean savePrevious) { this.savePrevious = savePrevious; } } ================================================ FILE: expansion/scoreboard/src/main/java/combatlogx/expansion/scoreboard/ScoreboardExpansion.java ================================================ package combatlogx.expansion.scoreboard; import java.lang.reflect.Method; import java.lang.reflect.Modifier; import java.util.logging.Logger; import org.jetbrains.annotations.NotNull; import org.bukkit.configuration.file.YamlConfiguration; import com.github.sirblobman.api.configuration.ConfigurationManager; import com.github.sirblobman.api.utility.VersionUtility; import com.github.sirblobman.combatlogx.api.ICombatLogX; import com.github.sirblobman.combatlogx.api.expansion.Expansion; import com.github.sirblobman.combatlogx.api.manager.ITimerManager; import combatlogx.expansion.scoreboard.manager.CustomScoreboardManager; public final class ScoreboardExpansion extends Expansion { private final ScoreboardConfiguration configuration; private final CustomScoreboardManager scoreboardManager; private Boolean usePaperAPI; public ScoreboardExpansion(@NotNull ICombatLogX plugin) { super(plugin); this.configuration = new ScoreboardConfiguration(); this.scoreboardManager = new CustomScoreboardManager(this); this.usePaperAPI = null; } @Override public void onLoad() { ConfigurationManager configurationManager = getConfigurationManager(); configurationManager.saveDefault("config.yml"); } @Override public void onEnable() { int majorVersion = VersionUtility.getMajorVersion(); int minorVersion = VersionUtility.getMinorVersion(); if (majorVersion == 1 && minorVersion < 8) { Logger logger = getLogger(); logger.warning("This expansion requires Spigot 1.8.8 or higher."); selfDisable(); return; } if (getPlugin().getFoliaHelper().isFolia()) { Logger logger = getLogger(); logger.warning("Folia does not currently support scoreboards."); selfDisable(); return; } reloadConfig(); ICombatLogX plugin = getPlugin(); ITimerManager timerManager = plugin.getTimerManager(); timerManager.addUpdaterTask(new ScoreboardUpdater(this)); } @Override public void onDisable() { int minorVersion = VersionUtility.getMinorVersion(); if (minorVersion < 8) { return; } CustomScoreboardManager scoreboardManager = getScoreboardManager(); scoreboardManager.removeAll(); } @Override public void reloadConfig() { ConfigurationManager configurationManager = getConfigurationManager(); configurationManager.reload("config.yml"); ScoreboardConfiguration configuration = getConfiguration(); YamlConfiguration yamlConfiguration = configurationManager.get("config.yml"); configuration.load(yamlConfiguration); } public @NotNull CustomScoreboardManager getScoreboardManager() { return this.scoreboardManager; } public @NotNull ScoreboardConfiguration getConfiguration() { return this.configuration; } public boolean isPaperScoreboard() { if (this.usePaperAPI != null) { return this.usePaperAPI; } try { Class componentClass = Class.forName("net.kyori.adventure.text.Component"); Class scoreboardClass = Class.forName("org.bukkit.scoreboard.Objective"); Method displayNameMethod = scoreboardClass.getDeclaredMethod("displayName", componentClass); int modifiers = displayNameMethod.getModifiers(); this.usePaperAPI = Modifier.isPublic(modifiers); } catch (ReflectiveOperationException ex) { this.usePaperAPI = false; } Logger logger = getLogger(); if (this.usePaperAPI) { logger.info("Using Paper API and Adventure Component for scoreboards"); } else { logger.info("Using Spigot and String for scoreboards."); } return this.usePaperAPI; } } ================================================ FILE: expansion/scoreboard/src/main/java/combatlogx/expansion/scoreboard/ScoreboardUpdater.java ================================================ package combatlogx.expansion.scoreboard; import org.jetbrains.annotations.NotNull; import org.bukkit.entity.Player; import com.github.sirblobman.combatlogx.api.object.TimerUpdater; import combatlogx.expansion.scoreboard.manager.CustomScoreboardManager; public final class ScoreboardUpdater implements TimerUpdater { private final ScoreboardExpansion expansion; public ScoreboardUpdater(@NotNull ScoreboardExpansion expansion) { this.expansion = expansion; } @Override public void update(@NotNull Player player, long timeLeftMillis) { CustomScoreboardManager scoreboardManager = getScoreboardManager(); scoreboardManager.updateScoreboard(player); } @Override public void remove(@NotNull Player player) { CustomScoreboardManager scoreboardManager = getScoreboardManager(); scoreboardManager.removeScoreboard(player); } private @NotNull CustomScoreboardManager getScoreboardManager() { return this.expansion.getScoreboardManager(); } } ================================================ FILE: expansion/scoreboard/src/main/java/combatlogx/expansion/scoreboard/manager/CustomScoreboardManager.java ================================================ package combatlogx.expansion.scoreboard.manager; import java.util.Collection; import java.util.HashMap; import java.util.Map; import java.util.UUID; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import org.bukkit.Bukkit; import org.bukkit.configuration.file.YamlConfiguration; import org.bukkit.entity.Player; import org.bukkit.scoreboard.DisplaySlot; import org.bukkit.scoreboard.Objective; import org.bukkit.scoreboard.Scoreboard; import com.github.sirblobman.api.configuration.PlayerDataManager; import com.github.sirblobman.combatlogx.api.ICombatLogX; import combatlogx.expansion.scoreboard.ScoreboardConfiguration; import combatlogx.expansion.scoreboard.ScoreboardExpansion; import combatlogx.expansion.scoreboard.scoreboard.CustomScoreboard; public final class CustomScoreboardManager { private final ScoreboardExpansion expansion; private final Map oldScoreboardMap; private final Map combatScoreboardMap; public CustomScoreboardManager(@NotNull ScoreboardExpansion expansion) { this.expansion = expansion; this.oldScoreboardMap = new HashMap<>(); this.combatScoreboardMap = new HashMap<>(); } public @NotNull ScoreboardExpansion getExpansion() { return this.expansion; } private @NotNull ICombatLogX getCombatLogX() { ScoreboardExpansion expansion = getExpansion(); return expansion.getPlugin(); } private @NotNull PlayerDataManager getPlayerDataManager() { ICombatLogX combatLogX = getCombatLogX(); return combatLogX.getPlayerDataManager(); } private @NotNull ScoreboardConfiguration getConfiguration() { ScoreboardExpansion expansion = getExpansion(); return expansion.getConfiguration(); } private boolean isGlobalEnabled() { ScoreboardConfiguration configuration = getConfiguration(); return configuration.isEnabled(); } private boolean isDisabled(@NotNull Player player) { if (isGlobalEnabled()) { PlayerDataManager playerDataManager = getPlayerDataManager(); YamlConfiguration configuration = playerDataManager.get(player); return !configuration.getBoolean("scoreboard", true); } return true; } private boolean shouldIgnorePrevious() { ScoreboardConfiguration configuration = getConfiguration(); return !configuration.isSavePrevious(); } public void updateScoreboard(@NotNull Player player) { UUID playerId = player.getUniqueId(); if (isDisabled(player)) { removeScoreboard(player); return; } CustomScoreboard customScoreboard = this.combatScoreboardMap.getOrDefault(playerId, null); if (customScoreboard == null) { createScoreboard(player); return; } customScoreboard.updateScoreboard(); } private void createScoreboard(@NotNull Player player) { CustomScoreboard customScoreboard = enableScoreboard(player); if (customScoreboard != null) { customScoreboard.updateScoreboard(); } } public void removeScoreboard(@NotNull Player player) { UUID uuid = player.getUniqueId(); CustomScoreboard customScoreboard = this.combatScoreboardMap.remove(uuid); if (customScoreboard == null) { return; } Scoreboard oldScoreboard = this.oldScoreboardMap.remove(uuid); if (oldScoreboard != null) { player.setScoreboard(oldScoreboard); } else { customScoreboard.disableScoreboard(); } } public void removeAll() { Collection onlinePlayerCollection = Bukkit.getOnlinePlayers(); for (Player player : onlinePlayerCollection) { removeScoreboard(player); } } private @Nullable CustomScoreboard enableScoreboard(@NotNull Player player) { if (isDisabled(player)) { return null; } UUID uuid = player.getUniqueId(); savePreviousScoreboard(player); ScoreboardExpansion expansion = getExpansion(); CustomScoreboard customScoreboard = new CustomScoreboard(expansion, player); customScoreboard.enableScoreboard(); this.combatScoreboardMap.put(uuid, customScoreboard); return customScoreboard; } private void savePreviousScoreboard(@NotNull Player player) { if (shouldIgnorePrevious()) { return; } Scoreboard oldScoreboard = player.getScoreboard(); Objective objective = oldScoreboard.getObjective(DisplaySlot.SIDEBAR); if (objective != null) { String objectiveName = objective.getName(); if (objectiveName.equals("combatlogx")) { return; } } UUID playerId = player.getUniqueId(); this.oldScoreboardMap.put(playerId, oldScoreboard); } } ================================================ FILE: expansion/scoreboard/src/main/java/combatlogx/expansion/scoreboard/scoreboard/CustomLine.java ================================================ package combatlogx.expansion.scoreboard.scoreboard; import org.jetbrains.annotations.NotNull; import org.bukkit.ChatColor; import org.bukkit.scoreboard.Team; public final class CustomLine { private final ChatColor color; private final Team team; private final int line; public CustomLine(@NotNull ChatColor color, @NotNull Team team, int line) { this.color = color; this.team = team; this.line = line; } public @NotNull ChatColor getColor() { return this.color; } public @NotNull Team getTeam() { return this.team; } public int getLine() { return this.line; } } ================================================ FILE: expansion/scoreboard/src/main/java/combatlogx/expansion/scoreboard/scoreboard/CustomScoreboard.java ================================================ package combatlogx.expansion.scoreboard.scoreboard; import java.util.ArrayList; import java.util.List; import java.util.regex.Pattern; import org.bukkit.Bukkit; import org.bukkit.ChatColor; import org.bukkit.entity.Entity; import org.bukkit.entity.Player; import org.bukkit.scoreboard.DisplaySlot; import org.bukkit.scoreboard.Objective; import org.bukkit.scoreboard.Score; import org.bukkit.scoreboard.Scoreboard; import org.bukkit.scoreboard.ScoreboardManager; import org.bukkit.scoreboard.Team; import com.github.sirblobman.api.language.ComponentHelper; import com.github.sirblobman.api.language.LanguageManager; import com.github.sirblobman.api.nms.MultiVersionHandler; import com.github.sirblobman.api.nms.scoreboard.ScoreboardHandler; import com.github.sirblobman.api.utility.Validate; import com.github.sirblobman.api.utility.VersionUtility; import com.github.sirblobman.combatlogx.api.ICombatLogX; import com.github.sirblobman.combatlogx.api.manager.ICombatManager; import com.github.sirblobman.combatlogx.api.manager.IPlaceholderManager; import com.github.sirblobman.combatlogx.api.object.TagInformation; import com.github.sirblobman.api.shaded.adventure.text.Component; import com.github.sirblobman.api.shaded.adventure.text.TextReplacementConfig; import combatlogx.expansion.scoreboard.ScoreboardExpansion; public final class CustomScoreboard { private final ScoreboardExpansion expansion; private final List customLineList; private final Scoreboard scoreboard; private final Player player; private Objective objective; public CustomScoreboard(ScoreboardExpansion expansion, Player player) { this.expansion = Validate.notNull(expansion, "expansion must not be null!"); this.player = Validate.notNull(player, "player must not be null!"); ScoreboardManager bukkitScoreboardManager = Bukkit.getScoreboardManager(); this.scoreboard = bukkitScoreboardManager.getNewScoreboard(); this.customLineList = new ArrayList<>(); createObjective(); initializeScoreboard(); } private ScoreboardExpansion getExpansion() { return this.expansion; } private ICombatLogX getCombatLogX() { ScoreboardExpansion expansion = getExpansion(); return expansion.getPlugin(); } private LanguageManager getLanguageManager() { ICombatLogX combatLogX = getCombatLogX(); return combatLogX.getLanguageManager(); } public Player getPlayer() { return this.player; } public Scoreboard getScoreboard() { return this.scoreboard; } public Objective getObjective() { return this.objective; } public void enableScoreboard() { Player player = getPlayer(); Scoreboard scoreboard = getScoreboard(); player.setScoreboard(scoreboard); } public void disableScoreboard() { ScoreboardManager scoreboardManager = Bukkit.getScoreboardManager(); Scoreboard scoreboard = scoreboardManager.getMainScoreboard(); Player player = getPlayer(); player.setScoreboard(scoreboard); } public void updateScoreboard() { updateTitle(); List lineList = getLines(); int lineListSize = lineList.size(); for (int line = 16; line > 0; line--) { int index = (16 - line); if (index >= lineListSize) { removeLine(line); continue; } Component value = lineList.get(index); setLine(line, value); } } private void createObjective() { ICombatLogX plugin = getCombatLogX(); MultiVersionHandler multiVersionHandler = plugin.getMultiVersionHandler(); ScoreboardHandler scoreboardHandler = multiVersionHandler.getScoreboardHandler(); Scoreboard scoreboard = getScoreboard(); this.objective = scoreboardHandler.createObjective(scoreboard, "combatlogx", "dummy", "Default Title"); this.objective.setDisplaySlot(DisplaySlot.SIDEBAR); updateTitle(); } private void initializeScoreboard() { Scoreboard scoreboard = getScoreboard(); ChatColor[] chatColorArray = { ChatColor.BLACK, ChatColor.DARK_BLUE, ChatColor.DARK_GREEN, ChatColor.DARK_AQUA, ChatColor.DARK_RED, ChatColor.DARK_PURPLE, ChatColor.GOLD, ChatColor.GRAY, ChatColor.DARK_GRAY, ChatColor.BLUE, ChatColor.GREEN, ChatColor.AQUA, ChatColor.RED, ChatColor.LIGHT_PURPLE, ChatColor.YELLOW, ChatColor.WHITE }; int chatColorArrayLength = chatColorArray.length; for (int i = 0; i < chatColorArrayLength; i++) { ChatColor chatColor = chatColorArray[i]; String chatColorString = chatColor.toString(); String teamName = ("line" + i); Team team = scoreboard.registerNewTeam(teamName); team.addEntry(chatColorString); CustomLine customLine = new CustomLine(chatColor, team, i + 1); this.customLineList.add(customLine); } } private CustomLine getLine(int line) { return this.customLineList.get(line - 1); } private void setLine(int line, Component value) { CustomLine customLine = getLine(line); Validate.notNull(customLine, "Could not find scoreboard line '" + line + "'."); ChatColor chatColor = customLine.getColor(); String chatColorString = chatColor.toString(); Objective objective = getObjective(); Score score = objective.getScore(chatColorString); score.setScore(line); ScoreboardExpansion expansion = getExpansion(); if (expansion.isPaperScoreboard()) { setLinePaper(line, value); } else { String valueString = ComponentHelper.toLegacy(value); setLineSpigot(line, valueString); } } private void setLinePaper(int line, Component prefix) { CustomLine customLine = getLine(line); Validate.notNull(customLine, "Could not find scoreboard line '" + line + "'."); PaperScoreboard.setLine(customLine, prefix); } @SuppressWarnings("deprecation") private void setLineSpigot(int line, String value) { CustomLine customLine = getLine(line); Validate.notNull(customLine, "Could not find scoreboard line '" + line + "'."); int lengthLimit = getLineLengthLimit(); int valueLength = value.length(); if (valueLength <= lengthLimit) { Team team = customLine.getTeam(); team.setPrefix(value); team.setSuffix(""); return; } String partOne = cut(value, lengthLimit); String partTwo = value.substring(lengthLimit); String partOneFinalColors = ChatColor.getLastColors(partOne); partTwo = cut((partOneFinalColors + partTwo), lengthLimit); Team team = customLine.getTeam(); team.setPrefix(partOne); team.setSuffix(partTwo); } private String cut(String original, int length) { int originalLength = original.length(); if (originalLength <= length) { return original; } return original.substring(0, length); } private void removeLine(int line) { CustomLine customLine = getLine(line); Validate.notNull(customLine, "Could not find scoreboard line '" + line + "'."); ChatColor chatColor = customLine.getColor(); String chatColorString = chatColor.toString(); Scoreboard scoreboard = getScoreboard(); scoreboard.resetScores(chatColorString); } private int getLineLengthLimit() { int minorVersion = VersionUtility.getMinorVersion(); return (minorVersion > 12 ? 64 : 16); } private List getLines() { Player player = getPlayer(); LanguageManager languageManager = getLanguageManager(); List preMessageList = languageManager.getMessageList(player, "expansion.scoreboard.lines"); List finalMessageList = new ArrayList<>(); ICombatLogX combatLogX = getCombatLogX(); ICombatManager combatManager = combatLogX.getCombatManager(); IPlaceholderManager placeholderManager = combatLogX.getPlaceholderManager(); TagInformation tagInformation = combatManager.getTagInformation(player); TextReplacementConfig replacementConfig = null; if (tagInformation != null) { List enemyList = tagInformation.getEnemies(); Pattern placeholderPattern = Pattern.compile("\\{(\\S+)}"); TextReplacementConfig.Builder builder = TextReplacementConfig.builder(); builder.match(placeholderPattern); builder.replacement((matchResult, builderCopy) -> { String placeholder = matchResult.group(1); Component replacement = placeholderManager.getPlaceholderReplacementComponent(player, enemyList, placeholder); return (replacement == null ? Component.text(placeholder) : replacement); }); replacementConfig = builder.build(); } for (Component preMessage : preMessageList) { Component finalMessage = preMessage; if (replacementConfig != null) { finalMessage = finalMessage.replaceText(replacementConfig); } finalMessageList.add(finalMessage); } return finalMessageList; } private Component getTitle() { Player player = getPlayer(); LanguageManager languageManager = getLanguageManager(); ICombatLogX combatLogX = getCombatLogX(); ICombatManager combatManager = combatLogX.getCombatManager(); IPlaceholderManager placeholderManager = combatLogX.getPlaceholderManager(); Component preMessage = languageManager.getMessage(player, "expansion.scoreboard.title"); TagInformation tagInformation = combatManager.getTagInformation(player); if (tagInformation != null) { List enemyList = tagInformation.getEnemies(); Pattern placeholderPattern = Pattern.compile("\\{(\\S+)}"); TextReplacementConfig.Builder builder = TextReplacementConfig.builder(); builder.match(placeholderPattern); builder.replacement((matchResult, builderCopy) -> { String placeholder = matchResult.group(1); String replacement = placeholderManager.getPlaceholderReplacement(player, enemyList, placeholder); return Component.text(replacement == null ? placeholder : replacement); }); TextReplacementConfig replacement = builder.build(); preMessage = preMessage.replaceText(replacement); } return preMessage; } private void updateTitle() { Component title = getTitle(); ScoreboardExpansion expansion = getExpansion(); if (expansion.isPaperScoreboard()) { updateTitlePaper(title); } else { String spigotTitle = ComponentHelper.toLegacy(title); updateTitleSpigot(spigotTitle); } } private void updateTitlePaper(Component title) { Objective objective = getObjective(); PaperScoreboard.setTitle(objective, title); } @SuppressWarnings("deprecation") private void updateTitleSpigot(String title) { Objective objective = getObjective(); objective.setDisplayName(title); } } ================================================ FILE: expansion/scoreboard/src/main/java/combatlogx/expansion/scoreboard/scoreboard/PaperScoreboard.java ================================================ package combatlogx.expansion.scoreboard.scoreboard; import org.jetbrains.annotations.NotNull; import org.bukkit.scoreboard.Objective; import org.bukkit.scoreboard.Team; import com.github.sirblobman.api.utility.paper.ComponentConverter; import com.github.sirblobman.api.shaded.adventure.text.Component; public final class PaperScoreboard { public static void setTitle(@NotNull Objective objective, @NotNull Component shadedComponent) { net.kyori.adventure.text.Component normalComponent = ComponentConverter.shadedToNormal(shadedComponent); objective.displayName(normalComponent); } public static void setLine(@NotNull CustomLine customLine, @NotNull Component shadedComponent) { net.kyori.adventure.text.Component prefix = ComponentConverter.shadedToNormal(shadedComponent); net.kyori.adventure.text.Component suffix = net.kyori.adventure.text.Component.empty(); Team team = customLine.getTeam(); team.prefix(prefix); team.suffix(suffix); } } ================================================ FILE: expansion/scoreboard/src/main/resources/config.yml ================================================ # This option is here to quickly toggle this expansion on a live server that must stay online. # We recommend that you remove the Scoreboard expansion jar if you will not use the feature. enabled: true # Set this to true to save the scoreboard the player had before combat. # Otherwise, the main server scoreboard will be restored instead. save-previous: true ## Reminder: ## The scoreboard title format and list of lines are in your selected language file ## (Default: en_us.lang.yml) ================================================ FILE: expansion/scoreboard/src/main/resources/expansion.yml ================================================ name: "${expansionName}" prefix: "${expansionPrefix}" description: "${expansionDescription}" main: "combatlogx.expansion.scoreboard.ScoreboardExpansion" version: "17.2" author: "SirBlobman" ================================================ FILE: gradle/wrapper/gradle-wrapper.properties ================================================ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists distributionUrl=https\://services.gradle.org/distributions/gradle-9.5.0-bin.zip networkTimeout=10000 retries=0 retryBackOffMs=500 validateDistributionUrl=true zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists ================================================ FILE: gradle.properties ================================================ org.gradle.parallel=true org.gradle.caching=true version.api=11.7-SNAPSHOT version.base=11.7.0.0 version.beta=false ================================================ FILE: gradlew ================================================ #!/bin/sh # # Copyright © 2015 the original authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # https://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # # SPDX-License-Identifier: Apache-2.0 # ############################################################################## # # Gradle start up script for POSIX generated by Gradle. # # Important for running: # # (1) You need a POSIX-compliant shell to run this script. If your /bin/sh is # noncompliant, but you have some other compliant shell such as ksh or # bash, then to run this script, type that shell name before the whole # command line, like: # # ksh Gradle # # Busybox and similar reduced shells will NOT work, because this script # requires all of these POSIX shell features: # * functions; # * expansions «$var», «${var}», «${var:-default}», «${var+SET}», # «${var#prefix}», «${var%suffix}», and «$( cmd )»; # * compound commands having a testable exit status, especially «case»; # * various built-in commands including «command», «set», and «ulimit». # # Important for patching: # # (2) This script targets any POSIX shell, so it avoids extensions provided # by Bash, Ksh, etc; in particular arrays are avoided. # # The "traditional" practice of packing multiple parameters into a # space-separated string is a well documented source of bugs and security # problems, so this is (mostly) avoided, by progressively accumulating # options in "$@", and eventually passing that to Java. # # Where the inherited environment variables (DEFAULT_JVM_OPTS, JAVA_OPTS, # and GRADLE_OPTS) rely on word-splitting, this is performed explicitly; # see the in-line comments for details. # # There are tweaks for specific operating systems such as AIX, CygWin, # Darwin, MinGW, and NonStop. # # (3) This script is generated from the Groovy template # https://github.com/gradle/gradle/blob//platforms/jvm/plugins-application/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt # within the Gradle project. # # You can find Gradle at https://github.com/gradle/gradle/. # ############################################################################## # Attempt to set APP_HOME # Resolve links: $0 may be a link app_path=$0 # Need this for daisy-chained symlinks. while APP_HOME=${app_path%"${app_path##*/}"} # leaves a trailing /; empty if no leading path [ -h "$app_path" ] do ls=$( ls -ld "$app_path" ) link=${ls#*' -> '} case $link in #( /*) app_path=$link ;; #( *) app_path=$APP_HOME$link ;; esac done # This is normally unused # shellcheck disable=SC2034 APP_BASE_NAME=${0##*/} # Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036) APP_HOME=$( cd -P "${APP_HOME:-./}" > /dev/null && printf '%s\n' "$PWD" ) || exit # Use the maximum available, or set MAX_FD != -1 to use that value. MAX_FD=maximum warn () { echo "$*" } >&2 die () { echo echo "$*" echo exit 1 } >&2 # OS specific support (must be 'true' or 'false'). cygwin=false msys=false darwin=false nonstop=false case "$( uname )" in #( CYGWIN* ) cygwin=true ;; #( Darwin* ) darwin=true ;; #( MSYS* | MINGW* ) msys=true ;; #( NONSTOP* ) nonstop=true ;; esac # Determine the Java command to use to start the JVM. if [ -n "$JAVA_HOME" ] ; then if [ -x "$JAVA_HOME/jre/sh/java" ] ; then # IBM's JDK on AIX uses strange locations for the executables JAVACMD=$JAVA_HOME/jre/sh/java else JAVACMD=$JAVA_HOME/bin/java fi if [ ! -x "$JAVACMD" ] ; then die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME Please set the JAVA_HOME variable in your environment to match the location of your Java installation." fi else JAVACMD=java if ! command -v java >/dev/null 2>&1 then die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. Please set the JAVA_HOME variable in your environment to match the location of your Java installation." fi fi # Increase the maximum file descriptors if we can. if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then case $MAX_FD in #( max*) # In POSIX sh, ulimit -H is undefined. That's why the result is checked to see if it worked. # shellcheck disable=SC2039,SC3045 MAX_FD=$( ulimit -H -n ) || warn "Could not query maximum file descriptor limit" esac case $MAX_FD in #( '' | soft) :;; #( *) # In POSIX sh, ulimit -n is undefined. That's why the result is checked to see if it worked. # shellcheck disable=SC2039,SC3045 ulimit -n "$MAX_FD" || warn "Could not set maximum file descriptor limit to $MAX_FD" esac fi # Collect all arguments for the java command, stacking in reverse order: # * args from the command line # * the main class name # * -classpath # * -D...appname settings # * --module-path (only if needed) # * DEFAULT_JVM_OPTS, JAVA_OPTS, and GRADLE_OPTS environment variables. # For Cygwin or MSYS, switch paths to Windows format before running java if "$cygwin" || "$msys" ; then APP_HOME=$( cygpath --path --mixed "$APP_HOME" ) JAVACMD=$( cygpath --unix "$JAVACMD" ) # Now convert the arguments - kludge to limit ourselves to /bin/sh for arg do if case $arg in #( -*) false ;; # don't mess with options #( /?*) t=${arg#/} t=/${t%%/*} # looks like a POSIX filepath [ -e "$t" ] ;; #( *) false ;; esac then arg=$( cygpath --path --ignore --mixed "$arg" ) fi # Roll the args list around exactly as many times as the number of # args, so each arg winds up back in the position where it started, but # possibly modified. # # NB: a `for` loop captures its iteration list before it begins, so # changing the positional parameters here affects neither the number of # iterations, nor the values presented in `arg`. shift # remove old arg set -- "$@" "$arg" # push replacement arg done fi # Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' # Collect all arguments for the java command: # * DEFAULT_JVM_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments, # and any embedded shellness will be escaped. # * For example: A user cannot expect ${Hostname} to be expanded, as it is an environment variable and will be # treated as '${Hostname}' itself on the command line. set -- \ "-Dorg.gradle.appname=$APP_BASE_NAME" \ -jar "$APP_HOME/gradle/wrapper/gradle-wrapper.jar" \ "$@" # Stop when "xargs" is not available. if ! command -v xargs >/dev/null 2>&1 then die "xargs is not available" fi # Use "xargs" to parse quoted args. # # With -n1 it outputs one arg per line, with the quotes and backslashes removed. # # In Bash we could simply go: # # readarray ARGS < <( xargs -n1 <<<"$var" ) && # set -- "${ARGS[@]}" "$@" # # but POSIX shell has neither arrays nor command substitution, so instead we # post-process each arg (as a line of input to sed) to backslash-escape any # character that might be a shell metacharacter, then use eval to reverse # that process (while maintaining the separation between arguments), and wrap # the whole thing up as a single "set" statement. # # This will of course break if any of these variables contains a newline or # an unmatched quote. # eval "set -- $( printf '%s\n' "$DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS" | xargs -n1 | sed ' s~[^-[:alnum:]+,./:=@_]~\\&~g; ' | tr '\n' ' ' )" '"$@"' exec "$JAVACMD" "$@" ================================================ FILE: gradlew.bat ================================================ @rem @rem Copyright 2015 the original author or authors. @rem @rem Licensed under the Apache License, Version 2.0 (the "License"); @rem you may not use this file except in compliance with the License. @rem You may obtain a copy of the License at @rem @rem https://www.apache.org/licenses/LICENSE-2.0 @rem @rem Unless required by applicable law or agreed to in writing, software @rem distributed under the License is distributed on an "AS IS" BASIS, @rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. @rem See the License for the specific language governing permissions and @rem limitations under the License. @rem @rem SPDX-License-Identifier: Apache-2.0 @rem @if "%DEBUG%"=="" @echo off @rem ########################################################################## @rem @rem Gradle startup script for Windows @rem @rem ########################################################################## @rem Set local scope for the variables, and ensure extensions are enabled setlocal EnableExtensions set DIRNAME=%~dp0 if "%DIRNAME%"=="" set DIRNAME=. @rem This is normally unused set APP_BASE_NAME=%~n0 set APP_HOME=%DIRNAME% @rem Resolve any "." and ".." in APP_HOME to make it shorter. for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m" @rem Find java.exe if defined JAVA_HOME goto findJavaFromJavaHome set JAVA_EXE=java.exe %JAVA_EXE% -version >NUL 2>&1 if %ERRORLEVEL% equ 0 goto execute echo. 1>&2 echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 1>&2 echo. 1>&2 echo Please set the JAVA_HOME variable in your environment to match the 1>&2 echo location of your Java installation. 1>&2 "%COMSPEC%" /c exit 1 :findJavaFromJavaHome set JAVA_HOME=%JAVA_HOME:"=% set JAVA_EXE=%JAVA_HOME%/bin/java.exe if exist "%JAVA_EXE%" goto execute echo. 1>&2 echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% 1>&2 echo. 1>&2 echo Please set the JAVA_HOME variable in your environment to match the 1>&2 echo location of your Java installation. 1>&2 "%COMSPEC%" /c exit 1 :execute @rem Setup the command line @rem Execute Gradle @rem endlocal doesn't take effect until after the line is parsed and variables are expanded @rem which allows us to clear the local environment before executing the java command endlocal & "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -jar "%APP_HOME%\gradle\wrapper\gradle-wrapper.jar" %* & call :exitWithErrorLevel :exitWithErrorLevel @rem Use "%COMSPEC%" /c exit to allow operators to work properly in scripts "%COMSPEC%" /c exit %ERRORLEVEL% ================================================ FILE: plugin/README.MD ================================================ # CombatLogX Plugin This is the plugin module for CombatLogX. It contains all the implementations, commands, and listeners that will be used on the Spigot server. ## Commands - **/combatlogx**: - **Aliases:** `/clx`, `/ctx`, `/combatlog`, `/combattagx`, `/combattag` - **/combatlogx help:** View the list of sub-commands for CombatLogX. - **/combatlogx about <expansion>:** View information about an expansion. - **/combatlogx reload:** Reload the configuration files for the plugin and expansions. - **/combatlogx toggle <bossbar/actionbar/scoreboard>:** Toggle the action bar, boss bar, and scoreboard for yourself. - **/combatlogx tag <player>:** Force a player to be tagged into combat. - **/combatlogx untag <player>:** Force a player to be untagged from combat. - **/combatlogx version:** View version information and a list of enabled expansions. - **/combatlogx forgive request <player>:** Send a request to an enemy to get out of combat. - **/combatlogx forgive accept:** Accept a request from an enemy to escape combat with you. - **/combatlogx forgive reject:** Deny a request from an enemy to escape combat with you. - **/combatlogx forgive toggle:** Prevent enemies from sending forgiveness requests to you. - **/combat-timer:** - **Aliases:** `/combattimer`, `/combattime`, `/ctime`, `/clt`, `/ct` - **/combat-timer:** Check how much time you have left in combat. - **/combat-timer <player>:** Check how much time a player has left in combat. ## Permissions - **combatlogx.bypass:** Default bypass permission, can be changed in the config.yml file. - **combatlogx.bypass.force.field:** Default bypass permission for the force field, can be changed in the configuration file for the force field expansion. - **combatlogx.command.combat-timer:** Gives access to the `/combat-timer` command. - **combatlogx.command.togglepvp:** Gives access to the `/togglepvp` command from the NewbieHelper expansion. - **combatlogx.command.togglepvp.admin:** Gives access to the admin features of the `/togglepvp` command. - **combatlogx.command.combatlogx:** Gives access to the base `/combatlogx` command, but not the sub-commands. - **combatlogx.command.combatlogx.toggle:** Gives access to `/combatlogx toggle` command to toggle boss bar, action bar, and scoreboard. - **combatlogx.command.combatlogx.about:** Gives access to information about expansions with `/combatlogx about`. - **combatlogx.command.combatlogx.help:** Gives access to information about CombatLogX commands with `/combatlogx help`. - **combatlogx.command.combatlogx.reload:** Gives access to reload configurations with `/combatlogx reload`. - **combatlogx.command.combatlogx.version:** Gives access to version information with `/combatlogx version`. - **combatlogx.command.combatlogx.tag:** Gives access to force tag players with `/combatlogx tag`. - **combatlogx.command.combatlogx.untag:** Gives access to force players out of combat with `/combatlogx untag`. - **combatlogx.command.combatlogx.forgive:** Gives access to `/combatlogx forgive`. - **combatlogx.command.combatlogx.forgive.accept:** Gives access to `/combatlogx forgive accept`. - **combatlogx.command.combatlogx.forgive.reject:** Gives access to `/combatlogx forgive reject`. - **combatlogx.command.combatlogx.forgive.request:** Gives access to `/combatlogx forgive request`. - **combatlogx.command.combatlogx.forgive.toggle:** Gives access to `/combatlogx forgive toggle`. ================================================ FILE: plugin/build.gradle.kts ================================================ import com.github.jengelman.gradle.plugins.shadow.tasks.ShadowJar import net.minecrell.pluginyml.bukkit.BukkitPluginDescription import net.minecrell.pluginyml.paper.PaperPluginDescription val pluginVersion = rootProject.version.toString(); val pluginDepend = listOf("BlueSlimeCore") val pluginSoftDepend = listOf( "AngelChest", "ASkyBlock", "BentoBox", // BSkyBlock is an addon of BentoBox and not its own plugin. "Citizens", "CMI", "CrackShot", "CrashClaim", "Essentials", "FabledSkyBlock", "FeatherBoard", "FlagWar", // Optional for the Towny Compatibility expansion. "GriefDefender", "GriefPrevention", "HuskHomes", "HuskSync", "HuskTowns", "iDisguise", "IridiumSkyblock", "Kingdoms", "Konquest", "Lands", "LibsDisguises", "MarriageMaster", "MCPets", "MythicMobs", "PlaceholderAPI", "PlayerParticles", "PreciousStones", "PremiumVanish", "ProtectionStones", "ProtocolLib", // Required for the Force Field expansion. "RedProtect", "Residence", "Sentinel", // Optional for the Citizens Compatibility expansion. "SuperiorSkyblock2", "SuperVanish", "Towny", "UltimateClaims", "uSkyBlock", "VanishNoPacket", "Vault", "WorldGuard" ) plugins { id("maven-publish") id("com.gradleup.shadow") version "9.2.2" id("de.eldoria.plugin-yml.bukkit") version "0.8.0" id("de.eldoria.plugin-yml.paper") version "0.8.0" } bukkit { name = "CombatLogX" description = "A modular server plugin that punishes players for logging out during combat." website = "https://modrinth.com/project/combatlogx/" main = "com.github.sirblobman.combatlogx.CombatPlugin" version = pluginVersion apiVersion = "1.13" load = BukkitPluginDescription.PluginLoadOrder.POSTWORLD foliaSupported = true authors = listOf("SirBlobman") depend = pluginDepend softDepend = pluginSoftDepend commands { register("combatlogx") { description = "Main command for CombatLogX." permission = "combatlogx.command.combatlogx" usage = "/ help" aliases = listOf("combatlog", "combattagx", "combattag", "clx", "ctx") } register("combat-timer") { description = "Check how much time you have left in combat." permission = "combatlogx.command.combat-timer" usage = "/ [player]" aliases = listOf("combattimer", "combattime", "ctime", "clt", "ct") } register("togglepvp") { description = "Enable or disable PVP for a player." permission = "combatlogx.command.togglepvp" description = """ / check / on/off / admin on/off """.trimIndent() aliases = listOf("toggle-pvp", "pvptoggle", "pvp") } } permissions { register("combatlogx.bypass") { description = "Default bypass permission if not configured." default = BukkitPluginDescription.Permission.Default.FALSE } register("combatlogx.bypass.force.field") { description = "Default force-field bypass permission if not configured." default = BukkitPluginDescription.Permission.Default.FALSE } register("combatlogx.command.combat-timer") { description = "Access to the '/combat-timer' command." default = BukkitPluginDescription.Permission.Default.OP } register("combatlogx.command.togglepvp") { description = "Access to the '/togglepvp' command." default = BukkitPluginDescription.Permission.Default.OP } register("combatlogx.command.togglepvp.admin") { description = "Access to the '/togglepvp admin' command." default = BukkitPluginDescription.Permission.Default.OP } register("combatlogx.command.combatlogx") { description = "Access to the '/combatlogx' command." default = BukkitPluginDescription.Permission.Default.OP } register("combatlogx.command.combatlogx.about") { description = "Access to the '/combatlogx about' command." default = BukkitPluginDescription.Permission.Default.OP } register("combatlogx.command.combatlogx.help") { description = "Access to the '/combatlogx help' command." default = BukkitPluginDescription.Permission.Default.OP } register("combatlogx.command.combatlogx.reload") { description = "Access to the '/combatlogx reload' command." default = BukkitPluginDescription.Permission.Default.OP } register("combatlogx.command.combatlogx.tag") { description = "Access to the '/combatlogx tag' command." default = BukkitPluginDescription.Permission.Default.OP } register("combatlogx.command.combatlogx.toggle") { description = "Access to the '/combatlogx toggle' command." default = BukkitPluginDescription.Permission.Default.OP } register("combatlogx.command.combatlogx.untag") { description = "Access to the '/combatlogx untag' command." default = BukkitPluginDescription.Permission.Default.OP } register("combatlogx.command.combatlogx.version") { description = "Access to the '/combatlogx version' command." default = BukkitPluginDescription.Permission.Default.OP } } } fun quickRegister(definition: NamedDomainObjectContainer, name: String, required: Boolean) { definition.register(name) { this.load = PaperPluginDescription.RelativeLoadOrder.BEFORE this.required = required this.joinClasspath = true } } paper { name = "CombatLogX" description = "A modular server plugin that punishes players for logging out during combat." website = "https://modrinth.com/project/combatlogx/" main = "com.github.sirblobman.combatlogx.CombatPlugin" version = pluginVersion apiVersion = "1.19" load = BukkitPluginDescription.PluginLoadOrder.POSTWORLD foliaSupported = true authors = listOf("SirBlobman") dependencies { pluginDepend.forEach { it -> quickRegister(serverDependencies, it, true) } pluginSoftDepend.forEach { it -> quickRegister(serverDependencies, it, false) } } permissions { register("combatlogx.bypass") { description = "Default bypass permission if not configured." default = BukkitPluginDescription.Permission.Default.FALSE } register("combatlogx.bypass.force.field") { description = "Default force-field bypass permission if not configured." default = BukkitPluginDescription.Permission.Default.FALSE } register("combatlogx.command.combat-timer") { description = "Access to the '/combat-timer' command." default = BukkitPluginDescription.Permission.Default.OP } register("combatlogx.command.togglepvp") { description = "Access to the '/togglepvp' command." default = BukkitPluginDescription.Permission.Default.OP } register("combatlogx.command.togglepvp.admin") { description = "Access to the '/togglepvp admin' command." default = BukkitPluginDescription.Permission.Default.OP } register("combatlogx.command.combatlogx") { description = "Access to the '/combatlogx' command." default = BukkitPluginDescription.Permission.Default.OP } register("combatlogx.command.combatlogx.about") { description = "Access to the '/combatlogx about' command." default = BukkitPluginDescription.Permission.Default.OP } register("combatlogx.command.combatlogx.help") { description = "Access to the '/combatlogx help' command." default = BukkitPluginDescription.Permission.Default.OP } register("combatlogx.command.combatlogx.reload") { description = "Access to the '/combatlogx reload' command." default = BukkitPluginDescription.Permission.Default.OP } register("combatlogx.command.combatlogx.tag") { description = "Access to the '/combatlogx tag' command." default = BukkitPluginDescription.Permission.Default.OP } register("combatlogx.command.combatlogx.toggle") { description = "Access to the '/combatlogx toggle' command." default = BukkitPluginDescription.Permission.Default.OP } register("combatlogx.command.combatlogx.untag") { description = "Access to the '/combatlogx untag' command." default = BukkitPluginDescription.Permission.Default.OP } register("combatlogx.command.combatlogx.version") { description = "Access to the '/combatlogx version' command." default = BukkitPluginDescription.Permission.Default.OP } } } repositories { maven("https://repo.helpch.at/releases/") } dependencies { // Local Dependencies implementation(project(":api")) // Java Dependencies implementation("org.zeroturnaround:zt-zip:1.17") // ZT Zip // Plugin Dependencies compileOnly("me.clip:placeholderapi:2.11.6") // PlaceholderAPI } tasks { named("jar") { enabled = false } named("shadowJar") { archiveClassifier.set(null as String?) archiveFileName.set("CombatLogX.jar") relocate("org.zeroturnaround.zip", "com.github.sirblobman.combatlogx.zip") relocate("org.slf4j", "com.github.sirblobman.combatlogx.zip.slf4j") } named("processResources") { inputs.property("pluginVersion", pluginVersion) filesMatching("config.yml") { expand(inputs.properties) } } named("build") { dependsOn("shadowJar") } } ================================================ FILE: plugin/gradle.properties ================================================ version.spigot=1.13.2-R0.1-SNAPSHOT bukkit.plugin.name=CombatLogX bukkit.plugin.prefix=CombatLogX bukkit.plugin.description=A modular combat tagging plugin. bukkit.plugin.website=https://www.spigotmc.org/resources/31689/ bukkit.plugin.main= ================================================ FILE: plugin/src/main/java/com/github/sirblobman/combatlogx/CombatPlugin.java ================================================ package com.github.sirblobman.combatlogx; import java.util.Arrays; import java.util.List; import java.util.logging.Level; import java.util.logging.Logger; import org.jetbrains.annotations.NotNull; import org.bukkit.configuration.file.YamlConfiguration; import org.bukkit.entity.Player; import org.bukkit.plugin.java.JavaPlugin; import com.github.sirblobman.api.configuration.ConfigurationManager; import com.github.sirblobman.api.core.CorePlugin; import com.github.sirblobman.api.language.Language; import com.github.sirblobman.api.language.LanguageManager; import com.github.sirblobman.api.plugin.ConfigurablePlugin; import com.github.sirblobman.api.update.SpigotUpdateManager; import com.github.sirblobman.api.utility.VersionUtility; import com.github.sirblobman.combatlogx.api.ICombatLogX; import com.github.sirblobman.combatlogx.api.configuration.CommandConfiguration; import com.github.sirblobman.combatlogx.api.configuration.MainConfiguration; import com.github.sirblobman.combatlogx.api.configuration.PunishConfiguration; import com.github.sirblobman.combatlogx.api.expansion.ExpansionManager; import com.github.sirblobman.combatlogx.api.manager.ICombatManager; import com.github.sirblobman.combatlogx.api.manager.ICrystalManager; import com.github.sirblobman.combatlogx.api.manager.IDeathManager; import com.github.sirblobman.combatlogx.api.manager.IForgiveManager; import com.github.sirblobman.combatlogx.api.manager.IPlaceholderManager; import com.github.sirblobman.combatlogx.api.manager.IPunishManager; import com.github.sirblobman.combatlogx.api.manager.ITimerManager; import com.github.sirblobman.combatlogx.api.object.UntagReason; import com.github.sirblobman.combatlogx.command.CommandCombatTimer; import com.github.sirblobman.combatlogx.command.CommandTogglePVP; import com.github.sirblobman.combatlogx.command.combatlogx.CommandCombatLogX; import com.github.sirblobman.combatlogx.configuration.ConfigurationChecker; import com.github.sirblobman.combatlogx.listener.ListenerConfiguration; import com.github.sirblobman.combatlogx.listener.ListenerDamage; import com.github.sirblobman.combatlogx.listener.ListenerDeath; import com.github.sirblobman.combatlogx.listener.ListenerEndCrystal; import com.github.sirblobman.combatlogx.listener.ListenerInvulnerable; import com.github.sirblobman.combatlogx.listener.ListenerPunish; import com.github.sirblobman.combatlogx.listener.ListenerUntag; import com.github.sirblobman.combatlogx.manager.CombatManager; import com.github.sirblobman.combatlogx.manager.CrystalManager; import com.github.sirblobman.combatlogx.manager.DeathManager; import com.github.sirblobman.combatlogx.manager.ForgiveManager; import com.github.sirblobman.combatlogx.manager.PlaceholderManager; import com.github.sirblobman.combatlogx.manager.PunishManager; import com.github.sirblobman.combatlogx.placeholder.BasePlaceholderExpansion; import com.github.sirblobman.combatlogx.task.TimerUpdateTask; import com.github.sirblobman.combatlogx.task.UntagTask; import com.github.sirblobman.api.shaded.bstats.bukkit.Metrics; import com.github.sirblobman.api.shaded.bstats.charts.SimplePie; public final class CombatPlugin extends ConfigurablePlugin implements ICombatLogX { private final TimerUpdateTask timerUpdateTask; private final CombatManager combatManager; private final PunishManager punishManager; private final ExpansionManager expansionManager; private final PlaceholderManager placeholderManager; private final DeathManager deathManager; private final ForgiveManager forgiveManager; private final CrystalManager crystalManager; private final MainConfiguration configuration; private final CommandConfiguration commandConfiguration; private final PunishConfiguration punishConfiguration; public CombatPlugin() { this.timerUpdateTask = new TimerUpdateTask(this); this.expansionManager = new ExpansionManager(this); this.placeholderManager = new PlaceholderManager(this); this.combatManager = new CombatManager(this); this.punishManager = new PunishManager(this); this.deathManager = new DeathManager(this); this.forgiveManager = new ForgiveManager(this); this.crystalManager = new CrystalManager(this); this.configuration = new MainConfiguration(this); this.commandConfiguration = new CommandConfiguration(); this.punishConfiguration = new PunishConfiguration(); } @Override public void onLoad() { ConfigurationChecker configurationChecker = new ConfigurationChecker(this); configurationChecker.checkVersion(); ConfigurationManager configurationManager = getConfigurationManager(); configurationManager.saveDefault("config.yml"); configurationManager.saveDefault("commands.yml"); configurationManager.saveDefault("punish.yml"); LanguageManager languageManager = getLanguageManager(); languageManager.saveDefaultLanguageFiles(); ExpansionManager expansionManager = getExpansionManager(); expansionManager.loadExpansions(); } @Override public void onEnable() { onReload(); LanguageManager languageManager = getLanguageManager(); languageManager.onPluginEnable(); broadcastMessageOnLoad(); registerCommands(); registerListeners(); registerTasks(); registerExpansions(); registerUpdates(); registerBasePlaceholders(); broadcastMessageOnEnable(); register_bStats(); } @Override public void onDisable() { untagAllPlayers(); ExpansionManager expansionManager = getExpansionManager(); expansionManager.disableExpansions(); broadcastMessageOnDisable(); } @Override public @NotNull ConfigurablePlugin getPlugin() { return this; } @Override public void onReload() { ConfigurationManager configurationManager = getConfigurationManager(); List fileNameList = Arrays.asList("commands.yml", "config.yml", "punish.yml"); for (String fileName : fileNameList) { configurationManager.reload(fileName); } reloadLanguage(); getConfiguration().load(configurationManager.get("config.yml")); getCommandConfiguration().load(configurationManager.get("commands.yml")); getPunishConfiguration().load(configurationManager.get("punish.yml")); ExpansionManager expansionManager = getExpansionManager(); expansionManager.reloadConfigs(); } @Override public @NotNull ExpansionManager getExpansionManager() { return this.expansionManager; } @Override public @NotNull ICombatManager getCombatManager() { return this.combatManager; } @Override public @NotNull IPunishManager getPunishManager() { return this.punishManager; } @Override public @NotNull ITimerManager getTimerManager() { return this.timerUpdateTask; } @Override public @NotNull IDeathManager getDeathManager() { return this.deathManager; } @Override public @NotNull IPlaceholderManager getPlaceholderManager() { return this.placeholderManager; } @Override public @NotNull IForgiveManager getForgiveManager() { return this.forgiveManager; } @Override public boolean isDebugModeDisabled() { ConfigurationManager configurationManager = getConfigurationManager(); YamlConfiguration configuration = configurationManager.get("config.yml"); return !configuration.getBoolean("debug-mode", false); } @Override public void printDebug(String @NotNull ... messageArray) { if (isDebugModeDisabled()) { return; } Logger logger = getLogger(); for (String message : messageArray) { String realMessage = ("[Debug] " + message); logger.info(realMessage); } } @Override public void printDebug(@NotNull Throwable ex) { if (isDebugModeDisabled()) { return; } Logger logger = getLogger(); logger.log(Level.WARNING, "[Debug] Full Error Details:", ex); } @Override public @NotNull MainConfiguration getConfiguration() { return this.configuration; } @Override public @NotNull CommandConfiguration getCommandConfiguration() { return this.commandConfiguration; } @Override public @NotNull PunishConfiguration getPunishConfiguration() { return this.punishConfiguration; } @Override public @NotNull ICrystalManager getCrystalManager() { return this.crystalManager; } @Override public @NotNull String getKeyName() { return "combatlogx"; } private void reloadLanguage() { LanguageManager languageManager = getLanguageManager(); languageManager.reloadLanguages(); } private void registerCommands() { new CommandCombatLogX(this).register(); new CommandCombatTimer(this).register(); new CommandTogglePVP(this).register(); } private void registerListeners() { new ListenerConfiguration(this).register(); new ListenerDamage(this).register(); new ListenerPunish(this).register(); new ListenerUntag(this).register(); new ListenerDeath(this).register(); new ListenerInvulnerable(this).register(); int minorVersion = VersionUtility.getMinorVersion(); if (minorVersion > 13) { new ListenerEndCrystal(this).register(); } } private void registerTasks() { ITimerManager timerManager = getTimerManager(); timerManager.register(); new UntagTask(this).register(); } private void registerExpansions() { ExpansionManager expansionManager = getExpansionManager(); expansionManager.enableExpansions(); } private void registerUpdates() { CorePlugin corePlugin = JavaPlugin.getPlugin(CorePlugin.class); SpigotUpdateManager updateManager = corePlugin.getSpigotUpdateManager(); updateManager.addResource(this, 31689L); } private void untagAllPlayers() { ICombatManager combatManager = getCombatManager(); List playerCombatList = combatManager.getPlayersInCombat(); for (Player player : playerCombatList) { combatManager.untag(player, UntagReason.EXPIRE); } } private void broadcastMessageOnLoad() { ConfigurationManager configurationManager = getConfigurationManager(); YamlConfiguration configuration = configurationManager.get("config.yml"); if (!configuration.getBoolean("broadcast.on-load")) { return; } LanguageManager languageManager = getLanguageManager(); languageManager.broadcastMessage("broadcast.on-load", null); } private void broadcastMessageOnEnable() { ConfigurationManager configurationManager = getConfigurationManager(); YamlConfiguration configuration = configurationManager.get("config.yml"); if (!configuration.getBoolean("broadcast.on-enable")) { return; } LanguageManager languageManager = getLanguageManager(); languageManager.broadcastMessage("broadcast.on-enable", null); } private void broadcastMessageOnDisable() { ConfigurationManager configurationManager = getConfigurationManager(); YamlConfiguration configuration = configurationManager.get("config.yml"); if (!configuration.getBoolean("broadcast.on-disable")) { return; } LanguageManager languageManager = getLanguageManager(); languageManager.broadcastMessage("broadcast.on-disable", null); } private void registerBasePlaceholders() { BasePlaceholderExpansion placeholderExpansion = new BasePlaceholderExpansion(this); IPlaceholderManager placeholderManager = getPlaceholderManager(); placeholderManager.registerPlaceholderExpansion(placeholderExpansion); } private void register_bStats() { Metrics metrics = new Metrics(this, 16090); metrics.addCustomChart(new SimplePie("selected_language", this::getDefaultLanguageCode)); } private String getDefaultLanguageCode() { LanguageManager languageManager = getLanguageManager(); Language defaultLanguage = languageManager.getDefaultLanguage(); return (defaultLanguage == null ? "none" : defaultLanguage.getLanguageName()); } } ================================================ FILE: plugin/src/main/java/com/github/sirblobman/combatlogx/command/CommandCombatTimer.java ================================================ package com.github.sirblobman.combatlogx.command; import java.text.DecimalFormat; import java.util.Collections; import java.util.List; import java.util.Set; import org.jetbrains.annotations.NotNull; import org.bukkit.entity.Player; import com.github.sirblobman.api.language.LanguageManager; import com.github.sirblobman.api.language.replacer.DoubleReplacer; import com.github.sirblobman.api.language.replacer.Replacer; import com.github.sirblobman.api.language.replacer.StringReplacer; import com.github.sirblobman.combatlogx.api.ICombatLogX; import com.github.sirblobman.combatlogx.api.command.CombatLogPlayerCommand; import com.github.sirblobman.combatlogx.api.manager.ICombatManager; import com.github.sirblobman.combatlogx.api.object.TagInformation; public final class CommandCombatTimer extends CombatLogPlayerCommand { public CommandCombatTimer(@NotNull ICombatLogX plugin) { super(plugin, "combat-timer"); setPermissionName("combatlogx.command.combat-timer"); } @Override protected @NotNull List onTabComplete(@NotNull Player player, String @NotNull [] args) { if (args.length == 1) { Set valueSet = getOnlinePlayerNames(); return getMatching(args[0], valueSet); } return Collections.emptyList(); } @Override protected boolean execute(@NotNull Player player, String @NotNull [] args) { if (args.length < 1) { checkSelf(player); return true; } Player target = findTarget(player, args[0]); if (target == null) { return true; } checkOther(player, target); return true; } private void checkSelf(@NotNull Player player) { ICombatLogX plugin = getCombatLogX(); ICombatManager combatManager = plugin.getCombatManager(); LanguageManager languageManager = getLanguageManager(); TagInformation tagInformation = combatManager.getTagInformation(player); if (tagInformation == null || tagInformation.isExpired()) { sendMessageWithPrefix(player, "error.self-not-in-combat"); return; } double timeLeftMillis = tagInformation.getMillisLeftCombined(); double timeLeftSeconds = (timeLeftMillis / 1_000.0D); DecimalFormat decimalFormat = languageManager.getDecimalFormat(player); Replacer replacer = new DoubleReplacer("{time_left}", timeLeftSeconds, decimalFormat); sendMessageWithPrefix(player, "command.combat-timer.time-left-self", replacer); } private void checkOther(@NotNull Player player, @NotNull Player target) { ICombatLogX plugin = getCombatLogX(); ICombatManager combatManager = plugin.getCombatManager(); LanguageManager languageManager = getLanguageManager(); String targetName = target.getName(); TagInformation tagInformation = combatManager.getTagInformation(target); if (tagInformation == null || tagInformation.isExpired()) { Replacer replacer = new StringReplacer("{target}", targetName); sendMessageWithPrefix(player, "error.target-not-in-combat", replacer); return; } double timeLeftMillis = tagInformation.getMillisLeftCombined(); double timeLeftSeconds = (timeLeftMillis / 1_000.0D); DecimalFormat decimalFormat = languageManager.getDecimalFormat(player); Replacer timeLeftReplacer = new DoubleReplacer("{time_left}", timeLeftSeconds, decimalFormat); Replacer targetNameReplacer = new StringReplacer("{target}", targetName); sendMessageWithPrefix(player, "command.combat-timer.time-left-other", timeLeftReplacer, targetNameReplacer); } } ================================================ FILE: plugin/src/main/java/com/github/sirblobman/combatlogx/command/CommandTogglePVP.java ================================================ package com.github.sirblobman.combatlogx.command; import java.util.Collections; import java.util.List; import org.jetbrains.annotations.NotNull; import org.bukkit.command.CommandSender; import com.github.sirblobman.api.language.replacer.Replacer; import com.github.sirblobman.api.language.replacer.StringReplacer; import com.github.sirblobman.combatlogx.api.ICombatLogX; import com.github.sirblobman.combatlogx.api.command.CombatLogCommand; public final class CommandTogglePVP extends CombatLogCommand { public CommandTogglePVP(@NotNull ICombatLogX plugin) { super(plugin, "togglepvp"); setPermissionName("combatlogx.command.togglepvp"); } @Override protected @NotNull List onTabComplete(@NotNull CommandSender sender, String @NotNull [] args) { return Collections.emptyList(); } @Override protected boolean execute(@NotNull CommandSender sender, String @NotNull [] args) { Replacer replacer = new StringReplacer("{value}", "Newbie Helper"); sendMessageWithPrefix(sender, "error.unknown-expansion", replacer); return true; } } ================================================ FILE: plugin/src/main/java/com/github/sirblobman/combatlogx/command/combatlogx/CommandCombatLogX.java ================================================ package com.github.sirblobman.combatlogx.command.combatlogx; import org.jetbrains.annotations.NotNull; import com.github.sirblobman.combatlogx.api.ICombatLogX; import com.github.sirblobman.combatlogx.api.command.CombatLogCommand; import com.github.sirblobman.combatlogx.command.combatlogx.forgive.SubCommandForgive; public final class CommandCombatLogX extends CombatLogCommand { public CommandCombatLogX(@NotNull ICombatLogX plugin) { super(plugin, "combatlogx"); setPermissionName("combatlogx.command.combatlogx"); addSubCommand(new SubCommandAbout(plugin)); addSubCommand(new SubCommandForgive(plugin)); addSubCommand(new SubCommandHelp(plugin)); addSubCommand(new SubCommandReload(plugin)); addSubCommand(new SubCommandTag(plugin)); addSubCommand(new SubCommandToggle(plugin)); addSubCommand(new SubCommandUntag(plugin)); addSubCommand(new SubCommandVersion(plugin)); } } ================================================ FILE: plugin/src/main/java/com/github/sirblobman/combatlogx/command/combatlogx/SubCommandAbout.java ================================================ package com.github.sirblobman.combatlogx.command.combatlogx; import java.util.Collections; import java.util.HashSet; import java.util.List; import java.util.Optional; import java.util.Set; import org.jetbrains.annotations.NotNull; import org.bukkit.command.CommandSender; import com.github.sirblobman.api.language.LanguageManager; import com.github.sirblobman.api.language.replacer.Replacer; import com.github.sirblobman.api.language.replacer.StringReplacer; import com.github.sirblobman.combatlogx.api.ICombatLogX; import com.github.sirblobman.combatlogx.api.command.CombatLogCommand; import com.github.sirblobman.combatlogx.api.expansion.Expansion; import com.github.sirblobman.combatlogx.api.expansion.Expansion.State; import com.github.sirblobman.combatlogx.api.expansion.ExpansionDescription; import com.github.sirblobman.combatlogx.api.expansion.ExpansionManager; import com.github.sirblobman.api.shaded.adventure.text.Component; public final class SubCommandAbout extends CombatLogCommand { public SubCommandAbout(@NotNull ICombatLogX plugin) { super(plugin, "about"); setPermissionName("combatlogx.command.combatlogx.about"); } @Override protected @NotNull List onTabComplete(@NotNull CommandSender sender, String @NotNull [] args) { if (args.length == 1) { Set valueSet = getExpansionNames(); return getMatching(args[0], valueSet); } return Collections.emptyList(); } @Override protected boolean execute(@NotNull CommandSender sender, String @NotNull [] args) { if (args.length < 1) { return false; } String expansionName = args[0]; Optional optionalExpansion = getExpansion(expansionName); if (!optionalExpansion.isPresent()) { Replacer replacer = new StringReplacer("{target}", expansionName); sendMessageWithPrefix(sender, "error.unknown-expansion", replacer); return true; } Expansion expansion = optionalExpansion.get(); sendExpansionInformation(sender, expansion); return true; } private void sendExpansionInformation(@NotNull CommandSender sender, @NotNull Expansion expansion) { String name = expansion.getName(); String prefix = expansion.getPrefix(); State state = expansion.getState(); ExpansionDescription information = expansion.getDescription(); String description = information.getDescription(); String website = information.getWebsite(); List authorList = information.getAuthors(); String authorString = String.join(", ", authorList); String version = information.getVersion(); Replacer[] replacerArray = { new StringReplacer("{name}", name), new StringReplacer("{prefix}", prefix), new StringReplacer("{version}", version), new StringReplacer("{state}", state.name()), new StringReplacer("{description}", description), new StringReplacer("{website}", website == null ? "N/A" : website), new StringReplacer("{authors}", authorString) }; LanguageManager languageManager = getLanguageManager(); String messageKey = "command.combatlogx.expansion-information"; List messageList = languageManager.getMessageList(sender, messageKey, replacerArray); for (Component message : messageList) { languageManager.sendMessage(sender, message); } } private Set getExpansionNames() { ExpansionManager expansionManager = getExpansionManager(); Set expansionNameSet = new HashSet<>(); List expansionList = expansionManager.getAllExpansions(); for (Expansion expansion : expansionList) { String expansionName = expansion.getName(); expansionNameSet.add(expansionName); } return Collections.unmodifiableSet(expansionNameSet); } private Optional getExpansion(String name) { ExpansionManager expansionManager = getExpansionManager(); return expansionManager.getExpansion(name); } } ================================================ FILE: plugin/src/main/java/com/github/sirblobman/combatlogx/command/combatlogx/SubCommandHelp.java ================================================ package com.github.sirblobman.combatlogx.command.combatlogx; import java.util.List; import org.jetbrains.annotations.NotNull; import org.bukkit.command.CommandSender; import com.github.sirblobman.api.language.LanguageManager; import com.github.sirblobman.combatlogx.api.ICombatLogX; import com.github.sirblobman.combatlogx.api.command.CombatLogCommand; import com.github.sirblobman.api.shaded.adventure.text.Component; public final class SubCommandHelp extends CombatLogCommand { public SubCommandHelp(@NotNull ICombatLogX plugin) { super(plugin, "help"); setPermissionName("combatlogx.command.combatlogx.help"); } @Override protected boolean execute(@NotNull CommandSender sender, String @NotNull [] args) { LanguageManager languageManager = getLanguageManager(); String messageKey = "command.combatlogx.help-message-list"; List messageList = languageManager.getMessageList(sender, messageKey); for (Component message : messageList) { languageManager.sendMessage(sender, message); } return true; } } ================================================ FILE: plugin/src/main/java/com/github/sirblobman/combatlogx/command/combatlogx/SubCommandReload.java ================================================ package com.github.sirblobman.combatlogx.command.combatlogx; import org.jetbrains.annotations.NotNull; import org.bukkit.command.CommandSender; import com.github.sirblobman.combatlogx.api.ICombatLogX; import com.github.sirblobman.combatlogx.api.command.CombatLogCommand; public final class SubCommandReload extends CombatLogCommand { public SubCommandReload(@NotNull ICombatLogX plugin) { super(plugin, "reload"); setPermissionName("combatlogx.command.combatlogx.reload"); } @Override protected boolean execute(@NotNull CommandSender sender, String @NotNull [] args) { try { ICombatLogX plugin = getCombatLogX(); plugin.onReload(); sendMessageWithPrefix(sender, "command.combatlogx.reload-success"); return true; } catch (Exception ex) { ex.printStackTrace(); sendMessageWithPrefix(sender, "command.combatlogx.reload-failure"); return true; } } } ================================================ FILE: plugin/src/main/java/com/github/sirblobman/combatlogx/command/combatlogx/SubCommandTag.java ================================================ package com.github.sirblobman.combatlogx.command.combatlogx; import java.math.BigInteger; import java.util.Collections; import java.util.List; import java.util.Set; import java.util.concurrent.TimeUnit; import java.util.stream.Collectors; import java.util.stream.IntStream; import org.jetbrains.annotations.NotNull; import org.bukkit.command.CommandSender; import org.bukkit.entity.Player; import com.github.sirblobman.api.language.replacer.Replacer; import com.github.sirblobman.api.language.replacer.StringReplacer; import com.github.sirblobman.combatlogx.api.ICombatLogX; import com.github.sirblobman.combatlogx.api.command.CombatLogCommand; import com.github.sirblobman.combatlogx.api.manager.ICombatManager; import com.github.sirblobman.combatlogx.api.object.TagReason; import com.github.sirblobman.combatlogx.api.object.TagType; public final class SubCommandTag extends CombatLogCommand { public SubCommandTag(@NotNull ICombatLogX plugin) { super(plugin, "tag"); setPermissionName("combatlogx.command.combatlogx.tag"); } @Override protected @NotNull List onTabComplete(@NotNull CommandSender sender, String @NotNull [] args) { if (args.length == 1) { Set valueSet = getOnlinePlayerNames(); return getMatching(args[0], valueSet); } if (args.length == 2) { IntStream intValueSet = IntStream.rangeClosed(1, 60); Set valueSet = intValueSet.mapToObj(Integer::toString).collect(Collectors.toSet()); return getMatching(args[1], valueSet); } return Collections.emptyList(); } @Override protected boolean execute(@NotNull CommandSender sender, String @NotNull [] args) { if (args.length < 1) { return false; } Player target = findTarget(sender, args[0]); if (target == null) { return true; } String targetName = target.getName(); Replacer replacer = new StringReplacer("{target}", targetName); ICombatLogX plugin = getCombatLogX(); ICombatManager combatManager = plugin.getCombatManager(); boolean successfulTag; if (args.length < 2) { successfulTag = combatManager.tag(target, null, TagType.UNKNOWN, TagReason.UNKNOWN); } else { BigInteger bigSeconds = parseInteger(sender, args[1]); if (bigSeconds == null) { return true; } long seconds = bigSeconds.longValue(); long milliseconds = TimeUnit.SECONDS.toMillis(seconds); long systemMillis = System.currentTimeMillis(); long combatEndTime = (systemMillis + milliseconds); successfulTag = combatManager.tag(target, null, TagType.UNKNOWN, TagReason.UNKNOWN, combatEndTime); } String messagePath = ("command.combatlogx." + (successfulTag ? "tag-player" : "tag-failure")); sendMessageWithPrefix(sender, messagePath, replacer); return true; } } ================================================ FILE: plugin/src/main/java/com/github/sirblobman/combatlogx/command/combatlogx/SubCommandToggle.java ================================================ package com.github.sirblobman.combatlogx.command.combatlogx; import java.util.Arrays; import java.util.Collections; import java.util.List; import java.util.Locale; import org.jetbrains.annotations.NotNull; import org.bukkit.configuration.file.YamlConfiguration; import org.bukkit.entity.Player; import com.github.sirblobman.api.configuration.PlayerDataManager; import com.github.sirblobman.api.language.LanguageManager; import com.github.sirblobman.api.language.replacer.Replacer; import com.github.sirblobman.api.language.replacer.StringReplacer; import com.github.sirblobman.combatlogx.api.ICombatLogX; import com.github.sirblobman.combatlogx.api.command.CombatLogPlayerCommand; public final class SubCommandToggle extends CombatLogPlayerCommand { public SubCommandToggle(@NotNull ICombatLogX plugin) { super(plugin, "toggle"); setPermissionName("combatlogx.command.combatlogx.toggle"); } @Override protected @NotNull List onTabComplete(@NotNull Player player, String @NotNull [] args) { if (args.length == 1) { return getMatching(args[0], "actionbar", "bossbar", "scoreboard"); } return Collections.emptyList(); } @Override protected boolean execute(@NotNull Player player, String @NotNull [] args) { if (args.length < 1) { return false; } String sub = args[0].toLowerCase(Locale.US); List validToggleList = Arrays.asList("actionbar", "bossbar", "scoreboard"); if (!validToggleList.contains(sub)) { return false; } toggleValue(player, sub); return true; } private void toggleValue(Player player, String value) { ICombatLogX plugin = getCombatLogX(); PlayerDataManager playerDataManager = plugin.getPlayerDataManager(); LanguageManager languageManager = getLanguageManager(); YamlConfiguration playerData = playerDataManager.get(player); boolean currentValue = playerData.getBoolean(value, true); playerData.set(value, !currentValue); playerDataManager.save(player); boolean status = playerData.getBoolean(value, true); String statusPath = ("placeholder.toggle." + (status ? "enabled" : "disabled")); String statusString = languageManager.getMessageString(player, statusPath); Replacer replacer = new StringReplacer("{status}", statusString); String messagePath = ("command.combatlogx.toggle-" + value); sendMessageWithPrefix(player, messagePath, replacer); } } ================================================ FILE: plugin/src/main/java/com/github/sirblobman/combatlogx/command/combatlogx/SubCommandUntag.java ================================================ package com.github.sirblobman.combatlogx.command.combatlogx; import java.util.Collections; import java.util.List; import java.util.Set; import org.jetbrains.annotations.NotNull; import org.bukkit.command.CommandSender; import org.bukkit.entity.Player; import com.github.sirblobman.api.language.replacer.Replacer; import com.github.sirblobman.api.language.replacer.StringReplacer; import com.github.sirblobman.combatlogx.api.ICombatLogX; import com.github.sirblobman.combatlogx.api.command.CombatLogCommand; import com.github.sirblobman.combatlogx.api.manager.ICombatManager; import com.github.sirblobman.combatlogx.api.object.UntagReason; public final class SubCommandUntag extends CombatLogCommand { public SubCommandUntag(@NotNull ICombatLogX plugin) { super(plugin, "untag"); setPermissionName("combatlogx.command.combatlogx.untag"); } @Override protected @NotNull List onTabComplete(@NotNull CommandSender sender, String @NotNull [] args) { if (args.length == 1) { Set valueSet = getOnlinePlayerNames(); return getMatching(args[0], valueSet); } return Collections.emptyList(); } @Override protected boolean execute(@NotNull CommandSender sender, String @NotNull [] args) { if (args.length < 1) { return false; } Player target = findTarget(sender, args[0]); if (target == null) { return true; } String targetName = target.getName(); Replacer replacer = new StringReplacer("{target}", targetName); ICombatLogX plugin = getCombatLogX(); ICombatManager combatManager = plugin.getCombatManager(); if (!combatManager.isInCombat(target)) { sendMessageWithPrefix(sender, "error.target-not-in-combat", replacer); return true; } combatManager.untag(target, UntagReason.EXPIRE); sendMessageWithPrefix(sender, "command.combatlogx.untag-player", replacer); return true; } } ================================================ FILE: plugin/src/main/java/com/github/sirblobman/combatlogx/command/combatlogx/SubCommandVersion.java ================================================ package com.github.sirblobman.combatlogx.command.combatlogx; import java.util.ArrayList; import java.util.List; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import org.bukkit.Bukkit; import org.bukkit.command.CommandSender; import org.bukkit.command.ConsoleCommandSender; import org.bukkit.plugin.Plugin; import org.bukkit.plugin.PluginDescriptionFile; import org.bukkit.plugin.PluginManager; import org.bukkit.plugin.java.JavaPlugin; import com.github.sirblobman.api.core.CorePlugin; import com.github.sirblobman.api.language.LanguageManager; import com.github.sirblobman.api.plugin.ConfigurablePlugin; import com.github.sirblobman.api.update.SpigotUpdateManager; import com.github.sirblobman.api.utility.VersionUtility; import com.github.sirblobman.combatlogx.api.ICombatLogX; import com.github.sirblobman.combatlogx.api.command.CombatLogCommand; import com.github.sirblobman.combatlogx.api.expansion.Expansion; import com.github.sirblobman.combatlogx.api.expansion.ExpansionDescription; import com.github.sirblobman.combatlogx.api.expansion.ExpansionManager; import com.github.sirblobman.api.shaded.adventure.text.Component; import com.github.sirblobman.api.shaded.adventure.text.TextComponent; import com.github.sirblobman.api.shaded.adventure.text.TextComponent.Builder; import com.github.sirblobman.api.shaded.adventure.text.format.NamedTextColor; import com.github.sirblobman.api.shaded.adventure.text.format.TextDecoration; public final class SubCommandVersion extends CombatLogCommand { public SubCommandVersion(@NotNull ICombatLogX plugin) { super(plugin, "version"); setPermissionName("combatlogx.command.combatlogx.version"); } @Override protected boolean execute(@NotNull CommandSender sender, String @NotNull [] args) { if (!(sender instanceof ConsoleCommandSender)) { sendMessageWithPrefix(sender, "error.console-only"); return true; } List messageList = new ArrayList<>(); messageList.add(Component.empty()); addJavaVersionInformation(messageList); messageList.add(Component.empty()); addServerVersionInformation(messageList); messageList.add(Component.empty()); addDependencyInformation(messageList); messageList.add(Component.empty()); addPluginVersionInformation(messageList); messageList.add(Component.empty()); addExpansionInformation(messageList); messageList.add(Component.empty()); LanguageManager languageManager = getLanguageManager(); for (Component message : messageList) { languageManager.sendMessage(sender, message); } return true; } private @NotNull Component withPrefix(@NotNull String prefix, @Nullable String value) { TextComponent.Builder builder = Component.text().color(NamedTextColor.WHITE); builder.append(Component.text(prefix).decorate(TextDecoration.BOLD)); builder.append(Component.text(":").decorate(TextDecoration.BOLD)); builder.appendSpace(); if (value != null) { builder.append(Component.text(value, NamedTextColor.GRAY)); } else { builder.append(Component.text("N/A", NamedTextColor.GRAY)); } return builder.build(); } private @NotNull Component listElement(@NotNull String value) { TextComponent.Builder builder = Component.text().color(NamedTextColor.GRAY); builder.append(Component.text(" - ", NamedTextColor.WHITE, TextDecoration.BOLD)); builder.append(Component.text(value)); return builder.build(); } private void addJavaVersionInformation(@NotNull List list) { String javaVersion = getProperty("java.version"); String javaVendor = getProperty("java.vendor"); String javaURL = getProperty("java.url"); list.add(withPrefix("Java Version", javaVersion)); list.add(withPrefix("Java Vendor", javaVendor)); list.add(withPrefix("Java URL", javaURL)); } private @NotNull String getProperty(String name) { try { return System.getProperty(name); } catch (SecurityException | IllegalArgumentException | NullPointerException ex) { return "Error"; } } private void addServerVersionInformation(@NotNull List list) { String version = Bukkit.getVersion(); String bukkitVersion = Bukkit.getBukkitVersion(); String minecraftVersion = VersionUtility.getMinecraftVersion(); String nmsVersion = VersionUtility.getNetMinecraftServerVersion(); list.add(withPrefix("Server Version", version)); list.add(withPrefix("Bukkit Version", bukkitVersion)); list.add(withPrefix("Minecraft Version", minecraftVersion)); list.add(withPrefix("NMS Version", nmsVersion)); } private void addDependencyInformation(@NotNull List list) { ICombatLogX combatLogX = getCombatLogX(); ConfigurablePlugin plugin = combatLogX.getPlugin(); PluginDescriptionFile description = plugin.getDescription(); list.add(Component.text("Dependency Information:", NamedTextColor.WHITE, TextDecoration.BOLD)); List loadBeforeList = description.getLoadBefore(); List softDependList = description.getSoftDepend(); List dependList = description.getDepend(); List fullDependencyList = new ArrayList<>(loadBeforeList); fullDependencyList.addAll(softDependList); fullDependencyList.addAll(dependList); if (fullDependencyList.isEmpty()) { list.add(listElement("None")); return; } Component missingText = Component.text("(not installed)", NamedTextColor.RED); PluginManager pluginManager = Bukkit.getPluginManager(); for (String dependencyName : fullDependencyList) { Plugin dependency = pluginManager.getPlugin(dependencyName); if (dependency == null) { list.add(listElement(dependencyName).append(Component.space()).append(missingText)); continue; } PluginDescriptionFile dependencyDescription = dependency.getDescription(); String dependencyFullName = dependencyDescription.getFullName(); list.add(listElement(dependencyFullName)); } } private void addPluginVersionInformation(@NotNull List list) { String localVersion = getPluginVersion(); String remoteVersion = getRemoteVersion(); list.add(Component.text("CombatLogX by SirBlobman", NamedTextColor.WHITE, TextDecoration.BOLD)); list.add(withPrefix("Local Version", localVersion)); list.add(withPrefix("Remote Version", remoteVersion)); } private void addExpansionInformation(@NotNull List list) { ExpansionManager expansionManager = getExpansionManager(); List enabledExpansionList = expansionManager.getEnabledExpansions(); int enabledExpansionListSize = enabledExpansionList.size(); Builder builder = Component.text().color(NamedTextColor.WHITE).decorate(TextDecoration.BOLD); builder.append(Component.text("Enabled Expansions (")); builder.append(Component.text(enabledExpansionListSize, NamedTextColor.GRAY)); builder.append(Component.text("):")); list.add(builder.build()); for (Expansion expansion : enabledExpansionList) { ExpansionDescription description = expansion.getDescription(); String expansionName = description.getFullName(); list.add(listElement(expansionName)); } } private @NotNull String getPluginVersion() { ICombatLogX combatLogX = getCombatLogX(); ConfigurablePlugin plugin = combatLogX.getPlugin(); PluginDescriptionFile information = plugin.getDescription(); return information.getVersion(); } private @NotNull String getRemoteVersion() { ICombatLogX combatLogX = getCombatLogX(); ConfigurablePlugin plugin = combatLogX.getPlugin(); CorePlugin corePlugin = JavaPlugin.getPlugin(CorePlugin.class); SpigotUpdateManager updateManager = corePlugin.getSpigotUpdateManager(); String spigotVersion = updateManager.getSpigotVersion(plugin); if (spigotVersion == null) { return "Not Available"; } return spigotVersion; } } ================================================ FILE: plugin/src/main/java/com/github/sirblobman/combatlogx/command/combatlogx/forgive/SubCommandForgive.java ================================================ package com.github.sirblobman.combatlogx.command.combatlogx.forgive; import org.jetbrains.annotations.NotNull; import com.github.sirblobman.combatlogx.api.ICombatLogX; import com.github.sirblobman.combatlogx.api.command.CombatLogPlayerCommand; public final class SubCommandForgive extends CombatLogPlayerCommand { public SubCommandForgive(@NotNull ICombatLogX plugin) { super(plugin, "forgive"); setPermissionName("combatlogx.command.combatlogx.forgive"); addSubCommand(new SubCommandForgiveAccept(plugin)); addSubCommand(new SubCommandForgiveReject(plugin)); addSubCommand(new SubCommandForgiveRequest(plugin)); addSubCommand(new SubCommandForgiveToggle(plugin)); } } ================================================ FILE: plugin/src/main/java/com/github/sirblobman/combatlogx/command/combatlogx/forgive/SubCommandForgiveAccept.java ================================================ package com.github.sirblobman.combatlogx.command.combatlogx.forgive; import java.util.Collections; import java.util.List; import org.jetbrains.annotations.NotNull; import org.bukkit.entity.Entity; import org.bukkit.entity.Player; import com.github.sirblobman.api.language.replacer.ComponentReplacer; import com.github.sirblobman.api.language.replacer.Replacer; import com.github.sirblobman.api.language.replacer.StringReplacer; import com.github.sirblobman.combatlogx.api.ICombatLogX; import com.github.sirblobman.combatlogx.api.command.CombatLogPlayerCommand; import com.github.sirblobman.combatlogx.api.manager.ICombatManager; import com.github.sirblobman.combatlogx.api.manager.IForgiveManager; import com.github.sirblobman.combatlogx.api.object.CombatTag; import com.github.sirblobman.combatlogx.api.object.UntagReason; import com.github.sirblobman.combatlogx.api.placeholder.PlaceholderHelper; import com.github.sirblobman.api.shaded.adventure.text.Component; public final class SubCommandForgiveAccept extends CombatLogPlayerCommand { public SubCommandForgiveAccept(@NotNull ICombatLogX plugin) { super(plugin, "accept"); setPermissionName("combatlogx.command.combatlogx.forgive.accept"); } @Override protected @NotNull List onTabComplete(@NotNull Player player, String @NotNull [] args) { return Collections.emptyList(); } @Override protected boolean execute(@NotNull Player player, String @NotNull [] args) { ICombatLogX combatLogX = getCombatLogX(); IForgiveManager forgiveManager = combatLogX.getForgiveManager(); CombatTag activeRequest = forgiveManager.getActiveRequest(player); if (activeRequest == null) { sendMessage(player, "command.combatlogx.forgive.no-active-request"); return true; } Entity enemy = activeRequest.getEnemy(); if (enemy == null) { sendMessage(player, "command.combatlogx.forgive.no-active-request"); return true; } ICombatManager combatManager = combatLogX.getCombatManager(); combatManager.untag(player, enemy, UntagReason.ENEMY_FORGIVE); String playerName = player.getName(); Component enemyName = PlaceholderHelper.getEnemyName(combatLogX, player, enemy); Replacer enemyNameReplacer = new ComponentReplacer("{enemy}", enemyName); Replacer playerNameReplacer = new StringReplacer("{player}", playerName); sendMessage(player, "command.combatlogx.forgive.accept-player", enemyNameReplacer); sendMessage(enemy, "command.combatlogx.forgive.accept-enemy", playerNameReplacer); return true; } } ================================================ FILE: plugin/src/main/java/com/github/sirblobman/combatlogx/command/combatlogx/forgive/SubCommandForgiveReject.java ================================================ package com.github.sirblobman.combatlogx.command.combatlogx.forgive; import java.util.Collections; import java.util.List; import org.jetbrains.annotations.NotNull; import org.bukkit.entity.Entity; import org.bukkit.entity.Player; import com.github.sirblobman.api.language.replacer.ComponentReplacer; import com.github.sirblobman.api.language.replacer.Replacer; import com.github.sirblobman.api.language.replacer.StringReplacer; import com.github.sirblobman.combatlogx.api.ICombatLogX; import com.github.sirblobman.combatlogx.api.command.CombatLogPlayerCommand; import com.github.sirblobman.combatlogx.api.manager.IForgiveManager; import com.github.sirblobman.combatlogx.api.object.CombatTag; import com.github.sirblobman.combatlogx.api.placeholder.PlaceholderHelper; import com.github.sirblobman.api.shaded.adventure.text.Component; public final class SubCommandForgiveReject extends CombatLogPlayerCommand { public SubCommandForgiveReject(ICombatLogX plugin) { super(plugin, "reject"); setPermissionName("combatlogx.command.combatlogx.forgive.reject"); } @Override protected @NotNull List onTabComplete(@NotNull Player player, String @NotNull [] args) { return Collections.emptyList(); } @Override protected boolean execute(@NotNull Player player, String @NotNull [] args) { ICombatLogX combatLogX = getCombatLogX(); IForgiveManager forgiveManager = combatLogX.getForgiveManager(); CombatTag activeRequest = forgiveManager.getActiveRequest(player); if (activeRequest == null) { sendMessage(player, "command.combatlogx.forgive.no-active-request"); return true; } forgiveManager.removeRequest(player); Entity enemy = activeRequest.getEnemy(); String playerName = player.getName(); Component enemyName = PlaceholderHelper.getEnemyName(combatLogX, player, enemy); Replacer replacerEnemy = new ComponentReplacer("{enemy}", enemyName); Replacer replacerPlayer = new StringReplacer("{player}", playerName); sendMessage(player, "command.combatlogx.forgive.reject-player", replacerEnemy); sendMessage(enemy, "command.combatlogx.forgive.reject-enemy", replacerPlayer); return true; } } ================================================ FILE: plugin/src/main/java/com/github/sirblobman/combatlogx/command/combatlogx/forgive/SubCommandForgiveRequest.java ================================================ package com.github.sirblobman.combatlogx.command.combatlogx.forgive; import java.util.ArrayList; import java.util.Collections; import java.util.List; import org.jetbrains.annotations.NotNull; import org.bukkit.entity.Entity; import org.bukkit.entity.Player; import com.github.sirblobman.api.language.replacer.Replacer; import com.github.sirblobman.api.language.replacer.StringReplacer; import com.github.sirblobman.combatlogx.api.ICombatLogX; import com.github.sirblobman.combatlogx.api.command.CombatLogPlayerCommand; import com.github.sirblobman.combatlogx.api.manager.ICombatManager; import com.github.sirblobman.combatlogx.api.manager.IForgiveManager; import com.github.sirblobman.combatlogx.api.object.CombatTag; import com.github.sirblobman.combatlogx.api.object.TagInformation; public final class SubCommandForgiveRequest extends CombatLogPlayerCommand { public SubCommandForgiveRequest(@NotNull ICombatLogX plugin) { super(plugin, "request"); setPermissionName("combatlogx.command.combatlogx.forgive.request"); } @Override protected @NotNull List onTabComplete(@NotNull Player player, String @NotNull [] args) { if (args.length == 1) { List valueSet = getEnemyPlayerNames(player); return getMatching(args[0], valueSet); } return Collections.emptyList(); } @Override protected boolean execute(@NotNull Player player, String @NotNull [] args) { ICombatLogX combatLogX = getCombatLogX(); ICombatManager combatManager = combatLogX.getCombatManager(); TagInformation tagInformation = combatManager.getTagInformation(player); if (tagInformation == null) { sendMessage(player, "error.self-not-in-combat"); return true; } Player target = findTarget(player, args[0]); if (target == null) { return true; } String targetName = target.getName(); Replacer targetReplacer = new StringReplacer("{target}", targetName); CombatTag combatTag = tagInformation.getTagForEnemy(target); if (combatTag == null) { sendMessage(player, "error.forgive-not-enemy", targetReplacer); return true; } IForgiveManager forgiveManager = combatLogX.getForgiveManager(); if (forgiveManager.getToggleValue(target)) { sendMessage(player, "error.enemy-not-forgiving", targetReplacer); return true; } forgiveManager.setRequest(player, combatTag); String playerName = player.getName(); Replacer playerReplacer = new StringReplacer("{player}", playerName); sendMessage(player, "command.combatlogx.forgive.request-sent", targetReplacer); sendMessage(target, "command.combatlogx.forgive.request-receive", playerReplacer); return true; } private List getEnemyPlayerNames(Player player) { ICombatLogX combatLogX = getCombatLogX(); ICombatManager combatManager = combatLogX.getCombatManager(); TagInformation tagInformation = combatManager.getTagInformation(player); if (tagInformation == null) { return Collections.emptyList(); } List enemies = tagInformation.getEnemies(); List enemyPlayerNameList = new ArrayList<>(); for (Entity enemy : enemies) { if (!(enemy instanceof Player)) { continue; } Player enemyPlayer = (Player) enemy; String enemyPlayerName = enemyPlayer.getName(); enemyPlayerNameList.add(enemyPlayerName); } return enemyPlayerNameList; } } ================================================ FILE: plugin/src/main/java/com/github/sirblobman/combatlogx/command/combatlogx/forgive/SubCommandForgiveToggle.java ================================================ package com.github.sirblobman.combatlogx.command.combatlogx.forgive; import java.util.Collections; import java.util.List; import org.jetbrains.annotations.NotNull; import org.bukkit.entity.Player; import com.github.sirblobman.combatlogx.api.ICombatLogX; import com.github.sirblobman.combatlogx.api.command.CombatLogPlayerCommand; import com.github.sirblobman.combatlogx.api.manager.IForgiveManager; public final class SubCommandForgiveToggle extends CombatLogPlayerCommand { public SubCommandForgiveToggle(@NotNull ICombatLogX plugin) { super(plugin, "toggle"); setPermissionName("combatlogx.command.combatlogx.forgive.toggle"); } @Override protected @NotNull List onTabComplete(@NotNull Player player, String @NotNull [] args) { return Collections.emptyList(); } @Override protected boolean execute(@NotNull Player player, String @NotNull [] args) { ICombatLogX combatLogX = getCombatLogX(); IForgiveManager forgiveManager = combatLogX.getForgiveManager(); boolean toggleValue = forgiveManager.getToggleValue(player); if (toggleValue) { forgiveManager.setToggle(player, false); sendMessage(player, "command.combatlogx.forgive.toggle-enable"); } else { forgiveManager.setToggle(player, true); sendMessage(player, "command.combatlogx.forgive.toggle-disable"); } return true; } } ================================================ FILE: plugin/src/main/java/com/github/sirblobman/combatlogx/configuration/ConfigurationChecker.java ================================================ package com.github.sirblobman.combatlogx.configuration; import java.io.File; import java.io.FilenameFilter; import java.io.IOException; import java.util.logging.Level; import java.util.logging.Logger; import org.jetbrains.annotations.NotNull; import org.bukkit.configuration.InvalidConfigurationException; import org.bukkit.configuration.file.YamlConfiguration; import com.github.sirblobman.api.utility.Validate; import com.github.sirblobman.combatlogx.CombatPlugin; import com.github.sirblobman.combatlogx.api.ICombatLogX; import org.zeroturnaround.zip.ZipUtil; public final class ConfigurationChecker { private final ICombatLogX plugin; public ConfigurationChecker(@NotNull CombatPlugin plugin) { this.plugin = Validate.notNull(plugin, "plugin must not be null!"); } public void checkVersion() { Logger logger = getLogger(); try { File dataFolder = plugin.getDataFolder(); if (!dataFolder.exists()) { logger.info("Configuration does not exist yet, no major changes necessary."); return; } FilenameFilter ymlOnly = (folder, fileName) -> fileName.endsWith(".yml"); File[] yamlFileArray = dataFolder.listFiles(ymlOnly); if (yamlFileArray == null || yamlFileArray.length == 0) { logger.info("Configuration does not exist yet, no major changes necessary."); return; } File configFile = new File(dataFolder, "config.yml"); if (!configFile.exists()) { logger.info("Configuration does not exist yet, no major changes necessary."); return; } File punishConfigFile = new File(dataFolder, "punish.yml"); if (!punishConfigFile.exists()) { makeBackup(); return; } YamlConfiguration configuration = new YamlConfiguration(); configuration.load(configFile); String generatedByVersion = configuration.getString("generated-by-version"); if (generatedByVersion == null || !generatedByVersion.startsWith("11.")) { makeBackup(); return; } logger.info("Configuration version is recent, no major changes necessary."); } catch (IOException | InvalidConfigurationException ex) { logger.log(Level.WARNING, "An error occurred while checking the configuration version:", ex); } } private ICombatLogX getPlugin() { return this.plugin; } private Logger getLogger() { ICombatLogX plugin = getPlugin(); return plugin.getLogger(); } private void makeBackup() throws IOException { Logger logger = getLogger(); logger.warning("Configuration version is outdated, backing up files..."); ICombatLogX plugin = getPlugin(); File dataFolder = plugin.getDataFolder(); File pluginsFolder = dataFolder.getParentFile(); File backupFile = new File(pluginsFolder, "CombatLogX-" + System.currentTimeMillis() + ".backup.zip"); ZipUtil.pack(dataFolder, backupFile); logger.warning("Configuration version is outdated, deleting old files..."); deleteFile(dataFolder); } private void deleteFile(File parentFile) throws IOException { String parentFileName = parentFile.getName(); if (parentFile.isDirectory() && parentFileName.equals("expansions")) { return; } if (parentFileName.endsWith(".jar")) { return; } if (!parentFile.isDirectory()) { if (!parentFile.delete()) { throw new IOException("Failed to delete a a file."); } return; } File[] fileArray = parentFile.listFiles(); if (fileArray == null || fileArray.length == 0) { if (!parentFile.delete()) { throw new IOException("Failed to delete a a file."); } return; } for (File file : fileArray) { String fileName = file.getName(); if (file.isDirectory() && fileName.equals("expansions")) { continue; } if (fileName.endsWith(".jar")) { continue; } deleteFile(file); } File[] fileArray2 = parentFile.listFiles(); if (fileArray2 == null || fileArray2.length == 0) { if (!parentFile.delete()) { throw new IOException("Failed to delete a a file."); } } } } ================================================ FILE: plugin/src/main/java/com/github/sirblobman/combatlogx/listener/ListenerConfiguration.java ================================================ package com.github.sirblobman.combatlogx.listener; import java.util.Collections; import java.util.List; import java.util.Set; import java.util.UUID; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import org.bukkit.entity.Entity; import org.bukkit.entity.LivingEntity; import org.bukkit.entity.Player; import org.bukkit.event.EventHandler; import org.bukkit.event.EventPriority; import org.bukkit.event.entity.EntityDeathEvent; import org.bukkit.event.entity.EntityExplodeEvent; import org.bukkit.event.entity.PlayerDeathEvent; import org.bukkit.event.player.PlayerRespawnEvent; import com.github.sirblobman.combatlogx.api.ICombatLogX; import com.github.sirblobman.combatlogx.api.configuration.CommandConfiguration; import com.github.sirblobman.combatlogx.api.configuration.MainConfiguration; import com.github.sirblobman.combatlogx.api.event.PlayerPreTagEvent; import com.github.sirblobman.combatlogx.api.event.PlayerTagEvent; import com.github.sirblobman.combatlogx.api.listener.CombatListener; import com.github.sirblobman.combatlogx.api.manager.ICombatManager; import com.github.sirblobman.combatlogx.api.manager.IPlaceholderManager; import com.github.sirblobman.combatlogx.api.object.TagReason; import com.github.sirblobman.combatlogx.api.object.UntagReason; public final class ListenerConfiguration extends CombatListener { public ListenerConfiguration(@NotNull ICombatLogX plugin) { super(plugin); } @EventHandler(priority = EventPriority.NORMAL, ignoreCancelled = true) public void beforeTag(PlayerPreTagEvent e) { printDebug("Detected PlayerPreTagEvent."); TagReason tagReason = e.getTagReason(); printDebug("Tag Reason: " + tagReason); if (isDisabled(tagReason)) { printDebug("Reason disabled by configuration."); e.setCancelled(true); return; } Player player = e.getPlayer(); printDebug("Player: " + player.getName()); if (isWorldDisabled(player)) { printDebug("Player is in disabled world, cancelling."); e.setCancelled(true); return; } if (checkBypass(player)) { printDebug("Player has bypass, cancelling."); e.setCancelled(true); return; } Entity enemy = e.getEnemy(); if (isSelfCombatDisabled(player, enemy)) { printDebug("Self combat is disabled, cancelling."); e.setCancelled(true); return; } printDebug("Finished default beforeTag check without cancellation."); } @EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true) public void onTag(PlayerTagEvent e) { Player player = e.getPlayer(); Entity enemy = e.getEnemy(); runTagCommands(player, enemy); } @EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true) public void onRespawn(PlayerRespawnEvent e) { Player player = e.getPlayer(); checkDeathUntag(player); } @EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true) public void onDeath(PlayerDeathEvent e) { Player player = e.getEntity(); checkDeathUntag(player); } @EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true) public void onDeath(EntityDeathEvent e) { LivingEntity entity = e.getEntity(); checkEnemyDeathUntag(entity); } @EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true) public void onExplode(EntityExplodeEvent e) { Entity entity = e.getEntity(); if (!(entity instanceof LivingEntity)) { return; } LivingEntity livingEntity = (LivingEntity) entity; checkEnemyDeathUntag(livingEntity); } private @NotNull MainConfiguration getConfiguration() { ICombatLogX plugin = getCombatLogX(); return plugin.getConfiguration(); } private boolean checkBypass(@NotNull Player player) { ICombatManager combatManager = getCombatManager(); return combatManager.canBypass(player); } private boolean isSelfCombatDisabled(@NotNull Player player, @Nullable Entity enemy) { MainConfiguration configuration = getConfiguration(); if (configuration.isSelfCombat()) { return false; } return (enemy != null && isEqual(player, enemy)); } private boolean isEqual(@NotNull Entity entity1, @NotNull Entity entity2) { if (entity1 == entity2) { return true; } UUID entityId1 = entity1.getUniqueId(); UUID entityId2 = entity2.getUniqueId(); return entityId1.equals(entityId2); } private void checkDeathUntag(@NotNull Player player) { ICombatManager combatManager = getCombatManager(); MainConfiguration configuration = getConfiguration(); if (configuration.isUntagOnSelfDeath() && combatManager.isInCombat(player)) { combatManager.untag(player, UntagReason.SELF_DEATH); } } private void checkEnemyDeathUntag(@NotNull LivingEntity enemy) { ICombatManager combatManager = getCombatManager(); MainConfiguration configuration = getConfiguration(); if (configuration.isUntagOnEnemyDeath()) { List playerList = combatManager.getPlayersInCombat(); for (Player player : playerList) { combatManager.untag(player, enemy, UntagReason.ENEMY_DEATH); } } } private void runTagCommands(@NotNull Player player, @Nullable Entity enemy) { ICombatLogX plugin = getCombatLogX(); CommandConfiguration commandConfiguration = plugin.getCommandConfiguration(); List tagCommandList = commandConfiguration.getTagCommands(); List enemyList = (enemy == null ? Collections.emptyList() : Collections.singletonList(enemy)); IPlaceholderManager placeholderManager = plugin.getPlaceholderManager(); placeholderManager.runReplacedCommands(player, enemyList, tagCommandList); } private boolean isDisabled(@NotNull TagReason reason) { MainConfiguration configuration = getConfiguration(); Set tagReasons = configuration.getEnabledTagReasons(); return !tagReasons.contains(reason); } } ================================================ FILE: plugin/src/main/java/com/github/sirblobman/combatlogx/listener/ListenerDamage.java ================================================ package com.github.sirblobman.combatlogx.listener; import org.jetbrains.annotations.Contract; import org.jetbrains.annotations.NotNull; import org.bukkit.entity.Entity; import org.bukkit.entity.Player; import org.bukkit.event.EventHandler; import org.bukkit.event.EventPriority; import org.bukkit.event.entity.EntityDamageByEntityEvent; import org.bukkit.event.player.PlayerFishEvent; import org.bukkit.event.player.PlayerFishEvent.State; import com.github.sirblobman.api.nms.EntityHandler; import com.github.sirblobman.api.nms.MultiVersionHandler; import com.github.sirblobman.combatlogx.api.ICombatLogX; import com.github.sirblobman.combatlogx.api.configuration.MainConfiguration; import com.github.sirblobman.combatlogx.api.listener.CombatListener; import com.github.sirblobman.combatlogx.api.manager.ICombatManager; import com.github.sirblobman.combatlogx.api.manager.ICrystalManager; import com.github.sirblobman.combatlogx.api.object.TagReason; import com.github.sirblobman.combatlogx.api.object.TagType; import com.github.sirblobman.combatlogx.api.utility.EntityHelper; public final class ListenerDamage extends CombatListener { public ListenerDamage(@NotNull ICombatLogX plugin) { super(plugin); } @EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true) public void onDamage(EntityDamageByEntityEvent e) { printDebug("Detected EntityDamageByEntityEvent."); Entity damaged = e.getEntity(); Entity damager = getDamager(e); if (damager == null) { printDebug("Damager is null, ignoring event."); return; } printDebug("Damager Name + Type: " + getName(damager) + " " + damager.getType().name()); printDebug("Damaged Name + Type: " + getName(damaged) + " " + damaged.getType().name()); checkTag(damager, damaged, TagReason.ATTACKER); checkTag(damaged, damager, TagReason.ATTACKED); } @EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true) public void onFish(PlayerFishEvent e) { MainConfiguration configuration = getConfiguration(); if (!configuration.isLinkFishingRod()) { return; } State state = e.getState(); if (state != State.CAUGHT_ENTITY) { return; } Entity caughtEntity = e.getCaught(); if (caughtEntity == null) { return; } Player player = e.getPlayer(); checkTag(player, caughtEntity, TagReason.ATTACKER); } private MainConfiguration getConfiguration() { ICombatLogX plugin = getCombatLogX(); return plugin.getConfiguration(); } private Entity getDamager(EntityDamageByEntityEvent e) { Entity entity = e.getDamager(); return getDamager(entity); } @Contract("null -> null") private Entity getDamager(Entity entity) { if (entity == null) { return null; } ICombatLogX plugin = getCombatLogX(); MainConfiguration configuration = getConfiguration(); if (configuration.isLinkProjectiles()) { entity = EntityHelper.linkProjectile(plugin, entity); } if (configuration.isLinkPets()) { entity = EntityHelper.linkPet(entity); } if (configuration.isLinkTnt()) { entity = EntityHelper.linkTNT(entity); } if (configuration.isLinkEndCrystals()) { ICombatLogX combatLogX = getCombatLogX(); ICrystalManager crystalManager = combatLogX.getCrystalManager(); Player player = crystalManager.getPlacer(entity); if (player != null) { entity = player; } } return entity; } private void checkTag(@NotNull Entity entity, @NotNull Entity enemy, @NotNull TagReason tagReason) { ICombatLogX plugin = getCombatLogX(); ICombatManager combatManager = getCombatManager(); plugin.printDebug("Checking if the entity '" + getName(entity) + "' should be tagged " + "for reason '" + tagReason + "' by enemy '" + getName(enemy) + "'."); if (!(entity instanceof Player)) { plugin.printDebug("Entity was not a player."); return; } if (!(enemy instanceof Player)) { plugin.printDebug("Enemy was not a player."); return; } Player playerEntity = (Player) entity; Player playerEnemy = (Player) enemy; plugin.printDebug("Triggering tag for player " + getName(playerEntity) + " with enemy " + getName(playerEnemy) + "..."); boolean tag = combatManager.tag(playerEntity, playerEnemy, TagType.PLAYER, tagReason); plugin.printDebug("CombatTag Status: " + tag); } private String getName(@NotNull Entity entity) { ICombatLogX plugin = getCombatLogX(); MultiVersionHandler multiVersionHandler = plugin.getMultiVersionHandler(); EntityHandler entityHandler = multiVersionHandler.getEntityHandler(); return entityHandler.getName(entity); } } ================================================ FILE: plugin/src/main/java/com/github/sirblobman/combatlogx/listener/ListenerDeath.java ================================================ package com.github.sirblobman.combatlogx.listener; import java.util.Collections; import java.util.List; import java.util.concurrent.ThreadLocalRandom; import org.jetbrains.annotations.NotNull; import org.bukkit.configuration.file.YamlConfiguration; import org.bukkit.entity.Entity; import org.bukkit.entity.Player; import org.bukkit.event.EventHandler; import org.bukkit.event.EventPriority; import org.bukkit.event.entity.PlayerDeathEvent; import org.bukkit.event.player.PlayerJoinEvent; import org.bukkit.event.player.PlayerQuitEvent; import org.bukkit.event.player.PlayerRespawnEvent; import com.github.sirblobman.api.configuration.PlayerDataManager; import com.github.sirblobman.api.folia.details.RunnableTask; import com.github.sirblobman.api.folia.scheduler.TaskScheduler; import com.github.sirblobman.api.language.ComponentHelper; import com.github.sirblobman.api.language.LanguageManager; import com.github.sirblobman.api.plugin.ConfigurablePlugin; import com.github.sirblobman.api.utility.paper.PaperChecker; import com.github.sirblobman.api.utility.paper.PaperHelper; import com.github.sirblobman.combatlogx.api.ICombatLogX; import com.github.sirblobman.combatlogx.api.configuration.PunishConfiguration; import com.github.sirblobman.combatlogx.api.listener.CombatListener; import com.github.sirblobman.combatlogx.api.manager.IDeathManager; import com.github.sirblobman.combatlogx.api.manager.IPlaceholderManager; import com.github.sirblobman.combatlogx.api.object.KillTime; import com.github.sirblobman.api.shaded.adventure.text.Component; import com.github.sirblobman.api.shaded.adventure.text.minimessage.MiniMessage; public final class ListenerDeath extends CombatListener { public ListenerDeath(@NotNull ICombatLogX plugin) { super(plugin); } @EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true) public void onJoin(PlayerJoinEvent e) { PunishConfiguration punishConfiguration = getPunishConfiguration(); KillTime killTime = punishConfiguration.getKillTime(); if (killTime != KillTime.JOIN) { return; } Player player = e.getPlayer(); PlayerDataManager playerDataManager = getPlayerDataManager(); YamlConfiguration playerData = playerDataManager.get(player); if (!playerData.getBoolean("kill-on-join", false)) { return; } playerData.set("kill-on-join", false); playerDataManager.save(player); IDeathManager deathManager = getDeathManager(); List enemyList = Collections.emptyList(); deathManager.kill(player, enemyList); } @EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true) public void onRespawn(PlayerRespawnEvent e) { Player player = e.getPlayer(); IDeathManager deathManager = getDeathManager(); deathManager.stopTracking(player); } @EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true) public void onQuit(PlayerQuitEvent e) { Player player = e.getPlayer(); ConfigurablePlugin plugin = getJavaPlugin(); IDeathManager deathManager = getDeathManager(); RunnableTask task = new RunnableTask(plugin, () -> deathManager.stopTracking(player)); TaskScheduler scheduler = getCombatLogX().getFoliaHelper().getScheduler(); scheduler.scheduleTask(task); } @EventHandler(priority = EventPriority.NORMAL, ignoreCancelled = true) public void onDeath(PlayerDeathEvent e) { Player player = e.getEntity(); ICombatLogX plugin = getCombatLogX(); IDeathManager deathManager = plugin.getDeathManager(); if (!deathManager.wasPunishKilled(player)) { return; } List enemyList = deathManager.getTrackedEnemies(player); String randomMessage = getRandomDeathMessage(); if (randomMessage == null) { return; } IPlaceholderManager placeholderManager = plugin.getPlaceholderManager(); String replacedMessage = placeholderManager.replaceAll(player, enemyList, randomMessage); LanguageManager languageManager = getLanguageManager(); MiniMessage miniMessage = languageManager.getMiniMessage(); Component componentMessage = miniMessage.deserialize(replacedMessage); if (PaperChecker.hasNativeComponentSupport()) { PaperHelper.setDeathMessage(componentMessage, e); } else { String legacyMessage = ComponentHelper.toLegacy(componentMessage); e.setDeathMessage(legacyMessage); } } private PunishConfiguration getPunishConfiguration() { ICombatLogX plugin = getCombatLogX(); return plugin.getPunishConfiguration(); } private String getRandomDeathMessage() { PunishConfiguration punishConfiguration = getPunishConfiguration(); List customDeathMessageList = punishConfiguration.getCustomDeathMessages(); if (customDeathMessageList.isEmpty()) { return null; } ThreadLocalRandom random = ThreadLocalRandom.current(); int customDeathMessageListSize = customDeathMessageList.size(); int customDeathMessageIndex = random.nextInt(customDeathMessageListSize); return customDeathMessageList.get(customDeathMessageIndex); } } ================================================ FILE: plugin/src/main/java/com/github/sirblobman/combatlogx/listener/ListenerEndCrystal.java ================================================ package com.github.sirblobman.combatlogx.listener; import java.util.UUID; import org.jetbrains.annotations.NotNull; import org.bukkit.entity.Entity; import org.bukkit.entity.EntityType; import org.bukkit.entity.Player; import org.bukkit.event.EventHandler; import org.bukkit.event.EventPriority; import org.bukkit.event.entity.EntityDamageByEntityEvent; import com.github.sirblobman.combatlogx.api.ICombatLogX; import com.github.sirblobman.combatlogx.api.configuration.MainConfiguration; import com.github.sirblobman.combatlogx.api.listener.CombatListener; import com.github.sirblobman.combatlogx.api.manager.ICombatManager; import com.github.sirblobman.combatlogx.api.manager.ICrystalManager; import com.github.sirblobman.combatlogx.api.object.TagReason; import com.github.sirblobman.combatlogx.api.object.TagType; import com.github.sirblobman.api.shaded.xseries.XEntityType; public final class ListenerEndCrystal extends CombatListener { public ListenerEndCrystal(@NotNull ICombatLogX plugin) { super(plugin); } @EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true) public void onDamage(EntityDamageByEntityEvent e) { ICombatLogX plugin = getCombatLogX(); MainConfiguration configuration = plugin.getConfiguration(); if (!configuration.isLinkEndCrystals()) { return; } Entity damaged = e.getEntity(); if (!(damaged instanceof Player player)) { return; } Entity damager = e.getDamager(); XEntityType damagerType = XEntityType.of(damager); if (damagerType != XEntityType.END_CRYSTAL) { return; } ICrystalManager crystalManager = plugin.getCrystalManager(); Player placer = crystalManager.getPlacer(damager); if (placer != null) { checkTag(placer, player, TagReason.ATTACKER); checkTag(player, placer, TagReason.ATTACKED); } UUID damagerId = damager.getUniqueId(); crystalManager.remove(damagerId); } private void checkTag(@NotNull Player player, @NotNull Player enemy, @NotNull TagReason tagReason) { ICombatManager combatManager = getCombatManager(); combatManager.tag(player, enemy, TagType.PLAYER, tagReason); } } ================================================ FILE: plugin/src/main/java/com/github/sirblobman/combatlogx/listener/ListenerInvulnerable.java ================================================ package com.github.sirblobman.combatlogx.listener; import org.jetbrains.annotations.NotNull; import org.bukkit.entity.Player; import org.bukkit.event.EventHandler; import org.bukkit.event.EventPriority; import org.bukkit.event.player.PlayerEvent; import org.bukkit.event.player.PlayerJoinEvent; import org.bukkit.event.player.PlayerTeleportEvent; import com.github.sirblobman.api.folia.scheduler.TaskScheduler; import com.github.sirblobman.combatlogx.api.ICombatLogX; import com.github.sirblobman.combatlogx.api.configuration.MainConfiguration; import com.github.sirblobman.combatlogx.api.listener.CombatListener; import com.github.sirblobman.combatlogx.task.PlayerVulnerableTask; public final class ListenerInvulnerable extends CombatListener { public ListenerInvulnerable(@NotNull ICombatLogX plugin) { super(plugin); } @EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true) public void onJoin(PlayerJoinEvent e) { checkEvent(e); } @EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true) public void onJoin(PlayerTeleportEvent e) { checkEvent(e); } private void checkEvent(PlayerEvent e) { if (isDisabled()) { return; } Player player = e.getPlayer(); setVulnerableLater(player); } private boolean isDisabled() { ICombatLogX plugin = getCombatLogX(); MainConfiguration configuration = plugin.getConfiguration(); return !configuration.isRemoveNoDamageCooldown(); } private void setVulnerableLater(Player player) { PlayerVulnerableTask task = new PlayerVulnerableTask(getCombatLogX(), player); task.setDelay(2L); TaskScheduler scheduler = getCombatLogX().getFoliaHelper().getScheduler(); scheduler.scheduleEntityTask(task); } } ================================================ FILE: plugin/src/main/java/com/github/sirblobman/combatlogx/listener/ListenerPunish.java ================================================ package com.github.sirblobman.combatlogx.listener; import org.jetbrains.annotations.NotNull; import org.bukkit.event.EventHandler; import org.bukkit.event.EventPriority; import com.github.sirblobman.combatlogx.api.ICombatLogX; import com.github.sirblobman.combatlogx.api.configuration.PunishConfiguration; import com.github.sirblobman.combatlogx.api.event.PlayerPunishEvent; import com.github.sirblobman.combatlogx.api.listener.CombatListener; import com.github.sirblobman.combatlogx.api.object.UntagReason; public final class ListenerPunish extends CombatListener { public ListenerPunish(@NotNull ICombatLogX plugin) { super(plugin); } @EventHandler(priority = EventPriority.NORMAL, ignoreCancelled = true) public void beforePunish(PlayerPunishEvent e) { UntagReason untagReason = e.getPunishReason(); if (shouldPunishForReason(untagReason)) { return; } e.setCancelled(true); } private boolean shouldPunishForReason(UntagReason reason) { ICombatLogX plugin = getCombatLogX(); PunishConfiguration punishConfiguration = plugin.getPunishConfiguration(); if (reason.isExpire()) { return punishConfiguration.isOnExpire(); } if (reason == UntagReason.KICK) { return punishConfiguration.isOnKick(); } if (reason == UntagReason.QUIT) { return punishConfiguration.isOnDisconnect(); } return false; } } ================================================ FILE: plugin/src/main/java/com/github/sirblobman/combatlogx/listener/ListenerUntag.java ================================================ package com.github.sirblobman.combatlogx.listener; import com.github.sirblobman.api.language.LanguageManager; import com.github.sirblobman.combatlogx.api.ICombatLogX; import com.github.sirblobman.combatlogx.api.configuration.CommandConfiguration; import com.github.sirblobman.combatlogx.api.configuration.PunishConfiguration; import com.github.sirblobman.combatlogx.api.event.PlayerUntagEvent; import com.github.sirblobman.combatlogx.api.listener.CombatListener; import com.github.sirblobman.combatlogx.api.manager.ICombatManager; import com.github.sirblobman.combatlogx.api.manager.IPlaceholderManager; import com.github.sirblobman.combatlogx.api.manager.IPunishManager; import com.github.sirblobman.combatlogx.api.object.UntagReason; import org.bukkit.entity.Entity; import org.bukkit.entity.Player; import org.bukkit.event.EventHandler; import org.bukkit.event.EventPriority; import org.bukkit.event.player.PlayerKickEvent; import org.bukkit.event.player.PlayerQuitEvent; import org.jetbrains.annotations.NotNull; import java.util.List; import java.util.Locale; public final class ListenerUntag extends CombatListener { public ListenerUntag(@NotNull ICombatLogX plugin) { super(plugin); } @EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true) public void onKick(PlayerKickEvent e) { Player player = e.getPlayer(); if (!isInCombat(player)) { return; } String reason = e.getReason(); boolean ignored = isKickReasonIgnored(reason); UntagReason untagReason = (ignored ? UntagReason.EXPIRE : UntagReason.KICK); ICombatManager combatManager = getCombatManager(); combatManager.untag(player, untagReason); } @EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true) public void onQuit(PlayerQuitEvent e) { Player player = e.getPlayer(); if (!isInCombat(player)) { return; } ICombatManager combatManager = getCombatManager(); combatManager.untag(player, UntagReason.QUIT); } @EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true) public void onUntag(PlayerUntagEvent e) { Player player = e.getPlayer(); UntagReason untagReason = e.getUntagReason(); sendUntagMessage(player, untagReason); List previousEnemies = e.getPreviousEnemies(); runUntagCommands(player, previousEnemies); ICombatLogX plugin = getCombatLogX(); IPunishManager punishManager = plugin.getPunishManager(); punishManager.punish(player, untagReason, previousEnemies); } private boolean isKickReasonIgnored(@NotNull String reason) { ICombatLogX plugin = getCombatLogX(); PunishConfiguration punishConfiguration = plugin.getPunishConfiguration(); return punishConfiguration.isKickIgnored(reason); } private void sendUntagMessage(Player player, UntagReason untagReason) { if (!untagReason.isExpire()) { return; } String untagReasonName = untagReason.name(); String untagReasonLower = untagReasonName.toLowerCase(Locale.US); String untagReasonReplaced = untagReasonLower.replace('_', '-'); ICombatLogX plugin = getCombatLogX(); LanguageManager languageManager = plugin.getLanguageManager(); String languagePath = ("combat-timer." + untagReasonReplaced); languageManager.sendModifiableMessageWithPrefix(player, languagePath); } private void runUntagCommands(Player player, List enemyList) { ICombatLogX plugin = getCombatLogX(); CommandConfiguration commandConfiguration = plugin.getCommandConfiguration(); List untagCommandList = commandConfiguration.getUntagCommands(); if (untagCommandList.isEmpty()) { return; } IPlaceholderManager placeholderManager = plugin.getPlaceholderManager(); placeholderManager.runReplacedCommands(player, enemyList, untagCommandList); } } ================================================ FILE: plugin/src/main/java/com/github/sirblobman/combatlogx/manager/CombatManager.java ================================================ package com.github.sirblobman.combatlogx.manager; import java.util.ArrayList; import java.util.Collections; import java.util.HashSet; import java.util.List; import java.util.Locale; import java.util.Map; import java.util.Set; import java.util.UUID; import java.util.concurrent.ConcurrentHashMap; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import org.bukkit.Bukkit; import org.bukkit.entity.Entity; import org.bukkit.entity.EntityType; import org.bukkit.entity.Player; import org.bukkit.permissions.Permission; import org.bukkit.permissions.PermissionAttachmentInfo; import org.bukkit.plugin.PluginManager; import com.github.sirblobman.api.language.LanguageManager; import com.github.sirblobman.api.language.replacer.ComponentReplacer; import com.github.sirblobman.api.language.replacer.Replacer; import com.github.sirblobman.api.nms.EntityHandler; import com.github.sirblobman.api.nms.MultiVersionHandler; import com.github.sirblobman.api.nms.ServerHandler; import com.github.sirblobman.api.utility.paper.PaperChecker; import com.github.sirblobman.api.utility.paper.PaperHelper; import com.github.sirblobman.combatlogx.api.ICombatLogX; import com.github.sirblobman.combatlogx.api.configuration.MainConfiguration; import com.github.sirblobman.combatlogx.api.event.PlayerEnemyRemoveEvent; import com.github.sirblobman.combatlogx.api.event.PlayerPreTagEvent; import com.github.sirblobman.combatlogx.api.event.PlayerReTagEvent; import com.github.sirblobman.combatlogx.api.event.PlayerTagEvent; import com.github.sirblobman.combatlogx.api.event.PlayerUntagEvent; import com.github.sirblobman.combatlogx.api.manager.ICombatManager; import com.github.sirblobman.combatlogx.api.manager.ITimerManager; import com.github.sirblobman.combatlogx.api.object.CombatTag; import com.github.sirblobman.combatlogx.api.object.TagInformation; import com.github.sirblobman.combatlogx.api.object.TagReason; import com.github.sirblobman.combatlogx.api.object.TagType; import com.github.sirblobman.combatlogx.api.object.TimerType; import com.github.sirblobman.combatlogx.api.object.UntagReason; import com.github.sirblobman.api.shaded.adventure.text.Component; public final class CombatManager extends Manager implements ICombatManager { private final Map combatMap; public CombatManager(@NotNull ICombatLogX plugin) { super(plugin); this.combatMap = new ConcurrentHashMap<>(); } @Override public boolean tag(@NotNull Player player, @Nullable Entity enemy, @NotNull TagType tagType, @NotNull TagReason tagReason) { int timerSeconds = getMaxTimerSeconds(player); long timerMillis = (timerSeconds * 1_000L); long systemMillis = System.currentTimeMillis(); long endMillis = (systemMillis + timerMillis); return tag(player, enemy, tagType, tagReason, endMillis); } @Override public boolean tag(@NotNull Player player, @Nullable Entity enemy, @NotNull TagType tagType, @NotNull TagReason tagReason, long customEndMillis) { ICombatLogX plugin = getCombatLogX(); if (player.hasMetadata("NPC")) { plugin.printDebug("player is an NPC and can't be tagged."); return false; } if (failsPreTagEvent(player, enemy, tagType, tagReason)) { plugin.printDebug("The PlayerPreTagEvent was cancelled."); return false; } MainConfiguration configuration = plugin.getConfiguration(); double minimumTps = configuration.getMinimumTps(); if (minimumTps > 0.0D) { double tps = getServerTPS(); if (tps < minimumTps) { plugin.printDebug("Server TPS: " + tps); plugin.printDebug("Minimum TPS: " + tps); plugin.printDebug("The server tps is too low to tag players."); return false; } } boolean alreadyInCombat = isInCombat(player); plugin.printDebug("Previous Combat Status: " + alreadyInCombat); PluginManager pluginManager = Bukkit.getPluginManager(); if (alreadyInCombat) { PlayerReTagEvent event = new PlayerReTagEvent(player, enemy, tagType, tagReason, customEndMillis); pluginManager.callEvent(event); if (event.isCancelled()) { return false; } customEndMillis = event.getEndTime(); } else { PlayerTagEvent event = new PlayerTagEvent(player, enemy, tagType, tagReason, customEndMillis); pluginManager.callEvent(event); customEndMillis = event.getEndTime(); sendTagMessage(player, enemy, tagType, tagReason); } UUID playerId = player.getUniqueId(); CombatTag combatTag = new CombatTag(enemy, tagType, tagReason, customEndMillis); TagInformation tagInformation = this.combatMap.computeIfAbsent(playerId, key -> new TagInformation(player)); tagInformation.addTag(combatTag); String playerName = player.getName(); plugin.printDebug("Successfully put player '" + playerName + "' into combat."); return true; } @Override public void untag(@NotNull Player player, @NotNull UntagReason untagReason) { if (!isInCombat(player)) { return; } TagInformation tagInformation = getTagInformation(player); if (tagInformation == null) { return; } UUID playerId = player.getUniqueId(); this.combatMap.remove(playerId); ICombatLogX plugin = getCombatLogX(); ITimerManager timerManager = plugin.getTimerManager(); timerManager.remove(player); PluginManager pluginManager = Bukkit.getPluginManager(); List enemyList = tagInformation.getEnemies(); for (Entity entity : enemyList) { PlayerEnemyRemoveEvent event = new PlayerEnemyRemoveEvent(player, untagReason, entity); pluginManager.callEvent(event); } PlayerUntagEvent event = new PlayerUntagEvent(player, untagReason, enemyList); pluginManager.callEvent(event); } @Override public void untag(@NotNull Player player, @NotNull Entity enemy, @NotNull UntagReason untagReason) { if (!isInCombat(player)) { return; } TagInformation tagInformation = getTagInformation(player); if (tagInformation == null || !tagInformation.isEnemy(enemy)) { return; } tagInformation.removeEnemy(enemy); PluginManager pluginManager = Bukkit.getPluginManager(); PlayerEnemyRemoveEvent event = new PlayerEnemyRemoveEvent(player, untagReason, enemy); pluginManager.callEvent(event); if (tagInformation.isExpired()) { untag(player, untagReason); } } @Override public boolean isInCombat(@NotNull Player player) { TagInformation tagInformation = getTagInformation(player); return (tagInformation != null); } @Override public @NotNull Set getPlayerIdsInCombat() { Set playerIdSet = this.combatMap.keySet(); return Collections.unmodifiableSet(playerIdSet); } @Override public @NotNull List getPlayersInCombat() { Set playerIdSet = getPlayerIdsInCombat(); List playerList = new ArrayList<>(); for (UUID playerId : playerIdSet) { Player player = Bukkit.getPlayer(playerId); if (player != null) { playerList.add(player); } } return Collections.unmodifiableList(playerList); } @Override public TagInformation getTagInformation(@NotNull Player player) { UUID playerId = player.getUniqueId(); return this.combatMap.get(playerId); } @Override public int getMaxTimerSeconds(@NotNull Player player) { ICombatLogX plugin = getCombatLogX(); MainConfiguration configuration = plugin.getConfiguration(); TimerType timerType = configuration.getTimerType(); if (timerType == TimerType.PERMISSION) { return getPermissionTimerSeconds(player); } return getGlobalTimerSeconds(); } @Override public @Nullable Permission getBypassPermission() { ICombatLogX combatLogX = getCombatLogX(); MainConfiguration configuration = combatLogX.getConfiguration(); return configuration.getBypassPermission(); } @Override public boolean canBypass(@NotNull Player player) { Permission bypassPermission = getBypassPermission(); if (bypassPermission == null) { return false; } return player.hasPermission(bypassPermission); } private int getGlobalTimerSeconds() { ICombatLogX combatLogX = getCombatLogX(); MainConfiguration configuration = combatLogX.getConfiguration(); return configuration.getDefaultTimer(); } private int getPermissionTimerSeconds(@NotNull Player player) { int defaultTimer = getGlobalTimerSeconds(); Set permissionAttachmentInfoSet = player.getEffectivePermissions(); if (permissionAttachmentInfoSet.isEmpty()) { return defaultTimer; } Set permissionNumberStrings = new HashSet<>(); for (PermissionAttachmentInfo permissionAttachmentInfo : permissionAttachmentInfoSet) { if (!permissionAttachmentInfo.getValue()) { continue; } String permissionName = permissionAttachmentInfo.getPermission(); if (permissionName.startsWith("combatlogx.timer.")) { String timerPart = permissionName.substring("combatlogx.timer.".length()); permissionNumberStrings.add(timerPart); } } if (permissionNumberStrings.isEmpty()) { return defaultTimer; } int lowestTimer = Integer.MAX_VALUE; boolean foundValue = false; for (String permission : permissionNumberStrings) { try { int value = Integer.parseInt(permission); lowestTimer = Math.min(lowestTimer, value); foundValue = true; } catch (NumberFormatException ignored) { // Ignored Exception } } return (foundValue ? lowestTimer : defaultTimer); } private @NotNull Component getUnknownEnemy(@NotNull Player player) { ICombatLogX plugin = getCombatLogX(); LanguageManager languageManager = plugin.getLanguageManager(); return languageManager.getMessage(player, "placeholder.unknown-enemy"); } private @NotNull Component getEntityName(@NotNull Player player, @Nullable Entity entity) { if (entity == null) { return getUnknownEnemy(player); } if (PaperChecker.hasNativeComponentSupport()) { Component customName = PaperHelper.getCustomName(entity); if (customName != null) { return customName; } } ICombatLogX plugin = getCombatLogX(); MultiVersionHandler multiVersionHandler = plugin.getMultiVersionHandler(); EntityHandler entityHandler = multiVersionHandler.getEntityHandler(); String entityName = entityHandler.getName(entity); return Component.text(entityName); } private @NotNull Component getEntityType(@NotNull Player player, @Nullable Entity entity) { if (entity == null) { return getUnknownEnemy(player); } EntityType entityType = entity.getType(); String entityTypeName = entityType.name(); return Component.text(entityTypeName); } private boolean failsPreTagEvent(@NotNull Player player, @Nullable Entity enemy, @NotNull TagType tagType, @NotNull TagReason tagReason) { PlayerPreTagEvent event = new PlayerPreTagEvent(player, enemy, tagType, tagReason); PluginManager pluginManager = Bukkit.getPluginManager(); pluginManager.callEvent(event); return event.isCancelled(); } private void sendTagMessage(@NotNull Player player, @Nullable Entity enemy, @NotNull TagType tagType, @NotNull TagReason tagReason) { if (tagType == TagType.DAMAGE) { return; } Component enemyName = getEntityName(player, enemy); Component enemyType = getEntityType(player, enemy); String tagReasonString = tagReason.name().toLowerCase(Locale.US); String tagTypeString = tagType.name().toLowerCase(Locale.US); Replacer enemyNameReplacer = new ComponentReplacer("{enemy}", enemyName); Replacer enemyTypeReplacer = new ComponentReplacer("{mob_type}", enemyType); String languagePath = ("tagged." + tagReasonString + "." + tagTypeString); ICombatLogX plugin = getCombatLogX(); LanguageManager languageManager = plugin.getLanguageManager(); languageManager.sendModifiableMessageWithPrefix(player, languagePath, enemyNameReplacer, enemyTypeReplacer); } private double getServerTPS() { if (PaperChecker.isPaper()) { try { return PaperHelper.getServer1mTps(); } catch (NoSuchMethodError ignored) { // Ignored Error } } ICombatLogX plugin = getCombatLogX(); MultiVersionHandler multiVersionHandler = plugin.getMultiVersionHandler(); ServerHandler serverHandler = multiVersionHandler.getServerHandler(); return serverHandler.getServerTps1m(); } } ================================================ FILE: plugin/src/main/java/com/github/sirblobman/combatlogx/manager/CrystalManager.java ================================================ package com.github.sirblobman.combatlogx.manager; import java.util.Map; import java.util.UUID; import java.util.concurrent.ConcurrentHashMap; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import org.bukkit.Bukkit; import org.bukkit.entity.Entity; import org.bukkit.entity.Player; import com.github.sirblobman.combatlogx.api.ICombatLogX; import com.github.sirblobman.combatlogx.api.manager.ICrystalManager; public final class CrystalManager extends Manager implements ICrystalManager { private final Map endCrystalMap; public CrystalManager(@NotNull ICombatLogX plugin) { super(plugin); this.endCrystalMap = new ConcurrentHashMap<>(); } @Override public @Nullable Player getPlacer(@NotNull Entity crystal) { UUID entityId = crystal.getUniqueId(); UUID playerId = this.endCrystalMap.get(entityId); if (playerId == null) { return null; } return Bukkit.getPlayer(playerId); } @Override public void setPlacer(@NotNull Entity crystal, @NotNull Player player) { UUID entityId = crystal.getUniqueId(); UUID playerId = player.getUniqueId(); this.endCrystalMap.put(entityId, playerId); } @Override public void remove(@NotNull UUID crystalId) { this.endCrystalMap.remove(crystalId); } } ================================================ FILE: plugin/src/main/java/com/github/sirblobman/combatlogx/manager/DeathManager.java ================================================ package com.github.sirblobman.combatlogx.manager; import java.util.Collections; import java.util.List; import java.util.Map; import java.util.UUID; import java.util.concurrent.ConcurrentHashMap; import org.jetbrains.annotations.NotNull; import org.bukkit.entity.Entity; import org.bukkit.entity.Player; import com.github.sirblobman.combatlogx.api.ICombatLogX; import com.github.sirblobman.combatlogx.api.manager.IDeathManager; public final class DeathManager extends Manager implements IDeathManager { private final Map> killedPlayerMap; public DeathManager(@NotNull ICombatLogX plugin) { super(plugin); this.killedPlayerMap = new ConcurrentHashMap<>(); } @Override public void kill(@NotNull Player player, @NotNull List enemyList) { UUID playerId = player.getUniqueId(); this.killedPlayerMap.put(playerId, enemyList); player.setHealth(0.0D); } @Override public boolean wasPunishKilled(@NotNull Player player) { UUID playerId = player.getUniqueId(); return this.killedPlayerMap.containsKey(playerId); } @Override public boolean stopTracking(@NotNull Player player) { UUID playerId = player.getUniqueId(); List oldValue = this.killedPlayerMap.remove(playerId); return (oldValue != null); } @Override public @NotNull List getTrackedEnemies(@NotNull Player player) { UUID playerId = player.getUniqueId(); return this.killedPlayerMap.getOrDefault(playerId, Collections.emptyList()); } } ================================================ FILE: plugin/src/main/java/com/github/sirblobman/combatlogx/manager/ForgiveManager.java ================================================ package com.github.sirblobman.combatlogx.manager; import java.util.Map; import java.util.UUID; import java.util.concurrent.ConcurrentHashMap; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import org.bukkit.OfflinePlayer; import org.bukkit.configuration.file.YamlConfiguration; import com.github.sirblobman.api.configuration.PlayerDataManager; import com.github.sirblobman.combatlogx.api.ICombatLogX; import com.github.sirblobman.combatlogx.api.manager.IForgiveManager; import com.github.sirblobman.combatlogx.api.object.CombatTag; public final class ForgiveManager extends Manager implements IForgiveManager { private final Map requestMap; public ForgiveManager(@NotNull ICombatLogX plugin) { super(plugin); this.requestMap = new ConcurrentHashMap<>(); } @Override public boolean getToggleValue(@NotNull OfflinePlayer player) { ICombatLogX plugin = getCombatLogX(); PlayerDataManager playerDataManager = plugin.getPlayerDataManager(); YamlConfiguration configuration = playerDataManager.get(player); return configuration.getBoolean("forgive-toggle", false); } @Override public void setToggle(@NotNull OfflinePlayer player, boolean value) { ICombatLogX plugin = getCombatLogX(); PlayerDataManager playerDataManager = plugin.getPlayerDataManager(); YamlConfiguration configuration = playerDataManager.get(player); configuration.set("forgive-toggle", value); playerDataManager.save(player); } @Override public @Nullable CombatTag getActiveRequest(@NotNull OfflinePlayer player) { UUID playerId = player.getUniqueId(); CombatTag combatTag = this.requestMap.get(playerId); if (combatTag == null) { return null; } if (combatTag.isExpired()) { removeRequest(player); return null; } return combatTag; } @Override public void setRequest(@NotNull OfflinePlayer player, @NotNull CombatTag tag) { UUID playerId = player.getUniqueId(); this.requestMap.put(playerId, tag); } @Override public void removeRequest(@NotNull OfflinePlayer player) { UUID playerId = player.getUniqueId(); this.requestMap.remove(playerId); } } ================================================ FILE: plugin/src/main/java/com/github/sirblobman/combatlogx/manager/Manager.java ================================================ package com.github.sirblobman.combatlogx.manager; import org.jetbrains.annotations.NotNull; import com.github.sirblobman.api.configuration.PlayerDataManager; import com.github.sirblobman.combatlogx.api.ICombatLogX; import com.github.sirblobman.combatlogx.api.ICombatLogXNeeded; public abstract class Manager implements ICombatLogXNeeded { private final ICombatLogX plugin; public Manager(@NotNull ICombatLogX plugin) { this.plugin = plugin; } @Override public final @NotNull ICombatLogX getCombatLogX() { return this.plugin; } protected final @NotNull PlayerDataManager getPlayerDataManager() { ICombatLogX plugin = getCombatLogX(); return plugin.getPlayerDataManager(); } protected final void printDebug(String @NotNull ... messages) { ICombatLogX plugin = getCombatLogX(); plugin.printDebug(messages); } } ================================================ FILE: plugin/src/main/java/com/github/sirblobman/combatlogx/manager/PlaceholderManager.java ================================================ package com.github.sirblobman.combatlogx.manager; import java.util.ArrayList; import java.util.Collection; import java.util.Collections; import java.util.LinkedHashMap; import java.util.List; import java.util.Map; import java.util.regex.Matcher; import java.util.regex.Pattern; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import org.bukkit.entity.Entity; import org.bukkit.entity.Player; import com.github.sirblobman.combatlogx.api.ICombatLogX; import com.github.sirblobman.combatlogx.api.manager.IPlaceholderManager; import com.github.sirblobman.combatlogx.api.placeholder.IPlaceholderExpansion; import com.github.sirblobman.combatlogx.api.placeholder.PlaceholderHelper; import com.github.sirblobman.combatlogx.api.utility.CommandHelper; import com.github.sirblobman.api.shaded.adventure.text.Component; public final class PlaceholderManager extends Manager implements IPlaceholderManager { private static final Pattern BRACKET_PLACEHOLDER_PATTERN; static { BRACKET_PLACEHOLDER_PATTERN = Pattern.compile("\\{(\\S+)}"); } private final Map expansionMap; public PlaceholderManager(@NotNull ICombatLogX plugin) { super(plugin); this.expansionMap = new LinkedHashMap<>(); } @Override public @Nullable IPlaceholderExpansion getPlaceholderExpansion(@NotNull String id) { return this.expansionMap.get(id); } @Override public @NotNull List getPlaceholderExpansions() { Collection valueCollection = this.expansionMap.values(); List valueList = new ArrayList<>(valueCollection); return Collections.unmodifiableList(valueList); } @Override public void registerPlaceholderExpansion(@NotNull IPlaceholderExpansion expansion) { String expansionId = expansion.getId(); IPlaceholderExpansion oldRegistry = this.expansionMap.putIfAbsent(expansionId, expansion); if (oldRegistry != null) { String errorMessage = "A placeholder expansion with id '" + expansionId + "' is already registered."; throw new IllegalArgumentException(errorMessage); } } @Override public @Nullable String getPlaceholderReplacement(@NotNull Player player, @NotNull List enemyList, @NotNull String placeholder) { int underscoreIndex = placeholder.indexOf('_'); if (underscoreIndex == -1) { return null; } String expansionId = placeholder.substring(0, underscoreIndex); IPlaceholderExpansion expansion = getPlaceholderExpansion(expansionId); if (expansion == null) { return null; } String subPlaceholder = placeholder.substring(underscoreIndex + 1); return expansion.getReplacementString(player, enemyList, subPlaceholder); } @Override public @Nullable Component getPlaceholderReplacementComponent(@NotNull Player player, @NotNull List enemyList, @NotNull String placeholder) { int underscoreIndex = placeholder.indexOf('_'); if (underscoreIndex == -1) { return null; } String expansionId = placeholder.substring(0, underscoreIndex); IPlaceholderExpansion expansion = getPlaceholderExpansion(expansionId); if (expansion == null) { return null; } String subPlaceholder = placeholder.substring(underscoreIndex + 1); return expansion.getReplacement(player, enemyList, subPlaceholder); } @Override public @NotNull String replaceAll(@NotNull Player player, @NotNull List enemyList, @NotNull String string) { StringBuffer buffer = new StringBuffer(); Matcher matcher = BRACKET_PLACEHOLDER_PATTERN.matcher(string); while (matcher.find()) { String placeholder = matcher.group(1); String replacement = getPlaceholderReplacement(player, enemyList, placeholder); if (replacement != null) { matcher.appendReplacement(buffer, replacement); } } matcher.appendTail(buffer); String replaced = buffer.toString(); return PlaceholderHelper.replacePlaceholderAPI(player, replaced); } @Override public void runReplacedCommands(@NotNull Player player, @NotNull List enemyList, @NotNull Iterable commands) { ICombatLogX plugin = getCombatLogX(); for (String originalCommand : commands) { String replacedCommand = replaceAll(player, enemyList, originalCommand); if (replacedCommand.startsWith("[PLAYER]")) { String playerCommand = replacedCommand.substring(8); CommandHelper.runSync(plugin, () -> CommandHelper.runAsPlayer(plugin, player, playerCommand)); } else if (replacedCommand.startsWith("[OP]")) { String opCommand = replacedCommand.substring(4); CommandHelper.runSync(plugin, () -> CommandHelper.runAsOperator(plugin, player, opCommand)); } else { CommandHelper.runSync(plugin, () -> CommandHelper.runAsConsole(plugin, replacedCommand)); } } } } ================================================ FILE: plugin/src/main/java/com/github/sirblobman/combatlogx/manager/PunishManager.java ================================================ package com.github.sirblobman.combatlogx.manager; import java.util.List; import org.jetbrains.annotations.NotNull; import org.bukkit.Bukkit; import org.bukkit.OfflinePlayer; import org.bukkit.configuration.file.YamlConfiguration; import org.bukkit.entity.Entity; import org.bukkit.entity.Player; import org.bukkit.plugin.PluginManager; import com.github.sirblobman.api.configuration.PlayerDataManager; import com.github.sirblobman.combatlogx.api.ICombatLogX; import com.github.sirblobman.combatlogx.api.configuration.CommandConfiguration; import com.github.sirblobman.combatlogx.api.configuration.PunishConfiguration; import com.github.sirblobman.combatlogx.api.event.PlayerPunishEvent; import com.github.sirblobman.combatlogx.api.manager.IDeathManager; import com.github.sirblobman.combatlogx.api.manager.IPlaceholderManager; import com.github.sirblobman.combatlogx.api.manager.IPunishManager; import com.github.sirblobman.combatlogx.api.object.KillTime; import com.github.sirblobman.combatlogx.api.object.SpecialPunishCommand; import com.github.sirblobman.combatlogx.api.object.UntagReason; public final class PunishManager extends Manager implements IPunishManager { public PunishManager(@NotNull ICombatLogX plugin) { super(plugin); } @Override public boolean punish(@NotNull Player player, @NotNull UntagReason punishReason, @NotNull List enemyList) { PlayerPunishEvent punishEvent = new PlayerPunishEvent(player, punishReason, enemyList); PluginManager pluginManager = Bukkit.getPluginManager(); pluginManager.callEvent(punishEvent); if (punishEvent.isCancelled()) { return false; } increasePunishmentCount(player); runKillCheck(player, enemyList); ICombatLogX plugin = getCombatLogX(); CommandConfiguration commandConfiguration = plugin.getCommandConfiguration(); List punishCommandList = commandConfiguration.getPunishCommands(); if (!punishCommandList.isEmpty()) { runPunishCommands(player, enemyList, punishCommandList); } if (commandConfiguration.isSpecialPunishCommandsEnabled()) { runSpecialPunishments(player, enemyList); } return true; } @Override public long getPunishmentCount(@NotNull OfflinePlayer player) { ICombatLogX combatLogX = getCombatLogX(); PunishConfiguration punishConfiguration = combatLogX.getPunishConfiguration(); if (punishConfiguration.isEnablePunishmentCounter()) { PlayerDataManager playerDataManager = getPlayerDataManager(); if (playerDataManager.hasData(player)) { YamlConfiguration playerData = playerDataManager.get(player); return playerData.getLong("punishment-count", 0L); } return 0L; } return 0L; } private void increasePunishmentCount(@NotNull OfflinePlayer player) { ICombatLogX combatLogX = getCombatLogX(); PunishConfiguration punishConfiguration = combatLogX.getPunishConfiguration(); if (!punishConfiguration.isEnablePunishmentCounter()) { return; } PlayerDataManager playerDataManager = getPlayerDataManager(); YamlConfiguration playerData = playerDataManager.get(player); long currentCount = playerData.getLong("punishment-count", 0L); playerData.set("punishment-count", currentCount + 1L); playerDataManager.save(player); } @Override public void resetPunishmentCount(@NotNull OfflinePlayer player) { ICombatLogX combatLogX = getCombatLogX(); PunishConfiguration punishConfiguration = combatLogX.getPunishConfiguration(); if (!punishConfiguration.isEnablePunishmentCounter()) { return; } PlayerDataManager playerDataManager = getPlayerDataManager(); YamlConfiguration playerData = playerDataManager.get(player); playerData.set("punishment-count", 0L); playerDataManager.save(player); } private void runKillCheck(@NotNull Player player, @NotNull List enemyList) { ICombatLogX combatLogX = getCombatLogX(); PunishConfiguration punishConfiguration = combatLogX.getPunishConfiguration(); KillTime killTime = punishConfiguration.getKillTime(); switch (killTime) { case JOIN: killOnJoin(player); break; case QUIT: killOnQuit(player, enemyList); break; default: break; } } private void killOnJoin(@NotNull OfflinePlayer player) { ICombatLogX plugin = getCombatLogX(); PlayerDataManager playerDataManager = plugin.getPlayerDataManager(); YamlConfiguration playerData = playerDataManager.get(player); playerData.set("kill-on-join", true); playerDataManager.save(player); } private void killOnQuit(@NotNull Player player, @NotNull List enemyList) { ICombatLogX plugin = getCombatLogX(); IDeathManager deathManager = plugin.getDeathManager(); deathManager.kill(player, enemyList); } private void runPunishCommands(@NotNull Player player, @NotNull List enemyList, @NotNull List punishCommandList) { if (punishCommandList.isEmpty()) { return; } ICombatLogX plugin = getCombatLogX(); IPlaceholderManager placeholderManager = plugin.getPlaceholderManager(); placeholderManager.runReplacedCommands(player, enemyList, punishCommandList); } private void runSpecialPunishments(@NotNull Player player, @NotNull List enemyList) { printDebug("Detected runSpecialPunishments method..."); long punishmentCount = getPunishmentCount(player); printDebug("Punishment Count: " + punishmentCount); ICombatLogX combatLogX = getCombatLogX(); CommandConfiguration commandConfiguration = combatLogX.getCommandConfiguration(); List specialPunishCommandList = commandConfiguration.getSpecialPunishCommandList(); boolean reset = false; for (SpecialPunishCommand specialPunishment : specialPunishCommandList) { int min = specialPunishment.getAmountMin(); int max = specialPunishment.getAmountMax(); if (punishmentCount < min || punishmentCount > max) { continue; } if (specialPunishment.isReset()) { reset = true; } List commandList = specialPunishment.getCommands(); runPunishCommands(player, enemyList, commandList); } if (reset) { resetPunishmentCount(player); } } } ================================================ FILE: plugin/src/main/java/com/github/sirblobman/combatlogx/placeholder/BasePlaceholderExpansion.java ================================================ package com.github.sirblobman.combatlogx.placeholder; import java.text.DecimalFormat; import java.util.Arrays; import java.util.List; import java.util.UUID; import java.util.concurrent.TimeUnit; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import org.bukkit.Bukkit; import org.bukkit.Location; import org.bukkit.World; import org.bukkit.entity.Entity; import org.bukkit.entity.EntityType; import org.bukkit.entity.LivingEntity; import org.bukkit.entity.Player; import org.bukkit.plugin.PluginManager; import com.github.sirblobman.api.language.LanguageManager; import com.github.sirblobman.api.nms.EntityHandler; import com.github.sirblobman.api.nms.MultiVersionHandler; import com.github.sirblobman.api.utility.paper.PaperChecker; import com.github.sirblobman.api.utility.paper.PaperHelper; import com.github.sirblobman.combatlogx.api.ICombatLogX; import com.github.sirblobman.combatlogx.api.configuration.PunishConfiguration; import com.github.sirblobman.combatlogx.api.manager.ICombatManager; import com.github.sirblobman.combatlogx.api.manager.IPunishManager; import com.github.sirblobman.combatlogx.api.object.CombatTag; import com.github.sirblobman.combatlogx.api.object.TagInformation; import com.github.sirblobman.combatlogx.api.placeholder.IPlaceholderExpansion; import com.github.sirblobman.api.shaded.adventure.text.Component; import com.github.sirblobman.api.shaded.adventure.text.format.NamedTextColor; import com.github.sirblobman.api.shaded.adventure.text.minimessage.MiniMessage; import com.github.sirblobman.api.shaded.adventure.text.serializer.legacy.LegacyComponentSerializer; import me.clip.placeholderapi.PlaceholderAPI; public final class BasePlaceholderExpansion implements IPlaceholderExpansion { private final ICombatLogX plugin; public BasePlaceholderExpansion(@NotNull ICombatLogX plugin) { this.plugin = plugin; } @Override public @NotNull ICombatLogX getCombatLogX() { return this.plugin; } @Override public @NotNull String getId() { return "combatlogx"; } @Override public @Nullable Component getReplacement(@NotNull Player player, @NotNull List enemyList, @NotNull String placeholder) { switch (placeholder) { case "enemy_count": return getEnemyCount(player); case "in_combat": return getInCombat(player); case "player": return Component.text(player.getName()); case "punishment_count": return getPunishmentCount(player); case "status": return getStatus(player); case "tag_count": return getTagCount(player); case "time_left": return getTimeLeft(player); case "time_left_decimal": return getTimeLeftDecimal(player); default: break; } if (placeholder.startsWith("time_left_")) { if (placeholder.startsWith("time_left_decimal_")) { String numberString = placeholder.substring("time_left_decimal_".length()); try { int index = (Integer.parseInt(numberString) - 1); return getTimeLeftDecimalSpecific(player, index); } catch (NumberFormatException ex) { return null; } } String numberString = placeholder.substring("time_left_".length()); try { int index = (Integer.parseInt(numberString) - 1); return getTimeLeftSpecific(player, index); } catch (NumberFormatException ex) { return null; } } if (placeholder.startsWith("current_enemy_")) { Entity currentEnemy = getSpecificEnemy(enemyList, 0); String enemyPlaceholder = placeholder.substring("current_enemy_".length()); return getEnemyPlaceholder(player, currentEnemy, enemyPlaceholder); } if (placeholder.startsWith("specific_enemy_")) { String subPlaceholder = placeholder.substring("specific_enemy_".length()); int nextUnderscore = subPlaceholder.indexOf('_'); if (nextUnderscore == -1) { return null; } int enemyIndex; try { String enemyIdString = subPlaceholder.substring(0, nextUnderscore); enemyIndex = (Integer.parseInt(enemyIdString) - 1); } catch (NumberFormatException ex) { return null; } Entity specificEnemy = getSpecificEnemy(enemyList, enemyIndex); String enemyPlaceholder = subPlaceholder.substring(nextUnderscore + 1); return getEnemyPlaceholder(player, specificEnemy, enemyPlaceholder); } return null; } private @Nullable Component getEnemyPlaceholder(@NotNull Player player, @Nullable Entity enemy, @NotNull String placeholder) { if (enemy == null) { return getUnknownEnemy(player); } switch (placeholder) { case "name": return getEnemyName(enemy); case "type": return getEnemyType(enemy); case "display_name": return getEnemyDisplayName(enemy); case "health": return getEnemyHealth(player, enemy); case "health_rounded": return getEnemyHealthRounded(enemy); case "hearts": return getEnemyHearts(enemy); case "hearts_count": return getEnemyHeartsCount(enemy); case "world": return getEnemyWorld(enemy); case "x": return getEnemyX(enemy); case "y": return getEnemyY(enemy); case "z": return getEnemyZ(enemy); default: break; } PluginManager pluginManager = Bukkit.getPluginManager(); if (pluginManager.isPluginEnabled("PlaceholderAPI") && enemy instanceof Player) { Player enemyPlayer = (Player) enemy; if (enemyPlayer.isOnline()) { return getEnemyPlaceholderAPI(enemyPlayer, placeholder); } } return null; } private @Nullable Entity getSpecificEnemy(@NotNull List enemyList, int index) { if (enemyList.isEmpty()) { return null; } int enemyListSize = enemyList.size(); if (index >= enemyListSize) { return null; } return enemyList.get(index); } private @NotNull Component getEnemyCount(@NotNull Player player) { ICombatLogX combatLogX = getCombatLogX(); ICombatManager combatManager = combatLogX.getCombatManager(); TagInformation tagInformation = combatManager.getTagInformation(player); if (tagInformation == null) { return Component.text(0); } List enemyIdList = tagInformation.getEnemyIds(); int enemyIdListSize = enemyIdList.size(); return Component.text(enemyIdListSize); } private @NotNull Component getInCombat(@NotNull Player player) { ICombatLogX combatLogX = getCombatLogX(); ICombatManager combatManager = combatLogX.getCombatManager(); boolean inCombat = combatManager.isInCombat(player); LanguageManager languageManager = combatLogX.getLanguageManager(); String keyPart = ((inCombat ? "" : "not-") + "in-combat"); String fullKey = ("placeholder.status." + keyPart); return languageManager.getMessage(player, fullKey); } private @NotNull Component getPunishmentCount(@NotNull Player player) { ICombatLogX combatLogX = getCombatLogX(); PunishConfiguration punishConfiguration = combatLogX.getPunishConfiguration(); if (punishConfiguration.isEnablePunishmentCounter()) { IPunishManager punishManager = combatLogX.getPunishManager(); long punishmentCount = punishManager.getPunishmentCount(player); return Component.text(punishmentCount); } return Component.text(0); } private @NotNull Component getStatus(@NotNull Player player) { ICombatLogX combatLogX = getCombatLogX(); ICombatManager combatManager = combatLogX.getCombatManager(); boolean inCombat = combatManager.isInCombat(player); LanguageManager languageManager = combatLogX.getLanguageManager(); String keyPart = (inCombat ? "fighting" : "idle"); String fullKey = ("placeholder.status." + keyPart); return languageManager.getMessage(player, fullKey); } private @NotNull Component getTagCount(@NotNull Player player) { ICombatLogX combatLogX = getCombatLogX(); ICombatManager combatManager = combatLogX.getCombatManager(); TagInformation tagInformation = combatManager.getTagInformation(player); if (tagInformation == null || tagInformation.isExpired()) { return Component.text(0); } List tagList = tagInformation.getTags(); int tagListSize = tagList.size(); return Component.text(tagListSize); } private @NotNull Component getTimeLeft(@NotNull Player player) { ICombatLogX combatLogX = getCombatLogX(); LanguageManager languageManager = combatLogX.getLanguageManager(); Component zero = languageManager.getMessage(player, "placeholder.time-left-zero"); ICombatManager combatManager = combatLogX.getCombatManager(); TagInformation tagInformation = combatManager.getTagInformation(player); if (tagInformation == null || tagInformation.isExpired()) { return zero; } long expireMillis = tagInformation.getExpireMillisCombined(); long systemMillis = System.currentTimeMillis(); long subtractMillis = (expireMillis - systemMillis); long timeLeftMillis = Math.max(0L, subtractMillis); if (timeLeftMillis == 0L) { return zero; } long secondsLeft = TimeUnit.MILLISECONDS.toSeconds(timeLeftMillis); if (secondsLeft <= 0L) { return zero; } return Component.text(secondsLeft); } private @NotNull Component getTimeLeftSpecific(@NotNull Player player, int index) { ICombatLogX combatLogX = getCombatLogX(); LanguageManager languageManager = combatLogX.getLanguageManager(); Component zero = languageManager.getMessage(player, "placeholder.time-left-zero"); ICombatManager combatManager = combatLogX.getCombatManager(); TagInformation tagInformation = combatManager.getTagInformation(player); if (tagInformation == null || tagInformation.isExpired()) { return zero; } List tagList = tagInformation.getTags(); int tagListSize = tagList.size(); if (index < 0 || index >= tagListSize) { return zero; } CombatTag combatTag = tagList.get(index); long expireMillis = combatTag.getExpireMillis(); long systemMillis = System.currentTimeMillis(); long subtractMillis = (expireMillis - systemMillis); long timeLeftMillis = Math.max(0L, subtractMillis); if (timeLeftMillis == 0L) { return zero; } long secondsLeft = TimeUnit.MILLISECONDS.toSeconds(timeLeftMillis); if (secondsLeft <= 0L) { return zero; } return Component.text(secondsLeft); } private @NotNull Component getTimeLeftDecimal(@NotNull Player player) { ICombatLogX combatLogX = getCombatLogX(); LanguageManager languageManager = combatLogX.getLanguageManager(); Component zero = languageManager.getMessage(player, "placeholder.time-left-zero"); ICombatManager combatManager = combatLogX.getCombatManager(); TagInformation tagInformation = combatManager.getTagInformation(player); if (tagInformation == null || tagInformation.isExpired()) { return zero; } long expireMillis = tagInformation.getExpireMillisCombined(); long systemMillis = System.currentTimeMillis(); long subtractMillis = (expireMillis - systemMillis); double timeLeftMillis = Math.max(0.0D, subtractMillis); if (timeLeftMillis <= 0.0D) { return zero; } double secondsLeft = (timeLeftMillis / 1_000.0D); if (secondsLeft <= 0.0D) { return zero; } DecimalFormat decimalFormat = languageManager.getDecimalFormat(player); String timeLeftString = decimalFormat.format(secondsLeft); return Component.text(timeLeftString); } private @NotNull Component getTimeLeftDecimalSpecific(@NotNull Player player, int index) { ICombatLogX combatLogX = getCombatLogX(); LanguageManager languageManager = combatLogX.getLanguageManager(); Component zero = languageManager.getMessage(player, "placeholder.time-left-zero"); ICombatManager combatManager = combatLogX.getCombatManager(); TagInformation tagInformation = combatManager.getTagInformation(player); if (tagInformation == null || tagInformation.isExpired()) { return zero; } List tagList = tagInformation.getTags(); int tagListSize = tagList.size(); if (index < 0 || index >= tagListSize) { return zero; } CombatTag combatTag = tagList.get(index); long expireMillis = combatTag.getExpireMillis(); long systemMillis = System.currentTimeMillis(); long subtractMillis = (expireMillis - systemMillis); double timeLeftMillis = Math.max(0.0D, subtractMillis); if (timeLeftMillis <= 0.0D) { return zero; } double secondsLeft = (timeLeftMillis / 1_000.0D); if (secondsLeft <= 0.0D) { return zero; } DecimalFormat decimalFormat = languageManager.getDecimalFormat(player); String timeLeftString = decimalFormat.format(secondsLeft); return Component.text(timeLeftString); } private @NotNull Component getUnknownEnemy(@NotNull Player player) { LanguageManager languageManager = plugin.getLanguageManager(); return languageManager.getMessage(player, "placeholder.unknown-enemy"); } private @NotNull Component getEnemyName(@NotNull Entity entity) { ICombatLogX plugin = getCombatLogX(); MultiVersionHandler multiVersionHandler = plugin.getMultiVersionHandler(); EntityHandler entityHandler = multiVersionHandler.getEntityHandler(); String entityName = entityHandler.getName(entity); return Component.text(entityName); } private @NotNull Component getEnemyDisplayName(@NotNull Entity enemy) { if (PaperChecker.hasNativeComponentSupport()) { Component customName = PaperHelper.getCustomName(enemy); if (customName != null) { return customName; } } return getEnemyName(enemy); } private @NotNull Component getEnemyType(@NotNull Entity enemy) { EntityType entityType = enemy.getType(); String entityTypeName = entityType.name(); return Component.text(entityTypeName); } private @NotNull Component getEnemyHealth(@NotNull Player player, @NotNull Entity enemy) { double enemyHealth = 0.0D; if (enemy instanceof LivingEntity) { enemyHealth = ((LivingEntity) enemy).getHealth(); } ICombatLogX combatLogX = getCombatLogX(); LanguageManager languageManager = combatLogX.getLanguageManager(); DecimalFormat decimalFormat = languageManager.getDecimalFormat(player); String healthString = decimalFormat.format(enemyHealth); return Component.text(healthString); } private @NotNull Component getEnemyHealthRounded(@NotNull Entity enemy) { double enemyHealth = 0.0D; if (enemy instanceof LivingEntity) { enemyHealth = ((LivingEntity) enemy).getHealth(); } long round = Math.round(enemyHealth); return Component.text(round); } private @NotNull Component getEnemyHearts(@NotNull Entity enemy) { double enemyHealth = 0.0D; if (enemy instanceof LivingEntity) { enemyHealth = ((LivingEntity) enemy).getHealth(); } double heartsDecimal = (enemyHealth / 2.0D); int hearts = (int) Math.round(Math.floor(heartsDecimal)); if (hearts > 10) { return Component.text(hearts); } char symbol = '❤'; char[] symbols = new char[hearts]; Arrays.fill(symbols, symbol); String heartsString = new String(symbols); return Component.text(heartsString, NamedTextColor.RED); } private @NotNull Component getEnemyHeartsCount(@NotNull Entity enemy) { double enemyHealth = 0.0D; if (enemy instanceof LivingEntity) { enemyHealth = ((LivingEntity) enemy).getHealth(); } double heartsDecimal = (enemyHealth / 2.0D); long hearts = Math.round(Math.floor(heartsDecimal)); return Component.text(hearts); } private @NotNull Component getEnemyWorld(@NotNull Entity enemy) { World world = enemy.getWorld(); String worldName = world.getName(); return Component.text(worldName); } private @NotNull Component getEnemyX(@NotNull Entity enemy) { Location location = enemy.getLocation(); int blockX = location.getBlockX(); return Component.text(blockX); } private @NotNull Component getEnemyY(@NotNull Entity enemy) { Location location = enemy.getLocation(); int blockY = location.getBlockY(); return Component.text(blockY); } private @NotNull Component getEnemyZ(@NotNull Entity enemy) { Location location = enemy.getLocation(); int blockZ = location.getBlockZ(); return Component.text(blockZ); } private @NotNull Component getEnemyPlaceholderAPI(@NotNull Player enemy, @NotNull String placeholder) { String placeholderString = ("{" + placeholder + "}"); String replacement = PlaceholderAPI.setBracketPlaceholders(enemy, placeholderString); if (replacement.contains("&")) { LegacyComponentSerializer serializer = LegacyComponentSerializer.legacyAmpersand(); return serializer.deserialize(replacement); } if (replacement.contains("§")) { LegacyComponentSerializer serializer = LegacyComponentSerializer.legacySection(); return serializer.deserialize(replacement); } ICombatLogX combatLogX = getCombatLogX(); LanguageManager languageManager = combatLogX.getLanguageManager(); MiniMessage miniMessage = languageManager.getMiniMessage(); return miniMessage.deserialize(replacement); } } ================================================ FILE: plugin/src/main/java/com/github/sirblobman/combatlogx/task/PlayerVulnerableTask.java ================================================ package com.github.sirblobman.combatlogx.task; import org.jetbrains.annotations.NotNull; import org.bukkit.entity.Player; import com.github.sirblobman.api.folia.details.EntityTaskDetails; import com.github.sirblobman.combatlogx.api.ICombatLogX; public final class PlayerVulnerableTask extends EntityTaskDetails { public PlayerVulnerableTask(@NotNull ICombatLogX plugin, @NotNull Player entity) { super(plugin.getPlugin(), entity); } @Override public void run() { Player entity = getEntity(); if (entity != null) { entity.setNoDamageTicks(0); } } } ================================================ FILE: plugin/src/main/java/com/github/sirblobman/combatlogx/task/TimerUpdateTask.java ================================================ package com.github.sirblobman.combatlogx.task; import java.util.Collections; import java.util.HashSet; import java.util.List; import java.util.Set; import org.jetbrains.annotations.NotNull; import org.bukkit.entity.Player; import com.github.sirblobman.api.folia.details.TaskDetails; import com.github.sirblobman.api.folia.scheduler.TaskScheduler; import com.github.sirblobman.combatlogx.api.ICombatLogX; import com.github.sirblobman.combatlogx.api.manager.ICombatManager; import com.github.sirblobman.combatlogx.api.manager.ITimerManager; import com.github.sirblobman.combatlogx.api.object.TagInformation; import com.github.sirblobman.combatlogx.api.object.TimerUpdater; public final class TimerUpdateTask extends TaskDetails implements ITimerManager { private final ICombatLogX plugin; private final Set timerUpdaterSet; public TimerUpdateTask(@NotNull ICombatLogX plugin) { super(plugin.getPlugin()); this.plugin = plugin; this.timerUpdaterSet = new HashSet<>(); } @Override public @NotNull ICombatLogX getCombatLogX() { return this.plugin; } @Override public @NotNull Set getTimerUpdaters() { return Collections.unmodifiableSet(this.timerUpdaterSet); } @Override public void addUpdaterTask(@NotNull TimerUpdater task) { this.timerUpdaterSet.add(task); } @Override public void run() { ICombatManager combatManager = this.plugin.getCombatManager(); List playerCombatList = combatManager.getPlayersInCombat(); playerCombatList.forEach(this::update); } @Override public void remove(@NotNull Player player) { Set timerUpdaterSet = getTimerUpdaters(); for (TimerUpdater timerUpdater : timerUpdaterSet) { timerUpdater.remove(player); } } public void register() { ICombatLogX plugin = getCombatLogX(); TaskScheduler scheduler = plugin.getFoliaHelper().getScheduler(); setDelay(5L); setPeriod(10L); scheduler.scheduleTask(this); } private void update(@NotNull Player player) { ICombatLogX plugin = getCombatLogX(); ICombatManager combatManager = plugin.getCombatManager(); TagInformation tagInformation = combatManager.getTagInformation(player); if (tagInformation == null) { return; } if (tagInformation.isExpired()) { return; } long timeLeftMillis = tagInformation.getMillisLeftCombined(); Set timerUpdaterSet = getTimerUpdaters(); for (TimerUpdater timerUpdater : timerUpdaterSet) { timerUpdater.update(player, timeLeftMillis); } } } ================================================ FILE: plugin/src/main/java/com/github/sirblobman/combatlogx/task/UntagTask.java ================================================ package com.github.sirblobman.combatlogx.task; import java.util.List; import org.jetbrains.annotations.NotNull; import org.bukkit.entity.Player; import com.github.sirblobman.api.folia.details.TaskDetails; import com.github.sirblobman.api.folia.scheduler.TaskScheduler; import com.github.sirblobman.combatlogx.api.ICombatLogX; import com.github.sirblobman.combatlogx.api.manager.ICombatManager; import com.github.sirblobman.combatlogx.api.object.TagInformation; import com.github.sirblobman.combatlogx.api.object.UntagReason; /** * This task is used to untag players from combat. It runs every 10 ticks. */ public final class UntagTask extends TaskDetails implements Runnable { private final ICombatLogX plugin; public UntagTask(@NotNull ICombatLogX plugin) { super(plugin.getPlugin()); this.plugin = plugin; } public void register() { ICombatLogX plugin = getCombatLogX(); TaskScheduler scheduler = plugin.getFoliaHelper().getScheduler(); setDelay(5L); setPeriod(10L); scheduler.scheduleTask(this); } @Override public void run() { ICombatLogX plugin = getCombatLogX(); ICombatManager combatManager = plugin.getCombatManager(); List playerCombatList = combatManager.getPlayersInCombat(); for (Player player : playerCombatList) { TagInformation tagInformation = combatManager.getTagInformation(player); if (tagInformation != null && tagInformation.isExpired()) { combatManager.untag(player, UntagReason.EXPIRE); } } } private @NotNull ICombatLogX getCombatLogX() { return this.plugin; } } ================================================ FILE: plugin/src/main/resources/commands.yml ================================================ # All commands in this configuration have some prefixes available: # [PLAYER] - Run the command as the player. # [OP] - Run the command as the player, but with "Server Operator" permissions (NOT recommended). # Any commands without a prefix will be executed by the server console. # All Commands in this configuration have some placeholders available: # Valid Placeholders: # {combatlogx_player} - The name of the player that was tagged. # {combatlogx_current_enemy_name} - The name of the enemy that tagged the player. The enemy can be unknown. # This is a list of commands that will be executed whenever a player is tagged. # # Set this to an empty list to disable all tag commands. # tag-command-list: [] # # Use the list format to add commands. # tag-command-list: # - "command1" # - "command2 with spaces" # - 'tellraw {player} {"text":"command 3 with internal quotes"}' tag-command-list: [ ] # This is a list of commands that will be executed whenever a player is untagged. # Valid Placeholders: # {combatlogx_player} - The name of the player that was untagged. # {combatlogx_enemy} - The name of the last known enemy that tagged the player. The enemy can be unknown. # # Set this to an empty list to disable all untag commands. # untag-command-list: [] # # Use the list format to add commands. # untag-command-list: # - "command1" # - "command2 with spaces" # - 'tellraw {player} {"text":"command 3 with internal quotes"}' untag-command-list: [ ] # This is a list of commands that will be used to punish players that log out during combat # Valid Placeholders: # {combatlogx_player} - The name of the player that is being punished. # # Set this to an empty list to disable all punishment commands. # punish-command-list: [] # # Use the list format to add commands. # punish-command-list: # - "command1" # - "command2 with spaces" # - 'tellraw {player} {"text":"command 3 with internal quotes"}' punish-command-list: [ ] # Set this option to 'true' to enable the 'special-punish-commands' option below. # Make sure to also set 'enable-punishment-counter' in the 'punish.yml' file to use these properly. special-punish-commands-enabled: false # This is a list of special punishment commands. # These commands will only execute if the player has logged out during combat for a specific amount of times. # Set the 'special-punish-commands-enabled' option to 'false' if you do not need these commands. special-punish-commands: example01: # How many combat logs are required to trigger this punishment? amount: min: 2 max: 4 # Should CombatLogX reset the punishment counter for the player to zero after executing this punishment? reset: false # What commands will be executed when this punishment is triggered? command-list: - "tempban {combatlogx_player} 15s You have been timed out for logging out during combat." example02: amount: min: 5 max: 9 reset: false command-list: - "tempban {combatlogx_player} 30m You have been timed out for logging out during combat after being warned." example03: amount: min: 10 max: 10 reset: true command-list: - "tempban {combatlogx_player} 1w You have been banned for one week due to logging out during combat multiple times." ================================================ FILE: plugin/src/main/resources/config.yml ================================================ # CombatLogX Configuration File # This file is in YAML format. # YAML Format Information: https://yaml.org/ # Make sure your editor is setup to use spaces instead of TAB characters. # You should also ensure that this file is saved as UTF-8. # DO NOT change this value or your config may be corrupted generated-by-version: "${pluginVersion}" # Should debug messages be sent to the console? # This option should be enabled if you are reporting an error or bug. # Default: false debug-mode: false # These are toggles for the different broadcast messages broadcast: on-load: true on-enable: true on-disable: true # This is a list of worlds that CombatLogX will ignore when tagging players. # World names are case-sensitive. "world" is not the same as "WoRlD" # Make sure you are not using the world aliases from Multiverse # # Empty list example # disabled-world-list: [] # # YAML List format example # disabled-world-list: # - "disabled_world_1" # - "DiSaBlEd_WoRlD_2" disabled-world-list: [ ] # This option changes the 'disabled-world-list' to a list of enabled worlds. # You can use this when you have fewer combat worlds than disabled worlds. # Default: false disabled-world-list-inverted: false # CombatLogX can link pets, such as wolves, cats, and other animals that can be tamed, to their owner. # This will only link the attacker, not the entity that was attacked. # Default: true link-pets: true # CombatLogX can link projectiles, such as arrows from skeletons, to their shooter. # This will only link the attacker, not the entity that was attacked. # Default: true link-projectiles: true # Which projectiles will be ignored when the 'link-projectiles' option is enabled? # If 'link-projectiles' is false, all projectiles will be ignored. # You can find a list of valid projectile types on the Spigot javadocs: # https://hub.spigotmc.org/javadocs/spigot/org/bukkit/entity/EntityType.html ignored-projectiles: - EGG - ENDER_PEARL - SNOWBALL # CombatLogX can link a fishing rod to the entity that cast it. # This will only link the attacker, not the entity that was attacked. # Default: true link-fishing-rod: true # CombatLogX can sometimes link TNT to the entity that caused it to explode. # This will only link the attacker, not the entity that was attacked. # Default: true link-tnt: true # CombatLogX can detect when players place end crystals. # This will only link the end crystal as an attacker when it explodes, not as a defender. # Default: true link-end-crystal: true timer: # CombatLogX has two different types of timers that you can select. # # GLOBAL: # Every player will be tagged for the length of the 'default-timer' value. # # PERMISSION: # Each player will be tagged for a different amount of time based on a permission. # Permission Format: "combatlogx.timer." # Permission Example: "combatlogx.timer.30" # Any player that does not have a permission will be tagged with the 'default-timer' value. # # Default: GLOBAL type: GLOBAL # This is the default amount of time that players will be tagged (in seconds). # This value will be used if the timer type is GLOBAL or if a permission cannot be detected. # Default: 10 default-timer: 10 # Which permission will prevent players from being tagged into combat? # You must add this permission manually. # OPs do not have this permission by default. # # Setting the value of this option to "" will disable the bypass feature. # Default: "combatlogx.bypass" bypass-permission: "combatlogx.bypass" # Should CombatLogX tag players when they shoot themselves with a projectile? # Default: false self-combat: false # Should CombatLogX remove players from combat when they are killed? # Default: true untag-on-death: true # Should CombatLogX remove players from combat when their enemy is killed? # This also removed combat if the enemy is a creeper and decides to explode. # Default: true untag-on-enemy-death: true # Should CombatLogX attempt to remove any damage cooldown effects from players during login and teleport events? # Default: true remove-no-damage-cooldown: true # How long must players wait between requests? # This cooldown is for the `/clx forgive request' command. # Default: 30 (seconds) forgive-request-cooldown: 30 # How long does a request last before it expires? # This cooldown is for the `/clx forgive request' command. # Default: 10 (seconds) forgive-request-expire: 10 # What is the minimum server TPS to allow tagging? minimum-tps: 15.0 # Which tag reasons are allowed? # You can see a full list here: # https://github.com/SirBlobman/CombatLogX/blob/main/api/src/main/java/com/github/sirblobman/combatlogx/api/object/TagReason.java # Default: all enabled-tag-reasons: - "*" ## END OF CONFIG.YML ## YOU ARE NOT FINISHED ## Don't forget to configure your expansions and other files ## commands.yml, language.yml, punish.yml ## /plugins/CombatLogX/expansions/ ================================================ FILE: plugin/src/main/resources/language/ar_sa.lang.yml ================================================ --- ## Extra Information: ## This is the default language file for CombatLogX. ## The default language is "en_us", also known as English (United States). ## Context will be added as YAML comments above the string. ## The color scheme for messages is gold, white, and sometimes red. ## Command feedback that is successful should always be green. ## Error messages should always be red. ## Variables in messages can be gray or white. ## Messages use the MiniMessage format in non-strict mode. ## More information about MiniMessage can be found here: ## https://docs.adventure.kyori.net/minimessage/format.html #The language code for this file. language-name: "en_us" #The format for decimal numbers. #The United States uses the number and two decimal places decimal-format: "0.00" #The prefix for CombatLogX. #This is shown in front of all messages and should not be changed unless necessary. prefix: "[CombatLogX]" broadcast: #Shown when the plugin is finished loading. on-load: "تم تحميل CombatLogX بنجاح." #Shown when the plugin is finished enabling. on-enable: "تم تمكين CombatLogX بنجاح." #Shown when the plugin is disabled for any reason. on-disable: "تم تعطيل CombatLogX بنجاح." placeholder: #This text is used for the {combatlogx_time_left} #This allows server configurations to change the display value of the zero to something like "Not in combat" time-left-zero: "0" #This text is used when a player does not have an enemy. #This can happen when players are tagged by a custom expansion or the tag command. unknown-enemy: "غير معروف" status: #Shown when the player is in combat. fighting: "قاتل" in-combat: "نعم" #Shown when the player is not in combat idle: "الخمول" not-in-combat: "لا" #These placeholders are shown when a player changes a value such as whether or not their bossbar is enabled. toggle: enabled: "تشغيل" disabled: "ايقاف" pvp-status: enabled: "تشغيل" disabled: "ايقاف" combat-timer: #Sent to a player when they escape from combat due to the timer running out. expire: "لم تعد في القتال." #Sent to a player when they escape from combat due to their enemy being killed. enemy-death: "لم تعد في القتال بسبب وفاة عدوك." #Sent when a player is killed during combat. self-death: "لم تعد في المعركة لأنك قد توفت." error: #Shown when the console tries to execute a command made for players. player-only: "فقط اللاعبين يمكنهم تنفيذ هذا الأمر" #Shown when a command that requires a player has invalid input. invalid-target: "{target} غير متصل أو غير موجود." #Shown when a command that requires a number has invalid input. invalid-integer: "{value} ليس عددا صحيحا." #Shown when a player does not have access to something that requires a permission. no-permission: "الصلاحية مفقودة: {permission}" #Shown when a player executes a command in a world that is disabled in the configuration. disabled-world: "هذا الأمر غير متوفر في هذا البعد" #Shown when a command requires a player in combat but the target player is not in combat. target-not-in-combat: "{target} ليس في القتال." #Shown when a player executes a command that requires them to be in combat. self-not-in-combat: "أنت لست في القتال." #Shown when a command that requires an expansion has invalid input. unknown-expansion: "{target} ليس توسعا أو لم يتم تثبيته." command: combatlogx: #Shown as the command output for '/combatlogx help'. help-message-list: - "" - "مساعدة أمر كومباتلوكس:" - " مساعدة /combatlogx: عرض صفحة المساعدة هذه" - " إعادة تحميل /combatlogx: إعادة تحميل config.yml و language.yml و جميع ملفات تهيئة التوسع" - " /combatlogx حول \\: تحقق من معلومات حول التوسع." - " علامة /combatlogx \\ [seconds]: إجبار اللاعب على القتال." - " /combatlogx تبديل Bossbar/actionbar/scoreboard: تمكين أو تعطيل نوع الإشعار." - " /combatlogx untag \\: إجبار لاعب على الخروج من القتال." - " إصدار /combatlogx: تحقق من إصدارك من CombatLogX." - "" #Shown as the command output for '/combatlogx reload' when reloading is successful. reload-success: - "تم بنجاح إعادة تحميل جميع ملفات التكوين من CombatLogX." - "تم بنجاح إعادة تحميل جميع ملفات اللغة من CombatLogX." - "تم بنجاح إعادة تحميل جميع ملفات التكوين من توسعات CombatLogX" #Shown as the command output for '/combatlogx reload' when reloading fails reload-failure: - "حدث خطأ أثناء إعادة تحميل التكوين" - "الرجاء التحقق من سجل الخادم الخاص بك وإصلاح الملف المكسور." #Shown as the command output for '/combatlogx tag ' when a player is tagged successfully. tag-player: "أجبر اللاعب بنجاح {target} على القتال." #Shown as the command output for '/combatlogx tag ' when the plugin failed to tag a player. tag-failure: "{target} لا يمكن وضعها في القتال. (مايابي لديه تجاوز؟)" #Shown as the command output for '/combatlogx untag '. untag-player: "اجبر اللاعب بنجاح {target} على الخروج من القتال." #Shown as the command output for '/combatlogx toggle bossbar'. toggle-bossbar: "زعيم الشريط: {status}" #Shown as the command output for '/combatlogx toggle actionbar'. toggle-actionbar: "شريط الإجراءات: {status}" #Shown as the command output for '/combatlogx toggle scoreboard'. toggle-scoreboard: "سجل النتيجة: {status}" combat-timer: #Shown as the command output for '/combat-timer'. time-left-self: "لديك {time_left} ثواني & متبقية." #Shown as the command output for '/combat-timer '. time-left-other: "{target} لديه {time_left} ثوان متبقية." #These messages are shown a player is tagged into combat. tagged: unknown: player: "أنت الآن في معركة مع {enemy} لسبب غير معروف. لا تقم بتسجيل الخروج!" mob: "أنت الآن في معركة مع a(n) {enemy} لسبب غير معروف. لا تقم بتسجيل الخروج!" mythic_mob: "أنت الآن في معركة مع a(n) {mob_type} لسبب غير معروف. لا تقم بتسجيل الخروج!" damage: "أنت الآن في القتال بسبب الضرر الذي لحق بك. لا تقم بتسجيل الخروج!" unknown: "لقد وضعت في المعركة بدون سبب. لا تسجل الخروج" attacked: player: "تتعرض للهجوم من قبل {enemy}. لا تقم بتسجيل الخروج!" mob: "تتعرض للهجوم بواسطة a(n) {mob_type}. لا تقم بتسجيل الخروج!" mythic_mob: "تتعرض للهجوم بواسطة a(n) {enemy}. لا تقم بتسجيل الخروج!" damage: "أنت الآن في القتال بسبب الضرر الذي لحق بك. لا تقم بتسجيل الخروج!" unknown: "تتعرض للهجوم بواسطة قوة مجهولة. لا تقم بتسجيل الخروج!" attacker: player: "أنت تهاجم {enemy}. لا تقم بتسجيل الخروج!" mob: "أنت تهاجم a(n) {mob_type}. لا تقم بتسجيل الخروج!" mythic_mob: "أنت تهاجم a(n) {enemy}. لا تقم بتسجيل الخروج!" damage: "أنت الآن في القتال بسبب الضرر الذي لحق بك. لا تقم بتسجيل الخروج!" unknown: "أنت تهاجم قوة مجهولة. لا تقم بتسجيل الخروج!" expansion: angel-chest: #Shown when opening an AngelChest is prevented during combat. prevent-opening: "لا يسمح لك بفتح صناديق الملاك أثناء القتال." #Shown when breaking an AngelChest is prevented during combat. prevent-breaking: "لا يسمح لك بكسر صناديق الملاك أثناء القتال." #Shown when fast looting an AngelChest is prevented during combat. prevent-fast-looting: "لا يسمح لك بسرقة صناديق الملاك بسرعة أثناء القتال." action-bar: #Shown above the hotbar while a player is in combat. timer: "قتال \u00BB {bars} {combatlogx_time_left} ثوان." #Shown above the hotbar for a brief period when combat ends. ended: "القتال \u00BB لم تعد في القتال." boss-bar: #Shown on top of the screen while a player is in combat. timer: "قتال \u00BB {combatlogx_time_left} ثوان." #Shown on top of the screen for a brief period when combat ends. ended: "القتال \u00BB لم تعد في القتال." scoreboard: #The scoreboard title for the sidebar. #Make sure to follow the scoreboard title limits for your Spigot version. title: "CombatLogX" #The scoreboard lines for the sidebar. #Make sure to follow the scoreboard line and character limits for your Spigot version. lines: - " " - "إحصائيات القتال:" - "\u00BB الوقت المتبقي: {combatlogx_time_left}" - "\u00BB Enemies: {combatlogx_enemy_count}" - "\u00BB الحالة: {combatlogx_status}" - " " - "Enemies" - "\u00BB {combatlogx_specific_enemy_1_name}" - "\u00BB {combatlogx_specific_enemy_2_name}" - "\u00BB {combatlogx_specific_enemy_3_name}" - " " cheat-prevention: #Shown when a command execution is prevented during combat. command-blocked: "ليس لديك حق الوصول إلى {command} أثناء القتال." #Shown when the riptide effect is prevented during combat. no-riptide: "تم تعطيل ترقية النهر أثناء القتال." #Shown when a totem of undying is prevented during combat. no-totem: "لا يسمح لك باستخدام totems من التراجع أثناء القتال." #Shown when an entity interaction is prevented during combat. no-entity-interaction: "غير مسموح لك باستخدام تلك الغوغاء أثناء القتال." #Shown when a chat message is prevented during combat. no-chat: "لا يسمح لك بإرسال رسائل الدردشة أثناء القتال." game-mode: #Shown when a player is forced into a specific game mmode during combat. force-switch: "تم تغيير وضع اللعبة الخاص بك إلى {game_mode}" #Shown when a game mode switch is prevented during combat. no-switch: "غير مسموح لك بتبديل أوضاع اللعبة أثناء القتال." flight: #Shown when a player's ability to fly is disabled during combat. force-disabled: "تمت إزالة قدرتك على التحليق." #Shown when a player's attempt to fly is prevented during combat. no-flying: "غير مسموح لك بالتحليق أثناء القتال." elytra: #Shown when a player's ability to glide is disabled during combat. force-disabled: "تم تعطيل elytra الخاص بك." #Shown when a player's attempt to glide is prevented during combat. no-gliding: "لا يسمح لك باستخدام elytra أثناء القتال." teleportation: #Shown when a player tries to enter a portal and is prevented during combat. block-portal: "لا يسمح لك باستخدام بوابة خلال القتال." #Shown when an ender pearl is prevented during combat. block-pearl: "غير مسموح لك باستخدام اللؤلؤة القديمة أثناء القتال." #Shown when a teleport is prevented during combat. block-other: "غير مسموح لك بالانتقال أثناء القتال." inventory: #Shown when a player's inventory is closed by the plugin during combat. force-closed: "تم إغلاق المخزون الخاص بك." #Shown when a player tries to open an inventory and is prevented during combat. no-opening: "غير مسموح لك بفتح المخزون أثناء القتال." blocks: #Shown when a player is prevented from breaking a block during combat. prevent-breaking: "لا يسمح لك بكسر الكتل أثناء القتال." #Shown when a player is prevented from breaking a block during combat. prevent-placing: "غير مسموح لك بوضع كتل أثناء القتال." #Shown when a player is prevented from breaking a block during combat. prevent-interaction: "لا يسمح لك باستخدام الكتل البرمجية أثناء القتال." #Shown when a player is prevented from breaking a block during combat. prevent-portal-creation: "غير مسموح لك بإنشاء بوابات خلال القتال." items: #Shown when a player is prevented from picking up an item during combat. no-pickup: "غير مسموح لك بالتقاط العناصر أثناء القتال." #Shown when a player is prevented from dropping an item during combat. no-dropping: "لا يسمح لك بإسقاط العناصر أثناء القتال." buckets: #Shown when a player is prevented from emptying a bucket during combat. no-empty: "لا يمكنك إفراغ الدلاء أثناء القتال." #Shown when a player is prevented from filling a bucket during combat. no-fill: "لا يمكنك ملء الدلاء أثناء القتال." damage-tagger: #Shown when a player is tagged for an unknown damage type. unknown-damage: "قمت بضرر! لا تقم بتسجيل الخروج!" #These messages are shown when a player is tagged for a known damage type. #You can find a list of damage types here: #https://hub.spigotmc.org/javadocs/spigot/org/bukkit/event/entity/EntityDamageEvent.DamageCause.html damage-type: contact: "لقد تم تسعيرك بواسطة خزف. لا تقم بتسجيل الخروج!" suffocation: "أنت تختنق في جدار. لا تقم بتسجيل الخروج!" fall: "وقعت ضرر في الخريف. لا تقم بتسجيل الخروج!" fire: "لقد دخلت في النار. لا تقم بتسجيل الخروج!" fire-tick: "أنت تحترق. لا تقم بتسجيل الخروج!" lava: "أنت تغلي في الحمم . لا تقم بتسجيل الخروج!" drowning: "أنت غرق. لا تقم بتسجيل الخروج!" block-explosion: "لقد تضررت من جراء الانفجار. لا تقم بتسجيل الخروج!" lightning: "تم صمامة التحديث! لا تقم بتسجيل الخروج!" starvation: "أنت جائع جدا. لا تقم بتسجيل الخروج!" poison: "لقد أخذت ضرر السموم. لا تقم بتسجيل الخروج!" magic: "قام شخص بإلقاء جرعة عليك. لا تقم بتسجيل الخروج!" wither: "أنت في الخروج. لا تقم بتسجيل الخروج!" falling-block: "سقطت كتلة عليك. لا تقم بتسجيل الخروج!" custom: "قمت بضرر مخصص. لا تقم بتسجيل الخروج!" fly-into-wall: "لقد واجهت طاقة حركية. لا تقم بتسجيل الخروج!" hot-floor: "الأرض هي الحمم الكبيرة! لا تقم بتسجيل الخروج!" cramming: "يتم إهدارك. لا تقم بتسجيل الخروج!" newbie-helper: togglepvp: #Shown as the command output for '/togglepvp'. self: "PVP: {status}" #Shown as the command output for '/togglepvp admin on/off '. admin: "قمت بتغيير pvp من {target} إلى {status}." #Shown when the '/togglepvp' command is on cooldown. cooldown: "يجب عليك الانتظار {time_left} ثانية لاستخدام هذا الأمر مرة أخرى." #These messages are shown when pvp is disabled for any reason. no-pvp: self: "لا يسمح لك بضرب هذا اللاعب أثناء تعطيل PvP الخاص بك." other: "هذا اللاعب لديه PvP معطل." protected: "هذا اللاعب محمي، لا يسمح لك بمهاجمته!" protection-disabled: #Shown when newbie protection is disabled due to the player attacking another player. attacker: "قمت بمهاجمة شخص ما، حماية الجديد الخاص بك معطلة الآن." #Shown when newbie protection expires. expired: "انتهت مدة حماية المبتدئين الخاص بك." #Shown for the '/togglepvp check ' command. check-format: - "معلومات {target}:" - "الحماية: {protected}" - "PvP: {pvp}" loot-protection: #Shown when an enemy dies and their loot is protected. enemy-died: "{enemy} مات . سيتم حماية النهب {time} ثوان." #Shown when a player tries to pick up an item that is loot protected by the plugin. protected: "هذا العنصر محمي حاليًا، انتظر {time} ثانية حتى يمكنك الحصول عليه." citizens-compatibility: #Shown when a player is prevented from joining the server due to their NPC still existing. prevent-join: "غير مسموح لك بالانضمام إلى الخادم حتى يتم قتل NPC أو إزالته." disguise-compatibility: #Shown when a disguise is removed from a player during combat. remove-disguise: "تمت إزالة التستر الخاص بك." essentials-compatibility: #Shown when a teleport request is cancelled during combat. prevent-teleport-request-self: "لا يمكنك إنشاء طلبات الانتقال أثناء القتال." #Shown when a teleport request is cancelled during combat. prevent-teleport-request-other: "لا يمكنك إرسال طلب نقل إلى لاعب في القتال." marriagemaster-compatibility: #Shown when a married player is prevented from teleporting to their partner during combat. prevent-teleport-self: "غير مسموح لك بالانتقال إلى شريكك أثناء القتال." #Shown when a married player is prevented from teleporting to their partner during combat. prevent-teleport-partner: "لا يسمح لك بالانتقال إلى شريكك أثناء وجودهم في القتال." region-protection: #Shown when a player tries to enter a no-pvp area during combat. default-no-entry: "لا يسمح لك بالدخول إلى هذه المنطقة أثناء القتال." factions-no-entry: لا يسمح لك بالدخول إلى هذه المنطقة أثناء القتال. griefdefender-no-entry: لا يسمح لك بالدخول إلى هذه المنطقة أثناء القتال. griefprevention-no-entry: لا يسمح لك بالدخول إلى هذه المنطقة أثناء القتال. kingdomsx-no-entry: لا يسمح لك بالدخول إلى هذه المنطقة أثناء القتال. konquest-no-entry: لا يسمح لك بالدخول إلى هذه المنطقة أثناء القتال. redprotect-no-entry: لا يسمح لك بالدخول إلى هذه المنطقة أثناء القتال. residence-no-entry: لا يسمح لك بالدخول إلى هذه المنطقة أثناء القتال. towny-no-entry: لا يسمح لك بالدخول إلى هذه المنطقة أثناء القتال. husktowns-no-entry: لا يسمح لك بالدخول إلى هذه المنطقة أثناء القتال. ultimateclaims-no-entry: لا يسمح لك بالدخول إلى هذه المنطقة أثناء القتال. protectionstones: prevent-area-creation: "غير مسموح لك بإنشاء منطقة محمية أثناء القتال." no-entry: لا يسمح لك بالدخول إلى هذه المنطقة أثناء القتال. preciousstones: prevent-field-creation: "غير مسموح لك بإنشاء حقل حماية أثناء القتال." no-entry: لا يسمح لك بالدخول إلى هذه المنطقة أثناء القتال. worldguard: no-entry-mob-combat: "لا يسمح لك بالدخول إلى منطقة معركة غير غوغائية أثناء القتال." no-entry-player-combat: "لا يسمح لك بالدخول إلى منطقة قتال غير لاعب أثناء القتال." no-entry-unknown-combat: لا يسمح لك بالدخول إلى هذه المنطقة أثناء القتال. lands: no-entry: لا يسمح لك بالدخول إلى هذه المنطقة أثناء القتال. war-disable-newbie-protection: "PvP تم تمكينه الآن بسبب إعلان الحرب." ================================================ FILE: plugin/src/main/resources/language/cs_cz.lang.yml ================================================ --- ## Extra Information: ## This is the default language file for CombatLogX. ## The default language is "en_us", also known as English (United States). ## Context will be added as YAML comments above the string. ## The color scheme for messages is gold, white, and sometimes red. ## Command feedback that is successful should always be green. ## Error messages should always be red. ## Variables in messages can be gray or white. ## Messages use the MiniMessage format in non-strict mode. ## More information about MiniMessage can be found here: ## https://docs.adventure.kyori.net/minimessage/format.html #The language code for this file. language-name: "cs_cz" #The format for decimal numbers. #The United States uses the number and two decimal places decimal-format: "0,00" #The prefix for CombatLogX. #This is shown in front of all messages and should not be changed unless necessary. prefix: "[CombatLogX]" broadcast: #Shown when the plugin is finished loading. on-load: "CombatLogX byl úspěšně načten." #Shown when the plugin is finished enabling. on-enable: "CombatLogX byl úspěšně aktivován." #Shown when the plugin is disabled for any reason. on-disable: "CombatLogX byl úspěšně zakázán." placeholder: #This text is used for the {combatlogx_time_left} #This allows server configurations to change the display value of the zero to something like "Not in combat" time-left-zero: "0" #This text is used when a player does not have an enemy. #This can happen when players are tagged by a custom expansion or the tag command. unknown-enemy: "Neznámá" status: #Shown when the player is in combat. fighting: "Boj" in-combat: "Ano" #Shown when the player is not in combat idle: "Nečinný" not-in-combat: "č." #These placeholders are shown when a player changes a value such as whether or not their bossbar is enabled. toggle: enabled: "ZAPNUTÝ" disabled: "VYPNUTO" pvp-status: enabled: "ZAPNUTÝ" disabled: "VYPNUTO" combat-timer: #Sent to a player when they escape from combat due to the timer running out. expire: "Už nejste v boji." #Sent to a player when they escape from combat due to their enemy being killed. enemy-death: "Už jsi v boji, protože tvůj nepřítel zemřel." #Sent when a player is killed during combat. self-death: "Už nejste v boji, protože jsi zemřel/a" error: #Shown when the console tries to execute a command made for players. player-only: "Pouze hráči mohou spustit tento příkaz" #Shown when a command that requires a player has invalid input. invalid-target: "{target} není online nebo neexistuje." #Shown when a command that requires a number has invalid input. invalid-integer: "{value} není platné celé číslo." #Shown when a player does not have access to something that requires a permission. no-permission: "Chybějící oprávnění: {permission}" #Shown when a player executes a command in a world that is disabled in the configuration. disabled-world: "Tento příkaz není k dispozici v tomto rozměru." #Shown when a command requires a player in combat but the target player is not in combat. target-not-in-combat: "{target} není v boji." #Shown when a player executes a command that requires them to be in combat. self-not-in-combat: "Nejste v boji." #Shown when a command that requires an expansion has invalid input. unknown-expansion: "{target} není rozšíření nebo není nainstalováno." command: combatlogx: #Shown as the command output for '/combatlogx help'. help-message-list: - "" - "Příkazová nápověda pro CombatLogX:" - " /combatlogx help: Zobrazit tuto nápovědu." - " /combatlogx reload: Znovu načtěte config.yml, language.yml a všechny konfigurační soubory." - " /combatlogx o \\: Podívejte se na informace o rozšíření." - " /combatlogx tag \\ [seconds]: Vynutit hráče do boje." - " /combatlogx přepíná bossbar/actionbar/scoreboard: Povolit nebo zakázat typ oznámení." - " /combatlogx untag \\: Vynutit hráče z boje." - " /combatlogx verze: Zkontrolujte verzi CombatLogX." - "" #Shown as the command output for '/combatlogx reload' when reloading is successful. reload-success: - "Všechny konfigurační soubory byly úspěšně obnoveny z CombatLogX." - "Všechny jazykové soubory z CombatLogX." - "Všechny konfigurační soubory z CombatLogX rozšíření byly úspěšně obnoveny." #Shown as the command output for '/combatlogx reload' when reloading fails reload-failure: - "Došlo k chybě při obnovování konfigurace." - "Zkontrolujte protokol serveru a opravte poškozený soubor." #Shown as the command output for '/combatlogx tag ' when a player is tagged successfully. tag-player: "Úspěšně vynucený hráč {target} do boje." #Shown as the command output for '/combatlogx tag ' when the plugin failed to tag a player. tag-failure: "{target} nebylo možné umístit do boje. (Je možné, že mají obchvat?)" #Shown as the command output for '/combatlogx untag '. untag-player: "Úspěšně vynucený hráč {target} mimo boj." #Shown as the command output for '/combatlogx toggle bossbar'. toggle-bossbar: "Boss Bar: {status}" #Shown as the command output for '/combatlogx toggle actionbar'. toggle-actionbar: "Panel akcí: {status}" #Shown as the command output for '/combatlogx toggle scoreboard'. toggle-scoreboard: "Srovnávací tabulka: {status}" combat-timer: #Shown as the command output for '/combat-timer'. time-left-self: "Máte ještě {time_left} sekund&a." #Shown as the command output for '/combat-timer '. time-left-other: "{target} zbývá {time_left} sekund ." #These messages are shown a player is tagged into combat. tagged: unknown: player: "Nyní jsi v boji s {enemy} z neznámého důvodu. Neodhlašuj se!" mob: "Nyní jsi v boji s a(n) {enemy} z neznámého důvodu. Neodhlašuj se!" mythic_mob: "Nyní jsi v boji s a(n) {mob_type} z neznámého důvodu. Neodhlašuj se!" damage: "Nyní jsi v boji kvůli poškození. Neodhlašuj se!" unknown: "Byli jste umístěni do boje bez důvodu. Neodhlašujte se." attacked: player: "Byli jste napadeni {enemy}. Neodhlásíte!" mob: "Byli jste napadeni a(n) {mob_type}. Neodhlásíte!" mythic_mob: "Byli jste napadeni a(n) {enemy}. Neodhlásíte!" damage: "Nyní jsi v boji kvůli poškození. Neodhlašuj se!" unknown: "Jsi útočen neznámou silou. Neodhlašuj se!" attacker: player: "Útočíte {enemy}. Neodhlásíte!" mob: "Útočíte a(n) {mob_type}. Neodhlásíte!" mythic_mob: "Útočíte a(n) {enemy}. Neodhlásíte!" damage: "Nyní jsi v boji kvůli poškození. Neodhlašuj se!" unknown: "Útočíš na neznámou sílu. Neodhlašuj se!" expansion: angel-chest: #Shown when opening an AngelChest is prevented during combat. prevent-opening: "Nemáš dovoleno otevřít andělové truhly během boje." #Shown when breaking an AngelChest is prevented during combat. prevent-breaking: "Nemáš dovoleno rozbít andělové truhly během boje." #Shown when fast looting an AngelChest is prevented during combat. prevent-fast-looting: "Nemáš dovoleno zrychlit úhlové truhly během boje." action-bar: #Shown above the hotbar while a player is in combat. timer: "Boj \u00BB {bars} {combatlogx_time_left} sekund." #Shown above the hotbar for a brief period when combat ends. ended: "Boj \u00BB Již nejste v boji." boss-bar: #Shown on top of the screen while a player is in combat. timer: "Boj \u00BB {combatlogx_time_left} sekund." #Shown on top of the screen for a brief period when combat ends. ended: "Boj \u00BB Již nejste v boji." scoreboard: #The scoreboard title for the sidebar. #Make sure to follow the scoreboard title limits for your Spigot version. title: "CombatLogX" #The scoreboard lines for the sidebar. #Make sure to follow the scoreboard line and character limits for your Spigot version. lines: - " " - "Statistiky bojů:" - "\u00BB Zbývající čas: {combatlogx_time_left}" - "\u00BB Enemies: {combatlogx_enemy_count}" - "\u00BB Stav: {combatlogx_status}" - " " - "Enemies" - "\u00BB {combatlogx_specific_enemy_1_name}" - "\u00BB {combatlogx_specific_enemy_2_name}" - "\u00BB {combatlogx_specific_enemy_3_name}" - " " cheat-prevention: #Shown when a command execution is prevented during combat. command-blocked: "Nemáte přístup k {command} během boje." #Shown when the riptide effect is prevented during combat. no-riptide: "Zaklínání riptidů je při boji zakázáno." #Shown when a totem of undying is prevented during combat. no-totem: "Nejste oprávněni používat celkové součty z odvracení během boje." #Shown when an entity interaction is prevented during combat. no-entity-interaction: "Nemáš dovoleno používat toto stvoření během boje." #Shown when a chat message is prevented during combat. no-chat: "Nemáte oprávnění odesílat zprávy v chatu během boje." game-mode: #Shown when a player is forced into a specific game mmode during combat. force-switch: "Tvůj herní režim byl změněn na {game_mode}." #Shown when a game mode switch is prevented during combat. no-switch: "Nejste oprávněni přepínat herní režimy během boje." flight: #Shown when a player's ability to fly is disabled during combat. force-disabled: "Tvá schopnost létat byla odstraněna." #Shown when a player's attempt to fly is prevented during combat. no-flying: "Nemáš dovoleno letět během boje." elytra: #Shown when a player's ability to glide is disabled during combat. force-disabled: "Vaše elytra byla zakázána." #Shown when a player's attempt to glide is prevented during combat. no-gliding: "Nejste oprávněni používat elytra během boje." teleportation: #Shown when a player tries to enter a portal and is prevented during combat. block-portal: "Nemáte oprávnění používat portál během boje." #Shown when an ender pearl is prevented during combat. block-pearl: "Nemáš dovoleno používat ender perly během boje." #Shown when a teleport is prevented during combat. block-other: "Nemáš dovoleno teleportovat během boje." inventory: #Shown when a player's inventory is closed by the plugin during combat. force-closed: "Váš inventář byl uzavřen." #Shown when a player tries to open an inventory and is prevented during combat. no-opening: "Nemáte oprávnění otevírat inventáře během boje." blocks: #Shown when a player is prevented from breaking a block during combat. prevent-breaking: "Nemáš dovoleno rozbít bloky během boje." #Shown when a player is prevented from breaking a block during combat. prevent-placing: "Nejste oprávněni pokládat bloky během boje." #Shown when a player is prevented from breaking a block during combat. prevent-interaction: "Nejste oprávněni používat bloky během boje." #Shown when a player is prevented from breaking a block during combat. prevent-portal-creation: "Nemáte oprávnění vytvářet portály během boje." items: #Shown when a player is prevented from picking up an item during combat. no-pickup: "Nejste oprávněni zvednout předměty během boje." #Shown when a player is prevented from dropping an item during combat. no-dropping: "Nejste oprávněni upustit předměty během boje." buckets: #Shown when a player is prevented from emptying a bucket during combat. no-empty: "Během boje nemůžete vyprázdnit bloky." #Shown when a player is prevented from filling a bucket during combat. no-fill: "Během boje nemůžete vyplnit bucket." damage-tagger: #Shown when a player is tagged for an unknown damage type. unknown-damage: "Poškodil jsi! Neodhlásej se!" #These messages are shown when a player is tagged for a known damage type. #You can find a list of damage types here: #https://hub.spigotmc.org/javadocs/spigot/org/bukkit/event/entity/EntityDamageEvent.DamageCause.html damage-type: contact: "Byli jste prikazeni kaktusem. Neodhlásíte!" suffocation: "Dýcháte se ve zdi. Neodhlásíte!" fall: "Zaznamenali jste pád poškození. Neodhlásíte!" fire: "Prošel jsi do ohně. Neodhlásit!" fire-tick: "Spalujete. Neodhlásit se!" lava: "Jsi vroucí v lávě. Neodhlašuj se!" drowning: "Točíte se. Neodhlásíte!" block-explosion: "Byli jste poškozeni výbuchem. Neodhlásíte!" lightning: "Ti byli smitlíni! Neodhlásíte!" starvation: "Jsi příliš hladový. Neodhlašuj se!" poison: "Udělal jsi jedovaté poškození. Neodhlásej se!" magic: "Někdo ti hodil lektvar. Neodhlásíte!" wither: "Odhlásíte se. Neodhlásíte!" falling-block: "padl na tebe blok. Neodhlásíte!" custom: "Provedli jste vlastní poškození. Neodhlásit!" fly-into-wall: "Zaznamenali jste kinetickou energii. Neodhlásíte!" hot-floor: "Podlaha je láva! Neodhlásíte!" cramming: "Jsi spoutaný. Neodhlašuj se!" newbie-helper: togglepvp: #Shown as the command output for '/togglepvp'. self: "PVP: {status}" #Shown as the command output for '/togglepvp admin on/off '. admin: "Změnili jste pvp z {target} na {status}." #Shown when the '/togglepvp' command is on cooldown. cooldown: "Musíš počkat {time_left} sekund, abys mohl znovu použít tento příkaz." #These messages are shown when pvp is disabled for any reason. no-pvp: self: "Není dovoleno stisknout tohoto přehrávače, když je váš PvP zakázaný." other: "Tento hráč má PvP vypnutý." protected: "Tento hráč je chráněn. Zatím nemáte dovoleno na něj zaútočit!" protection-disabled: #Shown when newbie protection is disabled due to the player attacking another player. attacker: "Zaútočili jste na někoho, ochrana novinek je nyní zakázána" #Shown when newbie protection expires. expired: "Ochrana před Vašimi novinkami vypršela." #Shown for the '/togglepvp check ' command. check-format: - "Informace pro {target}:" - "Ochrana: {protected}" - "PvP: {pvp}" loot-protection: #Shown when an enemy dies and their loot is protected. enemy-died: "{enemy} zemřel. Loot bude chráněn po dobu {time} sekund." #Shown when a player tries to pick up an item that is loot protected by the plugin. protected: "Tato položka je v současné době chráněna, počkejte {time} sekund, než ji budete moci vyzvednout." citizens-compatibility: #Shown when a player is prevented from joining the server due to their NPC still existing. prevent-join: "Nejste oprávněni připojit se k serveru, dokud nebude váš NPC zabit nebo odstraněn." disguise-compatibility: #Shown when a disguise is removed from a player during combat. remove-disguise: "Zmaskování bylo odstraněno." essentials-compatibility: #Shown when a teleport request is cancelled during combat. prevent-teleport-request-self: "Nemůžete vytvořit žádosti o teleportování během boje." #Shown when a teleport request is cancelled during combat. prevent-teleport-request-other: "Nemůžete odeslat žádost o teleportování hráči, který je v boji." marriagemaster-compatibility: #Shown when a married player is prevented from teleporting to their partner during combat. prevent-teleport-self: "Nemůžete teleportovat svého partnera během boje." #Shown when a married player is prevented from teleporting to their partner during combat. prevent-teleport-partner: "Nejste oprávněni teleportovat se svým partnerem, když jsou v boji." region-protection: #Shown when a player tries to enter a no-pvp area during combat. default-no-entry: "Nejste oprávněni vstoupit do této oblasti během boje." factions-no-entry: Nejste oprávněni vstoupit do této oblasti během boje. griefdefender-no-entry: Nejste oprávněni vstoupit do této oblasti během boje. griefprevention-no-entry: Nejste oprávněni vstoupit do této oblasti během boje. kingdomsx-no-entry: Nejste oprávněni vstoupit do této oblasti během boje. konquest-no-entry: Nejste oprávněni vstoupit do této oblasti během boje. redprotect-no-entry: Nejste oprávněni vstoupit do této oblasti během boje. residence-no-entry: Nejste oprávněni vstoupit do této oblasti během boje. towny-no-entry: Nejste oprávněni vstoupit do této oblasti během boje. husktowns-no-entry: Nejste oprávněni vstoupit do této oblasti během boje. ultimateclaims-no-entry: Nejste oprávněni vstoupit do této oblasti během boje. protectionstones: prevent-area-creation: "Nejste oprávněni vytvářet chráněnou oblast během boje." no-entry: Nejste oprávněni vstoupit do této oblasti během boje. preciousstones: prevent-field-creation: "Nejste oprávněni vytvářet ochranné pole během boje." no-entry: Nejste oprávněni vstoupit do této oblasti během boje. worldguard: no-entry-mob-combat: "Nemáš dovoleno vstupovat do oblasti mimo mob-boje během boje." no-entry-player-combat: "Nemáš dovoleno vstupovat do bojové oblasti mimo hráče během boje." no-entry-unknown-combat: Nejste oprávněni vstoupit do této oblasti během boje. lands: no-entry: Nejste oprávněni vstoupit do této oblasti během boje. war-disable-newbie-protection: "PvP nyní vynucuje povolení z důvodu válečného prohlášení" ================================================ FILE: plugin/src/main/resources/language/da_dk.lang.yml ================================================ --- ## Extra Information: ## This is the default language file for CombatLogX. ## The default language is "en_us", also known as English (United States). ## Context will be added as YAML comments above the string. ## The color scheme for messages is gold, white, and sometimes red. ## Command feedback that is successful should always be green. ## Error messages should always be red. ## Variables in messages can be gray or white. ## Messages use the MiniMessage format in non-strict mode. ## More information about MiniMessage can be found here: ## https://docs.adventure.kyori.net/minimessage/format.html #The language code for this file. language-name: "da_os" #The format for decimal numbers. #The United States uses the number and two decimal places decimal-format: "0.00" #The prefix for CombatLogX. #This is shown in front of all messages and should not be changed unless necessary. prefix: "[CombatLogX]" broadcast: #Shown when the plugin is finished loading. on-load: "CombatLogX blev indlæst med succes." #Shown when the plugin is finished enabling. on-enable: "CombatLogX blev aktiveret." #Shown when the plugin is disabled for any reason. on-disable: "CombatLogX blev deaktiveret med succes." placeholder: #This text is used for the {combatlogx_time_left} #This allows server configurations to change the display value of the zero to something like "Not in combat" time-left-zero: "0" #This text is used when a player does not have an enemy. #This can happen when players are tagged by a custom expansion or the tag command. unknown-enemy: "Ukendt" status: #Shown when the player is in combat. fighting: "Kampen" in-combat: "Ja" #Shown when the player is not in combat idle: "Tomgang" not-in-combat: "Nr." #These placeholders are shown when a player changes a value such as whether or not their bossbar is enabled. toggle: enabled: "TIL" disabled: "FRA" pvp-status: enabled: "TIL" disabled: "FRA" combat-timer: #Sent to a player when they escape from combat due to the timer running out. expire: "Du er ikke længere i kamp." #Sent to a player when they escape from combat due to their enemy being killed. enemy-death: "Du er ikke længere i kamp, fordi din fjende døde." #Sent when a player is killed during combat. self-death: "Du er ikke længere i kamp, fordi du døde." error: #Shown when the console tries to execute a command made for players. player-only: "Kun spillere kan udføre denne kommando" #Shown when a command that requires a player has invalid input. invalid-target: "{target} er ikke online eller eksisterer ikke." #Shown when a command that requires a number has invalid input. invalid-integer: "{value} er ikke et gyldigt heltal." #Shown when a player does not have access to something that requires a permission. no-permission: "Manglende tilladelse: {permission}" #Shown when a player executes a command in a world that is disabled in the configuration. disabled-world: "Kommandoen er ikke tilgængelig i denne dimension." #Shown when a command requires a player in combat but the target player is not in combat. target-not-in-combat: "{target} er ikke i kamp." #Shown when a player executes a command that requires them to be in combat. self-not-in-combat: "Du er ikke i kamp." #Shown when a command that requires an expansion has invalid input. unknown-expansion: "{target} er ikke en udvidelse eller er ikke installeret." command: combatlogx: #Shown as the command output for '/combatlogx help'. help-message-list: - "" - "CombatLogX Command Hjælp:" - " /combatlogx help: Se denne hjælpeside." - " /combatlogx genindlæs: Genindlæs config.yml, language.yml, og alle udvidelses konfigurationsfiler." - " /combatlogx about \\: Tjek information om en udvidelse." - " /combatlogx tag \\ [seconds]: Tving en spiller i kamp." - " /combatlogx toggle bossbar/actionbar/scoreboard: Aktiver eller deaktiver en notifikationstype." - " /combatlogx untag \\: Tving en spiller ud af kamp." - " /combatlogx version: Tjek din version af CombatLogX." - "" #Shown as the command output for '/combatlogx reload' when reloading is successful. reload-success: - "Alle konfigurationsfiler fra CombatLogX blev genindlæst." - "Alle sprogfiler fra CombatLogX blev genindlæst." - "Alle konfigurationsfiler fra CombatLogX-udvidelser blev genindlæst." #Shown as the command output for '/combatlogx reload' when reloading fails reload-failure: - "Der opstod en fejl under genindlæsning af konfigurationen." - "Kontroller venligst din serverlog og retter den ødelagte fil." #Shown as the command output for '/combatlogx tag ' when a player is tagged successfully. tag-player: "Tvungen spiller {target} i kamp." #Shown as the command output for '/combatlogx tag ' when the plugin failed to tag a player. tag-failure: "{target} kunne ikke placeres i kamp. (Måske har de en bypass?)" #Shown as the command output for '/combatlogx untag '. untag-player: "Tvungen spiller {target} ud af kamp." #Shown as the command output for '/combatlogx toggle bossbar'. toggle-bossbar: "Boss Bar: {status}" #Shown as the command output for '/combatlogx toggle actionbar'. toggle-actionbar: "Handlingsbjælke: {status}" #Shown as the command output for '/combatlogx toggle scoreboard'. toggle-scoreboard: "Scoreboard: {status}" combat-timer: #Shown as the command output for '/combat-timer'. time-left-self: "Du har {time_left} sekunder&a tilbage." #Shown as the command output for '/combat-timer '. time-left-other: "{target} har {time_left} sekunder tilbage." #These messages are shown a player is tagged into combat. tagged: unknown: player: "Du er nu i kamp med {enemy} af en ukendt grund. Log ikke ud!" mob: "Du er nu i kamp med en(n) {enemy} af en ukendt grund. Log ikke ud!" mythic_mob: "Du er nu i kamp med en(n) {mob_type} af en ukendt grund. Log ikke ud!" damage: "Du er nu i kamp på grund af at tage skade. Log ikke ud!" unknown: "Du blev placeret i kamp uden grund. Log ikke ud." attacked: player: "Du bliver angrebet af {enemy}. Log ikke ud!" mob: "Du bliver angrebet af en(n) {mob_type}. Log ikke ud!" mythic_mob: "Du bliver angrebet af en(n) {enemy}. Log ikke ud!" damage: "Du er nu i kamp på grund af at tage skade. Log ikke ud!" unknown: "Du bliver angrebet af en ukendt kraft. Log ikke ud!" attacker: player: "Du angriber {enemy}. Log ikke ud!" mob: "Du angriber en(n) {mob_type}. Log ikke ud!" mythic_mob: "Du angriber en(n) {enemy}. Log ikke ud!" damage: "Du er nu i kamp på grund af at tage skade. Log ikke ud!" unknown: "Du angriber en ukendt kraft. Log ikke ud!" expansion: angel-chest: #Shown when opening an AngelChest is prevented during combat. prevent-opening: "Du har ikke tilladelse til at åbne engel kister under kamp." #Shown when breaking an AngelChest is prevented during combat. prevent-breaking: "Du har ikke tilladelse til at bryde engel kister under kamp." #Shown when fast looting an AngelChest is prevented during combat. prevent-fast-looting: "Du har ikke tilladelse til hurtigt at plyndre engel kister under kamp." action-bar: #Shown above the hotbar while a player is in combat. timer: "Bekæmpelse \u00BB {bars} {combatlogx_time_left} sekunder." #Shown above the hotbar for a brief period when combat ends. ended: "Kamp \u00BB Du er ikke længere i kamp." boss-bar: #Shown on top of the screen while a player is in combat. timer: "Bekæmpelse \u00BB {combatlogx_time_left} sekunder." #Shown on top of the screen for a brief period when combat ends. ended: "Kamp \u00BB Du er ikke længere i kamp." scoreboard: #The scoreboard title for the sidebar. #Make sure to follow the scoreboard title limits for your Spigot version. title: "CombatLogX" #The scoreboard lines for the sidebar. #Make sure to follow the scoreboard line and character limits for your Spigot version. lines: - " " - "Kampstatistik:" - "\u00BB Tid tilbage: {combatlogx_time_left}" - "\u00BB Enemies: {combatlogx_enemy_count}" - "\u00BB Status: {combatlogx_status}" - " " - "Enemies" - "\u00BB {combatlogx_specific_enemy_1_name}" - "\u00BB {combatlogx_specific_enemy_2_name}" - "\u00BB {combatlogx_specific_enemy_3_name}" - " " cheat-prevention: #Shown when a command execution is prevented during combat. command-blocked: "Du har ikke adgang til {command} under kamp." #Shown when the riptide effect is prevented during combat. no-riptide: "Fortryllelsen af riptid er deaktiveret under kamp." #Shown when a totem of undying is prevented during combat. no-totem: "Du har ikke tilladelse til at bruge totems af udødelig under kamp." #Shown when an entity interaction is prevented during combat. no-entity-interaction: "Du har ikke tilladelse til at bruge denne mob under kamp." #Shown when a chat message is prevented during combat. no-chat: "Du har ikke tilladelse til at sende chatbeskeder under kamp." game-mode: #Shown when a player is forced into a specific game mmode during combat. force-switch: "Din spiltilstand blev ændret til {game_mode}." #Shown when a game mode switch is prevented during combat. no-switch: "Du har ikke tilladelse til at skifte spiltilstand under kamp." flight: #Shown when a player's ability to fly is disabled during combat. force-disabled: "Din evne til at flyve blev fjernet." #Shown when a player's attempt to fly is prevented during combat. no-flying: "Du har ikke tilladelse til at flyve under kamp." elytra: #Shown when a player's ability to glide is disabled during combat. force-disabled: "Din elytra blev deaktiveret." #Shown when a player's attempt to glide is prevented during combat. no-gliding: "Du har ikke tilladelse til at bruge elytra under kamp." teleportation: #Shown when a player tries to enter a portal and is prevented during combat. block-portal: "Du har ikke tilladelse til at bruge en portal under kamp." #Shown when an ender pearl is prevented during combat. block-pearl: "Du har ikke tilladelse til at bruge ender perler under kamp." #Shown when a teleport is prevented during combat. block-other: "Du har ikke tilladelse til at teleportere under kamp." inventory: #Shown when a player's inventory is closed by the plugin during combat. force-closed: "Din beholdning blev lukket." #Shown when a player tries to open an inventory and is prevented during combat. no-opening: "Du har ikke tilladelse til at åbne lagerbeholdninger under kamp." blocks: #Shown when a player is prevented from breaking a block during combat. prevent-breaking: "Du har ikke tilladelse til at bryde blokke under kamp." #Shown when a player is prevented from breaking a block during combat. prevent-placing: "Du har ikke tilladelse til at placere blokke under kamp." #Shown when a player is prevented from breaking a block during combat. prevent-interaction: "Du har ikke tilladelse til at bruge blokke under kamp." #Shown when a player is prevented from breaking a block during combat. prevent-portal-creation: "Du har ikke tilladelse til at oprette portaler under kamp." items: #Shown when a player is prevented from picking up an item during combat. no-pickup: "Du har ikke tilladelse til at afhente elementer under kamp." #Shown when a player is prevented from dropping an item during combat. no-dropping: "Du har ikke tilladelse til at droppe elementer under kamp." buckets: #Shown when a player is prevented from emptying a bucket during combat. no-empty: "Du kan ikke tømme spande under kamp." #Shown when a player is prevented from filling a bucket during combat. no-fill: "Du kan ikke fylde spande op under kamp." damage-tagger: #Shown when a player is tagged for an unknown damage type. unknown-damage: "Du tog skade! Log ikke ud!" #These messages are shown when a player is tagged for a known damage type. #You can find a list of damage types here: #https://hub.spigotmc.org/javadocs/spigot/org/bukkit/event/entity/EntityDamageEvent.DamageCause.html damage-type: contact: "Du blev stikket af en kaktus. Log ikke ud!" suffocation: "Du er kvælende i en væg. Log ikke ud!" fall: "Du tog faldskade. Log ikke ud!" fire: "Du gik i brand. Log ikke ud!" fire-tick: "Du brænder. Log ikke ud!" lava: "Du koger i lava. Log ikke ud!" drowning: "Du drukner. Log ikke ud!" block-explosion: "Du blev beskadiget af en eksplosion. Log ikke ud!" lightning: "Du er blevet smittet! Log ikke ud!" starvation: "Du er for sulten. Log ikke ud!" poison: "Du tog gift skade. Log ikke ud!" magic: "Nogen kastede en eliksir på dig. Log ikke ud!" wither: "Du visner væk. Log ikke ud!" falling-block: "En blok faldt på dig. Log ikke ud!" custom: "Du tog brugerdefineret skade. Log ikke ud!" fly-into-wall: "Du har oplevet kinetisk energi. Log ikke ud!" hot-floor: "Gulvet er lava! Log ikke ud!" cramming: "Du er ved at blive klemt. Log ikke ud!" newbie-helper: togglepvp: #Shown as the command output for '/togglepvp'. self: "PVP: {status}" #Shown as the command output for '/togglepvp admin on/off '. admin: "Du ændrede pvp af {target} til {status}." #Shown when the '/togglepvp' command is on cooldown. cooldown: "Du skal vente {time_left} sekunder for at bruge denne kommando igen." #These messages are shown when pvp is disabled for any reason. no-pvp: self: "Du har ikke tilladelse til at ramme den spiller, mens din PvP er deaktiveret." other: "Spilleren har PvP deaktiveret." protected: "At spilleren er beskyttet, du har ikke tilladelse til at angribe dem endnu!" protection-disabled: #Shown when newbie protection is disabled due to the player attacking another player. attacker: "Du angreb nogen, din newbie beskyttelse er nu deaktiveret." #Shown when newbie protection expires. expired: "Din beskyttelse af nybegyndere er udløbet." #Shown for the '/togglepvp check ' command. check-format: - "Information for {target}:" - "Beskyttelse: {protected}" - "PvP: {pvp}" loot-protection: #Shown when an enemy dies and their loot is protected. enemy-died: "{enemy} er død. Loot vil blive beskyttet i {time} sekunder." #Shown when a player tries to pick up an item that is loot protected by the plugin. protected: "Dette element er pt. beskyttet, vent {time} sekunder, indtil du kan hente det." citizens-compatibility: #Shown when a player is prevented from joining the server due to their NPC still existing. prevent-join: "Du har ikke tilladelse til at deltage i serveren, før din NPC er dræbt eller fjernet." disguise-compatibility: #Shown when a disguise is removed from a player during combat. remove-disguise: "Din forklædning blev fjernet." essentials-compatibility: #Shown when a teleport request is cancelled during combat. prevent-teleport-request-self: "Du kan ikke oprette teleporteringsforespørgsler under kamp." #Shown when a teleport request is cancelled during combat. prevent-teleport-request-other: "Du kan ikke sende en teleporteringsanmodning til en spiller, der er i kamp." marriagemaster-compatibility: #Shown when a married player is prevented from teleporting to their partner during combat. prevent-teleport-self: "Du har ikke tilladelse til at teleportere til din partner under kamp." #Shown when a married player is prevented from teleporting to their partner during combat. prevent-teleport-partner: "Du har ikke tilladelse til at teleportere til din partner, mens de er i kamp." region-protection: #Shown when a player tries to enter a no-pvp area during combat. default-no-entry: "Du har ikke tilladelse til at indtaste dette område under kamp." factions-no-entry: Du har ikke tilladelse til at indtaste dette område under kamp. griefdefender-no-entry: Du har ikke tilladelse til at indtaste dette område under kamp. griefprevention-no-entry: Du har ikke tilladelse til at indtaste dette område under kamp. kingdomsx-no-entry: Du har ikke tilladelse til at indtaste dette område under kamp. konquest-no-entry: Du har ikke tilladelse til at indtaste dette område under kamp. redprotect-no-entry: Du har ikke tilladelse til at indtaste dette område under kamp. residence-no-entry: Du har ikke tilladelse til at indtaste dette område under kamp. towny-no-entry: Du har ikke tilladelse til at indtaste dette område under kamp. husktowns-no-entry: Du har ikke tilladelse til at indtaste dette område under kamp. ultimateclaims-no-entry: Du har ikke tilladelse til at indtaste dette område under kamp. protectionstones: prevent-area-creation: "Du har ikke tilladelse til at oprette et beskyttet område under kamp." no-entry: Du har ikke tilladelse til at indtaste dette område under kamp. preciousstones: prevent-field-creation: "Du har ikke tilladelse til at oprette et beskyttelsesfelt under kamp." no-entry: Du har ikke tilladelse til at indtaste dette område under kamp. worldguard: no-entry-mob-combat: "Du har ikke tilladelse til at indtaste et ikke-mob-kampområde under kamp." no-entry-player-combat: "Du har ikke tilladelse til at indtaste et ikke-spiller-kampområde under kamp." no-entry-unknown-combat: Du har ikke tilladelse til at indtaste dette område under kamp. lands: no-entry: Du har ikke tilladelse til at indtaste dette område under kamp. war-disable-newbie-protection: "PvP er nu kraft aktiveret på grund af en krigserklæring." ================================================ FILE: plugin/src/main/resources/language/de_at.lang.yml ================================================ --- ## Extra Information: ## This is the default language file for CombatLogX. ## The default language is "en_us", also known as English (United States). ## Context will be added as YAML comments above the string. ## The color scheme for messages is gold, white, and sometimes red. ## Command feedback that is successful should always be green. ## Error messages should always be red. ## Variables in messages can be gray or white. ## Messages use the MiniMessage format in non-strict mode. ## More information about MiniMessage can be found here: ## https://docs.adventure.kyori.net/minimessage/format.html #The language code for this file. language-name: "de_de" #The format for decimal numbers. #The United States uses the number and two decimal places decimal-format: "0,00" #The prefix for CombatLogX. #This is shown in front of all messages and should not be changed unless necessary. prefix: "[CombatLogX]" broadcast: #Shown when the plugin is finished loading. on-load: "CombatLogX wurde erfolgreich geladen." #Shown when the plugin is finished enabling. on-enable: "CombatLogX wurde aktiviert." #Shown when the plugin is disabled for any reason. on-disable: "CombatLogX ist nun deaktiviert" placeholder: #This text is used for the {combatlogx_time_left} #This allows server configurations to change the display value of the zero to something like "Not in combat" time-left-zero: "0" #This text is used when a player does not have an enemy. #This can happen when players are tagged by a custom expansion or the tag command. unknown-enemy: "Unbekannt" status: #Shown when the player is in combat. fighting: "Im Kampf" in-combat: "Ja" #Shown when the player is not in combat idle: "Leerlauf" not-in-combat: "Nein" #These placeholders are shown when a player changes a value such as whether or not their bossbar is enabled. toggle: enabled: "An" disabled: "Aus" pvp-status: enabled: "An" disabled: "Aus" combat-timer: #Sent to a player when they escape from combat due to the timer running out. expire: "Du bist nicht mehr im Kampf." #Sent to a player when they escape from combat due to their enemy being killed. enemy-death: "Dein Feind ist tot." #Sent when a player is killed during combat. self-death: "Du bist nicht mehr im Kampf, weil du gestorben bist." error: #Shown when the console tries to execute a command made for players. player-only: "Du bist kein Spieler" #Shown when a command that requires a player has invalid input. invalid-target: "Konnte den Spieler {target} nicht finden." #Shown when a command that requires a number has invalid input. invalid-integer: "{value} ist keine gültige Zahl." #Shown when a player does not have access to something that requires a permission. no-permission: "Du hast nicht die Berechtigungen {permission} dafür." #Shown when a player executes a command in a world that is disabled in the configuration. disabled-world: "Dieser Befehl ist in dieser Dimension nicht verfügbar." #Shown when a command requires a player in combat but the target player is not in combat. target-not-in-combat: "{target} ist nicht im Kampf." #Shown when a player executes a command that requires them to be in combat. self-not-in-combat: "Du bist nicht im Kampf." #Shown when a command that requires an expansion has invalid input. unknown-expansion: "{target} ist keine Erweiterung oder ist nicht installiert." command: combatlogx: #Shown as the command output for '/combatlogx help'. help-message-list: - "" - "CombatLogX Befehlshilfe:" - " /combatlogx help: Diese Hilfeseite anzeigen." - " /combatlogx laden: Laden Sie die config.yml, language.yml und alle Konfigurationsdateien für die Erweiterung." - " /combatlogx über \\: Prüfe Informationen über eine Erweiterung." - " /combatlogx tag \\ [seconds]: Erzwinge einen Spieler in den Kampf." - " /combatlogx umschalten Bossbar/actionbar/scoreboard: Aktivieren oder deaktivieren Sie einen Benachrichtigungstyp." - " /combatlogx untag \\: Erzwinge einen Spieler aus dem Kampf." - " /combatlogx version: Überprüfen Sie Ihre CombatLogX." - "" #Shown as the command output for '/combatlogx reload' when reloading is successful. reload-success: - "Alle Konfigurationsdateien von CombatLogX erfolgreich neu geladen." - "Alle Sprachdateien von CombatLogX erfolgreich neu geladen." - "Alle Konfigurationsdateien von CombatLogX Erweiterungen erfolgreich neu geladen." #Shown as the command output for '/combatlogx reload' when reloading fails reload-failure: - "Beim erneuten Laden der Konfiguration ist ein Fehler aufgetreten." - "Bitte überprüfen Sie Ihr Serverlog und korrigieren Sie die beschädigte Datei." #Shown as the command output for '/combatlogx tag ' when a player is tagged successfully. tag-player: "Spieler {target} erfolgreich in den Kampf gezwungen." #Shown as the command output for '/combatlogx tag ' when the plugin failed to tag a player. tag-failure: "{target} konnte nicht im Kampf platziert werden. (Vielleicht haben sie eine Umgehung?)" #Shown as the command output for '/combatlogx untag '. untag-player: "Spieler erfolgreich erzwungen {target} aus dem Kampf." #Shown as the command output for '/combatlogx toggle bossbar'. toggle-bossbar: "Boss Bar: {status}" #Shown as the command output for '/combatlogx toggle actionbar'. toggle-actionbar: "Aktionsleiste: {status}" #Shown as the command output for '/combatlogx toggle scoreboard'. toggle-scoreboard: "Anzeiger: {status}" combat-timer: #Shown as the command output for '/combat-timer'. time-left-self: "Du hast {time_left} Sekunden&a übrig." #Shown as the command output for '/combat-timer '. time-left-other: "{target} hat {time_left} Sekunden verbleibend." #These messages are shown a player is tagged into combat. tagged: unknown: player: "Du bist jetzt im Kampf mit {enemy} aus einem unbekannten Grund. Melde dich nicht ab!" mob: "Du bist jetzt im Kampf mit ein(n) {enemy} aus einem unbekannten Grund. Melde dich nicht ab!" mythic_mob: "Du bist jetzt im Kampf mit ein(n) {mob_type} aus einem unbekannten Grund. Melde dich nicht ab!" damage: "Du bist jetzt im Kampf, weil du Schaden nimmst. Lade dich nicht aus!" unknown: "Du befindest dich jetzt im Kampf. Melde dich sich nicht ab!" attacked: player: "Du wirst angegriffen von {name}. Melde dich nicht ab!" mob: "Du wirst angegriffen von a(n) {mob_type}. Melde dich nicht ab!" mythic_mob: "Sie werden von ein(n) {enemy}angegriffen. Nicht ausloggen!" damage: "Du bist jetzt im Kampf, weil du Schaden nimmst. Lade dich nicht aus!" unknown: "Du wirst von einer unbekannten Kraft angegriffen. Melde dich nicht ab!" attacker: player: "Du wirst angegriffen von {name}. Melde dich nicht ab!" mob: "Wir wirst attakiert von {mob_type}. Melde dich nicht ab!" mythic_mob: "Du greifst ein(n) {enemy}an. Nicht ausloggen!" damage: "Du bist jetzt im Kampf, weil du Schaden nimmst. Lade dich nicht aus!" unknown: "Du greifst eine unbekannte Kraft an. Logge dich nicht aus!" expansion: angel-chest: #Shown when opening an AngelChest is prevented during combat. prevent-opening: "Du darfst keine Engeltruhen während des Kampfes öffnen." #Shown when breaking an AngelChest is prevented during combat. prevent-breaking: "Du darfst keine Engeltruhen während des Kampfes brechen." #Shown when fast looting an AngelChest is prevented during combat. prevent-fast-looting: "Du darfst keine Beute Engeltruhe während des Kampfes beschleunigen." action-bar: #Shown above the hotbar while a player is in combat. timer: "Kampf \u00BB {bars} {combatlogx_time_left} Sekunden." #Shown above the hotbar for a brief period when combat ends. ended: "Kampf \u00BB Sie sind nicht mehr im Kampf." boss-bar: #Shown on top of the screen while a player is in combat. timer: "Kampf \u00BB {combatlogx_time_left} Sekunden." #Shown on top of the screen for a brief period when combat ends. ended: "Kampf \u00BB Sie sind nicht mehr im Kampf." scoreboard: #The scoreboard title for the sidebar. #Make sure to follow the scoreboard title limits for your Spigot version. title: "CombatLogX" #The scoreboard lines for the sidebar. #Make sure to follow the scoreboard line and character limits for your Spigot version. lines: - " " - "Kampfstatistik:" - "\u00BB Zeit übrig: {combatlogx_time_left}" - "\u00BB Enemies: {combatlogx_enemy_count}" - "\u00BB Status: {combatlogx_status}" - " " - "Enemies" - "\u00BB {combatlogx_specific_enemy_1_name}" - "\u00BB {combatlogx_specific_enemy_2_name}" - "\u00BB {combatlogx_specific_enemy_3_name}" - " " cheat-prevention: #Shown when a command execution is prevented during combat. command-blocked: "Du kannst diesen Command {command} jetzt nicht benutzen." #Shown when the riptide effect is prevented during combat. no-riptide: "Riptide ist deaktiviert während dem Kampf." #Shown when a totem of undying is prevented during combat. no-totem: "Du darfst kein Totem-Of-Undying im Kampf benutzen." #Shown when an entity interaction is prevented during combat. no-entity-interaction: "Du darfst das Mob nicht benutzen." #Shown when a chat message is prevented during combat. no-chat: "Du darfst keine Nachrichten schicken.." game-mode: #Shown when a player is forced into a specific game mmode during combat. force-switch: "Dein Game-Mode wurde zu {game_mode} gewechselt." #Shown when a game mode switch is prevented during combat. no-switch: "Du darfst den Game-Mode nicht wechseln während dem Kampf." flight: #Shown when a player's ability to fly is disabled during combat. force-disabled: "Deine Fähigkeit zu fliegen wurde deaktiviert." #Shown when a player's attempt to fly is prevented during combat. no-flying: "Du darfst nicht fliegen während des Kampfes." elytra: #Shown when a player's ability to glide is disabled during combat. force-disabled: "Deine Elytra wurde deaktiviert." #Shown when a player's attempt to glide is prevented during combat. no-gliding: "Du darfst keine Elytra benutzen während des Kampes." teleportation: #Shown when a player tries to enter a portal and is prevented during combat. block-portal: "Du darfst kein Portal während des Kampfes benutzen." #Shown when an ender pearl is prevented during combat. block-pearl: "Du darfst keine Enderperle während des Kampfes benutzen." #Shown when a teleport is prevented during combat. block-other: "Du darfst dich nicht teleportieren während des Kampfes." inventory: #Shown when a player's inventory is closed by the plugin during combat. force-closed: "Dein Inventar wurde geschlossen." #Shown when a player tries to open an inventory and is prevented during combat. no-opening: "Du darfst das Inventar nicht während des Kampfes öffnen." blocks: #Shown when a player is prevented from breaking a block during combat. prevent-breaking: "Du darfst keine Blöcke abbauen während des Kampfes." #Shown when a player is prevented from breaking a block during combat. prevent-placing: "Du darfst keine Blöcke platzieren während des Kampfes." #Shown when a player is prevented from breaking a block during combat. prevent-interaction: "Du darfst keine Blöcke benutzen während des Kampfes." #Shown when a player is prevented from breaking a block during combat. prevent-portal-creation: "Du darfst keine Portale während des Kampfes erstellen." items: #Shown when a player is prevented from picking up an item during combat. no-pickup: "Du darfst keine Items aufnehmen während des Kampfes." #Shown when a player is prevented from dropping an item during combat. no-dropping: "Du darfst keine Items droppen während des Kampfes." buckets: #Shown when a player is prevented from emptying a bucket during combat. no-empty: "Du kannst die Eimer während des Kampfes nicht leeren." #Shown when a player is prevented from filling a bucket during combat. no-fill: "Du kannst keine Eimer während des Kampfes füllen." damage-tagger: #Shown when a player is tagged for an unknown damage type. unknown-damage: "Du hast Schaden genommen.!" #These messages are shown when a player is tagged for a known damage type. #You can find a list of damage types here: #https://hub.spigotmc.org/javadocs/spigot/org/bukkit/event/entity/EntityDamageEvent.DamageCause.html damage-type: contact: "Du wurdest von einem Kaktus gestochen. Melden Sie sich nicht ab!" suffocation: "Du erstickst in einer Wand. Melden Sie sich nicht ab!" fall: "Du hast Sturzschaden erlitten. Melden Sie sich nicht ab!" fire: "Du bist ins Feuer gegangen. Nicht abmelden!" fire-tick: "Du bist ins Feuer gegangen. Nicht abmelden!" lava: "Du kochst in Lava. Nicht abmelden!" drowning: "Du ertrinkst. Nicht abmelden!" block-explosion: "Sie wurden durch eine Explosion beschädigt. Nicht abmelden!" lightning: "Du wurdest vom Blitz getroffen! Nicht abmelden!" starvation: "Du bist zu hungrig. Nicht abmelden!" poison: "Du hast Giftschaden erlitten. Nicht abmelden!" magic: "Jemand hat einen Trank nach dir geworfen. Nicht abmelden!" wither: "Du hast Wither. Nicht abmelden!" falling-block: "Ein Block ist auf dich gefallen. Nicht abmelden!" custom: "Du hast benutzerdefinierten Schaden erlitten. Nicht abmelden!" fly-into-wall: "Du hast kinetische Energie erfahren. Nicht abmelden!" hot-floor: "Der Boden ist Lava! Nicht abmelden!" cramming: "Du wirst gequetscht. Nicht abmelden!" newbie-helper: togglepvp: #Shown as the command output for '/togglepvp'. self: "PvP: {status}" #Shown as the command output for '/togglepvp admin on/off '. admin: "Du hast PVP bei {target} {status}." #Shown when the '/togglepvp' command is on cooldown. cooldown: "Sie müssen {time_left} Sekunden warten, um diesen Befehl erneut nutzen zu können." #These messages are shown when pvp is disabled for any reason. no-pvp: self: "Du darfst diesen Spieler nicht treffen, während dein PvP deaktiviert ist." other: "Dieser Spieler hat PvP deaktiviert." protected: "Dieser Spieler ist geschützt, du darfst ihn noch nicht angreifen!" protection-disabled: #Shown when newbie protection is disabled due to the player attacking another player. attacker: "Sie haben jemanden angegriffen, Ihr Anfängerschutz ist jetzt deaktiviert." #Shown when newbie protection expires. expired: "Ihr Anfängerschutz ist abgelaufen." #Shown for the '/togglepvp check ' command. check-format: - "Informationen für {target}:" - "Schutz: {protected}" - "PvP: {pvp}" loot-protection: #Shown when an enemy dies and their loot is protected. enemy-died: "{enemy} ist gestorben. Loot wird für {time} Sekunden geschützt." #Shown when a player tries to pick up an item that is loot protected by the plugin. protected: "Dieses Item ist derzeit geschützt, warte {time} Sekunden, bis du es abholen kannst." citizens-compatibility: #Shown when a player is prevented from joining the server due to their NPC still existing. prevent-join: "Als Strafe für das Abmelden während des Kampfes dürfen Sie nicht beitreten, bis Ihr Klon getötet oder entfernt wurde." disguise-compatibility: #Shown when a disguise is removed from a player during combat. remove-disguise: "Deine Verkleidung wurde entfernt." essentials-compatibility: #Shown when a teleport request is cancelled during combat. prevent-teleport-request-self: "Du kannst keine Teleportierungsanfragen während des Kampfes erstellen." #Shown when a teleport request is cancelled during combat. prevent-teleport-request-other: "Du kannst keine Teleportierungsanfrage an einen Spieler senden, der im Kampf ist." marriagemaster-compatibility: #Shown when a married player is prevented from teleporting to their partner during combat. prevent-teleport-self: "Du darfst dich während des Kampfes nicht zu deinem Partner teleportieren." #Shown when a married player is prevented from teleporting to their partner during combat. prevent-teleport-partner: "Du darfst dich nicht zu deinem Partner teleportieren, während er im Kampf ist." region-protection: #Shown when a player tries to enter a no-pvp area during combat. default-no-entry: "Du darfst diesen Bereich während des Kampfes nicht betreten." factions-no-entry: Du darfst diesen Bereich während des Kampfes nicht betreten. griefdefender-no-entry: Du darfst diesen Bereich während des Kampfes nicht betreten. griefprevention-no-entry: Du darfst diesen Bereich während des Kampfes nicht betreten. kingdomsx-no-entry: Du darfst diesen Bereich während des Kampfes nicht betreten. konquest-no-entry: Du darfst diesen Bereich während des Kampfes nicht betreten. redprotect-no-entry: Du darfst diesen Bereich während des Kampfes nicht betreten. residence-no-entry: Du darfst diesen Bereich während des Kampfes nicht betreten. towny-no-entry: Du darfst diesen Bereich während des Kampfes nicht betreten. husktowns-no-entry: Du darfst diesen Bereich während des Kampfes nicht betreten. ultimateclaims-no-entry: Du darfst diesen Bereich während des Kampfes nicht betreten. protectionstones: prevent-area-creation: "Du darfst während des Kampfes keine geschützte Fläche erstellen." no-entry: Du darfst diesen Bereich während des Kampfes nicht betreten. preciousstones: prevent-field-creation: "Du darfst während des Kampfes kein Schutzfeld erstellen." no-entry: Du darfst diesen Bereich während des Kampfes nicht betreten. worldguard: no-entry-mob-combat: "Es ist dir nicht gestattet, während des Kampfes ein Nicht-Mob-Kampfgebiet zu betreten." no-entry-player-combat: "Es ist dir nicht gestattet, während des Kampfes ein Nicht-Spieler-Kampfgebiet zu betreten." no-entry-unknown-combat: Du darfst diesen Bereich während des Kampfes nicht betreten. lands: no-entry: Du darfst diesen Bereich während des Kampfes nicht betreten. war-disable-newbie-protection: "PvP ist jetzt aufgrund einer Kriegserklärung aktiviert." ================================================ FILE: plugin/src/main/resources/language/de_ch.lang.yml ================================================ --- ## Extra Information: ## This is the default language file for CombatLogX. ## The default language is "en_us", also known as English (United States). ## Context will be added as YAML comments above the string. ## The color scheme for messages is gold, white, and sometimes red. ## Command feedback that is successful should always be green. ## Error messages should always be red. ## Variables in messages can be gray or white. ## Messages use the MiniMessage format in non-strict mode. ## More information about MiniMessage can be found here: ## https://docs.adventure.kyori.net/minimessage/format.html #The language code for this file. language-name: "de_ch" #The format for decimal numbers. #The United States uses the number and two decimal places decimal-format: "0.00" #The prefix for CombatLogX. #This is shown in front of all messages and should not be changed unless necessary. prefix: "[CombatLogX]" broadcast: #Shown when the plugin is finished loading. on-load: "CombatLogX wurde erfolgreich geladen." #Shown when the plugin is finished enabling. on-enable: "CombatLogX wurde aktiviert." #Shown when the plugin is disabled for any reason. on-disable: "CombatLogX ist nun deaktiviert" placeholder: #This text is used for the {combatlogx_time_left} #This allows server configurations to change the display value of the zero to something like "Not in combat" time-left-zero: "0" #This text is used when a player does not have an enemy. #This can happen when players are tagged by a custom expansion or the tag command. unknown-enemy: "Nicht bekannt" status: #Shown when the player is in combat. fighting: "Im Kampf" in-combat: "Ja" #Shown when the player is not in combat idle: "Leerlauf" not-in-combat: "Nein" #These placeholders are shown when a player changes a value such as whether or not their bossbar is enabled. toggle: enabled: "An" disabled: "Aus" pvp-status: enabled: "An" disabled: "Aus" combat-timer: #Sent to a player when they escape from combat due to the timer running out. expire: "Du bist nicht mehr im Kampf." #Sent to a player when they escape from combat due to their enemy being killed. enemy-death: "Dein Feind ist tot." #Sent when a player is killed during combat. self-death: "Du bist nicht mehr im Kampf, weil du gestorben bist." error: #Shown when the console tries to execute a command made for players. player-only: "Du bist kein Spieler" #Shown when a command that requires a player has invalid input. invalid-target: "Konnte den Spieler {target} nicht finden." #Shown when a command that requires a number has invalid input. invalid-integer: "{value} ist keine gültige Zahl." #Shown when a player does not have access to something that requires a permission. no-permission: "Du hast nicht die Berechtigungen {permission} dafür." #Shown when a player executes a command in a world that is disabled in the configuration. disabled-world: "Dieser Befehl ist in dieser Dimension nicht verfügbar." #Shown when a command requires a player in combat but the target player is not in combat. target-not-in-combat: "{target} ist nicht im Kampf." #Shown when a player executes a command that requires them to be in combat. self-not-in-combat: "Du bist nicht im Kampf." #Shown when a command that requires an expansion has invalid input. unknown-expansion: "{target} ist keine Erweiterung oder ist nicht installiert." command: combatlogx: #Shown as the command output for '/combatlogx help'. help-message-list: - "" - "CombatLogX Befehlshilfe:" - " /combatlogx help: Diese Hilfeseite anzeigen." - " /combatlogx laden: Laden Sie die config.yml, language.yml und alle Konfigurationsdateien für die Erweiterung." - " /combatlogx über \\: Prüfe Informationen über eine Erweiterung." - " /combatlogx tag \\ [seconds]: Erzwinge einen Spieler in den Kampf." - " /combatlogx umschalten Bossbar/actionbar/scoreboard: Aktivieren oder deaktivieren Sie einen Benachrichtigungstyp." - " /combatlogx untag \\: Erzwinge einen Spieler aus dem Kampf." - " /combatlogx version: Überprüfen Sie Ihre CombatLogX." - "" #Shown as the command output for '/combatlogx reload' when reloading is successful. reload-success: - "Alle Konfigurationsdateien von CombatLogX erfolgreich neu geladen." - "Alle Sprachdateien von CombatLogX erfolgreich neu geladen." - "Alle Konfigurationsdateien von CombatLogX Erweiterungen erfolgreich neu geladen." #Shown as the command output for '/combatlogx reload' when reloading fails reload-failure: - "Beim erneuten Laden der Konfiguration ist ein Fehler aufgetreten." - "Bitte überprüfen Sie Ihr Serverlog und korrigieren Sie die beschädigte Datei." #Shown as the command output for '/combatlogx tag ' when a player is tagged successfully. tag-player: "Spieler {target} erfolgreich in den Kampf gezwungen." #Shown as the command output for '/combatlogx tag ' when the plugin failed to tag a player. tag-failure: "{target} konnte nicht im Kampf platziert werden. (Vielleicht haben sie eine Umgehung?)" #Shown as the command output for '/combatlogx untag '. untag-player: "Spieler erfolgreich erzwungen {target} aus dem Kampf." #Shown as the command output for '/combatlogx toggle bossbar'. toggle-bossbar: "Boss Bar: {status}" #Shown as the command output for '/combatlogx toggle actionbar'. toggle-actionbar: "Aktionsleiste: {status}" #Shown as the command output for '/combatlogx toggle scoreboard'. toggle-scoreboard: "Anzeiger: {status}" combat-timer: #Shown as the command output for '/combat-timer'. time-left-self: "Du hast {time_left} Sekunden&a übrig." #Shown as the command output for '/combat-timer '. time-left-other: "{target} hat {time_left} Sekunden verbleibend." #These messages are shown a player is tagged into combat. tagged: unknown: player: "Du bist jetzt im Kampf mit {enemy} aus einem unbekannten Grund. Melde dich nicht ab!" mob: "Du bist jetzt im Kampf mit ein(n) {enemy} aus einem unbekannten Grund. Melde dich nicht ab!" mythic_mob: "Du bist jetzt im Kampf mit ein(n) {mob_type} aus einem unbekannten Grund. Melde dich nicht ab!" damage: "Du bist jetzt im Kampf, weil du Schaden nimmst. Lade dich nicht aus!" unknown: "Du befindest dich jetzt im Kampf. Melde dich sich nicht ab!" attacked: player: "Du wirst angegriffen von {name}. Melde dich nicht ab!" mob: "Du wirst angegriffen von a(n) {mob_type}. Melde dich nicht ab!" mythic_mob: "Sie werden von ein(n) {enemy}angegriffen. Nicht ausloggen!" damage: "Du bist jetzt im Kampf, weil du Schaden nimmst. Lade dich nicht aus!" unknown: "Du wirst von einer unbekannten Kraft angegriffen. Melde dich nicht ab!" attacker: player: "Du wirst angegriffen von {name}. Melde dich nicht ab!" mob: "Wir wirst attakiert von {mob_type}. Melde dich nicht ab!" mythic_mob: "Du greifst ein(n) {enemy}an. Nicht ausloggen!" damage: "Du bist jetzt im Kampf, weil du Schaden nimmst. Lade dich nicht aus!" unknown: "Du greifst eine unbekannte Kraft an. Logge dich nicht aus!" expansion: angel-chest: #Shown when opening an AngelChest is prevented during combat. prevent-opening: "Du darfst keine Engeltruhen während des Kampfes öffnen." #Shown when breaking an AngelChest is prevented during combat. prevent-breaking: "Du darfst keine Engeltruhen während des Kampfes brechen." #Shown when fast looting an AngelChest is prevented during combat. prevent-fast-looting: "Du darfst keine Beute Engeltruhe während des Kampfes beschleunigen." action-bar: #Shown above the hotbar while a player is in combat. timer: "Kampf \u00BB {bars} {combatlogx_time_left} Sekunden." #Shown above the hotbar for a brief period when combat ends. ended: "Kampf \u00BB Sie sind nicht mehr im Kampf." boss-bar: #Shown on top of the screen while a player is in combat. timer: "Kampf \u00BB {combatlogx_time_left} Sekunden." #Shown on top of the screen for a brief period when combat ends. ended: "Kampf \u00BB Sie sind nicht mehr im Kampf." scoreboard: #The scoreboard title for the sidebar. #Make sure to follow the scoreboard title limits for your Spigot version. title: "CombatLogX" #The scoreboard lines for the sidebar. #Make sure to follow the scoreboard line and character limits for your Spigot version. lines: - " " - "Kampfstatistik:" - "\u00BB Zeit übrig: {combatlogx_time_left}" - "\u00BB Enemies: {combatlogx_enemy_count}" - "\u00BB Status: {combatlogx_status}" - " " - "Enemies" - "\u00BB {combatlogx_specific_enemy_1_name}" - "\u00BB {combatlogx_specific_enemy_2_name}" - "\u00BB {combatlogx_specific_enemy_3_name}" - " " cheat-prevention: #Shown when a command execution is prevented during combat. command-blocked: "Du kannst diesen Command {command} jetzt nicht benutzen." #Shown when the riptide effect is prevented during combat. no-riptide: "Riptide ist deaktiviert während dem Kampf." #Shown when a totem of undying is prevented during combat. no-totem: "Du darfst kein Totem-Of-Undying im Kampf benutzen." #Shown when an entity interaction is prevented during combat. no-entity-interaction: "Du darfst das Mob nicht benutzen." #Shown when a chat message is prevented during combat. no-chat: "Du darfst keine Nachrichten schicken.." game-mode: #Shown when a player is forced into a specific game mmode during combat. force-switch: "Dein Game-Mode wurde zu {game_mode} gewechselt." #Shown when a game mode switch is prevented during combat. no-switch: "Du darfst den Game-Mode nicht wechseln während dem Kampf." flight: #Shown when a player's ability to fly is disabled during combat. force-disabled: "Deine Fähigkeit zu fliegen wurde deaktiviert." #Shown when a player's attempt to fly is prevented during combat. no-flying: "Du darfst nicht fliegen während des Kampfes." elytra: #Shown when a player's ability to glide is disabled during combat. force-disabled: "Deine Elytra wurde deaktiviert." #Shown when a player's attempt to glide is prevented during combat. no-gliding: "Du darfst keine Elytra benutzen während des Kampes." teleportation: #Shown when a player tries to enter a portal and is prevented during combat. block-portal: "Du darfst kein Portal während des Kampfes benutzen." #Shown when an ender pearl is prevented during combat. block-pearl: "Du darfst keine Enderperle während des Kampfes benutzen." #Shown when a teleport is prevented during combat. block-other: "Du darfst dich nicht teleportieren während des Kampfes." inventory: #Shown when a player's inventory is closed by the plugin during combat. force-closed: "Dein Inventar wurde geschlossen." #Shown when a player tries to open an inventory and is prevented during combat. no-opening: "Du darfst das Inventar nicht während des Kampfes öffnen." blocks: #Shown when a player is prevented from breaking a block during combat. prevent-breaking: "Du darfst keine Blöcke abbauen während des Kampfes." #Shown when a player is prevented from breaking a block during combat. prevent-placing: "Du darfst keine Blöcke platzieren während des Kampfes." #Shown when a player is prevented from breaking a block during combat. prevent-interaction: "Du darfst keine Blöcke benutzen während des Kampfes." #Shown when a player is prevented from breaking a block during combat. prevent-portal-creation: "Du darfst keine Portale während des Kampfes erstellen." items: #Shown when a player is prevented from picking up an item during combat. no-pickup: "Du darfst keine Items aufnehmen während des Kampfes." #Shown when a player is prevented from dropping an item during combat. no-dropping: "Du darfst keine Items droppen während des Kampfes." buckets: #Shown when a player is prevented from emptying a bucket during combat. no-empty: "Du kannst die Eimer während des Kampfes nicht leeren." #Shown when a player is prevented from filling a bucket during combat. no-fill: "Du kannst keine Eimer während des Kampfes füllen." damage-tagger: #Shown when a player is tagged for an unknown damage type. unknown-damage: "Du hast Schaden genommen.!" #These messages are shown when a player is tagged for a known damage type. #You can find a list of damage types here: #https://hub.spigotmc.org/javadocs/spigot/org/bukkit/event/entity/EntityDamageEvent.DamageCause.html damage-type: contact: "Du wurdest von einem Kaktus gestochen. Melden Sie sich nicht ab!" suffocation: "Du erstickst in einer Wand. Melden Sie sich nicht ab!" fall: "Du hast Sturzschaden erlitten. Melden Sie sich nicht ab!" fire: "Du bist ins Feuer gegangen. Nicht abmelden!" fire-tick: "Du bist ins Feuer gegangen. Nicht abmelden!" lava: "Du kochst in Lava. Nicht abmelden!" drowning: "Du ertrinkst. Nicht abmelden!" block-explosion: "Sie wurden durch eine Explosion beschädigt. Nicht abmelden!" lightning: "Du wurdest vom Blitz getroffen! Nicht abmelden!" starvation: "Du bist zu hungrig. Nicht abmelden!" poison: "Du hast Giftschaden erlitten. Nicht abmelden!" magic: "Jemand hat einen Trank nach dir geworfen. Nicht abmelden!" wither: "Du hast Wither. Nicht abmelden!" falling-block: "Ein Block ist auf dich gefallen. Nicht abmelden!" custom: "Du hast benutzerdefinierten Schaden erlitten. Nicht abmelden!" fly-into-wall: "Du hast kinetische Energie erfahren. Nicht abmelden!" hot-floor: "Der Boden ist Lava! Nicht abmelden!" cramming: "Du wirst gequetscht. Nicht abmelden!" newbie-helper: togglepvp: #Shown as the command output for '/togglepvp'. self: "PvP: {status}" #Shown as the command output for '/togglepvp admin on/off '. admin: "Du hast PVP bei {target} {status}." #Shown when the '/togglepvp' command is on cooldown. cooldown: "Sie müssen {time_left} Sekunden warten, um diesen Befehl erneut nutzen zu können." #These messages are shown when pvp is disabled for any reason. no-pvp: self: "Du darfst diesen Spieler nicht treffen, während dein PvP deaktiviert ist." other: "Dieser Spieler hat PvP deaktiviert." protected: "Dieser Spieler ist geschützt, du darfst ihn noch nicht angreifen!" protection-disabled: #Shown when newbie protection is disabled due to the player attacking another player. attacker: "Sie haben jemanden angegriffen, Ihr Anfängerschutz ist jetzt deaktiviert." #Shown when newbie protection expires. expired: "Ihr Anfängerschutz ist abgelaufen." #Shown for the '/togglepvp check ' command. check-format: - "Informationen für {target}:" - "Schutz: {protected}" - "PvP: {pvp}" loot-protection: #Shown when an enemy dies and their loot is protected. enemy-died: "{enemy} ist gestorben. Loot wird für {time} Sekunden geschützt." #Shown when a player tries to pick up an item that is loot protected by the plugin. protected: "Dieses Item ist derzeit geschützt, warte {time} Sekunden, bis du es abholen kannst." citizens-compatibility: #Shown when a player is prevented from joining the server due to their NPC still existing. prevent-join: "Als Strafe für das Abmelden während des Kampfes dürfen Sie nicht beitreten, bis Ihr Klon getötet oder entfernt wurde." disguise-compatibility: #Shown when a disguise is removed from a player during combat. remove-disguise: "Deine Verkleidung wurde entfernt." essentials-compatibility: #Shown when a teleport request is cancelled during combat. prevent-teleport-request-self: "Du kannst keine Teleportierungsanfragen während des Kampfes erstellen." #Shown when a teleport request is cancelled during combat. prevent-teleport-request-other: "Du kannst keine Teleportierungsanfrage an einen Spieler senden, der im Kampf ist." marriagemaster-compatibility: #Shown when a married player is prevented from teleporting to their partner during combat. prevent-teleport-self: "Du darfst dich während des Kampfes nicht zu deinem Partner teleportieren." #Shown when a married player is prevented from teleporting to their partner during combat. prevent-teleport-partner: "Du darfst dich nicht zu deinem Partner teleportieren, während er im Kampf ist." region-protection: #Shown when a player tries to enter a no-pvp area during combat. default-no-entry: "Du darfst diesen Bereich während des Kampfes nicht betreten." factions-no-entry: Du darfst diesen Bereich während des Kampfes nicht betreten. griefdefender-no-entry: Du darfst diesen Bereich während des Kampfes nicht betreten. griefprevention-no-entry: Du darfst diesen Bereich während des Kampfes nicht betreten. kingdomsx-no-entry: Du darfst diesen Bereich während des Kampfes nicht betreten. konquest-no-entry: Du darfst diesen Bereich während des Kampfes nicht betreten. redprotect-no-entry: Du darfst diesen Bereich während des Kampfes nicht betreten. residence-no-entry: Du darfst diesen Bereich während des Kampfes nicht betreten. towny-no-entry: Du darfst diesen Bereich während des Kampfes nicht betreten. husktowns-no-entry: Du darfst diesen Bereich während des Kampfes nicht betreten. ultimateclaims-no-entry: Du darfst diesen Bereich während des Kampfes nicht betreten. protectionstones: prevent-area-creation: "Du darfst während des Kampfes keine geschützte Fläche erstellen." no-entry: Du darfst diesen Bereich während des Kampfes nicht betreten. preciousstones: prevent-field-creation: "Du darfst während des Kampfes kein Schutzfeld erstellen." no-entry: Du darfst diesen Bereich während des Kampfes nicht betreten. worldguard: no-entry-mob-combat: "Es ist dir nicht gestattet, während des Kampfes ein Nicht-Mob-Kampfgebiet zu betreten." no-entry-player-combat: "Es ist dir nicht gestattet, während des Kampfes ein Nicht-Spieler-Kampfgebiet zu betreten." no-entry-unknown-combat: Du darfst diesen Bereich während des Kampfes nicht betreten. lands: no-entry: Du darfst diesen Bereich während des Kampfes nicht betreten. war-disable-newbie-protection: "PvP ist jetzt aufgrund einer Kriegserklärung aktiviert." ================================================ FILE: plugin/src/main/resources/language/de_de.lang.yml ================================================ --- ## Extra Information: ## This is the default language file for CombatLogX. ## The default language is "en_us", also known as English (United States). ## Context will be added as YAML comments above the string. ## The color scheme for messages is gold, white, and sometimes red. ## Command feedback that is successful should always be green. ## Error messages should always be red. ## Variables in messages can be gray or white. ## Messages use the MiniMessage format in non-strict mode. ## More information about MiniMessage can be found here: ## https://docs.adventure.kyori.net/minimessage/format.html #The language code for this file. language-name: "de_de" #The format for decimal numbers. #The United States uses the number and two decimal places decimal-format: "0,00" #The prefix for CombatLogX. #This is shown in front of all messages and should not be changed unless necessary. prefix: "[CombatLogX]" broadcast: #Shown when the plugin is finished loading. on-load: "CombatLogX wurde erfolgreich geladen." #Shown when the plugin is finished enabling. on-enable: "CombatLogX wurde aktiviert." #Shown when the plugin is disabled for any reason. on-disable: "CombatLogX ist nun deaktiviert" placeholder: #This text is used for the {combatlogx_time_left} #This allows server configurations to change the display value of the zero to something like "Not in combat" time-left-zero: "0" #This text is used when a player does not have an enemy. #This can happen when players are tagged by a custom expansion or the tag command. unknown-enemy: "Unbekannt" status: #Shown when the player is in combat. fighting: "Im Kampf" in-combat: "Ja" #Shown when the player is not in combat idle: "Leerlauf" not-in-combat: "Nein" #These placeholders are shown when a player changes a value such as whether or not their bossbar is enabled. toggle: enabled: "An" disabled: "Aus" pvp-status: enabled: "An" disabled: "Aus" combat-timer: #Sent to a player when they escape from combat due to the timer running out. expire: "Du bist nicht mehr im Kampf." #Sent to a player when they escape from combat due to their enemy being killed. enemy-death: "Dein Feind ist tot." #Sent when a player is killed during combat. self-death: "Du bist nicht mehr im Kampf, weil du gestorben bist." error: #Shown when the console tries to execute a command made for players. player-only: "Du bist kein Spieler" #Shown when a command that requires a player has invalid input. invalid-target: "Konnte den Spieler {target} nicht finden." #Shown when a command that requires a number has invalid input. invalid-integer: "{value} ist keine gültige Zahl." #Shown when a player does not have access to something that requires a permission. no-permission: "Du hast nicht die Berechtigungen {permission} dafür." #Shown when a player executes a command in a world that is disabled in the configuration. disabled-world: "Dieser Befehl ist in dieser Dimension nicht verfügbar." #Shown when a command requires a player in combat but the target player is not in combat. target-not-in-combat: "{target} ist nicht im Kampf." #Shown when a player executes a command that requires them to be in combat. self-not-in-combat: "Du bist nicht im Kampf." #Shown when a command that requires an expansion has invalid input. unknown-expansion: "{target} ist keine Erweiterung oder ist nicht installiert." command: combatlogx: #Shown as the command output for '/combatlogx help'. help-message-list: - "" - "CombatLogX Befehlshilfe:" - " /combatlogx help: Diese Hilfeseite anzeigen." - " /combatlogx laden: Laden Sie die config.yml, language.yml und alle Konfigurationsdateien für die Erweiterung." - " /combatlogx über \\: Prüfe Informationen über eine Erweiterung." - " /combatlogx tag \\ [seconds]: Erzwinge einen Spieler in den Kampf." - " /combatlogx umschalten Bossbar/actionbar/scoreboard: Aktivieren oder deaktivieren Sie einen Benachrichtigungstyp." - " /combatlogx untag \\: Erzwinge einen Spieler aus dem Kampf." - " /combatlogx version: Überprüfen Sie Ihre CombatLogX." - "" #Shown as the command output for '/combatlogx reload' when reloading is successful. reload-success: - "Alle Konfigurationsdateien von CombatLogX erfolgreich neu geladen." - "Alle Sprachdateien von CombatLogX erfolgreich neu geladen." - "Alle Konfigurationsdateien von CombatLogX Erweiterungen erfolgreich neu geladen." #Shown as the command output for '/combatlogx reload' when reloading fails reload-failure: - "Beim erneuten Laden der Konfiguration ist ein Fehler aufgetreten." - "Bitte überprüfen Sie Ihr Serverlog und korrigieren Sie die beschädigte Datei." #Shown as the command output for '/combatlogx tag ' when a player is tagged successfully. tag-player: "Spieler {target} erfolgreich in den Kampf gezwungen." #Shown as the command output for '/combatlogx tag ' when the plugin failed to tag a player. tag-failure: "{target} konnte nicht im Kampf platziert werden. (Vielleicht haben sie eine Umgehung?)" #Shown as the command output for '/combatlogx untag '. untag-player: "Spieler erfolgreich erzwungen {target} aus dem Kampf." #Shown as the command output for '/combatlogx toggle bossbar'. toggle-bossbar: "Boss Bar: {status}" #Shown as the command output for '/combatlogx toggle actionbar'. toggle-actionbar: "Aktionsleiste: {status}" #Shown as the command output for '/combatlogx toggle scoreboard'. toggle-scoreboard: "Anzeiger: {status}" combat-timer: #Shown as the command output for '/combat-timer'. time-left-self: "Du hast {time_left} Sekunden&a übrig." #Shown as the command output for '/combat-timer '. time-left-other: "{target} hat {time_left} Sekunden verbleibend." #These messages are shown a player is tagged into combat. tagged: unknown: player: "Du bist jetzt im Kampf mit {enemy} aus einem unbekannten Grund. Melde dich nicht ab!" mob: "Du bist jetzt im Kampf mit ein(n) {enemy} aus einem unbekannten Grund. Melde dich nicht ab!" mythic_mob: "Du bist jetzt im Kampf mit ein(n) {mob_type} aus einem unbekannten Grund. Melde dich nicht ab!" damage: "Du bist jetzt im Kampf, weil du Schaden nimmst. Lade dich nicht aus!" unknown: "Du befindest dich jetzt im Kampf. Melde dich sich nicht ab!" attacked: player: "Du wirst angegriffen von {enemy}. Melde dich nicht ab!" mob: "Du wirst angegriffen von a(n) {mob_type}. Melde dich nicht ab!" mythic_mob: "Sie werden von ein(n) {enemy}angegriffen. Nicht ausloggen!" damage: "Du bist jetzt im Kampf, weil du Schaden nimmst. Lade dich nicht aus!" unknown: "Du wirst von einer unbekannten Kraft angegriffen. Melde dich nicht ab!" attacker: player: "Du wirst angegriffen von {enemy}. Melde dich nicht ab!" mob: "Wir wirst attakiert von {mob_type}. Melde dich nicht ab!" mythic_mob: "Du greifst ein(n) {enemy}an. Nicht ausloggen!" damage: "Du bist jetzt im Kampf, weil du Schaden nimmst. Lade dich nicht aus!" unknown: "Du greifst eine unbekannte Kraft an. Logge dich nicht aus!" expansion: angel-chest: #Shown when opening an AngelChest is prevented during combat. prevent-opening: "Du darfst keine Engeltruhen während des Kampfes öffnen." #Shown when breaking an AngelChest is prevented during combat. prevent-breaking: "Du darfst keine Engeltruhen während des Kampfes brechen." #Shown when fast looting an AngelChest is prevented during combat. prevent-fast-looting: "Du darfst keine Beute Engeltruhe während des Kampfes beschleunigen." action-bar: #Shown above the hotbar while a player is in combat. timer: "Kampf \u00BB {bars} {combatlogx_time_left} Sekunden." #Shown above the hotbar for a brief period when combat ends. ended: "Kampf \u00BB Sie sind nicht mehr im Kampf." boss-bar: #Shown on top of the screen while a player is in combat. timer: "Kampf \u00BB {combatlogx_time_left} Sekunden." #Shown on top of the screen for a brief period when combat ends. ended: "Kampf \u00BB Sie sind nicht mehr im Kampf." scoreboard: #The scoreboard title for the sidebar. #Make sure to follow the scoreboard title limits for your Spigot version. title: "CombatLogX" #The scoreboard lines for the sidebar. #Make sure to follow the scoreboard line and character limits for your Spigot version. lines: - " " - "Kampfstatistik:" - "\u00BB Zeit übrig: {combatlogx_time_left}" - "\u00BB Enemies: {combatlogx_enemy_count}" - "\u00BB Status: {combatlogx_status}" - " " - "Enemies" - "\u00BB {combatlogx_specific_enemy_1_name}" - "\u00BB {combatlogx_specific_enemy_2_name}" - "\u00BB {combatlogx_specific_enemy_3_name}" - " " cheat-prevention: #Shown when a command execution is prevented during combat. command-blocked: "Du kannst diesen Command {command} jetzt nicht benutzen." #Shown when the riptide effect is prevented during combat. no-riptide: "Riptide ist deaktiviert während dem Kampf." #Shown when a totem of undying is prevented during combat. no-totem: "Du darfst kein Totem-Of-Undying im Kampf benutzen." #Shown when an entity interaction is prevented during combat. no-entity-interaction: "Du darfst das Mob nicht benutzen." #Shown when a chat message is prevented during combat. no-chat: "Du darfst keine Nachrichten schicken.." game-mode: #Shown when a player is forced into a specific game mmode during combat. force-switch: "Dein Game-Mode wurde zu {game_mode} gewechselt." #Shown when a game mode switch is prevented during combat. no-switch: "Du darfst den Game-Mode nicht wechseln während dem Kampf." flight: #Shown when a player's ability to fly is disabled during combat. force-disabled: "Deine Fähigkeit zu fliegen wurde deaktiviert." #Shown when a player's attempt to fly is prevented during combat. no-flying: "Du darfst nicht fliegen während des Kampfes." elytra: #Shown when a player's ability to glide is disabled during combat. force-disabled: "Deine Elytra wurde deaktiviert." #Shown when a player's attempt to glide is prevented during combat. no-gliding: "Du darfst keine Elytra benutzen während des Kampes." teleportation: #Shown when a player tries to enter a portal and is prevented during combat. block-portal: "Du darfst kein Portal während des Kampfes benutzen." #Shown when an ender pearl is prevented during combat. block-pearl: "Du darfst keine Enderperle während des Kampfes benutzen." #Shown when a teleport is prevented during combat. block-other: "Du darfst dich nicht teleportieren während des Kampfes." inventory: #Shown when a player's inventory is closed by the plugin during combat. force-closed: "Dein Inventar wurde geschlossen." #Shown when a player tries to open an inventory and is prevented during combat. no-opening: "Du darfst das Inventar nicht während des Kampfes öffnen." blocks: #Shown when a player is prevented from breaking a block during combat. prevent-breaking: "Du darfst keine Blöcke abbauen während des Kampfes." #Shown when a player is prevented from breaking a block during combat. prevent-placing: "Du darfst keine Blöcke platzieren während des Kampfes." #Shown when a player is prevented from breaking a block during combat. prevent-interaction: "Du darfst keine Blöcke benutzen während des Kampfes." #Shown when a player is prevented from breaking a block during combat. prevent-portal-creation: "Du darfst keine Portale während des Kampfes erstellen." items: #Shown when a player is prevented from picking up an item during combat. no-pickup: "Du darfst keine Items aufnehmen während des Kampfes." #Shown when a player is prevented from dropping an item during combat. no-dropping: "Du darfst keine Items droppen während des Kampfes." buckets: #Shown when a player is prevented from emptying a bucket during combat. no-empty: "Du kannst die Eimer während des Kampfes nicht leeren." #Shown when a player is prevented from filling a bucket during combat. no-fill: "Du kannst keine Eimer während des Kampfes füllen." damage-tagger: #Shown when a player is tagged for an unknown damage type. unknown-damage: "Du hast Schaden genommen.!" #These messages are shown when a player is tagged for a known damage type. #You can find a list of damage types here: #https://hub.spigotmc.org/javadocs/spigot/org/bukkit/event/entity/EntityDamageEvent.DamageCause.html damage-type: contact: "Du wurdest von einem Kaktus gestochen. Melden Sie sich nicht ab!" suffocation: "Du erstickst in einer Wand. Melden Sie sich nicht ab!" fall: "Du hast Sturzschaden erlitten. Melden Sie sich nicht ab!" fire: "Du bist ins Feuer gegangen. Nicht abmelden!" fire-tick: "Du bist ins Feuer gegangen. Nicht abmelden!" lava: "Du kochst in Lava. Nicht abmelden!" drowning: "Du ertrinkst. Nicht abmelden!" block-explosion: "Sie wurden durch eine Explosion beschädigt. Nicht abmelden!" lightning: "Du wurdest vom Blitz getroffen! Nicht abmelden!" starvation: "Du bist zu hungrig. Nicht abmelden!" poison: "Du hast Giftschaden erlitten. Nicht abmelden!" magic: "Jemand hat einen Trank nach dir geworfen. Nicht abmelden!" wither: "Du hast Wither. Nicht abmelden!" falling-block: "Ein Block ist auf dich gefallen. Nicht abmelden!" custom: "Du hast benutzerdefinierten Schaden erlitten. Nicht abmelden!" fly-into-wall: "Du hast kinetische Energie erfahren. Nicht abmelden!" hot-floor: "Der Boden ist Lava! Nicht abmelden!" cramming: "Du wirst gequetscht. Nicht abmelden!" newbie-helper: togglepvp: #Shown as the command output for '/togglepvp'. self: "PvP: {status}" #Shown as the command output for '/togglepvp admin on/off '. admin: "Du hast PVP bei {target} {status}." #Shown when the '/togglepvp' command is on cooldown. cooldown: "Sie müssen {time_left} Sekunden warten, um diesen Befehl erneut nutzen zu können." #These messages are shown when pvp is disabled for any reason. no-pvp: self: "Du darfst diesen Spieler nicht treffen, während dein PvP deaktiviert ist." other: "Dieser Spieler hat PvP deaktiviert." protected: "Dieser Spieler ist geschützt, du darfst ihn noch nicht angreifen!" protection-disabled: #Shown when newbie protection is disabled due to the player attacking another player. attacker: "Sie haben jemanden angegriffen, Ihr Anfängerschutz ist jetzt deaktiviert." #Shown when newbie protection expires. expired: "Ihr Anfängerschutz ist abgelaufen." #Shown for the '/togglepvp check ' command. check-format: - "Informationen für {target}:" - "Schutz: {protected}" - "PvP: {pvp}" loot-protection: #Shown when an enemy dies and their loot is protected. enemy-died: "{enemy} ist gestorben. Loot wird für {time} Sekunden geschützt." #Shown when a player tries to pick up an item that is loot protected by the plugin. protected: "Dieses Item ist derzeit geschützt, warte {time} Sekunden, bis du es abholen kannst." citizens-compatibility: #Shown when a player is prevented from joining the server due to their NPC still existing. prevent-join: "Als Strafe für das Abmelden während des Kampfes dürfen Sie nicht beitreten, bis Ihr Klon getötet oder entfernt wurde." disguise-compatibility: #Shown when a disguise is removed from a player during combat. remove-disguise: "Deine Verkleidung wurde entfernt." essentials-compatibility: #Shown when a teleport request is cancelled during combat. prevent-teleport-request-self: "Du kannst keine Teleportierungsanfragen während des Kampfes erstellen." #Shown when a teleport request is cancelled during combat. prevent-teleport-request-other: "Du kannst keine Teleportierungsanfrage an einen Spieler senden, der im Kampf ist." marriagemaster-compatibility: #Shown when a married player is prevented from teleporting to their partner during combat. prevent-teleport-self: "Du darfst dich während des Kampfes nicht zu deinem Partner teleportieren." #Shown when a married player is prevented from teleporting to their partner during combat. prevent-teleport-partner: "Du darfst dich nicht zu deinem Partner teleportieren, während er im Kampf ist." region-protection: #Shown when a player tries to enter a no-pvp area during combat. default-no-entry: "Du darfst diesen Bereich während des Kampfes nicht betreten." factions-no-entry: Du darfst diesen Bereich während des Kampfes nicht betreten. griefdefender-no-entry: Du darfst diesen Bereich während des Kampfes nicht betreten. griefprevention-no-entry: Du darfst diesen Bereich während des Kampfes nicht betreten. kingdomsx-no-entry: Du darfst diesen Bereich während des Kampfes nicht betreten. konquest-no-entry: Du darfst diesen Bereich während des Kampfes nicht betreten. redprotect-no-entry: Du darfst diesen Bereich während des Kampfes nicht betreten. residence-no-entry: Du darfst diesen Bereich während des Kampfes nicht betreten. towny-no-entry: Du darfst diesen Bereich während des Kampfes nicht betreten. husktowns-no-entry: Du darfst diesen Bereich während des Kampfes nicht betreten. ultimateclaims-no-entry: Du darfst diesen Bereich während des Kampfes nicht betreten. protectionstones: prevent-area-creation: "Du darfst während des Kampfes keine geschützte Fläche erstellen." no-entry: Du darfst diesen Bereich während des Kampfes nicht betreten. preciousstones: prevent-field-creation: "Du darfst während des Kampfes kein Schutzfeld erstellen." no-entry: Du darfst diesen Bereich während des Kampfes nicht betreten. worldguard: no-entry-mob-combat: "Es ist dir nicht gestattet, während des Kampfes ein Nicht-Mob-Kampfgebiet zu betreten." no-entry-player-combat: "Es ist dir nicht gestattet, während des Kampfes ein Nicht-Spieler-Kampfgebiet zu betreten." no-entry-unknown-combat: Du darfst diesen Bereich während des Kampfes nicht betreten. lands: no-entry: Du darfst diesen Bereich während des Kampfes nicht betreten. war-disable-newbie-protection: "PvP ist jetzt aufgrund einer Kriegserklärung aktiviert." ================================================ FILE: plugin/src/main/resources/language/el_gr.lang.yml ================================================ --- ## Extra Information: ## This is the default language file for CombatLogX. ## The default language is "en_us", also known as English (United States). ## Context will be added as YAML comments above the string. ## The color scheme for messages is gold, white, and sometimes red. ## Command feedback that is successful should always be green. ## Error messages should always be red. ## Variables in messages can be gray or white. ## Messages use the MiniMessage format in non-strict mode. ## More information about MiniMessage can be found here: ## https://docs.adventure.kyori.net/minimessage/format.html #The language code for this file. language-name: "el_us" #The format for decimal numbers. #The United States uses the number and two decimal places decimal-format: "0.00" #The prefix for CombatLogX. #This is shown in front of all messages and should not be changed unless necessary. prefix: "[CombatLogX]" broadcast: #Shown when the plugin is finished loading. on-load: "CombatLogX φορτώθηκε με επιτυχία." #Shown when the plugin is finished enabling. on-enable: "Το CombatLogX ενεργοποιήθηκε επιτυχώς." #Shown when the plugin is disabled for any reason. on-disable: "CombatLogX απενεργοποιήθηκε επιτυχώς." placeholder: #This text is used for the {combatlogx_time_left} #This allows server configurations to change the display value of the zero to something like "Not in combat" time-left-zero: "0" #This text is used when a player does not have an enemy. #This can happen when players are tagged by a custom expansion or the tag command. unknown-enemy: "Άγνωστο" status: #Shown when the player is in combat. fighting: "Καταπολέμηση" in-combat: "Ναι" #Shown when the player is not in combat idle: "Αδρανής" not-in-combat: "Αριθ." #These placeholders are shown when a player changes a value such as whether or not their bossbar is enabled. toggle: enabled: "ΕΝΕΡΓΟΠΟΙΗΣΗ" disabled: "ΑΝΕΝΕΡΓΟ" pvp-status: enabled: "ΕΝΕΡΓΟΠΟΙΗΣΗ" disabled: "ΑΝΕΝΕΡΓΟ" combat-timer: #Sent to a player when they escape from combat due to the timer running out. expire: "Δεν είστε πλέον σε μάχη." #Sent to a player when they escape from combat due to their enemy being killed. enemy-death: "Δεν είστε πλέον σε μάχη, επειδή ο εχθρός σας πέθανε." #Sent when a player is killed during combat. self-death: "Δεν είσαι πλέον σε μάχη, επειδή πέθανες." error: #Shown when the console tries to execute a command made for players. player-only: "Μόνο οι παίκτες μπορούν να εκτελέσουν αυτήν την εντολή" #Shown when a command that requires a player has invalid input. invalid-target: "{target} δεν είναι online ή δεν υπάρχει." #Shown when a command that requires a number has invalid input. invalid-integer: "{value} δεν είναι ένας έγκυρος ακέραιος αριθμός." #Shown when a player does not have access to something that requires a permission. no-permission: "Λείπει άδεια: {permission}" #Shown when a player executes a command in a world that is disabled in the configuration. disabled-world: "Αυτή η εντολή δεν είναι διαθέσιμη σε αυτή τη διάσταση." #Shown when a command requires a player in combat but the target player is not in combat. target-not-in-combat: "{target} δεν είναι σε μάχη." #Shown when a player executes a command that requires them to be in combat. self-not-in-combat: "Δεν είστε σε μάχη." #Shown when a command that requires an expansion has invalid input. unknown-expansion: "{target} δεν είναι επέκταση ή δεν έχει εγκατασταθεί." command: combatlogx: #Shown as the command output for '/combatlogx help'. help-message-list: - "" - "CombatLogX Βοήθεια Εντολής:" - " /combatlogx βοήθεια: Δείτε αυτή τη σελίδα βοήθειας." - " /combatlogx επαναφόρτωση: Επαναφόρτωση του config.yml, language.yml και όλων των αρχείων ρύθμισης επέκτασης." - " /combatlogx σχετικά με \\: Ελέγξτε τις πληροφορίες σχετικά με μια επέκταση." - " /combatlogx tag \\ [seconds]: Εξαναγκασμός ενός παίκτη σε μάχη." - " /combatlogx εναλλαγή bossbar/actionbar/scoreboard: Ενεργοποίηση ή απενεργοποίηση ενός τύπου ειδοποίησης." - " /combatlogx καταργεί την ετικέτα \\: Εξαναγκασμός ενός παίκτη εκτός μάχης." - " /combatlogx έκδοση: Ελέγξτε την έκδοση του CombatLogX." - "" #Shown as the command output for '/combatlogx reload' when reloading is successful. reload-success: - "Επιτυχής φόρτωση όλων των αρχείων ρύθμισης παραμέτρων από το CombatLogX." - "Επιτυχής επαναφόρτωση όλων των αρχείων γλώσσας από το CombatLogX." - "Επιτυχής επαναφόρτωση όλων των αρχείων ρύθμισης παραμέτρων από επεκτάσεις CombatLogX." #Shown as the command output for '/combatlogx reload' when reloading fails reload-failure: - "Παρουσιάστηκε σφάλμα κατά την επαναφόρτωση των ρυθμίσεων." - "Παρακαλούμε ελέγξτε το αρχείο καταγραφής του διακομιστή σας και διορθώστε το κατεστραμμένο αρχείο." #Shown as the command output for '/combatlogx tag ' when a player is tagged successfully. tag-player: "Επιτυχής εξαναγκασμός παίκτη {target} στη μάχη." #Shown as the command output for '/combatlogx tag ' when the plugin failed to tag a player. tag-failure: "{target} δεν μπορούσε να τοποθετηθεί στη μάχη. (Μάλλον έχουν παρακάμψει?)" #Shown as the command output for '/combatlogx untag '. untag-player: "Επιτυχής εξαναγκασμένος παίκτης {target} εκτός μάχης." #Shown as the command output for '/combatlogx toggle bossbar'. toggle-bossbar: "Γραμμή αφεντικών: {status}" #Shown as the command output for '/combatlogx toggle actionbar'. toggle-actionbar: "Γραμμή ενεργειών: {status}" #Shown as the command output for '/combatlogx toggle scoreboard'. toggle-scoreboard: "Πίνακας αποτελεσμάτων: {status}" combat-timer: #Shown as the command output for '/combat-timer'. time-left-self: "Απομένουν {time_left} δευτερόλεπτα." #Shown as the command output for '/combat-timer '. time-left-other: "{target} έχει {time_left} δευτερόλεπτα απομένουν." #These messages are shown a player is tagged into combat. tagged: unknown: player: "Τώρα είστε σε μάχη με {enemy} για έναν άγνωστο λόγο. Μην αποσυνδεθείτε!" mob: "Τώρα είστε σε μάχη με a(n) {enemy} για έναν άγνωστο λόγο. Μην αποσυνδεθείτε!" mythic_mob: "Τώρα είστε σε μάχη με a(n) {mob_type} για έναν άγνωστο λόγο. Μην αποσυνδεθείτε!" damage: "Τώρα είστε σε μάχη λόγω της βλάβης. Μην αποσυνδέετε!" unknown: "Είσαι τοποθετημένος σε μάχες χωρίς λόγο. Μην αποσυνδεθείς." attacked: player: "Σας δέχονται επίθεση από {enemy}. Μην αποσυνδεθείτε!" mob: "Είστε υπό επίθεση από a(n) {mob_type}. Μην αποσυνδεθείτε!" mythic_mob: "Είστε υπό επίθεση από a(n) {enemy}. Μην αποσυνδεθείτε!" damage: "Τώρα είστε σε μάχη λόγω της βλάβης. Μην αποσυνδέετε!" unknown: "Είστε υπό επίθεση από άγνωστη δύναμη. Μην κάνετε αποσύνδεση!" attacker: player: "Επιτίθεστε {enemy}. Μην αποσυνδεθείτε!" mob: "Επιτίθεστε a(n) {mob_type}. Μην αποσυνδεθείτε!" mythic_mob: "Επιτίθεστε a(n) {enemy}. Μην αποσυνδεθείτε!" damage: "Τώρα είστε σε μάχη λόγω της βλάβης. Μην αποσυνδέετε!" unknown: "Επιτίθεστε σε μια άγνωστη δύναμη. Μην κάνετε αποσύνδεση!" expansion: angel-chest: #Shown when opening an AngelChest is prevented during combat. prevent-opening: "Δεν επιτρέπεται να ανοίξετε κιβώτια άγγελου κατά τη διάρκεια της μάχης." #Shown when breaking an AngelChest is prevented during combat. prevent-breaking: "Δεν επιτρέπεται να σπάσετε κιβώτια άγγελου κατά τη διάρκεια της μάχης." #Shown when fast looting an AngelChest is prevented during combat. prevent-fast-looting: "Δεν επιτρέπεται να λεηλατήσετε τα κιβώτια άγγελου κατά τη διάρκεια της μάχης." action-bar: #Shown above the hotbar while a player is in combat. timer: "Συνδυάστε \u00BB {bars} {combatlogx_time_left} δευτερόλεπτα." #Shown above the hotbar for a brief period when combat ends. ended: "Μάχη \u00BB Δεν είστε πλέον σε μάχη." boss-bar: #Shown on top of the screen while a player is in combat. timer: "Συνδυάστε \u00BB {combatlogx_time_left} δευτερόλεπτα." #Shown on top of the screen for a brief period when combat ends. ended: "Μάχη \u00BB Δεν είστε πλέον σε μάχη." scoreboard: #The scoreboard title for the sidebar. #Make sure to follow the scoreboard title limits for your Spigot version. title: "CombatLogX" #The scoreboard lines for the sidebar. #Make sure to follow the scoreboard line and character limits for your Spigot version. lines: - " " - "Καταστήματα Καταπολέμησης:" - "\u00BB Χρόνος που απομένει: {combatlogx_time_left}" - "\u00BB Enemies: {combatlogx_enemy_count}" - "\u00BB Κατάσταση: {combatlogx_status}" - " " - "Enemies" - "\u00BB {combatlogx_specific_enemy_1_name}" - "\u00BB {combatlogx_specific_enemy_2_name}" - "\u00BB {combatlogx_specific_enemy_3_name}" - " " cheat-prevention: #Shown when a command execution is prevented during combat. command-blocked: "Δεν έχετε πρόσβαση σε {command} κατά τη διάρκεια της μάχης." #Shown when the riptide effect is prevented during combat. no-riptide: "Η μαγεία riptide είναι απενεργοποιημένη κατά τη διάρκεια της μάχης." #Shown when a totem of undying is prevented during combat. no-totem: "Δεν επιτρέπεται να χρησιμοποιήσετε totems της δύσης κατά τη διάρκεια της μάχης." #Shown when an entity interaction is prevented during combat. no-entity-interaction: "Δεν επιτρέπεται να χρησιμοποιήσετε αυτό το πλύσιμο κατά τη διάρκεια της μάχης." #Shown when a chat message is prevented during combat. no-chat: "Δεν επιτρέπεται να στέλνετε μηνύματα συνομιλίας κατά τη διάρκεια της μάχης." game-mode: #Shown when a player is forced into a specific game mmode during combat. force-switch: "Η λειτουργία παιχνιδιού σας άλλαξε σε {game_mode}." #Shown when a game mode switch is prevented during combat. no-switch: "Δεν επιτρέπεται η αλλαγή λειτουργιών παιχνιδιού κατά τη διάρκεια της μάχης." flight: #Shown when a player's ability to fly is disabled during combat. force-disabled: "Η ικανότητά σας να πετάξετε αφαιρέθηκε." #Shown when a player's attempt to fly is prevented during combat. no-flying: "Δεν επιτρέπεται να πετάξετε κατά τη διάρκεια της μάχης." elytra: #Shown when a player's ability to glide is disabled during combat. force-disabled: "Η elytra σας απενεργοποιήθηκε." #Shown when a player's attempt to glide is prevented during combat. no-gliding: "Δεν επιτρέπεται να χρησιμοποιείτε elytra κατά τη διάρκεια της μάχης." teleportation: #Shown when a player tries to enter a portal and is prevented during combat. block-portal: "Δεν επιτρέπεται να χρησιμοποιήσετε μια πύλη κατά τη διάρκεια της μάχης." #Shown when an ender pearl is prevented during combat. block-pearl: "Δεν επιτρέπεται να χρησιμοποιείτε μαργαριτάρια κατά τη διάρκεια της μάχης." #Shown when a teleport is prevented during combat. block-other: "Δεν επιτρέπεται η τηλεμεταφορά κατά τη διάρκεια της μάχης." inventory: #Shown when a player's inventory is closed by the plugin during combat. force-closed: "Τα αποθέματά σας έκλεισαν." #Shown when a player tries to open an inventory and is prevented during combat. no-opening: "Δεν επιτρέπεται να ανοίξετε αποθέματα κατά τη διάρκεια της μάχης." blocks: #Shown when a player is prevented from breaking a block during combat. prevent-breaking: "Δεν επιτρέπεται να σπάσετε μπλοκ κατά τη διάρκεια της μάχης." #Shown when a player is prevented from breaking a block during combat. prevent-placing: "Δεν επιτρέπεται να τοποθετείτε μπλοκ κατά τη διάρκεια της μάχης." #Shown when a player is prevented from breaking a block during combat. prevent-interaction: "Δεν επιτρέπεται να χρησιμοποιείτε μπλοκ κατά τη διάρκεια της μάχης." #Shown when a player is prevented from breaking a block during combat. prevent-portal-creation: "Δεν επιτρέπεται να δημιουργήσετε πύλες κατά τη διάρκεια της μάχης." items: #Shown when a player is prevented from picking up an item during combat. no-pickup: "Δεν επιτρέπεται να παραλάβετε αντικείμενα κατά τη διάρκεια της μάχης." #Shown when a player is prevented from dropping an item during combat. no-dropping: "Δεν επιτρέπεται να ρίξετε αντικείμενα κατά τη διάρκεια της μάχης." buckets: #Shown when a player is prevented from emptying a bucket during combat. no-empty: "Δεν μπορείτε να αδειάσετε κάδους κατά τη διάρκεια της μάχης." #Shown when a player is prevented from filling a bucket during combat. no-fill: "Δεν μπορείτε να γεμίσετε κάδους κατά τη διάρκεια της μάχης." damage-tagger: #Shown when a player is tagged for an unknown damage type. unknown-damage: "Λάβατε ζημιά! Μην αποσυνδεθείτε!" #These messages are shown when a player is tagged for a known damage type. #You can find a list of damage types here: #https://hub.spigotmc.org/javadocs/spigot/org/bukkit/event/entity/EntityDamageEvent.DamageCause.html damage-type: contact: "Έχετε τραβηχτεί από έναν κάκτο. Μην αποσυνδεθείτε!" suffocation: "Καταπνίγετε σε έναν τοίχο. Μην αποσυνδεθείτε!" fall: "Τραβήξατε ζημιά. Μην αποσυνδεθείτε!" fire: "Μπήκατε στη φωτιά. Μην αποσυνδεθείτε!" fire-tick: "Κάνετε εγγραφή. Μην αποσυνδεθείτε!" lava: "Βράζετε στη λάβα. Μην αποσυνδεθείτε!" drowning: "Είστε πνιγμένοι. Μην αποσυνδεθείτε!" block-explosion: "Έχετε υποστεί ζημιά από έκρηξη. Μην αποσυνδεθείτε!" lightning: "Εσύ χτύπησε! Μην αποσυνδεθείτε!" starvation: "Είστε πολύ πεινασμένοι. Μην αποσυνδεθείτε!" poison: "Τραβήξατε ζημιά δηλητηρίασης. Μην αποσυνδεθείτε!" magic: "Κάποιος έριξε ένα φίλτρο σε σας. Μην αποσυνδεθείτε!" wither: "Απομακρύνεστε. Μην αποσυνδεθείτε!" falling-block: "Ένα μπλοκ έπεσε πάνω σου. Μην αποσυνδεθείς!" custom: "Λάβατε προσαρμοσμένη ζημιά. Μην αποσυνδεθείτε!" fly-into-wall: "Βιώσατε κινητική ενέργεια. Μην αποσυνδέετε!" hot-floor: "Ο όροφος είναι λάβα! Μην αποσυνδεθείτε!" cramming: "Είστε χαμένοι. Μην αποσυνδεθείτε!" newbie-helper: togglepvp: #Shown as the command output for '/togglepvp'. self: "PVP: {status}" #Shown as the command output for '/togglepvp admin on/off '. admin: "Αλλάξατε το pvp του {target} σε {status}." #Shown when the '/togglepvp' command is on cooldown. cooldown: "Πρέπει να περιμένετε {time_left} δευτερόλεπτα για να χρησιμοποιήσετε ξανά αυτήν την εντολή." #These messages are shown when pvp is disabled for any reason. no-pvp: self: "Δεν επιτρέπεται να χτυπήσετε αυτόν τον παίκτη ενώ το PvP σας είναι απενεργοποιημένο." other: "Αυτός ο παίκτης έχει PvP απενεργοποιημένο." protected: "Ο παίκτης είναι προστατευμένος, δεν επιτρέπεται να τον επιτεθείτε ακόμα!" protection-disabled: #Shown when newbie protection is disabled due to the player attacking another player. attacker: "Εσείς επιτεθήκατε σε κάποιον, η προστασία σας από νεογέννητους είναι τώρα απενεργοποιημένη." #Shown when newbie protection expires. expired: "Έχει λήξει η προστασία σας στο newbie." #Shown for the '/togglepvp check ' command. check-format: - "Πληροφορίες για {target}:" - "Προστασία: {protected}" - "PvP: {pvp}" loot-protection: #Shown when an enemy dies and their loot is protected. enemy-died: "{enemy} έχει πεθάνει. Λάφυρα θα προστατεύονται για {time} δευτερόλεπτα." #Shown when a player tries to pick up an item that is loot protected by the plugin. protected: "Αυτό το αντικείμενο προστατεύεται επί του παρόντος, περιμένετε {time} δευτερόλεπτα μέχρι να μπορείτε να το παραλάβετε." citizens-compatibility: #Shown when a player is prevented from joining the server due to their NPC still existing. prevent-join: "Δεν επιτρέπεται να γίνετε μέλος του διακομιστή μέχρι να τερματιστεί ή να αφαιρεθεί ο NPC σας." disguise-compatibility: #Shown when a disguise is removed from a player during combat. remove-disguise: "Η μεταμφίεση σας αφαιρέθηκε." essentials-compatibility: #Shown when a teleport request is cancelled during combat. prevent-teleport-request-self: "Δεν μπορείτε να δημιουργήσετε αιτήματα τηλεμεταφοράς κατά τη διάρκεια της μάχης." #Shown when a teleport request is cancelled during combat. prevent-teleport-request-other: "Δεν μπορείτε να στείλετε αίτημα τηλεμεταφοράς σε έναν παίκτη που είναι σε μάχη." marriagemaster-compatibility: #Shown when a married player is prevented from teleporting to their partner during combat. prevent-teleport-self: "Δεν επιτρέπεται η τηλεμεταφορά στον σύντροφό σας κατά τη διάρκεια της μάχης." #Shown when a married player is prevented from teleporting to their partner during combat. prevent-teleport-partner: "Δεν επιτρέπεται η τηλεμεταφορά στον σύντροφό σας ενώ είναι σε μάχη." region-protection: #Shown when a player tries to enter a no-pvp area during combat. default-no-entry: "Δεν επιτρέπεται να εισέλθετε σε αυτήν την περιοχή κατά τη διάρκεια της μάχης." factions-no-entry: Δεν επιτρέπεται να εισέλθετε σε αυτήν την περιοχή κατά τη διάρκεια της μάχης. griefdefender-no-entry: Δεν επιτρέπεται να εισέλθετε σε αυτήν την περιοχή κατά τη διάρκεια της μάχης. griefprevention-no-entry: Δεν επιτρέπεται να εισέλθετε σε αυτήν την περιοχή κατά τη διάρκεια της μάχης. kingdomsx-no-entry: Δεν επιτρέπεται να εισέλθετε σε αυτήν την περιοχή κατά τη διάρκεια της μάχης. konquest-no-entry: Δεν επιτρέπεται να εισέλθετε σε αυτήν την περιοχή κατά τη διάρκεια της μάχης. redprotect-no-entry: Δεν επιτρέπεται να εισέλθετε σε αυτήν την περιοχή κατά τη διάρκεια της μάχης. residence-no-entry: Δεν επιτρέπεται να εισέλθετε σε αυτήν την περιοχή κατά τη διάρκεια της μάχης. towny-no-entry: Δεν επιτρέπεται να εισέλθετε σε αυτήν την περιοχή κατά τη διάρκεια της μάχης. husktowns-no-entry: Δεν επιτρέπεται να εισέλθετε σε αυτήν την περιοχή κατά τη διάρκεια της μάχης. ultimateclaims-no-entry: Δεν επιτρέπεται να εισέλθετε σε αυτήν την περιοχή κατά τη διάρκεια της μάχης. protectionstones: prevent-area-creation: "Δεν επιτρέπεται να δημιουργήσετε μια προστατευμένη περιοχή κατά τη διάρκεια της μάχης." no-entry: Δεν επιτρέπεται να εισέλθετε σε αυτήν την περιοχή κατά τη διάρκεια της μάχης. preciousstones: prevent-field-creation: "Δεν επιτρέπεται να δημιουργήσετε ένα πεδίο προστασίας κατά τη διάρκεια της μάχης." no-entry: Δεν επιτρέπεται να εισέλθετε σε αυτήν την περιοχή κατά τη διάρκεια της μάχης. worldguard: no-entry-mob-combat: "Δεν επιτρέπεται να εισέλθετε σε μια μη μαχητική περιοχή κατά τη διάρκεια της μάχης." no-entry-player-combat: "Δεν επιτρέπεται να εισέλθετε σε μια περιοχή που δεν είναι παίχτης-μάχης κατά τη διάρκεια του αγώνα." no-entry-unknown-combat: Δεν επιτρέπεται να εισέλθετε σε αυτήν την περιοχή κατά τη διάρκεια της μάχης. lands: no-entry: Δεν επιτρέπεται να εισέλθετε σε αυτήν την περιοχή κατά τη διάρκεια της μάχης. war-disable-newbie-protection: "Το PvP είναι πλέον ενεργοποιημένο λόγω μιας διακήρυξης πολέμου." ================================================ FILE: plugin/src/main/resources/language/en_us.lang.yml ================================================ ## Extra Information: ## This is the default language file for CombatLogX. ## The default language is "en_us", also known as English (United States). ## Context will be added as YAML comments above the string. ## The color scheme for messages is gold, white, and sometimes red. ## Command feedback that is successful should always be green. ## Error messages should always be red. ## Variables in messages can be gray or white. ## Messages use the MiniMessage format in non-strict mode. ## More information about MiniMessage can be found here: ## https://docs.adventure.kyori.net/minimessage/format.html --- # The language code for this file. language-name: "en_us" # The format for decimal numbers. # The United States uses the number and two decimal places decimal-format: "0.00" # The prefix for CombatLogX that is shown in front of all messages. # Note to translators: Do not change this message. prefix: "[CombatLogX]" broadcast: # Shown when the plugin is finished loading. on-load: "CombatLogX was loaded successfully." # Shown when the plugin is finished enabling. on-enable: "CombatLogX was enabled successfully." # Shown when the plugin is disabled for any reason. on-disable: "CombatLogX was disabled successfully." placeholder: # This text is used for the {combatlogx_time_left} # This allows server configurations to change the display value of the zero to something like "Not in combat" time-left-zero: "0" # This text is used when a player does not have an enemy. # This can happen when players are tagged by a custom expansion or the tag command. unknown-enemy: "Unknown" status: # Shown when the player is in combat. fighting: "Fighting" in-combat: "Yes" # Shown when the player is not in combat idle: "Idle" not-in-combat: "No" # These placeholders are shown when a player changes a value such as whether or not their bossbar is enabled. toggle: enabled: "ON" disabled: "OFF" pvp-status: enabled: "ON" disabled: "OFF" # You can also change the location of these messages. # Example: # combat-timer: # expire: # type: ACTION_BAR # content: "" combat-timer: # Sent to a player when they escape from combat due to the timer running out. expire: "You are no longer in combat." # Sent to a player when they escape from combat due to their enemy being killed. enemy-death: "You are no longer in combat because your enemy died." # Sent when a player is killed during combat. self-death: "You are no longer in combat because you died." error: # Shown when the console tries to execute a command made for players. player-only: "Only players can execute this command" # Shown when a player tries to execute a command made for the server console. console-only: "This command can only be executed in the server console." # Shown when a command that requires a player has invalid input. invalid-target: "{target} is not online or does not exist." # Shown when a command that requires a number has invalid input. invalid-integer: "{value} is not a valid integer." # Shown when a player does not have access to something that requires a permission. no-permission: "Missing Permission: {permission}" # Shown when a player executes a command in a world that is disabled in the configuration. disabled-world: "That command is not available in this dimension." # Shown when a command requires a player in combat but the target player is not in combat. target-not-in-combat: "{target} is not in combat." # Shown when a player executes a command that requires them to be in combat. self-not-in-combat: "You are not in combat." # Shown when a command that requires an expansion has invalid input. unknown-expansion: "{target} is not an expansion or is not installed." forgive-not-enemy: "{target} is not one of your enemies." enemy-not-forgiving: "That enemy is not in the mood to forgive you." command: combatlogx: # Shown as the command output for '/combatlogx help'. help-message-list: - "" - "CombatLogX Command Help:" - " /combatlogx help: View this help page." - " /combatlogx reload: Reload the config.yml, language.yml, and all expansion config files." - " /combatlogx about \\: Check information about an expansion." - " /combatlogx tag \\ [seconds]: Force a player into combat." - " /combatlogx toggle bossbar/actionbar/scoreboard: Enable or disable a notification type." - " /combatlogx untag \\: Force a player out of combat." - " /combatlogx version: Check your version of CombatLogX." - " /combatlogx forgive request \\: Send a request to an enemy to remove their tag from you." - " /combatlogx forgive accept \\: Allow an enemy's request to escape from combat." - " /combatlogx forgive reject \\: Ignore an enemy's request to escape from combat." - " /combatlogx forgive toggle: Enable or disable requests for stopping combat." - "" # Shown as the command output for '/combatlogx reload' when reloading is successful. reload-success: - "Successfully reloaded all configuration files from CombatLogX." - "Successfully reloaded all language files from CombatLogX." - "Successfully reloaded all configuration files from CombatLogX expansions." # Shown as the command output for '/combatlogx reload' when reloading fails reload-failure: - "An error occurred while reloading the configuration." - "Please check your server log and fix the broken file." # Shown as the command output for '/combatlogx tag ' when a player is tagged successfully. tag-player: "Successfully forced player {target} into combat." # Shown as the command output for '/combatlogx tag ' when the plugin failed to tag a player. tag-failure: "{target} could not be placed into combat. (Maybe they have a bypass?)" # Shown as the command output for '/combatlogx untag '. untag-player: "Successfully forced player {target} out of combat." # Shown as the command output for '/combatlogx toggle bossbar'. toggle-bossbar: "Boss Bar: {status}" # Shown as the command output for '/combatlogx toggle actionbar'. toggle-actionbar: "Action Bar: {status}" # Shown as the command output for '/combatlogx toggle scoreboard'. toggle-scoreboard: "Scoreboard: {status}" # Shown as the command output for '/combatlogx about '. expansion-information: - "" - "Expansion Information for {name}:" - "Display Name: {prefix}" - "Version: {version}" - "State: {state}" - "" - "Description: {description}" - "Website: {website}" - "Authors: {authors}" forgive: toggle-disable: "You can no longer receive requests for forgiveness." toggle-enable: "You can now receive forgiveness requests." request-sent: "You sent a forgive request to {target}." request-receive: - "{player} sent a forgive request to you." - "Type /clx forgive accept to accept or." - "/clx forgive reject to deny." combat-timer: # Shown as the command output for '/combat-timer'. time-left-self: "You have {time_left} seconds remaining." # Shown as the command output for '/combat-timer '. time-left-other: "{target} has {time_left} seconds remaining." # These messages are shown a player is tagged into combat. # You can also change the location of these messages. # Example: # tagged: # attacked: # player: # type: ACTION_BAR # content: "" tagged: unknown: player: "You are now in combat with {enemy} for an unknown reason. Do not log out!" mob: "You are now in combat with a(n) {enemy} for an unknown reason. Do not log out!" mythic_mob: "You are now in combat with a(n) {mob_type} for an unknown reason. Do not log out!" damage: "You are now in combat due to taking damage. Do not log out!" unknown: "You were placed into combat without a reason. Do not log out." attacked: player: "You are being attacked by {enemy}. Do not log out!" mob: "You are being attacked by a(n) {mob_type}. Do not log out!" mythic_mob: "You are being attacked by a(n) {enemy}. Do not log out!" damage: "You are now in combat due to taking damage. Do not log out!" unknown: "You are being attacked by an unknown force. Do not log out!" attacker: player: "You are attacking {enemy}. Do not log out!" mob: "You are attacking a(n) {mob_type}. Do not log out!" mythic_mob: "You are attacking a(n) {enemy}. Do not log out!" damage: "You are now in combat due to taking damage. Do not log out!" unknown: "You are attacking an unknown force. Do not log out!" expansion: angel-chest: # Shown when opening an AngelChest is prevented during combat. prevent-opening: "You are not allowed to to open angel chests during combat." # Shown when breaking an AngelChest is prevented during combat. prevent-breaking: "You are not allowed to break angel chests during combat." # Shown when fast looting an AngelChest is prevented during combat. prevent-fast-looting: "You are not allowed to fast loot angel chests during combat." action-bar: # Shown above the hotbar while a player is in combat. timer: "Combat \u00BB {bars} {combatlogx_time_left} seconds." # Shown above the hotbar for a brief period when combat ends. ended: "Combat \u00BB You are no longer in combat." boss-bar: # Shown on top of the screen while a player is in combat. timer: "Combat \u00BB {combatlogx_time_left} seconds." # Shown on top of the screen for a brief period when combat ends. ended: "Combat \u00BB You are no longer in combat." scoreboard: # The scoreboard title for the sidebar. # Make sure to follow the scoreboard title limits for your Spigot version. title: "CombatLogX" # The scoreboard lines for the sidebar. # Make sure to follow the scoreboard line and character limits for your Spigot version. lines: - " " - "Combat Stats:" - "\u00BB Time Left: {combatlogx_time_left}" - "\u00BB Enemies: {combatlogx_enemy_count}" - "\u00BB Status: {combatlogx_status}" - " " - "Enemies" - "\u00BB {combatlogx_specific_enemy_1_name}" - "\u00BB {combatlogx_specific_enemy_2_name}" - "\u00BB {combatlogx_specific_enemy_3_name}" - " " cheat-prevention: # Shown when a command execution is prevented during combat. command-blocked: "You do not have access to {command} during combat." # Shown when the riptide effect is prevented during combat. no-riptide: "The riptide enchantment is disabled during combat." # Shown when a totem of undying is prevented during combat. no-totem: "You are not allowed to use totems of undying during combat." # Shown when an entity interaction is prevented during combat. no-entity-interaction: "You are not allowed to use that mob during combat." # Shown when a chat message is prevented during combat. no-chat: "You are not allowed to send chat messages during combat." game-mode: # Shown when a player is forced into a specific game mmode during combat. force-switch: "Your game mode was changed to {game_mode}." # Shown when a game mode switch is prevented during combat. no-switch: "You are not allowed to switch game modes during combat." flight: # Shown when a player's ability to fly is disabled during combat. force-disabled: "Your ability to fly was removed." # Shown when a player's attempt to fly is prevented during combat. no-flying: "You are not allowed to fly during combat." elytra: # Shown when a player's ability to glide is disabled during combat. force-disabled: "Your elytra was disabled." # Shown when a player's attempt to glide is prevented during combat. no-gliding: "You are not allowed to use elytra during combat." # Shown when a player tries to use fireworks. no-fireworks: "You are not allowed to launch fireworks during combat." teleportation: # Shown when a player tries to enter a portal and is prevented during combat. block-portal: "You are not allowed to use a portal during combat." # Shown when an ender pearl is prevented during combat. block-pearl: "You are not allowed to use ender pearls during combat." # Shown when a teleport is prevented during combat. block-other: "You are not allowed to teleport during combat." inventory: # Shown when a player's inventory is closed by the plugin during combat. force-closed: "Your inventory was closed." # Shown when a player tries to open an inventory and is prevented during combat. no-opening: "You are not allowed to open inventories during combat." blocks: # Shown when a player is prevented from breaking a block during combat. prevent-breaking: "You are not allowed to break blocks during combat." # Shown when a player is prevented from breaking a block during combat. prevent-placing: "You are not allowed to place blocks during combat." # Shown when a player is prevented from breaking a block during combat. prevent-interaction: "You are not allowed to use blocks during combat." # Shown when a player is prevented from breaking a block during combat. prevent-portal-creation: "You are not allowed to create portals during combat." items: # Shown when a player is prevented from picking up an item during combat. no-pickup: "You are not allowed to pick up items during combat." # Shown when a player is prevented from dropping an item during combat. no-dropping: "You are not allowed to drop items during combat." buckets: # Shown when a player is prevented from emptying a bucket during combat. no-empty: "You can't empty buckets during combat." # Shown when a player is prevented from filling a bucket during combat. no-fill: "You can't fill up buckets during combat." damage-tagger: # Shown when a player is tagged for an unknown damage type. unknown-damage: "You took damage! Do not log out!" # These messages are shown when a player is tagged for a known damage type. # You can find a list of damage types here: # https://hub.spigotmc.org/javadocs/spigot/org/bukkit/event/entity/EntityDamageEvent.DamageCause.html damage-type: block-explosion: "You were damaged by an explosion. Do not log out!" contact: "You were pricked by a cactus. Do not log out!" cramming: "You are being squished. Do not log out!" custom: "You took custom damage. Do not log out!" drowning: "You are drowning. Do not log out!" dryout: "You stayed out of water too long. Do not log out!" # May be triggered by custom plugins. entity-explosion: "You were damaged by an End Crystal explosion. Do not log out!" # Only triggered by end crystals. fall: "You took fall damage. Do not log out!" falling-block: "A block fell on you. Do not log out!" fire: "You walked into fire. Do not log out!" fire-tick: "You are burning. Do not log out!" fly-into-wall: "You experienced kinetic energy. Do not log out!" freeze: "You are freezing. Do not log out!" hot-floor: "The floor is lava! Do not log out!" lava: "You are boiling in lava. Do not log out!" lightning: "Thou hast been smitten! Do not log out!" magic: "Someone threw a potion at you. Do not log out!" melting: "You are melting! Do not log out." # May be triggered by custom plugins. poison: "You took poison damage. Do not log out!" starvation: "You are too hungry. Do not log out!" suffocation: "You are suffocating in a wall. Do not log out!" void: "You are falling into the void. Do not log out!" wither: "You are withering away. Do not log out!" world-border: "You are too close to the border. Do not log out!" newbie-helper: togglepvp: # Shown as the command output for '/togglepvp'. self: "PVP: {status}" # Shown as the command output for '/togglepvp admin on/off '. admin: "You changed the pvp of {target} to {status}." # Shown when the '/togglepvp' command is on cooldown. cooldown: "You must wait {time_left} seconds to use this command again." # These messages are shown when pvp is disabled for any reason. no-pvp: self: "You are not allowed to hit that player while your PvP is disabled." other: "That player has PvP disabled." protected: "That player is protected, you are not allowed to attack them yet!" cancel: "You are protected, you are not allowed to attack other players yet!" protection-disabled: # Shown when newbie protection is disabled due to the player attacking another player. attacker: "You attacked someone, your newbie protection is now disabled." # Shown when newbie protection expires. expired: "Your newbie protection has expired." # Shown for the '/togglepvp check ' command. check-format: - "Information for {target}:" - "Protection: {protected}" - "PvP: {pvp}" loot-protection: # Shown when an enemy dies and their loot is protected. enemy-died: "{enemy} has died. Loot will be protected for {time} seconds." # Shown when a player tries to pick up an item that is loot protected by the plugin. protected: "This item is currently protected, wait {time} seconds until you can pick it up." citizens-compatibility: # Shown when a player is prevented from joining the server due to their NPC still existing. prevent-join: "You are not allowed to join the server until your NPC is killed or removed." disguise-compatibility: # Shown when a disguise is removed from a player during combat. remove-disguise: "Your disguise was removed." essentials-compatibility: # Shown when a teleport request is cancelled during combat. prevent-teleport-request-self: "You can't create teleport requests during combat." # Shown when a teleport request is cancelled during combat. prevent-teleport-request-other: "You can't send a teleport request to a player that is in combat." marriagemaster-compatibility: # Shown when a married player is prevented from teleporting to their partner during combat. prevent-teleport-self: "You are not allowed to teleport to your partner during combat." # Shown when a married player is prevented from teleporting to their partner during combat. prevent-teleport-partner: "You are not allowed to teleport to your partner while they are in combat." huskhomes-compatibility: prevent-teleport: "You are not allowed to teleport during combat." region-protection: # Shown when a player tries to enter a no-pvp area during combat. default-no-entry: &noEntryMessage "You are not allowed to enter that area during combat." factions-no-entry: *noEntryMessage griefdefender-no-entry: *noEntryMessage griefprevention-no-entry: *noEntryMessage kingdomsx-no-entry: *noEntryMessage konquest-no-entry: *noEntryMessage redprotect-no-entry: *noEntryMessage residence-no-entry: *noEntryMessage towny-no-entry: *noEntryMessage husktowns-no-entry: *noEntryMessage ultimateclaims-no-entry: *noEntryMessage protectionstones: prevent-area-creation: "You are not allowed to create a protected area during combat." no-entry: *noEntryMessage preciousstones: prevent-field-creation: "You are not allowed to create a protection field during combat." no-entry: *noEntryMessage worldguard: no-entry-mob-combat: "You are not allowed to enter a non-mob-combat area during combat." no-entry-player-combat: "You are not allowed to enter a non-player-combat area during combat." no-entry-unknown-combat: *noEntryMessage lands: no-entry: *noEntryMessage war-disable-newbie-protection: "PvP is now force enabled due to a war declaration." ================================================ FILE: plugin/src/main/resources/language/es_ar.lang.yml ================================================ --- ## Extra Information: ## This is the default language file for CombatLogX. ## The default language is "en_us", also known as English (United States). ## Context will be added as YAML comments above the string. ## The color scheme for messages is gold, white, and sometimes red. ## Command feedback that is successful should always be green. ## Error messages should always be red. ## Variables in messages can be gray or white. ## Messages use the MiniMessage format in non-strict mode. ## More information about MiniMessage can be found here: ## https://docs.adventure.kyori.net/minimessage/format.html #The language code for this file. language-name: "es_ar" #The format for decimal numbers. #The United States uses the number and two decimal places decimal-format: "0.00" #The prefix for CombatLogX. #This is shown in front of all messages and should not be changed unless necessary. prefix: "[CombatLogX]" broadcast: #Shown when the plugin is finished loading. on-load: "CombatLogX ha sido cargado correctamente." #Shown when the plugin is finished enabling. on-enable: "CombatLogX ha sido habilitado correctamente." #Shown when the plugin is disabled for any reason. on-disable: "CombatLogX ha sido deshabilitado correctamente." placeholder: #This text is used for the {combatlogx_time_left} #This allows server configurations to change the display value of the zero to something like "Not in combat" time-left-zero: "0" #This text is used when a player does not have an enemy. #This can happen when players are tagged by a custom expansion or the tag command. unknown-enemy: "Desconocido" status: #Shown when the player is in combat. fighting: "Combatiendo" in-combat: "" #Shown when the player is not in combat idle: "Inactivo" not-in-combat: "No" #These placeholders are shown when a player changes a value such as whether or not their bossbar is enabled. toggle: enabled: "Activado" disabled: "Desactivado" pvp-status: enabled: "Activado" disabled: "Desactivado" combat-timer: #Sent to a player when they escape from combat due to the timer running out. expire: "Ya no estás en modo de combate." #Sent to a player when they escape from combat due to their enemy being killed. enemy-death: "Ya no estás en modo de combate debido a que tu enemigo murió." #Sent when a player is killed during combat. self-death: "Ya no estás en combate porque has muerto." error: #Shown when the console tries to execute a command made for players. player-only: "Solo jugadores pueden ejecutar este comando." #Shown when a command that requires a player has invalid input. invalid-target: "{target} no está conectado o no existe." #Shown when a command that requires a number has invalid input. invalid-integer: "{value} no es un entero válido." #Shown when a player does not have access to something that requires a permission. no-permission: "Permiso faltante: {permission}" #Shown when a player executes a command in a world that is disabled in the configuration. disabled-world: "%%red%%¡Ese comando no se encuentra disponible en esta dimensión!" #Shown when a command requires a player in combat but the target player is not in combat. target-not-in-combat: "{target} no está en combate." #Shown when a player executes a command that requires them to be in combat. self-not-in-combat: "No estás en combate." #Shown when a command that requires an expansion has invalid input. unknown-expansion: "{target} no es una expansión o no está instalada." command: combatlogx: #Shown as the command output for '/combatlogx help'. help-message-list: - "" - "Ayuda de CombatLogX:" - " /combatlogx help: Muestra este menú." - " /combatlogx reload: Reinicia los archivos config.yml, language.yml, y todos los archivos de configuración de sus expansiones." - " /combatlogx about \\: Revisa la información sobre una expansión." - " [seconds]" - " /combatlogx toggle bossbar/actionbar/scoreboard: Habilita o deshabilita alguno de estos mensajes." - " /combatlogx untag \\: Quitar forzosamente el modo combate." - " /combatlogx version: Muestra la versión de CombatLogX." - "" #Shown as the command output for '/combatlogx reload' when reloading is successful. reload-success: - "Se han recargado exitosamente todos los archivos de configuración de CombatLogX." - "Se ha recargado exitosamente el archivo de lenguaje de CombatLogX." - "Se han recargado exitosamente todos los archivos de configuración pertenecientes a las expansiones de CombatLogX." #Shown as the command output for '/combatlogx reload' when reloading fails reload-failure: - "Se ha producido un error al recargar la configuración." - "Compruebe el registro de su servidor y corrija el archivo roto." #Shown as the command output for '/combatlogx tag ' when a player is tagged successfully. tag-player: "Se ha forzado exitosamente al jugador {target} para entrar en modo combate." #Shown as the command output for '/combatlogx tag ' when the plugin failed to tag a player. tag-failure: "{target} no puede ser puesto en combate. (¿Talvez tenga un permiso de excepción?)" #Shown as the command output for '/combatlogx untag '. untag-player: "Se ha retirado forzosamente al jugador {target} su modo de combate." #Shown as the command output for '/combatlogx toggle bossbar'. toggle-bossbar: "Barra de Boss: {status}" #Shown as the command output for '/combatlogx toggle actionbar'. toggle-actionbar: "Barra de acciones: {status}" #Shown as the command output for '/combatlogx toggle scoreboard'. toggle-scoreboard: "Marcador: {status}" combat-timer: #Shown as the command output for '/combat-timer'. time-left-self: "Tienes {time_left} segundos restantes." #Shown as the command output for '/combat-timer '. time-left-other: "{target} tiene {time_left} segundos restantes." #These messages are shown a player is tagged into combat. tagged: unknown: player: "Ahora estás en combate con {enemy} por una razón desconocida. ¡No te desconectes!" mob: " Ahora estás en combate con un(a) {enemy} por una razón desconocida. ¡No cierre sesión!" mythic_mob: "Ahora estás en combate con {mob_type} por una razón desconocida. ¡No te desconectes!" damage: "Ahora estás en combate debido a recibir daño. ¡No te desconectes!" unknown: "Fuiste puesto en combate sin motivo alguno. No cierre la sesión." attacked: player: "Estás siendo atacado por {enemy}. ¡No te desconectes!" mob: "Estás siendo atacado por un(os) {mob_type}. ¡No te desconectes!" mythic_mob: "Estás siendo atacado por un(os) {enemy}. ¡No te desconectes!" damage: "Ahora estás en combate debido a recibir daño. ¡No te desconectes!" unknown: "Estás siendo atacado por una fuerza desconocida. ¡No cierre sesión!" attacker: player: "Estás atacando a {enemy}. ¡No te desconectes!" mob: "Estás atacando un(os) {mob_type}.¡No te salgas!" mythic_mob: "Estás atacando un(os) {enemy}.¡No te salgas!" damage: "Ahora estás en combate debido a recibir daño. ¡No te desconectes!" unknown: "Estás atacando a una fuerza desconocida. ¡No cierre sesión!" expansion: angel-chest: #Shown when opening an AngelChest is prevented during combat. prevent-opening: "No puedes abrir cofres de ángel durante el combate." #Shown when breaking an AngelChest is prevented during combat. prevent-breaking: "No puedes romper cofres de ángel durante el combate." #Shown when fast looting an AngelChest is prevented during combat. prevent-fast-looting: "No se te permite saquear cofres ángeles rápidamente durante el combate." action-bar: #Shown above the hotbar while a player is in combat. timer: "Combate » {bars} {time_left_decimal} segundos." #Shown above the hotbar for a brief period when combat ends. ended: "Combate » Ya no estás en combate." boss-bar: #Shown on top of the screen while a player is in combat. timer: "Combate » {time_left_decimal} segundos." #Shown on top of the screen for a brief period when combat ends. ended: "Combate » Ya no estás en combate." scoreboard: #The scoreboard title for the sidebar. #Make sure to follow the scoreboard title limits for your Spigot version. title: "CombatLogX" #The scoreboard lines for the sidebar. #Make sure to follow the scoreboard line and character limits for your Spigot version. lines: - " " - "Estadísticas del combate" - "» Tiempo restante: {time_left}" - "» En Combate: {in_combat}" - "» Status: {status}" - " " - "Estadísticas del enemigo" - "» Nombre: {enemy_name}" - "» Vida: {enemy_health}" - "» VidaR: {enemy_health_rounded}" - " " cheat-prevention: #Shown when a command execution is prevented during combat. command-blocked: "No tienes acceso al comando {command} durante este combate." #Shown when the riptide effect is prevented during combat. no-riptide: "No tienes permitido usar el encantamiento de Propulsión Acuática durante el combate." #Shown when a totem of undying is prevented during combat. no-totem: "No tienes permitido usar Totems de la Inmortalidad durante el combate." #Shown when an entity interaction is prevented during combat. no-entity-interaction: "No tienes permitido interactuar con esta criatura durante el combate." #Shown when a chat message is prevented during combat. no-chat: "No tienes permitido enviar mensajes durante el combate." game-mode: #Shown when a player is forced into a specific game mmode during combat. force-switch: "Tu modo de juego ha cambiado a {game_mode}." #Shown when a game mode switch is prevented during combat. no-switch: "No tienes permitido cambiar tu modo de juego en combate." flight: #Shown when a player's ability to fly is disabled during combat. force-disabled: "Tu habilidad de volar fue removida." #Shown when a player's attempt to fly is prevented during combat. no-flying: "No tienes permitido volar durante el combate." elytra: #Shown when a player's ability to glide is disabled during combat. force-disabled: "Tus élitros se han desactivado." #Shown when a player's attempt to glide is prevented during combat. no-gliding: "No tienes permitido usar élitros en combate." teleportation: #Shown when a player tries to enter a portal and is prevented during combat. block-portal: "No tienes permitido usar portales durante el combate." #Shown when an ender pearl is prevented during combat. block-pearl: "No tienes permitido usar Perlas de Enderman en combate." #Shown when a teleport is prevented during combat. block-other: "No tienes permitido teletransportarte durante el combate." inventory: #Shown when a player's inventory is closed by the plugin during combat. force-closed: "Tu inventario ha sido cerrado." #Shown when a player tries to open an inventory and is prevented during combat. no-opening: "No tienes permitido abrir inventarios durante el combate." blocks: #Shown when a player is prevented from breaking a block during combat. prevent-breaking: "No tienes permitido romper bloques durante el combate." #Shown when a player is prevented from breaking a block during combat. prevent-placing: "No tienes permitido colocar bloques durante el combate." #Shown when a player is prevented from breaking a block during combat. prevent-interaction: "No tienes permitido usar bloques durante el combate." #Shown when a player is prevented from breaking a block during combat. prevent-portal-creation: "No tienes permitido crear portales durante el combate." items: #Shown when a player is prevented from picking up an item during combat. no-pickup: "No tienes permitido recoger objetos durante el combate." #Shown when a player is prevented from dropping an item during combat. no-dropping: "No tienes permitido arrojar objetos durante el combate." buckets: #Shown when a player is prevented from emptying a bucket during combat. no-empty: "No puedes usar baldes durante el combate." #Shown when a player is prevented from filling a bucket during combat. no-fill: "No puedes llenar baldes durante el combate." damage-tagger: #Shown when a player is tagged for an unknown damage type. unknown-damage: "¡Te han herido! ¡No te desconectes!" #These messages are shown when a player is tagged for a known damage type. #You can find a list of damage types here: #https://hub.spigotmc.org/javadocs/spigot/org/bukkit/event/entity/EntityDamageEvent.DamageCause.html damage-type: contact: "Fuiste pinchido por un cactus. ¡No te desconectes!" suffocation: "Te estás sofocando en una pared. ¡No te salgas!" fall: "Te caiste. ¡No te desconectes!" fire: "Estás caminado sobre brasas. ¡No te desconectes!" fire-tick: "Estás ardiendo. ¡No te desconectes!" lava: "Te estás fundiendo en la lava. ¡No te desconectes!" drowning: "Te ahogas. ¡No te desconectes!" block-explosion: "Fuiste afectado por una explosión. ¡No te desconectes!" lightning: "¡Te alcanzó un rayo! ¡No te desconectes!" starvation: "Estás muriendo de hambre. ¡No te desconectes!" poison: "Estás envenenado. ¡No te desconectes!" magic: "Alguien tiró una poción hacia tí. ¡No te desconectes!" wither: "Estás siendo marchitando. ¡No te desconectes!" falling-block: "Un bloque te cayó encima. ¡No te desconectes!" custom: "Te han herido. ¡No te desconectes!" fly-into-wall: "Acabas de experimentar la energía cinética. ¡No te desconectes!" hot-floor: "¡El suelo es lava! ¡No te desconectes!" cramming: "Serás aplastado. ¡No te desconectes!" newbie-helper: togglepvp: #Shown as the command output for '/togglepvp'. self: "PVP: {status}" #Shown as the command output for '/togglepvp admin on/off '. admin: "Cambiaste el modo combate al jugador {target} a {status}." #Shown when the '/togglepvp' command is on cooldown. cooldown: "Debes esperar {time_left} segundos para usar este comando de nuevo." #These messages are shown when pvp is disabled for any reason. no-pvp: self: "No puedes atacarte si tienes el modo de combate desactivado." other: "Ese jugador tiene el modo de combate desactivado." protected: "Ese jugador está protegido, ¡no tienes permitido atacarlo!" protection-disabled: #Shown when newbie protection is disabled due to the player attacking another player. attacker: "Atacaste a alguien, tu protección de combate se ha desactivado." #Shown when newbie protection expires. expired: "Tu protección de combate ha expirado." #Shown for the '/togglepvp check ' command. check-format: - "Información para {target}:" - "Protección: {protected}" - "Estado: {pvp}" loot-protection: #Shown when an enemy dies and their loot is protected. enemy-died: "{enemy} ha muerto. El botín estará protegido por {time} segundos." #Shown when a player tries to pick up an item that is loot protected by the plugin. protected: "Este objeto está actualmente protegido, espera {time} segundos antes de poder recogerlo." citizens-compatibility: #Shown when a player is prevented from joining the server due to their NPC still existing. prevent-join: "No puedes unirte al servidor hasta que tu NPC sea eliminado." disguise-compatibility: #Shown when a disguise is removed from a player during combat. remove-disguise: "Tu disfraz ha sido removido." essentials-compatibility: #Shown when a teleport request is cancelled during combat. prevent-teleport-request-self: "No puedes enviarte solicitudes de teletransportación durante el combate." #Shown when a teleport request is cancelled during combat. prevent-teleport-request-other: "No puedes enviar solicitudes de teletransportación durante el combate." marriagemaster-compatibility: #Shown when a married player is prevented from teleporting to their partner during combat. prevent-teleport-self: "No puedes teletransportarte a tu pareja durante el combate." #Shown when a married player is prevented from teleporting to their partner during combat. prevent-teleport-partner: "No puedes teletransportarte a tu pareja mientras estén en combate." region-protection: #Shown when a player tries to enter a no-pvp area during combat. default-no-entry: "No puedes entrar en esa zona durante el combate." factions-no-entry: No tienes permitido entrar a este lugar durante el combate. griefdefender-no-entry: No tienes permitido entrar a este lugar durante el combate. griefprevention-no-entry: No tienes permitido entrar a este lugar durante el combate. kingdomsx-no-entry: No tienes permitido entrar a este lugar durante el combate. konquest-no-entry: No tienes permitido entrar a este lugar durante el combate. redprotect-no-entry: No tienes permitido entrar a este lugar durante el combate. residence-no-entry: No tienes permitido entrar a este lugar durante el combate. towny-no-entry: No tienes permitido entrar a este lugar durante el combate. husktowns-no-entry: No puedes entrar en esa zona durante el combate. ultimateclaims-no-entry: No tienes permitido entrar a este lugar durante el combate. protectionstones: prevent-area-creation: "No tienes permitido crear un area protegida durante el combate." no-entry: No tienes permitido entrar a este lugar durante el combate. preciousstones: prevent-field-creation: "No tienes permitido crear un area protegida durante el combate." no-entry: No tienes permitido entrar a este lugar durante el combate. worldguard: no-entry-mob-combat: "No tienes permitido entrar a zonas que no admitan PvE durante el combate." no-entry-player-combat: "No tienes permitido entrar a zonas que no admitan PvP durante el combate." no-entry-unknown-combat: No tienes permitido entrar a este lugar durante el combate. lands: no-entry: No tienes permitido entrar a este lugar durante el combate. war-disable-newbie-protection: "PvP esta activada debido a una declaración de guerra." ================================================ FILE: plugin/src/main/resources/language/es_cl.lang.yml ================================================ --- ## Extra Information: ## This is the default language file for CombatLogX. ## The default language is "en_us", also known as English (United States). ## Context will be added as YAML comments above the string. ## The color scheme for messages is gold, white, and sometimes red. ## Command feedback that is successful should always be green. ## Error messages should always be red. ## Variables in messages can be gray or white. ## Messages use the MiniMessage format in non-strict mode. ## More information about MiniMessage can be found here: ## https://docs.adventure.kyori.net/minimessage/format.html #The language code for this file. language-name: "es_cl" #The format for decimal numbers. #The United States uses the number and two decimal places decimal-format: "0.00" #The prefix for CombatLogX. #This is shown in front of all messages and should not be changed unless necessary. prefix: "[CombatLogX]" broadcast: #Shown when the plugin is finished loading. on-load: "CombatLogX ha sido cargado correctamente." #Shown when the plugin is finished enabling. on-enable: "CombatLogX ha sido habilitado correctamente." #Shown when the plugin is disabled for any reason. on-disable: "CombatLogX ha sido deshabilitado correctamente." placeholder: #This text is used for the {combatlogx_time_left} #This allows server configurations to change the display value of the zero to something like "Not in combat" time-left-zero: "0" #This text is used when a player does not have an enemy. #This can happen when players are tagged by a custom expansion or the tag command. unknown-enemy: "Desconocido" status: #Shown when the player is in combat. fighting: "Combatiendo" in-combat: "" #Shown when the player is not in combat idle: "Inactivo" not-in-combat: "No" #These placeholders are shown when a player changes a value such as whether or not their bossbar is enabled. toggle: enabled: "Activado" disabled: "Desactivado" pvp-status: enabled: "Activado" disabled: "Desactivado" combat-timer: #Sent to a player when they escape from combat due to the timer running out. expire: "Ya no estás en modo de combate." #Sent to a player when they escape from combat due to their enemy being killed. enemy-death: "Ya no estás en modo de combate debido a que tu enemigo murió." #Sent when a player is killed during combat. self-death: "Ya no estás en combate porque has muerto." error: #Shown when the console tries to execute a command made for players. player-only: "Solo jugadores pueden ejecutar este comando." #Shown when a command that requires a player has invalid input. invalid-target: "{target} no está conectado o no existe." #Shown when a command that requires a number has invalid input. invalid-integer: "{value} no es un entero válido." #Shown when a player does not have access to something that requires a permission. no-permission: "Permiso faltante: {permission}" #Shown when a player executes a command in a world that is disabled in the configuration. disabled-world: "%%red%%¡Ese comando no se encuentra disponible en esta dimensión!" #Shown when a command requires a player in combat but the target player is not in combat. target-not-in-combat: "{target} no está en combate." #Shown when a player executes a command that requires them to be in combat. self-not-in-combat: "No estás en combate." #Shown when a command that requires an expansion has invalid input. unknown-expansion: "{target} no es una expansión o no está instalada." command: combatlogx: #Shown as the command output for '/combatlogx help'. help-message-list: - "" - "Ayuda de CombatLogX:" - " /combatlogx help: Muestra este menú." - " /combatlogx reload: Reinicia los archivos config.yml, language.yml, y todos los archivos de configuración de sus expansiones." - " /combatlogx about \\: Revisa la información sobre una expansión." - " [seconds]" - " /combatlogx toggle bossbar/actionbar/scoreboard: Habilita o deshabilita alguno de estos mensajes." - " /combatlogx untag \\: Quitar forzosamente el modo combate." - " /combatlogx version: Muestra la versión de CombatLogX." - "" #Shown as the command output for '/combatlogx reload' when reloading is successful. reload-success: - "Se han recargado exitosamente todos los archivos de configuración de CombatLogX." - "Se ha recargado exitosamente el archivo de lenguaje de CombatLogX." - "Se han recargado exitosamente todos los archivos de configuración pertenecientes a las expansiones de CombatLogX." #Shown as the command output for '/combatlogx reload' when reloading fails reload-failure: - "Se ha producido un error al recargar la configuración." - "Compruebe el registro de su servidor y corrija el archivo roto." #Shown as the command output for '/combatlogx tag ' when a player is tagged successfully. tag-player: "Se ha forzado exitosamente al jugador {target} para entrar en modo combate." #Shown as the command output for '/combatlogx tag ' when the plugin failed to tag a player. tag-failure: "{target} no puede ser puesto en combate. (¿Talvez tenga un permiso de excepción?)" #Shown as the command output for '/combatlogx untag '. untag-player: "Se ha retirado forzosamente al jugador {target} su modo de combate." #Shown as the command output for '/combatlogx toggle bossbar'. toggle-bossbar: "Barra de Boss: {status}" #Shown as the command output for '/combatlogx toggle actionbar'. toggle-actionbar: "Barra de acciones: {status}" #Shown as the command output for '/combatlogx toggle scoreboard'. toggle-scoreboard: "Marcador: {status}" combat-timer: #Shown as the command output for '/combat-timer'. time-left-self: "Tienes {time_left} segundos restantes." #Shown as the command output for '/combat-timer '. time-left-other: "{target} tiene {time_left} segundos restantes." #These messages are shown a player is tagged into combat. tagged: unknown: player: "Ahora estás en combate con {enemy} por una razón desconocida. ¡No te desconectes!" mob: " Ahora estás en combate con un(a) {enemy} por una razón desconocida. ¡No cierre sesión!" mythic_mob: "Ahora estás en combate con {mob_type} por una razón desconocida. ¡No te desconectes!" damage: "Ahora estás en combate debido a recibir daño. ¡No te desconectes!" unknown: "Fuiste puesto en combate sin motivo alguno. No cierre la sesión." attacked: player: "Estás siendo atacado por {enemy}. ¡No te desconectes!" mob: "Estás siendo atacado por un(os) {mob_type}. ¡No te desconectes!" mythic_mob: "Estás siendo atacado por un(os) {enemy}. ¡No te desconectes!" damage: "Ahora estás en combate debido a recibir daño. ¡No te desconectes!" unknown: "Estás siendo atacado por una fuerza desconocida. ¡No cierre sesión!" attacker: player: "Estás atacando a {enemy}. ¡No te desconectes!" mob: "Estás atacando un(os) {mob_type}.¡No te salgas!" mythic_mob: "Estás atacando un(os) {enemy}.¡No te salgas!" damage: "Ahora estás en combate debido a recibir daño. ¡No te desconectes!" unknown: "Estás atacando a una fuerza desconocida. ¡No cierre sesión!" expansion: angel-chest: #Shown when opening an AngelChest is prevented during combat. prevent-opening: "No puedes abrir cofres de ángel durante el combate." #Shown when breaking an AngelChest is prevented during combat. prevent-breaking: "No puedes romper cofres de ángel durante el combate." #Shown when fast looting an AngelChest is prevented during combat. prevent-fast-looting: "No se te permite saquear cofres ángeles rápidamente durante el combate." action-bar: #Shown above the hotbar while a player is in combat. timer: "Combate » {bars} {time_left_decimal} segundos." #Shown above the hotbar for a brief period when combat ends. ended: "Combate » Ya no estás en combate." boss-bar: #Shown on top of the screen while a player is in combat. timer: "Combate » {time_left_decimal} segundos." #Shown on top of the screen for a brief period when combat ends. ended: "Combate » Ya no estás en combate." scoreboard: #The scoreboard title for the sidebar. #Make sure to follow the scoreboard title limits for your Spigot version. title: "CombatLogX" #The scoreboard lines for the sidebar. #Make sure to follow the scoreboard line and character limits for your Spigot version. lines: - " " - "Estadísticas del combate" - "» Tiempo restante: {time_left}" - "» En Combate: {in_combat}" - "» Status: {status}" - " " - "Estadísticas del enemigo" - "» Nombre: {enemy_name}" - "» Vida: {enemy_health}" - "» VidaR: {enemy_health_rounded}" - " " cheat-prevention: #Shown when a command execution is prevented during combat. command-blocked: "No tienes acceso al comando {command} durante este combate." #Shown when the riptide effect is prevented during combat. no-riptide: "No tienes permitido usar el encantamiento de Propulsión Acuática durante el combate." #Shown when a totem of undying is prevented during combat. no-totem: "No tienes permitido usar Totems de la Inmortalidad durante el combate." #Shown when an entity interaction is prevented during combat. no-entity-interaction: "No tienes permitido interactuar con esta criatura durante el combate." #Shown when a chat message is prevented during combat. no-chat: "No tienes permitido enviar mensajes durante el combate." game-mode: #Shown when a player is forced into a specific game mmode during combat. force-switch: "Tu modo de juego ha cambiado a {game_mode}." #Shown when a game mode switch is prevented during combat. no-switch: "No tienes permitido cambiar tu modo de juego en combate." flight: #Shown when a player's ability to fly is disabled during combat. force-disabled: "Tu habilidad de volar fue removida." #Shown when a player's attempt to fly is prevented during combat. no-flying: "No tienes permitido volar durante el combate." elytra: #Shown when a player's ability to glide is disabled during combat. force-disabled: "Tus élitros se han desactivado." #Shown when a player's attempt to glide is prevented during combat. no-gliding: "No tienes permitido usar élitros en combate." teleportation: #Shown when a player tries to enter a portal and is prevented during combat. block-portal: "No tienes permitido usar portales durante el combate." #Shown when an ender pearl is prevented during combat. block-pearl: "No tienes permitido usar Perlas de Enderman en combate." #Shown when a teleport is prevented during combat. block-other: "No tienes permitido teletransportarte durante el combate." inventory: #Shown when a player's inventory is closed by the plugin during combat. force-closed: "Tu inventario ha sido cerrado." #Shown when a player tries to open an inventory and is prevented during combat. no-opening: "No tienes permitido abrir inventarios durante el combate." blocks: #Shown when a player is prevented from breaking a block during combat. prevent-breaking: "No tienes permitido romper bloques durante el combate." #Shown when a player is prevented from breaking a block during combat. prevent-placing: "No tienes permitido colocar bloques durante el combate." #Shown when a player is prevented from breaking a block during combat. prevent-interaction: "No tienes permitido usar bloques durante el combate." #Shown when a player is prevented from breaking a block during combat. prevent-portal-creation: "No tienes permitido crear portales durante el combate." items: #Shown when a player is prevented from picking up an item during combat. no-pickup: "No tienes permitido recoger objetos durante el combate." #Shown when a player is prevented from dropping an item during combat. no-dropping: "No tienes permitido arrojar objetos durante el combate." buckets: #Shown when a player is prevented from emptying a bucket during combat. no-empty: "No puedes usar baldes durante el combate." #Shown when a player is prevented from filling a bucket during combat. no-fill: "No puedes llenar baldes durante el combate." damage-tagger: #Shown when a player is tagged for an unknown damage type. unknown-damage: "¡Te han herido! ¡No te desconectes!" #These messages are shown when a player is tagged for a known damage type. #You can find a list of damage types here: #https://hub.spigotmc.org/javadocs/spigot/org/bukkit/event/entity/EntityDamageEvent.DamageCause.html damage-type: contact: "Fuiste pinchido por un cactus. ¡No te desconectes!" suffocation: "Te estás sofocando en una pared. ¡No te salgas!" fall: "Te caiste. ¡No te desconectes!" fire: "Estás caminado sobre brasas. ¡No te desconectes!" fire-tick: "Estás ardiendo. ¡No te desconectes!" lava: "Te estás fundiendo en la lava. ¡No te desconectes!" drowning: "Te ahogas. ¡No te desconectes!" block-explosion: "Fuiste afectado por una explosión. ¡No te desconectes!" lightning: "¡Te alcanzó un rayo! ¡No te desconectes!" starvation: "Estás muriendo de hambre. ¡No te desconectes!" poison: "Estás envenenado. ¡No te desconectes!" magic: "Alguien tiró una poción hacia tí. ¡No te desconectes!" wither: "Estás siendo marchitando. ¡No te desconectes!" falling-block: "Un bloque te cayó encima. ¡No te desconectes!" custom: "Te han herido. ¡No te desconectes!" fly-into-wall: "Acabas de experimentar la energía cinética. ¡No te desconectes!" hot-floor: "¡El suelo es lava! ¡No te desconectes!" cramming: "Serás aplastado. ¡No te desconectes!" newbie-helper: togglepvp: #Shown as the command output for '/togglepvp'. self: "PVP: {status}" #Shown as the command output for '/togglepvp admin on/off '. admin: "Cambiaste el modo combate al jugador {target} a {status}." #Shown when the '/togglepvp' command is on cooldown. cooldown: "Debes esperar {time_left} segundos para usar este comando de nuevo." #These messages are shown when pvp is disabled for any reason. no-pvp: self: "No puedes atacarte si tienes el modo de combate desactivado." other: "Ese jugador tiene el modo de combate desactivado." protected: "Ese jugador está protegido, ¡no tienes permitido atacarlo!" protection-disabled: #Shown when newbie protection is disabled due to the player attacking another player. attacker: "Atacaste a alguien, tu protección de combate se ha desactivado." #Shown when newbie protection expires. expired: "Tu protección de combate ha expirado." #Shown for the '/togglepvp check ' command. check-format: - "Información para {target}:" - "Protección: {protected}" - "Estado: {pvp}" loot-protection: #Shown when an enemy dies and their loot is protected. enemy-died: "{enemy} ha muerto. El botín estará protegido por {time} segundos." #Shown when a player tries to pick up an item that is loot protected by the plugin. protected: "Este objeto está actualmente protegido, espera {time} segundos antes de poder recogerlo." citizens-compatibility: #Shown when a player is prevented from joining the server due to their NPC still existing. prevent-join: "No puedes unirte al servidor hasta que tu NPC sea eliminado." disguise-compatibility: #Shown when a disguise is removed from a player during combat. remove-disguise: "Tu disfraz ha sido removido." essentials-compatibility: #Shown when a teleport request is cancelled during combat. prevent-teleport-request-self: "No puedes enviarte solicitudes de teletransportación durante el combate." #Shown when a teleport request is cancelled during combat. prevent-teleport-request-other: "No puedes enviar solicitudes de teletransportación durante el combate." marriagemaster-compatibility: #Shown when a married player is prevented from teleporting to their partner during combat. prevent-teleport-self: "No puedes teletransportarte a tu pareja durante el combate." #Shown when a married player is prevented from teleporting to their partner during combat. prevent-teleport-partner: "No puedes teletransportarte a tu pareja mientras estén en combate." region-protection: #Shown when a player tries to enter a no-pvp area during combat. default-no-entry: "No puedes entrar en esa zona durante el combate." factions-no-entry: No tienes permitido entrar a este lugar durante el combate. griefdefender-no-entry: No tienes permitido entrar a este lugar durante el combate. griefprevention-no-entry: No tienes permitido entrar a este lugar durante el combate. kingdomsx-no-entry: No tienes permitido entrar a este lugar durante el combate. konquest-no-entry: No tienes permitido entrar a este lugar durante el combate. redprotect-no-entry: No tienes permitido entrar a este lugar durante el combate. residence-no-entry: No tienes permitido entrar a este lugar durante el combate. towny-no-entry: No tienes permitido entrar a este lugar durante el combate. husktowns-no-entry: No puedes entrar en esa zona durante el combate. ultimateclaims-no-entry: No tienes permitido entrar a este lugar durante el combate. protectionstones: prevent-area-creation: "No tienes permitido crear un area protegida durante el combate." no-entry: No tienes permitido entrar a este lugar durante el combate. preciousstones: prevent-field-creation: "No tienes permitido crear un area protegida durante el combate." no-entry: No tienes permitido entrar a este lugar durante el combate. worldguard: no-entry-mob-combat: "No tienes permitido entrar a zonas que no admitan PvE durante el combate." no-entry-player-combat: "No tienes permitido entrar a zonas que no admitan PvP durante el combate." no-entry-unknown-combat: No tienes permitido entrar a este lugar durante el combate. lands: no-entry: No tienes permitido entrar a este lugar durante el combate. war-disable-newbie-protection: "PvP esta activada debido a una declaración de guerra." ================================================ FILE: plugin/src/main/resources/language/es_ec.lang.yml ================================================ --- ## Extra Information: ## This is the default language file for CombatLogX. ## The default language is "en_us", also known as English (United States). ## Context will be added as YAML comments above the string. ## The color scheme for messages is gold, white, and sometimes red. ## Command feedback that is successful should always be green. ## Error messages should always be red. ## Variables in messages can be gray or white. ## Messages use the MiniMessage format in non-strict mode. ## More information about MiniMessage can be found here: ## https://docs.adventure.kyori.net/minimessage/format.html #The language code for this file. language-name: "es_ec" #The format for decimal numbers. #The United States uses the number and two decimal places decimal-format: "0.00" #The prefix for CombatLogX. #This is shown in front of all messages and should not be changed unless necessary. prefix: "[CombatLogX]" broadcast: #Shown when the plugin is finished loading. on-load: "CombatLogX ha sido cargado correctamente." #Shown when the plugin is finished enabling. on-enable: "CombatLogX ha sido habilitado correctamente." #Shown when the plugin is disabled for any reason. on-disable: "CombatLogX ha sido deshabilitado correctamente." placeholder: #This text is used for the {combatlogx_time_left} #This allows server configurations to change the display value of the zero to something like "Not in combat" time-left-zero: "0" #This text is used when a player does not have an enemy. #This can happen when players are tagged by a custom expansion or the tag command. unknown-enemy: "Desconocido" status: #Shown when the player is in combat. fighting: "Combatiendo" in-combat: "" #Shown when the player is not in combat idle: "Inactivo" not-in-combat: "No" #These placeholders are shown when a player changes a value such as whether or not their bossbar is enabled. toggle: enabled: "Activado" disabled: "Desactivado" pvp-status: enabled: "Activado" disabled: "Desactivado" combat-timer: #Sent to a player when they escape from combat due to the timer running out. expire: "Ya no estás en modo de combate." #Sent to a player when they escape from combat due to their enemy being killed. enemy-death: "Ya no estás en modo de combate debido a que tu enemigo murió." #Sent when a player is killed during combat. self-death: "Ya no estás en combate porque has muerto." error: #Shown when the console tries to execute a command made for players. player-only: "Solo jugadores pueden ejecutar este comando." #Shown when a command that requires a player has invalid input. invalid-target: "{target} no está conectado o no existe." #Shown when a command that requires a number has invalid input. invalid-integer: "{value} no es un entero válido." #Shown when a player does not have access to something that requires a permission. no-permission: "Permiso faltante: {permission}" #Shown when a player executes a command in a world that is disabled in the configuration. disabled-world: "%%red%%¡Ese comando no se encuentra disponible en esta dimensión!" #Shown when a command requires a player in combat but the target player is not in combat. target-not-in-combat: "{target} no está en combate." #Shown when a player executes a command that requires them to be in combat. self-not-in-combat: "No estás en combate." #Shown when a command that requires an expansion has invalid input. unknown-expansion: "{target} no es una expansión o no está instalada." command: combatlogx: #Shown as the command output for '/combatlogx help'. help-message-list: - "" - "Ayuda de CombatLogX:" - " /combatlogx help: Muestra este menú." - " /combatlogx reload: Reinicia los archivos config.yml, language.yml, y todos los archivos de configuración de sus expansiones." - " /combatlogx about \\: Revisa la información sobre una expansión." - " [seconds]" - " /combatlogx toggle bossbar/actionbar/scoreboard: Habilita o deshabilita alguno de estos mensajes." - " /combatlogx untag \\: Quitar forzosamente el modo combate." - " /combatlogx version: Muestra la versión de CombatLogX." - "" #Shown as the command output for '/combatlogx reload' when reloading is successful. reload-success: - "Se han recargado exitosamente todos los archivos de configuración de CombatLogX." - "Se ha recargado exitosamente el archivo de lenguaje de CombatLogX." - "Se han recargado exitosamente todos los archivos de configuración pertenecientes a las expansiones de CombatLogX." #Shown as the command output for '/combatlogx reload' when reloading fails reload-failure: - "Se ha producido un error al recargar la configuración." - "Compruebe el registro de su servidor y corrija el archivo roto." #Shown as the command output for '/combatlogx tag ' when a player is tagged successfully. tag-player: "Se ha forzado exitosamente al jugador {target} para entrar en modo combate." #Shown as the command output for '/combatlogx tag ' when the plugin failed to tag a player. tag-failure: "{target} no puede ser puesto en combate. (¿Talvez tenga un permiso de excepción?)" #Shown as the command output for '/combatlogx untag '. untag-player: "Se ha retirado forzosamente al jugador {target} su modo de combate." #Shown as the command output for '/combatlogx toggle bossbar'. toggle-bossbar: "Barra de Boss: {status}" #Shown as the command output for '/combatlogx toggle actionbar'. toggle-actionbar: "Barra de acciones: {status}" #Shown as the command output for '/combatlogx toggle scoreboard'. toggle-scoreboard: "Marcador: {status}" combat-timer: #Shown as the command output for '/combat-timer'. time-left-self: "Tienes {time_left} segundos restantes." #Shown as the command output for '/combat-timer '. time-left-other: "{target} tiene {time_left} segundos restantes." #These messages are shown a player is tagged into combat. tagged: unknown: player: "Ahora estás en combate con {enemy} por una razón desconocida. ¡No te desconectes!" mob: " Ahora estás en combate con un(a) {enemy} por una razón desconocida. ¡No cierre sesión!" mythic_mob: "Ahora estás en combate con {mob_type} por una razón desconocida. ¡No te desconectes!" damage: "Ahora estás en combate debido a recibir daño. ¡No te desconectes!" unknown: "Fuiste puesto en combate sin motivo alguno. No cierre la sesión." attacked: player: "Estás siendo atacado por {enemy}. ¡No te desconectes!" mob: "Estás siendo atacado por un(os) {mob_type}. ¡No te desconectes!" mythic_mob: "Estás siendo atacado por un(os) {enemy}. ¡No te desconectes!" damage: "Ahora estás en combate debido a recibir daño. ¡No te desconectes!" unknown: "Estás siendo atacado por una fuerza desconocida. ¡No cierre sesión!" attacker: player: "Estás atacando a {enemy}. ¡No te desconectes!" mob: "Estás atacando un(os) {mob_type}.¡No te salgas!" mythic_mob: "Estás atacando un(os) {enemy}.¡No te salgas!" damage: "Ahora estás en combate debido a recibir daño. ¡No te desconectes!" unknown: "Estás atacando a una fuerza desconocida. ¡No cierre sesión!" expansion: angel-chest: #Shown when opening an AngelChest is prevented during combat. prevent-opening: "No puedes abrir cofres de ángel durante el combate." #Shown when breaking an AngelChest is prevented during combat. prevent-breaking: "No puedes romper cofres de ángel durante el combate." #Shown when fast looting an AngelChest is prevented during combat. prevent-fast-looting: "No se te permite saquear cofres ángeles rápidamente durante el combate." action-bar: #Shown above the hotbar while a player is in combat. timer: "Combate » {bars} {time_left_decimal} segundos." #Shown above the hotbar for a brief period when combat ends. ended: "Combate » Ya no estás en combate." boss-bar: #Shown on top of the screen while a player is in combat. timer: "Combate » {time_left_decimal} segundos." #Shown on top of the screen for a brief period when combat ends. ended: "Combate » Ya no estás en combate." scoreboard: #The scoreboard title for the sidebar. #Make sure to follow the scoreboard title limits for your Spigot version. title: "CombatLogX" #The scoreboard lines for the sidebar. #Make sure to follow the scoreboard line and character limits for your Spigot version. lines: - " " - "Estadísticas del combate" - "» Tiempo restante: {time_left}" - "» En Combate: {in_combat}" - "» Status: {status}" - " " - "Estadísticas del enemigo" - "» Nombre: {enemy_name}" - "» Vida: {enemy_health}" - "» VidaR: {enemy_health_rounded}" - " " cheat-prevention: #Shown when a command execution is prevented during combat. command-blocked: "No tienes acceso al comando {command} durante este combate." #Shown when the riptide effect is prevented during combat. no-riptide: "No tienes permitido usar el encantamiento de Propulsión Acuática durante el combate." #Shown when a totem of undying is prevented during combat. no-totem: "No tienes permitido usar Totems de la Inmortalidad durante el combate." #Shown when an entity interaction is prevented during combat. no-entity-interaction: "No tienes permitido interactuar con esta criatura durante el combate." #Shown when a chat message is prevented during combat. no-chat: "No tienes permitido enviar mensajes durante el combate." game-mode: #Shown when a player is forced into a specific game mmode during combat. force-switch: "Tu modo de juego ha cambiado a {game_mode}." #Shown when a game mode switch is prevented during combat. no-switch: "No tienes permitido cambiar tu modo de juego en combate." flight: #Shown when a player's ability to fly is disabled during combat. force-disabled: "Tu habilidad de volar fue removida." #Shown when a player's attempt to fly is prevented during combat. no-flying: "No tienes permitido volar durante el combate." elytra: #Shown when a player's ability to glide is disabled during combat. force-disabled: "Tus élitros se han desactivado." #Shown when a player's attempt to glide is prevented during combat. no-gliding: "No tienes permitido usar élitros en combate." teleportation: #Shown when a player tries to enter a portal and is prevented during combat. block-portal: "No tienes permitido usar portales durante el combate." #Shown when an ender pearl is prevented during combat. block-pearl: "No tienes permitido usar Perlas de Enderman en combate." #Shown when a teleport is prevented during combat. block-other: "No tienes permitido teletransportarte durante el combate." inventory: #Shown when a player's inventory is closed by the plugin during combat. force-closed: "Tu inventario ha sido cerrado." #Shown when a player tries to open an inventory and is prevented during combat. no-opening: "No tienes permitido abrir inventarios durante el combate." blocks: #Shown when a player is prevented from breaking a block during combat. prevent-breaking: "No tienes permitido romper bloques durante el combate." #Shown when a player is prevented from breaking a block during combat. prevent-placing: "No tienes permitido colocar bloques durante el combate." #Shown when a player is prevented from breaking a block during combat. prevent-interaction: "No tienes permitido usar bloques durante el combate." #Shown when a player is prevented from breaking a block during combat. prevent-portal-creation: "No tienes permitido crear portales durante el combate." items: #Shown when a player is prevented from picking up an item during combat. no-pickup: "No tienes permitido recoger objetos durante el combate." #Shown when a player is prevented from dropping an item during combat. no-dropping: "No tienes permitido arrojar objetos durante el combate." buckets: #Shown when a player is prevented from emptying a bucket during combat. no-empty: "No puedes usar baldes durante el combate." #Shown when a player is prevented from filling a bucket during combat. no-fill: "No puedes llenar baldes durante el combate." damage-tagger: #Shown when a player is tagged for an unknown damage type. unknown-damage: "¡Te han herido! ¡No te desconectes!" #These messages are shown when a player is tagged for a known damage type. #You can find a list of damage types here: #https://hub.spigotmc.org/javadocs/spigot/org/bukkit/event/entity/EntityDamageEvent.DamageCause.html damage-type: contact: "Fuiste pinchido por un cactus. ¡No te desconectes!" suffocation: "Te estás sofocando en una pared. ¡No te salgas!" fall: "Te caiste. ¡No te desconectes!" fire: "Estás caminado sobre brasas. ¡No te desconectes!" fire-tick: "Estás ardiendo. ¡No te desconectes!" lava: "Te estás fundiendo en la lava. ¡No te desconectes!" drowning: "Te ahogas. ¡No te desconectes!" block-explosion: "Fuiste afectado por una explosión. ¡No te desconectes!" lightning: "¡Te alcanzó un rayo! ¡No te desconectes!" starvation: "Estás muriendo de hambre. ¡No te desconectes!" poison: "Estás envenenado. ¡No te desconectes!" magic: "Alguien tiró una poción hacia tí. ¡No te desconectes!" wither: "Estás siendo marchitando. ¡No te desconectes!" falling-block: "Un bloque te cayó encima. ¡No te desconectes!" custom: "Te han herido. ¡No te desconectes!" fly-into-wall: "Acabas de experimentar la energía cinética. ¡No te desconectes!" hot-floor: "¡El suelo es lava! ¡No te desconectes!" cramming: "Serás aplastado. ¡No te desconectes!" newbie-helper: togglepvp: #Shown as the command output for '/togglepvp'. self: "PVP: {status}" #Shown as the command output for '/togglepvp admin on/off '. admin: "Cambiaste el modo combate al jugador {target} a {status}." #Shown when the '/togglepvp' command is on cooldown. cooldown: "Debes esperar {time_left} segundos para usar este comando de nuevo." #These messages are shown when pvp is disabled for any reason. no-pvp: self: "No puedes atacarte si tienes el modo de combate desactivado." other: "Ese jugador tiene el modo de combate desactivado." protected: "Ese jugador está protegido, ¡no tienes permitido atacarlo!" protection-disabled: #Shown when newbie protection is disabled due to the player attacking another player. attacker: "Atacaste a alguien, tu protección de combate se ha desactivado." #Shown when newbie protection expires. expired: "Tu protección de combate ha expirado." #Shown for the '/togglepvp check ' command. check-format: - "Información para {target}:" - "Protección: {protected}" - "Estado: {pvp}" loot-protection: #Shown when an enemy dies and their loot is protected. enemy-died: "{enemy} ha muerto. El botín estará protegido por {time} segundos." #Shown when a player tries to pick up an item that is loot protected by the plugin. protected: "Este objeto está actualmente protegido, espera {time} segundos antes de poder recogerlo." citizens-compatibility: #Shown when a player is prevented from joining the server due to their NPC still existing. prevent-join: "No puedes unirte al servidor hasta que tu NPC sea eliminado." disguise-compatibility: #Shown when a disguise is removed from a player during combat. remove-disguise: "Tu disfraz ha sido removido." essentials-compatibility: #Shown when a teleport request is cancelled during combat. prevent-teleport-request-self: "No puedes enviarte solicitudes de teletransportación durante el combate." #Shown when a teleport request is cancelled during combat. prevent-teleport-request-other: "No puedes enviar solicitudes de teletransportación durante el combate." marriagemaster-compatibility: #Shown when a married player is prevented from teleporting to their partner during combat. prevent-teleport-self: "No puedes teletransportarte a tu pareja durante el combate." #Shown when a married player is prevented from teleporting to their partner during combat. prevent-teleport-partner: "No puedes teletransportarte a tu pareja mientras estén en combate." region-protection: #Shown when a player tries to enter a no-pvp area during combat. default-no-entry: "No puedes entrar en esa zona durante el combate." factions-no-entry: No tienes permitido entrar a este lugar durante el combate. griefdefender-no-entry: No tienes permitido entrar a este lugar durante el combate. griefprevention-no-entry: No tienes permitido entrar a este lugar durante el combate. kingdomsx-no-entry: No tienes permitido entrar a este lugar durante el combate. konquest-no-entry: No tienes permitido entrar a este lugar durante el combate. redprotect-no-entry: No tienes permitido entrar a este lugar durante el combate. residence-no-entry: No tienes permitido entrar a este lugar durante el combate. towny-no-entry: No tienes permitido entrar a este lugar durante el combate. husktowns-no-entry: No puedes entrar en esa zona durante el combate. ultimateclaims-no-entry: No tienes permitido entrar a este lugar durante el combate. protectionstones: prevent-area-creation: "No tienes permitido crear un area protegida durante el combate." no-entry: No tienes permitido entrar a este lugar durante el combate. preciousstones: prevent-field-creation: "No tienes permitido crear un area protegida durante el combate." no-entry: No tienes permitido entrar a este lugar durante el combate. worldguard: no-entry-mob-combat: "No tienes permitido entrar a zonas que no admitan PvE durante el combate." no-entry-player-combat: "No tienes permitido entrar a zonas que no admitan PvP durante el combate." no-entry-unknown-combat: No tienes permitido entrar a este lugar durante el combate. lands: no-entry: No tienes permitido entrar a este lugar durante el combate. war-disable-newbie-protection: "PvP esta activada debido a una declaración de guerra." ================================================ FILE: plugin/src/main/resources/language/es_es.lang.yml ================================================ --- ## Extra Information: ## This is the default language file for CombatLogX. ## The default language is "en_us", also known as English (United States). ## Context will be added as YAML comments above the string. ## The color scheme for messages is gold, white, and sometimes red. ## Command feedback that is successful should always be green. ## Error messages should always be red. ## Variables in messages can be gray or white. ## Messages use the MiniMessage format in non-strict mode. ## More information about MiniMessage can be found here: ## https://docs.adventure.kyori.net/minimessage/format.html #The language code for this file. language-name: "es_es" #The format for decimal numbers. #The United States uses the number and two decimal places decimal-format: "0.00" #The prefix for CombatLogX. #This is shown in front of all messages and should not be changed unless necessary. prefix: "[CombatLogX]" broadcast: #Shown when the plugin is finished loading. on-load: "CombatLogX ha sido cargado correctamente." #Shown when the plugin is finished enabling. on-enable: "CombatLogX ha sido habilitado correctamente." #Shown when the plugin is disabled for any reason. on-disable: "CombatLogX ha sido deshabilitado correctamente." placeholder: #This text is used for the {combatlogx_time_left} #This allows server configurations to change the display value of the zero to something like "Not in combat" time-left-zero: "0" #This text is used when a player does not have an enemy. #This can happen when players are tagged by a custom expansion or the tag command. unknown-enemy: "Desconocido" status: #Shown when the player is in combat. fighting: "Combatiendo" in-combat: "" #Shown when the player is not in combat idle: "Inactivo" not-in-combat: "No" #These placeholders are shown when a player changes a value such as whether or not their bossbar is enabled. toggle: enabled: "Activado" disabled: "Desactivado" pvp-status: enabled: "Activado" disabled: "Desactivado" combat-timer: #Sent to a player when they escape from combat due to the timer running out. expire: "Ya no estás en modo de combate." #Sent to a player when they escape from combat due to their enemy being killed. enemy-death: "Ya no estás en modo de combate debido a que tu enemigo murió." #Sent when a player is killed during combat. self-death: "Ya no estás en combate porque has muerto." error: #Shown when the console tries to execute a command made for players. player-only: "Solo jugadores pueden ejecutar este comando." #Shown when a command that requires a player has invalid input. invalid-target: "{target} no está conectado o no existe." #Shown when a command that requires a number has invalid input. invalid-integer: "{value} no es un entero válido." #Shown when a player does not have access to something that requires a permission. no-permission: "Permiso faltante: {permission}" #Shown when a player executes a command in a world that is disabled in the configuration. disabled-world: "%%red%%¡Ese comando no se encuentra disponible en esta dimensión!" #Shown when a command requires a player in combat but the target player is not in combat. target-not-in-combat: "{target} no está en combate." #Shown when a player executes a command that requires them to be in combat. self-not-in-combat: "No estás en combate." #Shown when a command that requires an expansion has invalid input. unknown-expansion: "{target} no es una expansión o no está instalada." command: combatlogx: #Shown as the command output for '/combatlogx help'. help-message-list: - "" - "Ayuda de CombatLogX:" - " /combatlogx help: Muestra este menú." - " /combatlogx reload: Reinicia los archivos config.yml, language.yml, y todos los archivos de configuración de sus expansiones." - " /combatlogx about \\: Revisa la información sobre una expansión." - " [seconds]" - " /combatlogx toggle bossbar/actionbar/scoreboard: Habilita o deshabilita alguno de estos mensajes." - " /combatlogx untag \\: Quitar forzosamente el modo combate." - " /combatlogx version: Muestra la versión de CombatLogX." - "" #Shown as the command output for '/combatlogx reload' when reloading is successful. reload-success: - "Se han recargado exitosamente todos los archivos de configuración de CombatLogX." - "Se ha recargado exitosamente el archivo de lenguaje de CombatLogX." - "Se han recargado exitosamente todos los archivos de configuración pertenecientes a las expansiones de CombatLogX." #Shown as the command output for '/combatlogx reload' when reloading fails reload-failure: - "Se ha producido un error al recargar la configuración." - "Compruebe el registro de su servidor y corrija el archivo roto." #Shown as the command output for '/combatlogx tag ' when a player is tagged successfully. tag-player: "Se ha forzado exitosamente al jugador {target} para entrar en modo combate." #Shown as the command output for '/combatlogx tag ' when the plugin failed to tag a player. tag-failure: "{target} no puede ser puesto en combate. (¿Talvez tenga un permiso de excepción?)" #Shown as the command output for '/combatlogx untag '. untag-player: "Se ha retirado forzosamente al jugador {target} su modo de combate." #Shown as the command output for '/combatlogx toggle bossbar'. toggle-bossbar: "Barra de Boss: {status}" #Shown as the command output for '/combatlogx toggle actionbar'. toggle-actionbar: "Barra de acciones: {status}" #Shown as the command output for '/combatlogx toggle scoreboard'. toggle-scoreboard: "Marcador: {status}" combat-timer: #Shown as the command output for '/combat-timer'. time-left-self: "Tienes {time_left} segundos restantes." #Shown as the command output for '/combat-timer '. time-left-other: "{target} tiene {time_left} segundos restantes." #These messages are shown a player is tagged into combat. tagged: unknown: player: "Ahora estás en combate con {enemy} por una razón desconocida. ¡No te desconectes!" mob: " Ahora estás en combate con un(a) {enemy} por una razón desconocida. ¡No cierre sesión!" mythic_mob: "Ahora estás en combate con {mob_type} por una razón desconocida. ¡No te desconectes!" damage: "Ahora estás en combate debido a recibir daño. ¡No te desconectes!" unknown: "Fuiste puesto en combate sin motivo alguno. No cierre la sesión." attacked: player: "Estás siendo atacado por {enemy}. ¡No te desconectes!" mob: "Estás siendo atacado por un(os) {mob_type}. ¡No te desconectes!" mythic_mob: "Estás siendo atacado por un(os) {enemy}. ¡No te desconectes!" damage: "Ahora estás en combate debido a recibir daño. ¡No te desconectes!" unknown: "Estás siendo atacado por una fuerza desconocida. ¡No cierre sesión!" attacker: player: "Estás atacando a {enemy}. ¡No te desconectes!" mob: "Estás atacando un(os) {mob_type}.¡No te salgas!" mythic_mob: "Estás atacando un(os) {enemy}.¡No te salgas!" damage: "Ahora estás en combate debido a recibir daño. ¡No te desconectes!" unknown: "Estás atacando a una fuerza desconocida. ¡No cierre sesión!" expansion: angel-chest: #Shown when opening an AngelChest is prevented during combat. prevent-opening: "No puedes abrir cofres de ángel durante el combate." #Shown when breaking an AngelChest is prevented during combat. prevent-breaking: "No puedes romper cofres de ángel durante el combate." #Shown when fast looting an AngelChest is prevented during combat. prevent-fast-looting: "No se te permite saquear cofres ángeles rápidamente durante el combate." action-bar: #Shown above the hotbar while a player is in combat. timer: "Combate » {bars} {time_left_decimal} segundos." #Shown above the hotbar for a brief period when combat ends. ended: "Combate » Ya no estás en combate." boss-bar: #Shown on top of the screen while a player is in combat. timer: "Combate » {time_left_decimal} segundos." #Shown on top of the screen for a brief period when combat ends. ended: "Combate » Ya no estás en combate." scoreboard: #The scoreboard title for the sidebar. #Make sure to follow the scoreboard title limits for your Spigot version. title: "CombatLogX" #The scoreboard lines for the sidebar. #Make sure to follow the scoreboard line and character limits for your Spigot version. lines: - " " - "Estadísticas del combate" - "» Tiempo restante: {time_left}" - "» En Combate: {in_combat}" - "» Status: {status}" - " " - "Estadísticas del enemigo" - "» Nombre: {enemy_name}" - "» Vida: {enemy_health}" - "» VidaR: {enemy_health_rounded}" - " " cheat-prevention: #Shown when a command execution is prevented during combat. command-blocked: "No tienes acceso al comando {command} durante este combate." #Shown when the riptide effect is prevented during combat. no-riptide: "No tienes permitido usar el encantamiento de Propulsión Acuática durante el combate." #Shown when a totem of undying is prevented during combat. no-totem: "No tienes permitido usar Totems de la Inmortalidad durante el combate." #Shown when an entity interaction is prevented during combat. no-entity-interaction: "No tienes permitido interactuar con esta criatura durante el combate." #Shown when a chat message is prevented during combat. no-chat: "No tienes permitido enviar mensajes durante el combate." game-mode: #Shown when a player is forced into a specific game mmode during combat. force-switch: "Tu modo de juego ha cambiado a {game_mode}." #Shown when a game mode switch is prevented during combat. no-switch: "No tienes permitido cambiar tu modo de juego en combate." flight: #Shown when a player's ability to fly is disabled during combat. force-disabled: "Tu habilidad de volar fue removida." #Shown when a player's attempt to fly is prevented during combat. no-flying: "No tienes permitido volar durante el combate." elytra: #Shown when a player's ability to glide is disabled during combat. force-disabled: "Tus élitros se han desactivado." #Shown when a player's attempt to glide is prevented during combat. no-gliding: "No tienes permitido usar élitros en combate." teleportation: #Shown when a player tries to enter a portal and is prevented during combat. block-portal: "No tienes permitido usar portales durante el combate." #Shown when an ender pearl is prevented during combat. block-pearl: "No tienes permitido usar Perlas de Enderman en combate." #Shown when a teleport is prevented during combat. block-other: "No tienes permitido teletransportarte durante el combate." inventory: #Shown when a player's inventory is closed by the plugin during combat. force-closed: "Tu inventario ha sido cerrado." #Shown when a player tries to open an inventory and is prevented during combat. no-opening: "No tienes permitido abrir inventarios durante el combate." blocks: #Shown when a player is prevented from breaking a block during combat. prevent-breaking: "No tienes permitido romper bloques durante el combate." #Shown when a player is prevented from breaking a block during combat. prevent-placing: "No tienes permitido colocar bloques durante el combate." #Shown when a player is prevented from breaking a block during combat. prevent-interaction: "No tienes permitido usar bloques durante el combate." #Shown when a player is prevented from breaking a block during combat. prevent-portal-creation: "No tienes permitido crear portales durante el combate." items: #Shown when a player is prevented from picking up an item during combat. no-pickup: "No tienes permitido recoger objetos durante el combate." #Shown when a player is prevented from dropping an item during combat. no-dropping: "No tienes permitido arrojar objetos durante el combate." buckets: #Shown when a player is prevented from emptying a bucket during combat. no-empty: "No puedes usar baldes durante el combate." #Shown when a player is prevented from filling a bucket during combat. no-fill: "No puedes llenar baldes durante el combate." damage-tagger: #Shown when a player is tagged for an unknown damage type. unknown-damage: "¡Te han herido! ¡No te desconectes!" #These messages are shown when a player is tagged for a known damage type. #You can find a list of damage types here: #https://hub.spigotmc.org/javadocs/spigot/org/bukkit/event/entity/EntityDamageEvent.DamageCause.html damage-type: contact: "Fuiste pinchido por un cactus. ¡No te desconectes!" suffocation: "Te estás sofocando en una pared. ¡No te salgas!" fall: "Te caiste. ¡No te desconectes!" fire: "Estás caminado sobre brasas. ¡No te desconectes!" fire-tick: "Estás ardiendo. ¡No te desconectes!" lava: "Te estás fundiendo en la lava. ¡No te desconectes!" drowning: "Te ahogas. ¡No te desconectes!" block-explosion: "Fuiste afectado por una explosión. ¡No te desconectes!" lightning: "¡Te alcanzó un rayo! ¡No te desconectes!" starvation: "Estás muriendo de hambre. ¡No te desconectes!" poison: "Estás envenenado. ¡No te desconectes!" magic: "Alguien tiró una poción hacia tí. ¡No te desconectes!" wither: "Estás siendo marchitando. ¡No te desconectes!" falling-block: "Un bloque te cayó encima. ¡No te desconectes!" custom: "Te han herido. ¡No te desconectes!" fly-into-wall: "Acabas de experimentar la energía cinética. ¡No te desconectes!" hot-floor: "¡El suelo es lava! ¡No te desconectes!" cramming: "Serás aplastado. ¡No te desconectes!" newbie-helper: togglepvp: #Shown as the command output for '/togglepvp'. self: "PVP: {status}" #Shown as the command output for '/togglepvp admin on/off '. admin: "Cambiaste el modo combate al jugador {target} a {status}." #Shown when the '/togglepvp' command is on cooldown. cooldown: "Debes esperar {time_left} segundos para usar este comando de nuevo." #These messages are shown when pvp is disabled for any reason. no-pvp: self: "No puedes atacarte si tienes el modo de combate desactivado." other: "Ese jugador tiene el modo de combate desactivado." protected: "Ese jugador está protegido, ¡no tienes permitido atacarlo!" protection-disabled: #Shown when newbie protection is disabled due to the player attacking another player. attacker: "Atacaste a alguien, tu protección de combate se ha desactivado." #Shown when newbie protection expires. expired: "Tu protección de combate ha expirado." #Shown for the '/togglepvp check ' command. check-format: - "Información para {target}:" - "Protección: {protected}" - "Estado: {pvp}" loot-protection: #Shown when an enemy dies and their loot is protected. enemy-died: "{enemy} ha muerto. El botín estará protegido por {time} segundos." #Shown when a player tries to pick up an item that is loot protected by the plugin. protected: "Este objeto está actualmente protegido, espera {time} segundos antes de poder recogerlo." citizens-compatibility: #Shown when a player is prevented from joining the server due to their NPC still existing. prevent-join: "No puedes unirte al servidor hasta que tu NPC sea eliminado." disguise-compatibility: #Shown when a disguise is removed from a player during combat. remove-disguise: "Tu disfraz ha sido removido." essentials-compatibility: #Shown when a teleport request is cancelled during combat. prevent-teleport-request-self: "No puedes enviarte solicitudes de teletransportación durante el combate." #Shown when a teleport request is cancelled during combat. prevent-teleport-request-other: "No puedes enviar solicitudes de teletransportación durante el combate." marriagemaster-compatibility: #Shown when a married player is prevented from teleporting to their partner during combat. prevent-teleport-self: "No puedes teletransportarte a tu pareja durante el combate." #Shown when a married player is prevented from teleporting to their partner during combat. prevent-teleport-partner: "No puedes teletransportarte a tu pareja mientras estén en combate." region-protection: #Shown when a player tries to enter a no-pvp area during combat. default-no-entry: "No puedes entrar en esa zona durante el combate." factions-no-entry: No tienes permitido entrar a este lugar durante el combate. griefdefender-no-entry: No tienes permitido entrar a este lugar durante el combate. griefprevention-no-entry: No tienes permitido entrar a este lugar durante el combate. kingdomsx-no-entry: No tienes permitido entrar a este lugar durante el combate. konquest-no-entry: No tienes permitido entrar a este lugar durante el combate. redprotect-no-entry: No tienes permitido entrar a este lugar durante el combate. residence-no-entry: No tienes permitido entrar a este lugar durante el combate. towny-no-entry: No tienes permitido entrar a este lugar durante el combate. husktowns-no-entry: No puedes entrar en esa zona durante el combate. ultimateclaims-no-entry: No tienes permitido entrar a este lugar durante el combate. protectionstones: prevent-area-creation: "No tienes permitido crear un area protegida durante el combate." no-entry: No tienes permitido entrar a este lugar durante el combate. preciousstones: prevent-field-creation: "No tienes permitido crear un area protegida durante el combate." no-entry: No tienes permitido entrar a este lugar durante el combate. worldguard: no-entry-mob-combat: "No tienes permitido entrar a zonas que no admitan PvE durante el combate." no-entry-player-combat: "No tienes permitido entrar a zonas que no admitan PvP durante el combate." no-entry-unknown-combat: No tienes permitido entrar a este lugar durante el combate. lands: no-entry: No tienes permitido entrar a este lugar durante el combate. war-disable-newbie-protection: "PvP esta activada debido a una declaración de guerra." ================================================ FILE: plugin/src/main/resources/language/es_mx.lang.yml ================================================ --- ## Extra Information: ## This is the default language file for CombatLogX. ## The default language is "en_us", also known as English (United States). ## Context will be added as YAML comments above the string. ## The color scheme for messages is gold, white, and sometimes red. ## Command feedback that is successful should always be green. ## Error messages should always be red. ## Variables in messages can be gray or white. ## Messages use the MiniMessage format in non-strict mode. ## More information about MiniMessage can be found here: ## https://docs.adventure.kyori.net/minimessage/format.html #The language code for this file. language-name: "es_mx" #The format for decimal numbers. #The United States uses the number and two decimal places decimal-format: "0.00" #The prefix for CombatLogX. #This is shown in front of all messages and should not be changed unless necessary. prefix: "[CombatLogX]" broadcast: #Shown when the plugin is finished loading. on-load: "CombatLogX se cargó correctamente." #Shown when the plugin is finished enabling. on-enable: "CombatLogX se ha activado correctamente." #Shown when the plugin is disabled for any reason. on-disable: "CombatLogX se ha desactivado correctamente." placeholder: #This text is used for the {combatlogx_time_left} #This allows server configurations to change the display value of the zero to something like "Not in combat" time-left-zero: "0" #This text is used when a player does not have an enemy. #This can happen when players are tagged by a custom expansion or the tag command. unknown-enemy: "Desconocido" status: #Shown when the player is in combat. fighting: "Luchando" in-combat: "" #Shown when the player is not in combat idle: "Inactivo" not-in-combat: "No" #These placeholders are shown when a player changes a value such as whether or not their bossbar is enabled. toggle: enabled: "ACTIVADO" disabled: "Desactivado" pvp-status: enabled: "ACTIVADO" disabled: "Desactivado" combat-timer: #Sent to a player when they escape from combat due to the timer running out. expire: "Ya no estás en combate." #Sent to a player when they escape from combat due to their enemy being killed. enemy-death: "Ya no estás en combate porque tu enemigo murió." #Sent when a player is killed during combat. self-death: "Ya no estás en combate porque estás muerto." error: #Shown when the console tries to execute a command made for players. player-only: "Solo los jugadores pueden ejecutar este comando" #Shown when a command that requires a player has invalid input. invalid-target: "{target} no está conectado o no existe." #Shown when a command that requires a number has invalid input. invalid-integer: "{value} no es un entero válido." #Shown when a player does not have access to something that requires a permission. no-permission: "No estás autorizado porque te falta un permiso: {permission}" #Shown when a player executes a command in a world that is disabled in the configuration. disabled-world: "Este comando no está disponible en esta dimensión." #Shown when a command requires a player in combat but the target player is not in combat. target-not-in-combat: "El jugador {target} no está en combate." #Shown when a player executes a command that requires them to be in combat. self-not-in-combat: "No estás en combate." #Shown when a command that requires an expansion has invalid input. unknown-expansion: "{target} no es una expansión o no está instalado." command: combatlogx: #Shown as the command output for '/combatlogx help'. help-message-list: - "" - "Ayuda de comandos de CombatLogX:" - " /combatlogx help: Ver esta página de ayuda." - " /combatlogx reload: Recarga el archivo config.yml, language.yml y todos los archivos de configuración de expansión." - " /combatlogx about \\: Verifica la información sobre una expansión." - " /combatlogx tag \\ [seconds]: Forzar a un jugador en combate." - " /combatlogx toggle bossbar/actionbar/scoreboard: Activar o desactivar un tipo de notificación" - " /combatlogx untag \\: Forzar a un jugador fuera de combate." - " /combatlogx version: Revisa la versión de CombatLogX." - "" #Shown as the command output for '/combatlogx reload' when reloading is successful. reload-success: - "Se han recargado correctamente todos los archivos de configuración de CombatLogX." - "Se han recargado correctamente todos los archivos de idioma de CombatLogX." - "Se han recargado correctamente todos los archivos de configuración de las expansiones de CombatLogX." #Shown as the command output for '/combatlogx reload' when reloading fails reload-failure: - "Ha ocurrido un error mientras se recargaba la configuración." - "Por favor, revisa el registro de tu servidor y corrige el archivo que no carga." #Shown as the command output for '/combatlogx tag ' when a player is tagged successfully. tag-player: "Has forzado al jugador {target} en combate." #Shown as the command output for '/combatlogx tag ' when the plugin failed to tag a player. tag-failure: "{target} no pudo ser colocado en combate. (¿Tal vez tienen un bypass?)" #Shown as the command output for '/combatlogx untag '. untag-player: "Has forzado al jugador {target} fuera de combate." #Shown as the command output for '/combatlogx toggle bossbar'. toggle-bossbar: "Barra de jefe final: {status}" #Shown as the command output for '/combatlogx toggle actionbar'. toggle-actionbar: "Barra de acciones: {status}" #Shown as the command output for '/combatlogx toggle scoreboard'. toggle-scoreboard: "Marcador: {status}" combat-timer: #Shown as the command output for '/combat-timer'. time-left-self: "Tienes {time_left} segundos restantes." #Shown as the command output for '/combat-timer '. time-left-other: "{target} tiene {time_left} segundos restantes." #These messages are shown a player is tagged into combat. tagged: unknown: player: "Estás en combate con {enemy} por una razón desconocida. ¡No te desconectes!" mob: "Estás en combate con un(a) {enemy} por una razón desconocida. ¡No te desconectes!" mythic_mob: "Estás en combate con un(a) {mob_type} por una razón desconocida. ¡No te desconectes!" damage: "Estás en combate por recibir daño. ¡No te desconectes!" unknown: "Estás en combate por una razón desconocida. ¡No te desconectes!" attacked: player: "Te ataco {enemy}. ¡No te desconectes!" mob: "Te ataco un(a) {mob_type}. ¡No te desconectes!" mythic_mob: "Te ataco un(a) {enemy}. ¡No te desconectes!" damage: "Estás en combate por recibir daño. ¡No te desconectes!" unknown: "Te ataco una fuerza desconocida. ¡No te desconectes!" attacker: player: "Estás atacando a {enemy}. ¡No te desconectes!" mob: "Estás atacando a un(a) {mob_type}. ¡No te desconectes!" mythic_mob: "Estás atacando un(a) {enemy}. ¡No te desconectes!" damage: "Estás en combate por recibir daño. ¡No te desconectes!" unknown: "Estás atacando a una fuerza desconocida. ¡No te desconectes!" expansion: angel-chest: #Shown when opening an AngelChest is prevented during combat. prevent-opening: "No puedes abrir cofres de ángel durante el combate." #Shown when breaking an AngelChest is prevented during combat. prevent-breaking: "No puedes romper cofres de ángel durante el combate." #Shown when fast looting an AngelChest is prevented during combat. prevent-fast-looting: "No puedes abrir cofres ángel rápidamente durante el combate." action-bar: #Shown above the hotbar while a player is in combat. timer: "Combate \u00BB {bars} {combatlogx_time_left} segundos." #Shown above the hotbar for a brief period when combat ends. ended: "Combate \u00BB Ya no estás en combate." boss-bar: #Shown on top of the screen while a player is in combat. timer: "Combate \u00BB {combatlogx_time_left} segundos." #Shown on top of the screen for a brief period when combat ends. ended: "Combate \u00BB Ya no estás en combate." scoreboard: #The scoreboard title for the sidebar. #Make sure to follow the scoreboard title limits for your Spigot version. title: "CombatLogX" #The scoreboard lines for the sidebar. #Make sure to follow the scoreboard line and character limits for your Spigot version. lines: - " " - "Estadísticas de combate:" - "\u00BB Tiempo restante: {combatlogx_time_left}" - "\u00BB Enemigos: {combatlogx_enemy_count}" - "\u00BB Estado: {combatlogx_status}" - " " - "Enemigos" - "\u00BB {combatlogx_specific_enemy_1_name}" - "\u00BB {combatlogx_specific_enemy_2_name}" - "\u00BB {combatlogx_specific_enemy_3_name}" - " " cheat-prevention: #Shown when a command execution is prevented during combat. command-blocked: "No tienes acceso a {command} durante el combate." #Shown when the riptide effect is prevented during combat. no-riptide: "El encantamiento \"riptide\" está desactivado durante el combate." #Shown when a totem of undying is prevented during combat. no-totem: "No puedes usar Totems de la Inmortalidad durante el combate." #Shown when an entity interaction is prevented during combat. no-entity-interaction: "No puedes usar ese criatura durante el combate." #Shown when a chat message is prevented during combat. no-chat: "No puedes enviar mensajes durante el combate." game-mode: #Shown when a player is forced into a specific game mmode during combat. force-switch: "Tu modo de juego ha cambiado a {game_mode}." #Shown when a game mode switch is prevented during combat. no-switch: "No puedes cambiar tu modo de juego durante el combate." flight: #Shown when a player's ability to fly is disabled during combat. force-disabled: "Se ha eliminado tu capacidad de volar." #Shown when a player's attempt to fly is prevented during combat. no-flying: "No puedes volar durante el combate." elytra: #Shown when a player's ability to glide is disabled during combat. force-disabled: "Tu elytra fue desactivado." #Shown when a player's attempt to glide is prevented during combat. no-gliding: "No puedes usar elytra durante el combate." teleportation: #Shown when a player tries to enter a portal and is prevented during combat. block-portal: "No puedes usar portales durante el combate." #Shown when an ender pearl is prevented during combat. block-pearl: "No puedes usar Perlas de Enderman en combate." #Shown when a teleport is prevented during combat. block-other: "No puedes teletransportarte durante el combate." inventory: #Shown when a player's inventory is closed by the plugin during combat. force-closed: "Se cerro tu inventario." #Shown when a player tries to open an inventory and is prevented during combat. no-opening: "No puedes abrir inventarios durante el combate." blocks: #Shown when a player is prevented from breaking a block during combat. prevent-breaking: "No puedes destruir bloques durante el combate." #Shown when a player is prevented from breaking a block during combat. prevent-placing: "No puedes colocar bloques durante el combate." #Shown when a player is prevented from breaking a block during combat. prevent-interaction: "No puedes usar bloques durante el combate." #Shown when a player is prevented from breaking a block during combat. prevent-portal-creation: "No puedes crear portales durante el combate." items: #Shown when a player is prevented from picking up an item during combat. no-pickup: "No puedes recoger objetos durante el combate." #Shown when a player is prevented from dropping an item during combat. no-dropping: "No puedes soltar objetos durante el combate." buckets: #Shown when a player is prevented from emptying a bucket during combat. no-empty: "No puedes vaciar cubos durante el combate." #Shown when a player is prevented from filling a bucket during combat. no-fill: "No puedes llenar cubos durante el combate." damage-tagger: #Shown when a player is tagged for an unknown damage type. unknown-damage: "¡Has recibido daño! ¡No te desconectes!" #These messages are shown when a player is tagged for a known damage type. #You can find a list of damage types here: #https://hub.spigotmc.org/javadocs/spigot/org/bukkit/event/entity/EntityDamageEvent.DamageCause.html damage-type: contact: "Te pico un cactus. ¡No te desconectes!" suffocation: "Estás asfixiando en una pared. ¡No te desconectes!" fall: "Has recibido daño por caída. ¡No te desconectes!" fire: "Has entrado un fuego. ¡No te desconectes!" fire-tick: "Estás quemando. ¡No te desconectes!" lava: "Estas quemando en lava. ¡No te desconectes!" drowning: "Estás ahogándose. ¡No te desconectes!" block-explosion: "Fuiste afectado por una explosión. ¡No te desconectes!" lightning: "¡Te alcanzó un rayo! ¡No te desconectes!" starvation: "Tienes demasiado hambre. ¡No te desconectes!" poison: "Has recibido daño venenoso. ¡No te desconectes!" magic: "Alguien te lanzó una poción. ¡No te desconectes!" wither: "Tienes el efecto de 'Wither'. ¡No te desconectes!" falling-block: "Un bloque cayó sobre ti. ¡No te desconectes!" custom: "Has recibido un daño especial. ¡No te desconectes!" fly-into-wall: "Experimentaste con energía cinética. ¡No te desconectes!" hot-floor: "¡El suelo es lava! ¡No te desconectes!" cramming: "Estás aplastado. ¡No te desconectes!" newbie-helper: togglepvp: #Shown as the command output for '/togglepvp'. self: "PVP: {status}" #Shown as the command output for '/togglepvp admin on/off '. admin: "Has cambiado el pvp de {target} a {status}." #Shown when the '/togglepvp' command is on cooldown. cooldown: "Tienes que esperar {time_left} segundos para usar este comando de nuevo." #These messages are shown when pvp is disabled for any reason. no-pvp: self: "No puedes atacar ese jugador si tienes el PvP desactivado." other: "Ese jugador tiene el PvP desactivado." protected: "¡Ese jugador está protegido, no puedes atacarlo todavía!" protection-disabled: #Shown when newbie protection is disabled due to the player attacking another player. attacker: "Has atacado a alguien, tu protección de novato está desactivada." #Shown when newbie protection expires. expired: "Tu protección de novato ha expirado." #Shown for the '/togglepvp check ' command. check-format: - "Información de {target}:" - "Protección: {protected}" - "Estado de PvP: {pvp}" loot-protection: #Shown when an enemy dies and their loot is protected. enemy-died: "{enemy} ha muerto. El botín estará protegido por {time} segundos." #Shown when a player tries to pick up an item that is loot protected by the plugin. protected: "Este objeto está protegido, espere {time} segundos hasta que pueda recogerlo." citizens-compatibility: #Shown when a player is prevented from joining the server due to their NPC still existing. prevent-join: "No puedes unirte al servidor hasta que tu NPC sea eliminado." disguise-compatibility: #Shown when a disguise is removed from a player during combat. remove-disguise: "Tu disfraz ha sido eliminado." essentials-compatibility: #Shown when a teleport request is cancelled during combat. prevent-teleport-request-self: "No puedes enviar solicitudes de teletransportación durante el combate." #Shown when a teleport request is cancelled during combat. prevent-teleport-request-other: "No puedes enviar una solicitud de teletransporte a un jugador que esté en combate." marriagemaster-compatibility: #Shown when a married player is prevented from teleporting to their partner during combat. prevent-teleport-self: "No puedes teletransportarte a tu pareja durante el combate." #Shown when a married player is prevented from teleporting to their partner during combat. prevent-teleport-partner: "No puedes teletransportarte a tu pareja mientras estén en combate." region-protection: #Shown when a player tries to enter a no-pvp area during combat. default-no-entry: "No puedes entrar en esa zona durante el combate." factions-no-entry: No puedes entrar en esa zona durante el combate. griefdefender-no-entry: No puedes entrar en esa zona durante el combate. griefprevention-no-entry: No puedes entrar en esa zona durante el combate. kingdomsx-no-entry: No puedes entrar en esa zona durante el combate. konquest-no-entry: No puedes entrar en esa zona durante el combate. redprotect-no-entry: No puedes entrar en esa zona durante el combate. residence-no-entry: No puedes entrar en esa zona durante el combate. towny-no-entry: No puedes entrar en esa zona durante el combate. husktowns-no-entry: No puedes entrar en esa zona durante el combate. ultimateclaims-no-entry: No puedes entrar en esa zona durante el combate. protectionstones: prevent-area-creation: "No puedes crear un área protegida durante el combate." no-entry: No puedes entrar en esa zona durante el combate. preciousstones: prevent-field-creation: "No puedes crear un área protegida durante el combate." no-entry: No puedes entrar en esa zona durante el combate. worldguard: no-entry-mob-combat: "No puedes entrar en esa zona durante combate de tipo PvE." no-entry-player-combat: "No puedes entrar en esa zona durante el combate." no-entry-unknown-combat: No puedes entrar en esa zona durante el combate. lands: no-entry: No puedes entrar en esa zona durante el combate. war-disable-newbie-protection: "PvP esta activada porque hay una declaración de guerra." ================================================ FILE: plugin/src/main/resources/language/es_uy.lang.yml ================================================ --- ## Extra Information: ## This is the default language file for CombatLogX. ## The default language is "en_us", also known as English (United States). ## Context will be added as YAML comments above the string. ## The color scheme for messages is gold, white, and sometimes red. ## Command feedback that is successful should always be green. ## Error messages should always be red. ## Variables in messages can be gray or white. ## Messages use the MiniMessage format in non-strict mode. ## More information about MiniMessage can be found here: ## https://docs.adventure.kyori.net/minimessage/format.html #The language code for this file. language-name: "es_uy" #The format for decimal numbers. #The United States uses the number and two decimal places decimal-format: "0.00" #The prefix for CombatLogX. #This is shown in front of all messages and should not be changed unless necessary. prefix: "[CombatLogX]" broadcast: #Shown when the plugin is finished loading. on-load: "CombatLogX ha sido cargado correctamente." #Shown when the plugin is finished enabling. on-enable: "CombatLogX ha sido habilitado correctamente." #Shown when the plugin is disabled for any reason. on-disable: "CombatLogX ha sido deshabilitado correctamente." placeholder: #This text is used for the {combatlogx_time_left} #This allows server configurations to change the display value of the zero to something like "Not in combat" time-left-zero: "0" #This text is used when a player does not have an enemy. #This can happen when players are tagged by a custom expansion or the tag command. unknown-enemy: "Desconocido" status: #Shown when the player is in combat. fighting: "Combatiendo" in-combat: "" #Shown when the player is not in combat idle: "Inactivo" not-in-combat: "No" #These placeholders are shown when a player changes a value such as whether or not their bossbar is enabled. toggle: enabled: "Activado" disabled: "Desactivado" pvp-status: enabled: "Activado" disabled: "Desactivado" combat-timer: #Sent to a player when they escape from combat due to the timer running out. expire: "Ya no estás en modo de combate." #Sent to a player when they escape from combat due to their enemy being killed. enemy-death: "Ya no estás en modo de combate debido a que tu enemigo murió." #Sent when a player is killed during combat. self-death: "Ya no estás en combate porque has muerto." error: #Shown when the console tries to execute a command made for players. player-only: "Solo jugadores pueden ejecutar este comando." #Shown when a command that requires a player has invalid input. invalid-target: "{target} no está conectado o no existe." #Shown when a command that requires a number has invalid input. invalid-integer: "{value} no es un entero válido." #Shown when a player does not have access to something that requires a permission. no-permission: "Permiso faltante: {permission}" #Shown when a player executes a command in a world that is disabled in the configuration. disabled-world: "%%red%%¡Ese comando no se encuentra disponible en esta dimensión!" #Shown when a command requires a player in combat but the target player is not in combat. target-not-in-combat: "{target} no está en combate." #Shown when a player executes a command that requires them to be in combat. self-not-in-combat: "No estás en combate." #Shown when a command that requires an expansion has invalid input. unknown-expansion: "{target} no es una expansión o no está instalada." command: combatlogx: #Shown as the command output for '/combatlogx help'. help-message-list: - "" - "Ayuda de CombatLogX:" - " /combatlogx help: Muestra este menú." - " /combatlogx reload: Reinicia los archivos config.yml, language.yml, y todos los archivos de configuración de sus expansiones." - " /combatlogx about \\: Revisa la información sobre una expansión." - " [seconds]" - " /combatlogx toggle bossbar/actionbar/scoreboard: Habilita o deshabilita alguno de estos mensajes." - " /combatlogx untag \\: Quitar forzosamente el modo combate." - " /combatlogx version: Muestra la versión de CombatLogX." - "" #Shown as the command output for '/combatlogx reload' when reloading is successful. reload-success: - "Se han recargado exitosamente todos los archivos de configuración de CombatLogX." - "Se ha recargado exitosamente el archivo de lenguaje de CombatLogX." - "Se han recargado exitosamente todos los archivos de configuración pertenecientes a las expansiones de CombatLogX." #Shown as the command output for '/combatlogx reload' when reloading fails reload-failure: - "Se ha producido un error al recargar la configuración." - "Compruebe el registro de su servidor y corrija el archivo roto." #Shown as the command output for '/combatlogx tag ' when a player is tagged successfully. tag-player: "Se ha forzado exitosamente al jugador {target} para entrar en modo combate." #Shown as the command output for '/combatlogx tag ' when the plugin failed to tag a player. tag-failure: "{target} no puede ser puesto en combate. (¿Talvez tenga un permiso de excepción?)" #Shown as the command output for '/combatlogx untag '. untag-player: "Se ha retirado forzosamente al jugador {target} su modo de combate." #Shown as the command output for '/combatlogx toggle bossbar'. toggle-bossbar: "Barra de Boss: {status}" #Shown as the command output for '/combatlogx toggle actionbar'. toggle-actionbar: "Barra de acciones: {status}" #Shown as the command output for '/combatlogx toggle scoreboard'. toggle-scoreboard: "Marcador: {status}" combat-timer: #Shown as the command output for '/combat-timer'. time-left-self: "Tienes {time_left} segundos restantes." #Shown as the command output for '/combat-timer '. time-left-other: "{target} tiene {time_left} segundos restantes." #These messages are shown a player is tagged into combat. tagged: unknown: player: "Ahora estás en combate con {enemy} por una razón desconocida. ¡No te desconectes!" mob: " Ahora estás en combate con un(a) {enemy} por una razón desconocida. ¡No cierre sesión!" mythic_mob: "Ahora estás en combate con {mob_type} por una razón desconocida. ¡No te desconectes!" damage: "Ahora estás en combate debido a recibir daño. ¡No te desconectes!" unknown: "Fuiste puesto en combate sin motivo alguno. No cierre la sesión." attacked: player: "Estás siendo atacado por {enemy}. ¡No te desconectes!" mob: "Estás siendo atacado por un(os) {mob_type}. ¡No te desconectes!" mythic_mob: "Estás siendo atacado por un(os) {enemy}. ¡No te desconectes!" damage: "Ahora estás en combate debido a recibir daño. ¡No te desconectes!" unknown: "Estás siendo atacado por una fuerza desconocida. ¡No cierre sesión!" attacker: player: "Estás atacando a {enemy}. ¡No te desconectes!" mob: "Estás atacando un(os) {mob_type}.¡No te salgas!" mythic_mob: "Estás atacando un(os) {enemy}.¡No te salgas!" damage: "Ahora estás en combate debido a recibir daño. ¡No te desconectes!" unknown: "Estás atacando a una fuerza desconocida. ¡No cierre sesión!" expansion: angel-chest: #Shown when opening an AngelChest is prevented during combat. prevent-opening: "No puedes abrir cofres de ángel durante el combate." #Shown when breaking an AngelChest is prevented during combat. prevent-breaking: "No puedes romper cofres de ángel durante el combate." #Shown when fast looting an AngelChest is prevented during combat. prevent-fast-looting: "No se te permite saquear cofres ángeles rápidamente durante el combate." action-bar: #Shown above the hotbar while a player is in combat. timer: "Combate » {bars} {time_left_decimal} segundos." #Shown above the hotbar for a brief period when combat ends. ended: "Combate » Ya no estás en combate." boss-bar: #Shown on top of the screen while a player is in combat. timer: "Combate » {time_left_decimal} segundos." #Shown on top of the screen for a brief period when combat ends. ended: "Combate » Ya no estás en combate." scoreboard: #The scoreboard title for the sidebar. #Make sure to follow the scoreboard title limits for your Spigot version. title: "CombatLogX" #The scoreboard lines for the sidebar. #Make sure to follow the scoreboard line and character limits for your Spigot version. lines: - " " - "Estadísticas del combate" - "» Tiempo restante: {time_left}" - "» En Combate: {in_combat}" - "» Status: {status}" - " " - "Estadísticas del enemigo" - "» Nombre: {enemy_name}" - "» Vida: {enemy_health}" - "» VidaR: {enemy_health_rounded}" - " " cheat-prevention: #Shown when a command execution is prevented during combat. command-blocked: "No tienes acceso al comando {command} durante este combate." #Shown when the riptide effect is prevented during combat. no-riptide: "No tienes permitido usar el encantamiento de Propulsión Acuática durante el combate." #Shown when a totem of undying is prevented during combat. no-totem: "No tienes permitido usar Totems de la Inmortalidad durante el combate." #Shown when an entity interaction is prevented during combat. no-entity-interaction: "No tienes permitido interactuar con esta criatura durante el combate." #Shown when a chat message is prevented during combat. no-chat: "No tienes permitido enviar mensajes durante el combate." game-mode: #Shown when a player is forced into a specific game mmode during combat. force-switch: "Tu modo de juego ha cambiado a {game_mode}." #Shown when a game mode switch is prevented during combat. no-switch: "No tienes permitido cambiar tu modo de juego en combate." flight: #Shown when a player's ability to fly is disabled during combat. force-disabled: "Tu habilidad de volar fue removida." #Shown when a player's attempt to fly is prevented during combat. no-flying: "No tienes permitido volar durante el combate." elytra: #Shown when a player's ability to glide is disabled during combat. force-disabled: "Tus élitros se han desactivado." #Shown when a player's attempt to glide is prevented during combat. no-gliding: "No tienes permitido usar élitros en combate." teleportation: #Shown when a player tries to enter a portal and is prevented during combat. block-portal: "No tienes permitido usar portales durante el combate." #Shown when an ender pearl is prevented during combat. block-pearl: "No tienes permitido usar Perlas de Enderman en combate." #Shown when a teleport is prevented during combat. block-other: "No tienes permitido teletransportarte durante el combate." inventory: #Shown when a player's inventory is closed by the plugin during combat. force-closed: "Tu inventario ha sido cerrado." #Shown when a player tries to open an inventory and is prevented during combat. no-opening: "No tienes permitido abrir inventarios durante el combate." blocks: #Shown when a player is prevented from breaking a block during combat. prevent-breaking: "No tienes permitido romper bloques durante el combate." #Shown when a player is prevented from breaking a block during combat. prevent-placing: "No tienes permitido colocar bloques durante el combate." #Shown when a player is prevented from breaking a block during combat. prevent-interaction: "No tienes permitido usar bloques durante el combate." #Shown when a player is prevented from breaking a block during combat. prevent-portal-creation: "No tienes permitido crear portales durante el combate." items: #Shown when a player is prevented from picking up an item during combat. no-pickup: "No tienes permitido recoger objetos durante el combate." #Shown when a player is prevented from dropping an item during combat. no-dropping: "No tienes permitido arrojar objetos durante el combate." buckets: #Shown when a player is prevented from emptying a bucket during combat. no-empty: "No puedes usar baldes durante el combate." #Shown when a player is prevented from filling a bucket during combat. no-fill: "No puedes llenar baldes durante el combate." damage-tagger: #Shown when a player is tagged for an unknown damage type. unknown-damage: "¡Te han herido! ¡No te desconectes!" #These messages are shown when a player is tagged for a known damage type. #You can find a list of damage types here: #https://hub.spigotmc.org/javadocs/spigot/org/bukkit/event/entity/EntityDamageEvent.DamageCause.html damage-type: contact: "Fuiste pinchido por un cactus. ¡No te desconectes!" suffocation: "Te estás sofocando en una pared. ¡No te salgas!" fall: "Te caiste. ¡No te desconectes!" fire: "Estás caminado sobre brasas. ¡No te desconectes!" fire-tick: "Estás ardiendo. ¡No te desconectes!" lava: "Te estás fundiendo en la lava. ¡No te desconectes!" drowning: "Te ahogas. ¡No te desconectes!" block-explosion: "Fuiste afectado por una explosión. ¡No te desconectes!" lightning: "¡Te alcanzó un rayo! ¡No te desconectes!" starvation: "Estás muriendo de hambre. ¡No te desconectes!" poison: "Estás envenenado. ¡No te desconectes!" magic: "Alguien tiró una poción hacia tí. ¡No te desconectes!" wither: "Estás siendo marchitando. ¡No te desconectes!" falling-block: "Un bloque te cayó encima. ¡No te desconectes!" custom: "Te han herido. ¡No te desconectes!" fly-into-wall: "Acabas de experimentar la energía cinética. ¡No te desconectes!" hot-floor: "¡El suelo es lava! ¡No te desconectes!" cramming: "Serás aplastado. ¡No te desconectes!" newbie-helper: togglepvp: #Shown as the command output for '/togglepvp'. self: "PVP: {status}" #Shown as the command output for '/togglepvp admin on/off '. admin: "Cambiaste el modo combate al jugador {target} a {status}." #Shown when the '/togglepvp' command is on cooldown. cooldown: "Debes esperar {time_left} segundos para usar este comando de nuevo." #These messages are shown when pvp is disabled for any reason. no-pvp: self: "No puedes atacarte si tienes el modo de combate desactivado." other: "Ese jugador tiene el modo de combate desactivado." protected: "Ese jugador está protegido, ¡no tienes permitido atacarlo!" protection-disabled: #Shown when newbie protection is disabled due to the player attacking another player. attacker: "Atacaste a alguien, tu protección de combate se ha desactivado." #Shown when newbie protection expires. expired: "Tu protección de combate ha expirado." #Shown for the '/togglepvp check ' command. check-format: - "Información para {target}:" - "Protección: {protected}" - "Estado: {pvp}" loot-protection: #Shown when an enemy dies and their loot is protected. enemy-died: "{enemy} ha muerto. El botín estará protegido por {time} segundos." #Shown when a player tries to pick up an item that is loot protected by the plugin. protected: "Este objeto está actualmente protegido, espera {time} segundos antes de poder recogerlo." citizens-compatibility: #Shown when a player is prevented from joining the server due to their NPC still existing. prevent-join: "No puedes unirte al servidor hasta que tu NPC sea eliminado." disguise-compatibility: #Shown when a disguise is removed from a player during combat. remove-disguise: "Tu disfraz ha sido removido." essentials-compatibility: #Shown when a teleport request is cancelled during combat. prevent-teleport-request-self: "No puedes enviarte solicitudes de teletransportación durante el combate." #Shown when a teleport request is cancelled during combat. prevent-teleport-request-other: "No puedes enviar solicitudes de teletransportación durante el combate." marriagemaster-compatibility: #Shown when a married player is prevented from teleporting to their partner during combat. prevent-teleport-self: "No puedes teletransportarte a tu pareja durante el combate." #Shown when a married player is prevented from teleporting to their partner during combat. prevent-teleport-partner: "No puedes teletransportarte a tu pareja mientras estén en combate." region-protection: #Shown when a player tries to enter a no-pvp area during combat. default-no-entry: "No puedes entrar en esa zona durante el combate." factions-no-entry: No tienes permitido entrar a este lugar durante el combate. griefdefender-no-entry: No tienes permitido entrar a este lugar durante el combate. griefprevention-no-entry: No tienes permitido entrar a este lugar durante el combate. kingdomsx-no-entry: No tienes permitido entrar a este lugar durante el combate. konquest-no-entry: No tienes permitido entrar a este lugar durante el combate. redprotect-no-entry: No tienes permitido entrar a este lugar durante el combate. residence-no-entry: No tienes permitido entrar a este lugar durante el combate. towny-no-entry: No tienes permitido entrar a este lugar durante el combate. husktowns-no-entry: No puedes entrar en esa zona durante el combate. ultimateclaims-no-entry: No tienes permitido entrar a este lugar durante el combate. protectionstones: prevent-area-creation: "No tienes permitido crear un area protegida durante el combate." no-entry: No tienes permitido entrar a este lugar durante el combate. preciousstones: prevent-field-creation: "No tienes permitido crear un area protegida durante el combate." no-entry: No tienes permitido entrar a este lugar durante el combate. worldguard: no-entry-mob-combat: "No tienes permitido entrar a zonas que no admitan PvE durante el combate." no-entry-player-combat: "No tienes permitido entrar a zonas que no admitan PvP durante el combate." no-entry-unknown-combat: No tienes permitido entrar a este lugar durante el combate. lands: no-entry: No tienes permitido entrar a este lugar durante el combate. war-disable-newbie-protection: "PvP esta activada debido a una declaración de guerra." ================================================ FILE: plugin/src/main/resources/language/es_ve.lang.yml ================================================ --- ## Extra Information: ## This is the default language file for CombatLogX. ## The default language is "en_us", also known as English (United States). ## Context will be added as YAML comments above the string. ## The color scheme for messages is gold, white, and sometimes red. ## Command feedback that is successful should always be green. ## Error messages should always be red. ## Variables in messages can be gray or white. ## Messages use the MiniMessage format in non-strict mode. ## More information about MiniMessage can be found here: ## https://docs.adventure.kyori.net/minimessage/format.html #The language code for this file. language-name: "es_ve" #The format for decimal numbers. #The United States uses the number and two decimal places decimal-format: "0.00" #The prefix for CombatLogX. #This is shown in front of all messages and should not be changed unless necessary. prefix: "[CombatLogX]" broadcast: #Shown when the plugin is finished loading. on-load: "CombatLogX ha sido cargado correctamente." #Shown when the plugin is finished enabling. on-enable: "CombatLogX ha sido habilitado correctamente." #Shown when the plugin is disabled for any reason. on-disable: "CombatLogX ha sido deshabilitado correctamente." placeholder: #This text is used for the {combatlogx_time_left} #This allows server configurations to change the display value of the zero to something like "Not in combat" time-left-zero: "0" #This text is used when a player does not have an enemy. #This can happen when players are tagged by a custom expansion or the tag command. unknown-enemy: "Desconocido" status: #Shown when the player is in combat. fighting: "Combatiendo" in-combat: "" #Shown when the player is not in combat idle: "Inactivo" not-in-combat: "No" #These placeholders are shown when a player changes a value such as whether or not their bossbar is enabled. toggle: enabled: "Activado" disabled: "Desactivado" pvp-status: enabled: "Activado" disabled: "Desactivado" combat-timer: #Sent to a player when they escape from combat due to the timer running out. expire: "Ya no estás en modo de combate." #Sent to a player when they escape from combat due to their enemy being killed. enemy-death: "Ya no estás en modo de combate debido a que tu enemigo murió." #Sent when a player is killed during combat. self-death: "Ya no estás en combate porque has muerto." error: #Shown when the console tries to execute a command made for players. player-only: "Solo jugadores pueden ejecutar este comando." #Shown when a command that requires a player has invalid input. invalid-target: "{target} no está conectado o no existe." #Shown when a command that requires a number has invalid input. invalid-integer: "{value} no es un entero válido." #Shown when a player does not have access to something that requires a permission. no-permission: "Permiso faltante: {permission}" #Shown when a player executes a command in a world that is disabled in the configuration. disabled-world: "%%red%%¡Ese comando no se encuentra disponible en esta dimensión!" #Shown when a command requires a player in combat but the target player is not in combat. target-not-in-combat: "{target} no está en combate." #Shown when a player executes a command that requires them to be in combat. self-not-in-combat: "No estás en combate." #Shown when a command that requires an expansion has invalid input. unknown-expansion: "{target} no es una expansión o no está instalada." command: combatlogx: #Shown as the command output for '/combatlogx help'. help-message-list: - "" - "Ayuda de CombatLogX:" - " /combatlogx help: Muestra este menú." - " /combatlogx reload: Reinicia los archivos config.yml, language.yml, y todos los archivos de configuración de sus expansiones." - " /combatlogx about \\: Revisa la información sobre una expansión." - " [seconds]" - " /combatlogx toggle bossbar/actionbar/scoreboard: Habilita o deshabilita alguno de estos mensajes." - " /combatlogx untag \\: Quitar forzosamente el modo combate." - " /combatlogx version: Muestra la versión de CombatLogX." - "" #Shown as the command output for '/combatlogx reload' when reloading is successful. reload-success: - "Se han recargado exitosamente todos los archivos de configuración de CombatLogX." - "Se ha recargado exitosamente el archivo de lenguaje de CombatLogX." - "Se han recargado exitosamente todos los archivos de configuración pertenecientes a las expansiones de CombatLogX." #Shown as the command output for '/combatlogx reload' when reloading fails reload-failure: - "Se ha producido un error al recargar la configuración." - "Compruebe el registro de su servidor y corrija el archivo roto." #Shown as the command output for '/combatlogx tag ' when a player is tagged successfully. tag-player: "Se ha forzado exitosamente al jugador {target} para entrar en modo combate." #Shown as the command output for '/combatlogx tag ' when the plugin failed to tag a player. tag-failure: "{target} no puede ser puesto en combate. (¿Talvez tenga un permiso de excepción?)" #Shown as the command output for '/combatlogx untag '. untag-player: "Se ha retirado forzosamente al jugador {target} su modo de combate." #Shown as the command output for '/combatlogx toggle bossbar'. toggle-bossbar: "Barra de Boss: {status}" #Shown as the command output for '/combatlogx toggle actionbar'. toggle-actionbar: "Barra de acciones: {status}" #Shown as the command output for '/combatlogx toggle scoreboard'. toggle-scoreboard: "Marcador: {status}" combat-timer: #Shown as the command output for '/combat-timer'. time-left-self: "Tienes {time_left} segundos restantes." #Shown as the command output for '/combat-timer '. time-left-other: "{target} tiene {time_left} segundos restantes." #These messages are shown a player is tagged into combat. tagged: unknown: player: "Ahora estás en combate con {enemy} por una razón desconocida. ¡No te desconectes!" mob: " Ahora estás en combate con un(a) {enemy} por una razón desconocida. ¡No cierre sesión!" mythic_mob: "Ahora estás en combate con {mob_type} por una razón desconocida. ¡No te desconectes!" damage: "Ahora estás en combate debido a recibir daño. ¡No te desconectes!" unknown: "Fuiste puesto en combate sin motivo alguno. No cierre la sesión." attacked: player: "Estás siendo atacado por {enemy}. ¡No te desconectes!" mob: "Estás siendo atacado por un(os) {mob_type}. ¡No te desconectes!" mythic_mob: "Estás siendo atacado por un(os) {enemy}. ¡No te desconectes!" damage: "Ahora estás en combate debido a recibir daño. ¡No te desconectes!" unknown: "Estás siendo atacado por una fuerza desconocida. ¡No cierre sesión!" attacker: player: "Estás atacando a {enemy}. ¡No te desconectes!" mob: "Estás atacando un(os) {mob_type}.¡No te salgas!" mythic_mob: "Estás atacando un(os) {enemy}.¡No te salgas!" damage: "Ahora estás en combate debido a recibir daño. ¡No te desconectes!" unknown: "Estás atacando a una fuerza desconocida. ¡No cierre sesión!" expansion: angel-chest: #Shown when opening an AngelChest is prevented during combat. prevent-opening: "No puedes abrir cofres de ángel durante el combate." #Shown when breaking an AngelChest is prevented during combat. prevent-breaking: "No puedes romper cofres de ángel durante el combate." #Shown when fast looting an AngelChest is prevented during combat. prevent-fast-looting: "No se te permite saquear cofres ángeles rápidamente durante el combate." action-bar: #Shown above the hotbar while a player is in combat. timer: "Combate » {bars} {time_left_decimal} segundos." #Shown above the hotbar for a brief period when combat ends. ended: "Combate » Ya no estás en combate." boss-bar: #Shown on top of the screen while a player is in combat. timer: "Combate » {time_left_decimal} segundos." #Shown on top of the screen for a brief period when combat ends. ended: "Combate » Ya no estás en combate." scoreboard: #The scoreboard title for the sidebar. #Make sure to follow the scoreboard title limits for your Spigot version. title: "CombatLogX" #The scoreboard lines for the sidebar. #Make sure to follow the scoreboard line and character limits for your Spigot version. lines: - " " - "Estadísticas del combate" - "» Tiempo restante: {time_left}" - "» En Combate: {in_combat}" - "» Status: {status}" - " " - "Estadísticas del enemigo" - "» Nombre: {enemy_name}" - "» Vida: {enemy_health}" - "» VidaR: {enemy_health_rounded}" - " " cheat-prevention: #Shown when a command execution is prevented during combat. command-blocked: "No tienes acceso al comando {command} durante este combate." #Shown when the riptide effect is prevented during combat. no-riptide: "No tienes permitido usar el encantamiento de Propulsión Acuática durante el combate." #Shown when a totem of undying is prevented during combat. no-totem: "No tienes permitido usar Totems de la Inmortalidad durante el combate." #Shown when an entity interaction is prevented during combat. no-entity-interaction: "No tienes permitido interactuar con esta criatura durante el combate." #Shown when a chat message is prevented during combat. no-chat: "No tienes permitido enviar mensajes durante el combate." game-mode: #Shown when a player is forced into a specific game mmode during combat. force-switch: "Tu modo de juego ha cambiado a {game_mode}." #Shown when a game mode switch is prevented during combat. no-switch: "No tienes permitido cambiar tu modo de juego en combate." flight: #Shown when a player's ability to fly is disabled during combat. force-disabled: "Tu habilidad de volar fue removida." #Shown when a player's attempt to fly is prevented during combat. no-flying: "No tienes permitido volar durante el combate." elytra: #Shown when a player's ability to glide is disabled during combat. force-disabled: "Tus élitros se han desactivado." #Shown when a player's attempt to glide is prevented during combat. no-gliding: "No tienes permitido usar élitros en combate." teleportation: #Shown when a player tries to enter a portal and is prevented during combat. block-portal: "No tienes permitido usar portales durante el combate." #Shown when an ender pearl is prevented during combat. block-pearl: "No tienes permitido usar Perlas de Enderman en combate." #Shown when a teleport is prevented during combat. block-other: "No tienes permitido teletransportarte durante el combate." inventory: #Shown when a player's inventory is closed by the plugin during combat. force-closed: "Tu inventario ha sido cerrado." #Shown when a player tries to open an inventory and is prevented during combat. no-opening: "No tienes permitido abrir inventarios durante el combate." blocks: #Shown when a player is prevented from breaking a block during combat. prevent-breaking: "No tienes permitido romper bloques durante el combate." #Shown when a player is prevented from breaking a block during combat. prevent-placing: "No tienes permitido colocar bloques durante el combate." #Shown when a player is prevented from breaking a block during combat. prevent-interaction: "No tienes permitido usar bloques durante el combate." #Shown when a player is prevented from breaking a block during combat. prevent-portal-creation: "No tienes permitido crear portales durante el combate." items: #Shown when a player is prevented from picking up an item during combat. no-pickup: "No tienes permitido recoger objetos durante el combate." #Shown when a player is prevented from dropping an item during combat. no-dropping: "No tienes permitido arrojar objetos durante el combate." buckets: #Shown when a player is prevented from emptying a bucket during combat. no-empty: "No puedes usar baldes durante el combate." #Shown when a player is prevented from filling a bucket during combat. no-fill: "No puedes llenar baldes durante el combate." damage-tagger: #Shown when a player is tagged for an unknown damage type. unknown-damage: "¡Te han herido! ¡No te desconectes!" #These messages are shown when a player is tagged for a known damage type. #You can find a list of damage types here: #https://hub.spigotmc.org/javadocs/spigot/org/bukkit/event/entity/EntityDamageEvent.DamageCause.html damage-type: contact: "Fuiste pinchido por un cactus. ¡No te desconectes!" suffocation: "Te estás sofocando en una pared. ¡No te salgas!" fall: "Te caiste. ¡No te desconectes!" fire: "Estás caminado sobre brasas. ¡No te desconectes!" fire-tick: "Estás ardiendo. ¡No te desconectes!" lava: "Te estás fundiendo en la lava. ¡No te desconectes!" drowning: "Te ahogas. ¡No te desconectes!" block-explosion: "Fuiste afectado por una explosión. ¡No te desconectes!" lightning: "¡Te alcanzó un rayo! ¡No te desconectes!" starvation: "Estás muriendo de hambre. ¡No te desconectes!" poison: "Estás envenenado. ¡No te desconectes!" magic: "Alguien tiró una poción hacia tí. ¡No te desconectes!" wither: "Estás siendo marchitando. ¡No te desconectes!" falling-block: "Un bloque te cayó encima. ¡No te desconectes!" custom: "Te han herido. ¡No te desconectes!" fly-into-wall: "Acabas de experimentar la energía cinética. ¡No te desconectes!" hot-floor: "¡El suelo es lava! ¡No te desconectes!" cramming: "Serás aplastado. ¡No te desconectes!" newbie-helper: togglepvp: #Shown as the command output for '/togglepvp'. self: "PVP: {status}" #Shown as the command output for '/togglepvp admin on/off '. admin: "Cambiaste el modo combate al jugador {target} a {status}." #Shown when the '/togglepvp' command is on cooldown. cooldown: "Debes esperar {time_left} segundos para usar este comando de nuevo." #These messages are shown when pvp is disabled for any reason. no-pvp: self: "No puedes atacarte si tienes el modo de combate desactivado." other: "Ese jugador tiene el modo de combate desactivado." protected: "Ese jugador está protegido, ¡no tienes permitido atacarlo!" protection-disabled: #Shown when newbie protection is disabled due to the player attacking another player. attacker: "Atacaste a alguien, tu protección de combate se ha desactivado." #Shown when newbie protection expires. expired: "Tu protección de combate ha expirado." #Shown for the '/togglepvp check ' command. check-format: - "Información para {target}:" - "Protección: {protected}" - "Estado: {pvp}" loot-protection: #Shown when an enemy dies and their loot is protected. enemy-died: "{enemy} ha muerto. El botín estará protegido por {time} segundos." #Shown when a player tries to pick up an item that is loot protected by the plugin. protected: "Este objeto está actualmente protegido, espera {time} segundos antes de poder recogerlo." citizens-compatibility: #Shown when a player is prevented from joining the server due to their NPC still existing. prevent-join: "No puedes unirte al servidor hasta que tu NPC sea eliminado." disguise-compatibility: #Shown when a disguise is removed from a player during combat. remove-disguise: "Tu disfraz ha sido removido." essentials-compatibility: #Shown when a teleport request is cancelled during combat. prevent-teleport-request-self: "No puedes enviarte solicitudes de teletransportación durante el combate." #Shown when a teleport request is cancelled during combat. prevent-teleport-request-other: "No puedes enviar solicitudes de teletransportación durante el combate." marriagemaster-compatibility: #Shown when a married player is prevented from teleporting to their partner during combat. prevent-teleport-self: "No puedes teletransportarte a tu pareja durante el combate." #Shown when a married player is prevented from teleporting to their partner during combat. prevent-teleport-partner: "No puedes teletransportarte a tu pareja mientras estén en combate." region-protection: #Shown when a player tries to enter a no-pvp area during combat. default-no-entry: "No puedes entrar en esa zona durante el combate." factions-no-entry: No tienes permitido entrar a este lugar durante el combate. griefdefender-no-entry: No tienes permitido entrar a este lugar durante el combate. griefprevention-no-entry: No tienes permitido entrar a este lugar durante el combate. kingdomsx-no-entry: No tienes permitido entrar a este lugar durante el combate. konquest-no-entry: No tienes permitido entrar a este lugar durante el combate. redprotect-no-entry: No tienes permitido entrar a este lugar durante el combate. residence-no-entry: No tienes permitido entrar a este lugar durante el combate. towny-no-entry: No tienes permitido entrar a este lugar durante el combate. husktowns-no-entry: No puedes entrar en esa zona durante el combate. ultimateclaims-no-entry: No tienes permitido entrar a este lugar durante el combate. protectionstones: prevent-area-creation: "No tienes permitido crear un area protegida durante el combate." no-entry: No tienes permitido entrar a este lugar durante el combate. preciousstones: prevent-field-creation: "No tienes permitido crear un area protegida durante el combate." no-entry: No tienes permitido entrar a este lugar durante el combate. worldguard: no-entry-mob-combat: "No tienes permitido entrar a zonas que no admitan PvE durante el combate." no-entry-player-combat: "No tienes permitido entrar a zonas que no admitan PvP durante el combate." no-entry-unknown-combat: No tienes permitido entrar a este lugar durante el combate. lands: no-entry: No tienes permitido entrar a este lugar durante el combate. war-disable-newbie-protection: "PvP esta activada debido a una declaración de guerra." ================================================ FILE: plugin/src/main/resources/language/fi_fi.lang.yml ================================================ --- ## Extra Information: ## This is the default language file for CombatLogX. ## The default language is "en_us", also known as English (United States). ## Context will be added as YAML comments above the string. ## The color scheme for messages is gold, white, and sometimes red. ## Command feedback that is successful should always be green. ## Error messages should always be red. ## Variables in messages can be gray or white. ## Messages use the MiniMessage format in non-strict mode. ## More information about MiniMessage can be found here: ## https://docs.adventure.kyori.net/minimessage/format.html #The language code for this file. language-name: "fi_me" #The format for decimal numbers. #The United States uses the number and two decimal places decimal-format: "0.00" #The prefix for CombatLogX. #This is shown in front of all messages and should not be changed unless necessary. prefix: "[CombatLogX]" broadcast: #Shown when the plugin is finished loading. on-load: "CombatLogX ladattiin onnistuneesti." #Shown when the plugin is finished enabling. on-enable: "CombatLogX otettiin käyttöön onnistuneesti." #Shown when the plugin is disabled for any reason. on-disable: "CombatLogX poistettiin käytöstä onnistuneesti." placeholder: #This text is used for the {combatlogx_time_left} #This allows server configurations to change the display value of the zero to something like "Not in combat" time-left-zero: "0" #This text is used when a player does not have an enemy. #This can happen when players are tagged by a custom expansion or the tag command. unknown-enemy: "Tuntematon" status: #Shown when the player is in combat. fighting: "Taistelu" in-combat: "Kyllä" #Shown when the player is not in combat idle: "Käyttämätön" not-in-combat: "Ei" #These placeholders are shown when a player changes a value such as whether or not their bossbar is enabled. toggle: enabled: "KÄYTÖSSÄ" disabled: "POIS" pvp-status: enabled: "KÄYTÖSSÄ" disabled: "POIS" combat-timer: #Sent to a player when they escape from combat due to the timer running out. expire: "Et ole enää taistelussa." #Sent to a player when they escape from combat due to their enemy being killed. enemy-death: "Et ole enää taistelussa, koska vihollinen kuoli." #Sent when a player is killed during combat. self-death: "Et ole enää taistelussa, koska olet kuollut." error: #Shown when the console tries to execute a command made for players. player-only: "Vain pelaajat voivat suorittaa tämän komennon" #Shown when a command that requires a player has invalid input. invalid-target: "{target} ei ole olemassa tai ei ole olemassa." #Shown when a command that requires a number has invalid input. invalid-integer: "{value} ei ole kelvollinen kokonaisluku." #Shown when a player does not have access to something that requires a permission. no-permission: "Käyttöoikeus puuttuu: {permission}" #Shown when a player executes a command in a world that is disabled in the configuration. disabled-world: "Tämä komento ei ole käytettävissä tässä ulottuvuudessa." #Shown when a command requires a player in combat but the target player is not in combat. target-not-in-combat: "{target} ei ole taistelussa." #Shown when a player executes a command that requires them to be in combat. self-not-in-combat: "Et ole taistelussa." #Shown when a command that requires an expansion has invalid input. unknown-expansion: "{target} ei ole laajennusta tai sitä ei ole asennettu." command: combatlogx: #Shown as the command output for '/combatlogx help'. help-message-list: - "" - "CombatLogX Command Help:" - " /combatlogx ohje: Näytä tämä ohjesivu." - " /combatlogx uudelleenlataus: Lataa uudelleen config.yml, language.yml ja kaikki laajennuksen asetustiedostot." - " /combatlogx noin \\: Tarkista tiedot laajennuksesta." - " /combatlogx tag \\ [seconds]: Pakota pelaaja taisteluun." - " /combatlogx vaihda bossbar/actionbar/tulostaulu: Ota ilmoitustyyppi käyttöön tai poista se käytöstä." - " /combatlogx untag \\: Pakota pelaaja pois taistelusta." - " /combatlogx versio: Tarkista versio CombatLogX." - "" #Shown as the command output for '/combatlogx reload' when reloading is successful. reload-success: - "Kaikki asetustiedostot ladattiin onnistuneesti CombatLogXista." - "Kaikki kielitiedostot ladattiin onnistuneesti CombatLogXista." - "Kaikki asetustiedostot ladattiin onnistuneesti CombatLogX-laajennuksesta." #Shown as the command output for '/combatlogx reload' when reloading fails reload-failure: - "Virhe ladattaessa konfiguraatiota uudelleen." - "Tarkista palvelimen loki ja korjaa rikkinäinen tiedosto." #Shown as the command output for '/combatlogx tag ' when a player is tagged successfully. tag-player: "Onnistuneesti pakotti pelaajan {target} taisteluun." #Shown as the command output for '/combatlogx tag ' when the plugin failed to tag a player. tag-failure: "{target} ei voitu sijoittaa taisteluun. (Ehkä niillä on ohitus?)" #Shown as the command output for '/combatlogx untag '. untag-player: "Onnistuneesti pakotti pelaajan {target} taistelusta." #Shown as the command output for '/combatlogx toggle bossbar'. toggle-bossbar: "Boss Bar: {status}" #Shown as the command output for '/combatlogx toggle actionbar'. toggle-actionbar: "Toimintopalkki: {status}" #Shown as the command output for '/combatlogx toggle scoreboard'. toggle-scoreboard: "Tulostaulu: {status}" combat-timer: #Shown as the command output for '/combat-timer'. time-left-self: "Sinulla on {time_left} sekuntia&a jäljellä." #Shown as the command output for '/combat-timer '. time-left-other: "{target} on {time_left} sekuntia jäljellä." #These messages are shown a player is tagged into combat. tagged: unknown: player: "Olet nyt taistelussa {enemy} kanssa tuntemattomasta syystä. Älä kirjaudu ulos!" mob: "Olet nyt taistelussa a (n) {enemy} tuntemattomasta syystä. Älä kirjaudu ulos!" mythic_mob: "Olet nyt taistelussa a (n) {mob_type} tuntemattomasta syystä. Älä kirjaudu ulos!" damage: "Olet nyt taistelussa vahingoittumisen vuoksi. Älä kirjaudu ulos!" unknown: "Sinut asetettiin taisteluun ilman syytä. Älä kirjaudu ulos." attacked: player: "Sinua vastaan hyökätään {enemy}. Älä kirjaudu ulos!" mob: "a (n) {mob_type}hyökkäsi sinua. Älä kirjaudu ulos!" mythic_mob: "a (n) {enemy}hyökkäsi sinua. Älä kirjaudu ulos!" damage: "Olet nyt taistelussa vahingoittumisen vuoksi. Älä kirjaudu ulos!" unknown: "Tuntematon voima hyökkää sinua vastaan. Älä kirjaudu ulos!" attacker: player: "Hyökkäät {enemy}. Älä kirjaudu ulos!" mob: "Hyökkäät (n) {mob_type}. Älä kirjaudu ulos!" mythic_mob: "Hyökkäät (n) {enemy}. Älä kirjaudu ulos!" damage: "Olet nyt taistelussa vahingoittumisen vuoksi. Älä kirjaudu ulos!" unknown: "Hyökkäät tuntematonta voimaa. Älä kirjaudu ulos!" expansion: angel-chest: #Shown when opening an AngelChest is prevented during combat. prevent-opening: "Et saa avata enkeliharkkuja taistelun aikana." #Shown when breaking an AngelChest is prevented during combat. prevent-breaking: "Et saa rikkoa enkeliharkkuja taistelun aikana." #Shown when fast looting an AngelChest is prevented during combat. prevent-fast-looting: "Sinulla ei ole lupaa paastota enkeliharkkuja taistelun aikana." action-bar: #Shown above the hotbar while a player is in combat. timer: "Taistelu \u00BB {bars} {combatlogx_time_left} sekuntia." #Shown above the hotbar for a brief period when combat ends. ended: "Taistele \u00BB Et ole enää taistelussa." boss-bar: #Shown on top of the screen while a player is in combat. timer: "Taistelu \u00BB {combatlogx_time_left} sekuntia." #Shown on top of the screen for a brief period when combat ends. ended: "Taistele \u00BB Et ole enää taistelussa." scoreboard: #The scoreboard title for the sidebar. #Make sure to follow the scoreboard title limits for your Spigot version. title: "CombatLogX" #The scoreboard lines for the sidebar. #Make sure to follow the scoreboard line and character limits for your Spigot version. lines: - " " - "Taistelutilastot:" - "\u00BB Aikaa jäljellä: {combatlogx_time_left}" - "\u00BB Enemies: {combatlogx_enemy_count}" - "\u00BB Tila: {combatlogx_status}" - " " - "Enemies" - "\u00BB {combatlogx_specific_enemy_1_name}" - "\u00BB {combatlogx_specific_enemy_2_name}" - "\u00BB {combatlogx_specific_enemy_3_name}" - " " cheat-prevention: #Shown when a command execution is prevented during combat. command-blocked: "Sinulla ei ole pääsyä {command} taistelun aikana." #Shown when the riptide effect is prevented during combat. no-riptide: "Riptiden lumoaminen on poistettu käytöstä taistelun aikana." #Shown when a totem of undying is prevented during combat. no-totem: "Sinulla ei ole lupaa käyttää rauhoittavia toteamuksia taistelun aikana." #Shown when an entity interaction is prevented during combat. no-entity-interaction: "Et saa käyttää tuota mobia taistelun aikana." #Shown when a chat message is prevented during combat. no-chat: "Et voi lähettää chat-viestejä torjumisen aikana." game-mode: #Shown when a player is forced into a specific game mmode during combat. force-switch: "Pelitilasi on vaihdettu {game_mode}." #Shown when a game mode switch is prevented during combat. no-switch: "Sinulla ei ole oikeutta vaihtaa pelitiloja kamppailun aikana." flight: #Shown when a player's ability to fly is disabled during combat. force-disabled: "Kykysi lentää poistettiin." #Shown when a player's attempt to fly is prevented during combat. no-flying: "Et saa lentää taistelun aikana." elytra: #Shown when a player's ability to glide is disabled during combat. force-disabled: "Elytra on poistettu käytöstä." #Shown when a player's attempt to glide is prevented during combat. no-gliding: "Sinulla ei ole oikeutta käyttää elytraa taistelun aikana." teleportation: #Shown when a player tries to enter a portal and is prevented during combat. block-portal: "Portaalia ei saa käyttää taistelun aikana." #Shown when an ender pearl is prevented during combat. block-pearl: "Et saa käyttää enderöidä helmiä taistelun aikana." #Shown when a teleport is prevented during combat. block-other: "Sinulla ei ole oikeutta teleporttaukseen taistelun aikana." inventory: #Shown when a player's inventory is closed by the plugin during combat. force-closed: "Tavaraluettelosi on suljettu." #Shown when a player tries to open an inventory and is prevented during combat. no-opening: "Tavaraluetteloja ei saa avata taistelun aikana." blocks: #Shown when a player is prevented from breaking a block during combat. prevent-breaking: "Sinulla ei ole lupaa rikkoa lohkoja taistelun aikana." #Shown when a player is prevented from breaking a block during combat. prevent-placing: "Sinulla ei ole oikeutta asettaa palikoita taistelun aikana." #Shown when a player is prevented from breaking a block during combat. prevent-interaction: "Sinulla ei ole oikeutta käyttää lohkoja torjumisen aikana." #Shown when a player is prevented from breaking a block during combat. prevent-portal-creation: "Sinulla ei ole oikeutta luoda portaaleja taistelun aikana." items: #Shown when a player is prevented from picking up an item during combat. no-pickup: "Sinulla ei ole oikeutta noutaa esineitä taistelun aikana." #Shown when a player is prevented from dropping an item during combat. no-dropping: "Sinulla ei ole oikeutta pudottaa esineitä taistelun aikana." buckets: #Shown when a player is prevented from emptying a bucket during combat. no-empty: "Et voi tyhjentää kauhoja taistelun aikana." #Shown when a player is prevented from filling a bucket during combat. no-fill: "Kauhoja ei voi täyttää taistelun aikana." damage-tagger: #Shown when a player is tagged for an unknown damage type. unknown-damage: "Otit vahingon! Älä kirjaudu ulos!" #These messages are shown when a player is tagged for a known damage type. #You can find a list of damage types here: #https://hub.spigotmc.org/javadocs/spigot/org/bukkit/event/entity/EntityDamageEvent.DamageCause.html damage-type: contact: "Kaktus prikkasi sinua. Älä kirjaudu ulos!" suffocation: "Olet tukehtumassa seinään. Älä kirjaudu ulos!" fall: "Otit vahingon. Älä kirjaudu ulos!" fire: "Sinä kävelit tuleen. Älä kirjaudu ulos!" fire-tick: "Olet polttamassa. Älä kirjaudu ulos!" lava: "Kiehuu laavassa. Älä kirjaudu ulos!" drowning: "Olet hukkumassa. Älä kirjaudu ulos!" block-explosion: "Räjähdys vahingoitti sinua. Älä kirjaudu ulos!" lightning: "Sinut on lyöty! Älä kirjaudu ulos!" starvation: "Sinulla on liian nälkäinen. Älä kirjaudu ulos!" poison: "Otit myrkkyvaurion. Älä kirjaudu ulos!" magic: "Joku heitti juoman sinulle. Älä kirjaudu ulos!" wither: "Sinä kuihtut. Älä kirjaudu ulos!" falling-block: "Kuutio putosi päälle. Älä kirjaudu ulos!" custom: "Otit mukautetun vahingon. Älä kirjaudu ulos!" fly-into-wall: "Koit kineettistä energiaa. Älä kirjaudu ulos!" hot-floor: "Lattia on laa! Älä kirjaudu ulos!" cramming: "Sinut on viety pois. Älä kirjaudu ulos!" newbie-helper: togglepvp: #Shown as the command output for '/togglepvp'. self: "PVP: {status}" #Shown as the command output for '/togglepvp admin on/off '. admin: "Olet muuttanut PCP {target} {status}." #Shown when the '/togglepvp' command is on cooldown. cooldown: "Sinun täytyy odottaa {time_left} sekuntia käyttääksesi tätä komentoa uudelleen." #These messages are shown when pvp is disabled for any reason. no-pvp: self: "Et saa lyödä tuota pelaajaa kun PvP on poistettu käytöstä." other: "Tällä pelaajalla on PvP poistettu käytöstä." protected: "Tämä pelaaja on suojattu, sinulla ei ole vielä oikeutta hyökätä heidän kimppuun!" protection-disabled: #Shown when newbie protection is disabled due to the player attacking another player. attacker: "Hyökkäät jotakuta vastaan, uusi suojauksesi on nyt poistettu käytöstä." #Shown when newbie protection expires. expired: "newbie suojauksesi on vanhentunut." #Shown for the '/togglepvp check ' command. check-format: - "Tietoa kohteelle {target}:" - "Suojaus: {protected}" - "PvP: {pvp}" loot-protection: #Shown when an enemy dies and their loot is protected. enemy-died: "{enemy} on kuollut. Loot on suojattu {time} sekunnin ajan." #Shown when a player tries to pick up an item that is loot protected by the plugin. protected: "Tämä kohde on tällä hetkellä suojattu, odota {time} sekuntia kunnes voit noutaa sen." citizens-compatibility: #Shown when a player is prevented from joining the server due to their NPC still existing. prevent-join: "Palvelimeen ei saa liittyä ennen kuin NPC on kuollut tai poistettu." disguise-compatibility: #Shown when a disguise is removed from a player during combat. remove-disguise: "Sinun naamiosi poistettiin." essentials-compatibility: #Shown when a teleport request is cancelled during combat. prevent-teleport-request-self: "Et voi luoda teleporttauspyyntöjä torjumisen aikana." #Shown when a teleport request is cancelled during combat. prevent-teleport-request-other: "Et voi lähettää teleporttauspyyntöä pelaajalle, joka on taistelussa." marriagemaster-compatibility: #Shown when a married player is prevented from teleporting to their partner during combat. prevent-teleport-self: "Sinulla ei ole lupaa teleportata kumppanillesi taistelun aikana." #Shown when a married player is prevented from teleporting to their partner during combat. prevent-teleport-partner: "Sinulla ei ole lupaa teleportata kumppanillesi, kun he ovat taistelussa." region-protection: #Shown when a player tries to enter a no-pvp area during combat. default-no-entry: "Sinulla ei ole oikeutta tulla alueelle taistelun aikana." factions-no-entry: Sinulla ei ole oikeutta tulla alueelle taistelun aikana. griefdefender-no-entry: Sinulla ei ole oikeutta tulla alueelle taistelun aikana. griefprevention-no-entry: Sinulla ei ole oikeutta tulla alueelle taistelun aikana. kingdomsx-no-entry: Sinulla ei ole oikeutta tulla alueelle taistelun aikana. konquest-no-entry: Sinulla ei ole oikeutta tulla alueelle taistelun aikana. redprotect-no-entry: Sinulla ei ole oikeutta tulla alueelle taistelun aikana. residence-no-entry: Sinulla ei ole oikeutta tulla alueelle taistelun aikana. towny-no-entry: Sinulla ei ole oikeutta tulla alueelle taistelun aikana. husktowns-no-entry: Sinulla ei ole oikeutta tulla alueelle taistelun aikana. ultimateclaims-no-entry: Sinulla ei ole oikeutta tulla alueelle taistelun aikana. protectionstones: prevent-area-creation: "Suojattua aluetta ei saa luoda torjumisen aikana." no-entry: Sinulla ei ole oikeutta tulla alueelle taistelun aikana. preciousstones: prevent-field-creation: "Sinulla ei ole lupaa luoda suojauskenttää torjumisen aikana." no-entry: Sinulla ei ole oikeutta tulla alueelle taistelun aikana. worldguard: no-entry-mob-combat: "Et saa syöttää ei-mob-taistelualueelle taistelun aikana." no-entry-player-combat: "Et saa syöttää ei-pelaaja-taistelualuetta taistelun aikana." no-entry-unknown-combat: Sinulla ei ole oikeutta tulla alueelle taistelun aikana. lands: no-entry: Sinulla ei ole oikeutta tulla alueelle taistelun aikana. war-disable-newbie-protection: "PvP on nyt käytössä sotajulistuksen vuoksi." ================================================ FILE: plugin/src/main/resources/language/fr_ca.lang.yml ================================================ --- ## Extra Information: ## This is the default language file for CombatLogX. ## The default language is "en_us", also known as English (United States). ## Context will be added as YAML comments above the string. ## The color scheme for messages is gold, white, and sometimes red. ## Command feedback that is successful should always be green. ## Error messages should always be red. ## Variables in messages can be gray or white. ## Messages use the MiniMessage format in non-strict mode. ## More information about MiniMessage can be found here: ## https://docs.adventure.kyori.net/minimessage/format.html #The language code for this file. language-name: "fr_fr" #The format for decimal numbers. #The United States uses the number and two decimal places decimal-format: "0.00" #The prefix for CombatLogX that is shown in front of all messages. #Note to translators: Do not change this message. prefix: "[CombatLogX]" broadcast: #Shown when the plugin is finished loading. on-load: "CombatLogX a été chargé avec succès." #Shown when the plugin is finished enabling. on-enable: "CombatLogX a été activé avec succès." #Shown when the plugin is disabled for any reason. on-disable: "CombatLogX a été désactivé avec succès." placeholder: #This text is used for the {combatlogx_time_left} #This allows server configurations to change the display value of the zero to something like "Not in combat" time-left-zero: "0" #This text is used when a player does not have an enemy. #This can happen when players are tagged by a custom expansion or the tag command. unknown-enemy: "Inconnu" status: #Shown when the player is in combat. fighting: "Combattez" in-combat: "Oui" #Shown when the player is not in combat idle: "au ralenti" not-in-combat: "Non" #These placeholders are shown when a player changes a value such as whether or not their bossbar is enabled. toggle: enabled: "ACTIVÉ" disabled: "DÉSACTIVÉ" pvp-status: enabled: "ACTIVÉ" disabled: "DÉSACTIVÉ" combat-timer: #Sent to a player when they escape from combat due to the timer running out. expire: "Vous n'êtes plus en combat." #Sent to a player when they escape from combat due to their enemy being killed. enemy-death: "Vous n'êtes plus en combat car votre ennemi est mort." #Sent when a player is killed during combat. self-death: "Vous n'êtes plus en combat car vous êtes mort." error: #Shown when the console tries to execute a command made for players. player-only: "Seuls les joueurs peuvent exécuter cette commande" #Shown when a command that requires a player has invalid input. invalid-target: "{target} n'est pas en ligne ou n'existe pas." #Shown when a command that requires a number has invalid input. invalid-integer: "{value} n'est pas un entier valide." #Shown when a player does not have access to something that requires a permission. no-permission: "Permission manquante : {permission}" #Shown when a player executes a command in a world that is disabled in the configuration. disabled-world: "Cette commande n'est pas disponible dans cette dimension." #Shown when a command requires a player in combat but the target player is not in combat. target-not-in-combat: "{target} n'est pas en combat." #Shown when a player executes a command that requires them to be in combat. self-not-in-combat: "Vous n'êtes pas en combat." #Shown when a command that requires an expansion has invalid input. unknown-expansion: "{target} n'est pas une extension ou n'est pas installé." forgive-not-enemy: "{target} n'est pas l'un de vos ennemis." enemy-not-forgiving: "Cet ennemi n'est pas d'humeur à vous pardonner." command: combatlogx: #Shown as the command output for '/combatlogx help'. help-message-list: - "" - "Aide de commande CombatLogX :" - " /combatlogx help: Voir cette page d'aide." - " /combatlogx reload: Recharger le config.yml, language.yml et tous les fichiers de configuration d'extension." - " /combatlogx about \\: Vérifiez les informations sur une extension." - " Balise /combatlogx \\ [seconds]: Forcer un joueur au combat." - " /combatlogx active bossbar/actionbar/scoreboard: Activer ou désactiver un type de notification." - " /combatlogx untag \\: Forcer un joueur hors combat." - " /combatlogx version: Vérifiez votre version de CombatLogX." - " /combatlogx forgive request \\: Envoyez une requête à un ennemi pour vous retirer son tag." - " /combatlogx forgive accept \\: Permet à un ennemi de s'échapper du combat." - " /combatlogx forgive reject \\: Ignore la demande de fin de combat d'un ennemi." - " /combatlogx forgive toggle: Activez ou désactivez les demandes d'arrêt du combat." - "" #Shown as the command output for '/combatlogx reload' when reloading is successful. reload-success: - "Tous les fichiers de configuration de CombatLogX ont été rechargés." - "Tous les fichiers de langue de CombatLogX ont été rechargés." - "Tous les fichiers de configuration des extensions CombatLogX ont été rechargés." #Shown as the command output for '/combatlogx reload' when reloading fails reload-failure: - "Une erreur s'est produite lors du rechargement de la configuration." - "Veuillez vérifier le journal de votre serveur et corriger le fichier cassé." #Shown as the command output for '/combatlogx tag ' when a player is tagged successfully. tag-player: "Joueur forcé avec succès {target} au combat." #Shown as the command output for '/combatlogx tag ' when the plugin failed to tag a player. tag-failure: "{target} n'a pas pu être placé en combat. (Peut-être ont-ils un contournement ?)" #Shown as the command output for '/combatlogx untag '. untag-player: "Joueur forcé avec succès {target} hors combat." #Shown as the command output for '/combatlogx toggle bossbar'. toggle-bossbar: "Barre de Boss : {status}" #Shown as the command output for '/combatlogx toggle actionbar'. toggle-actionbar: "Barre d'action : {status}" #Shown as the command output for '/combatlogx toggle scoreboard'. toggle-scoreboard: "Tableau de bord : {status}" forgive: toggle-disable: "Vous ne pouvez plus recevoir de demandes de merci." toggle-enable: "Vous pouvez a nouveau recevoir des demandes de merci." request-sent: "Vous avez envoyé une demande de merci à {target}." request-receive: - "{player} vous a envoyé une demande de merci." - "Tapez /clx forgive accept pour accepter ou." - "/clx forgive reject pour refuser." combat-timer: #Shown as the command output for '/combat-timer'. time-left-self: "Vous avez {time_left} secondes restantes." #Shown as the command output for '/combat-timer '. time-left-other: "{target} a {time_left} secondes restantes." #These messages are shown a player is tagged into combat. #You can also change the location of these messages. #Example: #tagged: #attacked: #player: #type: ACTION_BAR #content: "" tagged: unknown: player: "Vous êtes maintenant en combat avec {enemy} pour une raison inconnue. Ne déconnectez pas !" mob: "Vous êtes maintenant en combat avec a(n) {enemy} pour une raison inconnue. Ne déconnectez pas !" mythic_mob: "Vous êtes maintenant en combat avec a(n) {mob_type} pour une raison inconnue. Ne déconnectez pas !" damage: "Vous êtes en combat en raison de la prise de dégâts. Ne déconnectez pas !" unknown: "Vous avez été mis en combat sans raison. Ne déconnectez pas." attacked: player: "Vous êtes attaqué par {enemy}. Ne déconnectez pas !" mob: "Vous êtes attaqué par un(n) {mob_type}. Ne vous déconnectez pas !" mythic_mob: "Vous êtes attaqué par un(n) {enemy}. Ne vous déconnectez pas !" damage: "Vous êtes en combat en raison de la prise de dégâts. Ne déconnectez pas !" unknown: "Vous êtes attaqué par une force inconnue. Ne déconnectez pas !" attacker: player: "Vous attaquez {enemy}. Ne déconnectez pas !" mob: "Vous attaquez un(n) {mob_type}. Ne déconnectez pas !" mythic_mob: "Vous attaquez un(n) {enemy}. Ne déconnectez pas !" damage: "Vous êtes en combat en raison de la prise de dégâts. Ne déconnectez pas !" unknown: "Vous attaquez une force inconnue. Ne déconnectez pas !" expansion: angel-chest: #Shown when opening an AngelChest is prevented during combat. prevent-opening: "Vous n'êtes pas autorisé à ouvrir des coffres d'ange pendant le combat." #Shown when breaking an AngelChest is prevented during combat. prevent-breaking: "Vous n'êtes pas autorisé à casser des coffres d'ange pendant le combat." #Shown when fast looting an AngelChest is prevented during combat. prevent-fast-looting: "Vous n'êtes pas autorisé à ramasser rapidement des coffres d'ange pendant le combat." action-bar: #Shown above the hotbar while a player is in combat. timer: "Combat \u00BB {bars} {combatlogx_time_left} secondes." #Shown above the hotbar for a brief period when combat ends. ended: "Combat \u00BB Vous n'êtes plus en combat." boss-bar: #Shown on top of the screen while a player is in combat. timer: "Combat \u00BB {combatlogx_time_left} secondes." #Shown on top of the screen for a brief period when combat ends. ended: "Combat \u00BB Vous n'êtes plus en combat." scoreboard: #The scoreboard title for the sidebar. #Make sure to follow the scoreboard title limits for your Spigot version. title: "CombatLogX" #The scoreboard lines for the sidebar. #Make sure to follow the scoreboard line and character limits for your Spigot version. lines: - " " - "Statistiques de combat :" - "\u00BB Temps restant : {combatlogx_time_left}" - "\u00BB Enemies: {combatlogx_enemy_count}" - "\u00BB Statut : {combatlogx_status}" - " " - "Enemies" - "\u00BB {combatlogx_specific_enemy_1_name}" - "\u00BB {combatlogx_specific_enemy_2_name}" - "\u00BB {combatlogx_specific_enemy_3_name}" - " " cheat-prevention: #Shown when a command execution is prevented during combat. command-blocked: "Vous n'avez pas accès à {command} pendant le combat." #Shown when the riptide effect is prevented during combat. no-riptide: "L'enchantement de l'énigme est désactivé pendant le combat." #Shown when a totem of undying is prevented during combat. no-totem: "Vous n'êtes pas autorisé à utiliser des totems d'ondulation pendant le combat." #Shown when an entity interaction is prevented during combat. no-entity-interaction: "Vous n'êtes pas autorisé à utiliser ce mob pendant le combat." #Shown when a chat message is prevented during combat. no-chat: "Vous n'êtes pas autorisé à envoyer des messages pendant le combat." game-mode: #Shown when a player is forced into a specific game mmode during combat. force-switch: "Votre mode de jeu a été changé à {game_mode}." #Shown when a game mode switch is prevented during combat. no-switch: "Vous n'êtes pas autorisé à changer de mode de jeu pendant le combat." flight: #Shown when a player's ability to fly is disabled during combat. force-disabled: "Votre capacité à voler a été supprimée." #Shown when a player's attempt to fly is prevented during combat. no-flying: "Vous n'êtes pas autorisé à voler pendant le combat." elytra: #Shown when a player's ability to glide is disabled during combat. force-disabled: "Votre elytra a été désactivé." #Shown when a player's attempt to glide is prevented during combat. no-gliding: "Vous n'êtes pas autorisé à utiliser des elytres pendant le combat." teleportation: #Shown when a player tries to enter a portal and is prevented during combat. block-portal: "Vous n'êtes pas autorisé à utiliser un portail pendant le combat." #Shown when an ender pearl is prevented during combat. block-pearl: "Vous n'êtes pas autorisé à utiliser des perles d'Ender pendant le combat." #Shown when a teleport is prevented during combat. block-other: "Vous n'êtes pas autorisé à vous téléporter pendant le combat." inventory: #Shown when a player's inventory is closed by the plugin during combat. force-closed: "Votre inventaire a été fermé." #Shown when a player tries to open an inventory and is prevented during combat. no-opening: "Vous n'êtes pas autorisé à ouvrir des inventaires pendant le combat." blocks: #Shown when a player is prevented from breaking a block during combat. prevent-breaking: "Vous n'êtes pas autorisé à casser des blocs pendant le combat." #Shown when a player is prevented from breaking a block during combat. prevent-placing: "Vous n'êtes pas autorisé à placer des blocs pendant le combat." #Shown when a player is prevented from breaking a block during combat. prevent-interaction: "Vous n'êtes pas autorisé à utiliser des blocs pendant le combat." #Shown when a player is prevented from breaking a block during combat. prevent-portal-creation: "Vous n'êtes pas autorisé à créer des portails pendant le combat." items: #Shown when a player is prevented from picking up an item during combat. no-pickup: "Vous n'êtes pas autorisé à ramasser des objets pendant le combat." #Shown when a player is prevented from dropping an item during combat. no-dropping: "Vous n'êtes pas autorisé à lâcher des objets pendant le combat." buckets: #Shown when a player is prevented from emptying a bucket during combat. no-empty: "Vous ne pouvez pas vider des seaux pendant le combat." #Shown when a player is prevented from filling a bucket during combat. no-fill: "Vous ne pouvez pas remplir de seaux pendant le combat." damage-tagger: #Shown when a player is tagged for an unknown damage type. unknown-damage: "Vous avez subi des dégâts ! Ne déconnectez pas !" #These messages are shown when a player is tagged for a known damage type. #You can find a list of damage types here: #https://hub.spigotmc.org/javadocs/spigot/org/bukkit/event/entity/EntityDamageEvent.DamageCause.html damage-type: contact: "Vous avez été piqué par un cactus. Ne déconnectez pas !" suffocation: "Vous étouffez dans un mur. Ne déconnectez pas !" fall: "Vous avez subi des dégâts de chute. Ne déconnectez pas !" fire: "Vous avez marché dans le feu. Ne vous déconnectez pas !" fire-tick: "Vous brûlez. Ne déconnectez pas !" lava: "Vous faites bouillir dans de la lave. Ne déconnectez pas !" drowning: "Vous vous noiez. Ne déconnectez pas !" block-explosion: "Vous avez été endommagé par une explosion. Ne déconnectez pas !" lightning: "Tu as été frappé ! Ne te déconnectez pas !" starvation: "Vous avez trop faim. Ne déconnectez pas !" poison: "Vous avez pris des dégâts empoisonnés. Ne déconnectez pas !" magic: "Quelqu'un vous a jeté une potion. Ne vous déconnectez pas !" wither: "Vous vous dessaisissez. Ne déconnectez pas !" falling-block: "Un bloc est tombé sur vous. Ne déconnectez pas !" custom: "Vous avez subi des dégâts personnalisés. Ne déconnectez pas !" fly-into-wall: "Vous avez expérimenté l'énergie cinétique. Ne déconnectez pas !" hot-floor: "Le sol est de la lave ! Ne déconnectez pas !" cramming: "Vous êtes écrasé. Ne déconnectez pas !" newbie-helper: togglepvp: #Shown as the command output for '/togglepvp'. self: "PVP : {status}" #Shown as the command output for '/togglepvp admin on/off '. admin: "Vous avez changé le pvp de {target} à {status}." #Shown when the '/togglepvp' command is on cooldown. cooldown: "Vous devez attendre {time_left} secondes pour utiliser cette commande à nouveau." #These messages are shown when pvp is disabled for any reason. no-pvp: self: "Vous n'êtes pas autorisé à frapper ce joueur tant que votre JcJ est désactivé." other: "Ce joueur a le JcJ désactivé." protected: "Ce joueur est protégé, vous ne pouvez pas encore l'attaquer !" protection-disabled: #Shown when newbie protection is disabled due to the player attacking another player. attacker: "Vous avez attaqué quelqu'un, votre protection de débutant est maintenant désactivée." #Shown when newbie protection expires. expired: "Votre protection de débutant a expiré." #Shown for the '/togglepvp check ' command. check-format: - "Informations pour {target}:" - "Protection : {protected}" - "PvP : {pvp}" loot-protection: #Shown when an enemy dies and their loot is protected. enemy-died: "{enemy} est mort. Le butin sera protégé pendant {time} secondes." #Shown when a player tries to pick up an item that is loot protected by the plugin. protected: "Cet objet est actuellement protégé, attendez {time} secondes jusqu'à ce que vous puissiez le prendre." citizens-compatibility: #Shown when a player is prevented from joining the server due to their NPC still existing. prevent-join: "Vous n'êtes pas autorisé à rejoindre le serveur tant que votre PNJ n'est pas tué ou supprimé." disguise-compatibility: #Shown when a disguise is removed from a player during combat. remove-disguise: "Votre déguisement a été supprimé." essentials-compatibility: #Shown when a teleport request is cancelled during combat. prevent-teleport-request-self: "Vous ne pouvez pas créer de demande de téléportation pendant le combat." #Shown when a teleport request is cancelled during combat. prevent-teleport-request-other: "Vous ne pouvez pas envoyer de demande de téléportation à un joueur en combat." marriagemaster-compatibility: #Shown when a married player is prevented from teleporting to their partner during combat. prevent-teleport-self: "Vous n'êtes pas autorisé à vous téléporter à votre partenaire pendant le combat." #Shown when a married player is prevented from teleporting to their partner during combat. prevent-teleport-partner: "Vous n'êtes pas autorisé à vous téléporter à votre partenaire pendant qu'ils sont en combat." huskhomes-compatibility: prevent-teleport: "Vous n'êtes pas autorisé à vous téléporter pendant le combat." region-protection: #Shown when a player tries to enter a no-pvp area during combat. default-no-entry: "Vous n'êtes pas autorisé à entrer dans cette zone pendant le combat." factions-no-entry: Vous n'êtes pas autorisé à entrer dans cette zone pendant le combat. griefdefender-no-entry: Vous n'êtes pas autorisé à entrer dans cette zone pendant le combat. griefprevention-no-entry: Vous n'êtes pas autorisé à entrer dans cette zone pendant le combat. kingdomsx-no-entry: Vous n'êtes pas autorisé à entrer dans cette zone pendant le combat. konquest-no-entry: Vous n'êtes pas autorisé à entrer dans cette zone pendant le combat. redprotect-no-entry: Vous n'êtes pas autorisé à entrer dans cette zone pendant le combat. residence-no-entry: Vous n'êtes pas autorisé à entrer dans cette zone pendant le combat. towny-no-entry: Vous n'êtes pas autorisé à entrer dans cette zone pendant le combat. husktowns-no-entry: Vous n'êtes pas autorisé à entrer dans cette zone pendant le combat. ultimateclaims-no-entry: Vous n'êtes pas autorisé à entrer dans cette zone pendant le combat. protectionstones: prevent-area-creation: "Vous n'êtes pas autorisé à créer une zone protégée pendant le combat." no-entry: Vous n'êtes pas autorisé à entrer dans cette zone pendant le combat. preciousstones: prevent-field-creation: "Vous n'êtes pas autorisé à créer un champ de protection pendant le combat." no-entry: Vous n'êtes pas autorisé à entrer dans cette zone pendant le combat. worldguard: no-entry-mob-combat: "Vous n'êtes pas autorisé à entrer dans une zone de combat hors mob-pendant le combat." no-entry-player-combat: "Vous n'êtes pas autorisé à entrer dans une zone de combat non-joueur pendant le combat." no-entry-unknown-combat: Vous n'êtes pas autorisé à entrer dans cette zone pendant le combat. lands: no-entry: Vous n'êtes pas autorisé à entrer dans cette zone pendant le combat. war-disable-newbie-protection: "Le PvP est maintenant activé par force en raison d'une déclaration de guerre." ================================================ FILE: plugin/src/main/resources/language/fr_fr.lang.yml ================================================ --- ## Extra Information: ## This is the default language file for CombatLogX. ## The default language is "en_us", also known as English (United States). ## Context will be added as YAML comments above the string. ## The color scheme for messages is gold, white, and sometimes red. ## Command feedback that is successful should always be green. ## Error messages should always be red. ## Variables in messages can be gray or white. ## Messages use the MiniMessage format in non-strict mode. ## More information about MiniMessage can be found here: ## https://docs.adventure.kyori.net/minimessage/format.html #The language code for this file. language-name: "fr_fr" #The format for decimal numbers. #The United States uses the number and two decimal places decimal-format: "0.00" #The prefix for CombatLogX that is shown in front of all messages. #Note to translators: Do not change this message. prefix: "[CombatLogX]" broadcast: #Shown when the plugin is finished loading. on-load: "CombatLogX a été chargé avec succès." #Shown when the plugin is finished enabling. on-enable: "CombatLogX a été activé avec succès." #Shown when the plugin is disabled for any reason. on-disable: "CombatLogX a été désactivé avec succès." placeholder: #This text is used for the {combatlogx_time_left} #This allows server configurations to change the display value of the zero to something like "Not in combat" time-left-zero: "0" #This text is used when a player does not have an enemy. #This can happen when players are tagged by a custom expansion or the tag command. unknown-enemy: "Inconnu" status: #Shown when the player is in combat. fighting: "Combattez" in-combat: "Oui" #Shown when the player is not in combat idle: "au ralenti" not-in-combat: "Non" #These placeholders are shown when a player changes a value such as whether or not their bossbar is enabled. toggle: enabled: "ACTIVÉ" disabled: "DÉSACTIVÉ" pvp-status: enabled: "ACTIVÉ" disabled: "DÉSACTIVÉ" combat-timer: #Sent to a player when they escape from combat due to the timer running out. expire: "Vous n'êtes plus en combat." #Sent to a player when they escape from combat due to their enemy being killed. enemy-death: "Vous n'êtes plus en combat car votre ennemi est mort." #Sent when a player is killed during combat. self-death: "Vous n'êtes plus en combat car vous êtes mort." error: #Shown when the console tries to execute a command made for players. player-only: "Seuls les joueurs peuvent exécuter cette commande" #Shown when a command that requires a player has invalid input. invalid-target: "{target} n'est pas en ligne ou n'existe pas." #Shown when a command that requires a number has invalid input. invalid-integer: "{value} n'est pas un entier valide." #Shown when a player does not have access to something that requires a permission. no-permission: "Permission manquante : {permission}" #Shown when a player executes a command in a world that is disabled in the configuration. disabled-world: "Cette commande n'est pas disponible dans cette dimension." #Shown when a command requires a player in combat but the target player is not in combat. target-not-in-combat: "{target} n'est pas en combat." #Shown when a player executes a command that requires them to be in combat. self-not-in-combat: "Vous n'êtes pas en combat." #Shown when a command that requires an expansion has invalid input. unknown-expansion: "{target} n'est pas une extension ou n'est pas installé." forgive-not-enemy: "{target} n'est pas l'un de vos ennemis." enemy-not-forgiving: "Cet ennemi n'est pas d'humeur à vous pardonner." command: combatlogx: #Shown as the command output for '/combatlogx help'. help-message-list: - "" - "Aide de commande CombatLogX :" - " /combatlogx help: Voir cette page d'aide." - " /combatlogx reload: Recharger le config.yml, language.yml et tous les fichiers de configuration d'extension." - " /combatlogx about \\: Vérifiez les informations sur une extension." - " Balise /combatlogx \\ [seconds]: Forcer un joueur au combat." - " /combatlogx active bossbar/actionbar/scoreboard: Activer ou désactiver un type de notification." - " /combatlogx untag \\: Forcer un joueur hors combat." - " /combatlogx version: Vérifiez votre version de CombatLogX." - " /combatlogx forgive request \\: Envoyez une requête à un ennemi pour vous retirer son tag." - " /combatlogx forgive accept \\: Permet à un ennemi de s'échapper du combat." - " /combatlogx forgive reject \\: Ignore la demande de fin de combat d'un ennemi." - " /combatlogx forgive toggle: Activez ou désactivez les demandes d'arrêt du combat." - "" #Shown as the command output for '/combatlogx reload' when reloading is successful. reload-success: - "Tous les fichiers de configuration de CombatLogX ont été rechargés." - "Tous les fichiers de langue de CombatLogX ont été rechargés." - "Tous les fichiers de configuration des extensions CombatLogX ont été rechargés." #Shown as the command output for '/combatlogx reload' when reloading fails reload-failure: - "Une erreur s'est produite lors du rechargement de la configuration." - "Veuillez vérifier le journal de votre serveur et corriger le fichier cassé." #Shown as the command output for '/combatlogx tag ' when a player is tagged successfully. tag-player: "Joueur forcé avec succès {target} au combat." #Shown as the command output for '/combatlogx tag ' when the plugin failed to tag a player. tag-failure: "{target} n'a pas pu être placé en combat. (Peut-être ont-ils un contournement ?)" #Shown as the command output for '/combatlogx untag '. untag-player: "Joueur forcé avec succès {target} hors combat." #Shown as the command output for '/combatlogx toggle bossbar'. toggle-bossbar: "Barre de Boss : {status}" #Shown as the command output for '/combatlogx toggle actionbar'. toggle-actionbar: "Barre d'action : {status}" #Shown as the command output for '/combatlogx toggle scoreboard'. toggle-scoreboard: "Tableau de bord : {status}" forgive: toggle-disable: "Vous ne pouvez plus recevoir de demandes de merci." toggle-enable: "Vous pouvez a nouveau recevoir des demandes de merci." request-sent: "Vous avez envoyé une demande de merci à {target}." request-receive: - "{player} vous a envoyé une demande de merci." - "Tapez /clx forgive accept pour accepter ou." - "/clx forgive reject pour refuser." combat-timer: #Shown as the command output for '/combat-timer'. time-left-self: "Vous avez {time_left} secondes restantes." #Shown as the command output for '/combat-timer '. time-left-other: "{target} a {time_left} secondes restantes." #These messages are shown a player is tagged into combat. #You can also change the location of these messages. #Example: #tagged: #attacked: #player: #type: ACTION_BAR #content: "" tagged: unknown: player: "Vous êtes maintenant en combat avec {enemy} pour une raison inconnue. Ne déconnectez pas !" mob: "Vous êtes maintenant en combat avec a(n) {enemy} pour une raison inconnue. Ne déconnectez pas !" mythic_mob: "Vous êtes maintenant en combat avec a(n) {mob_type} pour une raison inconnue. Ne déconnectez pas !" damage: "Vous êtes en combat en raison de la prise de dégâts. Ne déconnectez pas !" unknown: "Vous avez été mis en combat sans raison. Ne déconnectez pas." attacked: player: "Vous êtes attaqué par {enemy}. Ne déconnectez pas !" mob: "Vous êtes attaqué par un(n) {mob_type}. Ne vous déconnectez pas !" mythic_mob: "Vous êtes attaqué par un(n) {enemy}. Ne vous déconnectez pas !" damage: "Vous êtes en combat en raison de la prise de dégâts. Ne déconnectez pas !" unknown: "Vous êtes attaqué par une force inconnue. Ne déconnectez pas !" attacker: player: "Vous attaquez {enemy}. Ne déconnectez pas !" mob: "Vous attaquez un(n) {mob_type}. Ne déconnectez pas !" mythic_mob: "Vous attaquez un(n) {enemy}. Ne déconnectez pas !" damage: "Vous êtes en combat en raison de la prise de dégâts. Ne déconnectez pas !" unknown: "Vous attaquez une force inconnue. Ne déconnectez pas !" expansion: angel-chest: #Shown when opening an AngelChest is prevented during combat. prevent-opening: "Vous n'êtes pas autorisé à ouvrir des coffres d'ange pendant le combat." #Shown when breaking an AngelChest is prevented during combat. prevent-breaking: "Vous n'êtes pas autorisé à casser des coffres d'ange pendant le combat." #Shown when fast looting an AngelChest is prevented during combat. prevent-fast-looting: "Vous n'êtes pas autorisé à ramasser rapidement des coffres d'ange pendant le combat." action-bar: #Shown above the hotbar while a player is in combat. timer: "Combat \u00BB {bars} {combatlogx_time_left} secondes." #Shown above the hotbar for a brief period when combat ends. ended: "Combat \u00BB Vous n'êtes plus en combat." boss-bar: #Shown on top of the screen while a player is in combat. timer: "Combat \u00BB {combatlogx_time_left} secondes." #Shown on top of the screen for a brief period when combat ends. ended: "Combat \u00BB Vous n'êtes plus en combat." scoreboard: #The scoreboard title for the sidebar. #Make sure to follow the scoreboard title limits for your Spigot version. title: "CombatLogX" #The scoreboard lines for the sidebar. #Make sure to follow the scoreboard line and character limits for your Spigot version. lines: - " " - "Statistiques de combat :" - "\u00BB Temps restant : {combatlogx_time_left}" - "\u00BB Enemies: {combatlogx_enemy_count}" - "\u00BB Statut : {combatlogx_status}" - " " - "Enemies" - "\u00BB {combatlogx_specific_enemy_1_name}" - "\u00BB {combatlogx_specific_enemy_2_name}" - "\u00BB {combatlogx_specific_enemy_3_name}" - " " cheat-prevention: #Shown when a command execution is prevented during combat. command-blocked: "Vous n'avez pas accès à {command} pendant le combat." #Shown when the riptide effect is prevented during combat. no-riptide: "L'enchantement de l'énigme est désactivé pendant le combat." #Shown when a totem of undying is prevented during combat. no-totem: "Vous n'êtes pas autorisé à utiliser des totems d'ondulation pendant le combat." #Shown when an entity interaction is prevented during combat. no-entity-interaction: "Vous n'êtes pas autorisé à utiliser ce mob pendant le combat." #Shown when a chat message is prevented during combat. no-chat: "Vous n'êtes pas autorisé à envoyer des messages pendant le combat." game-mode: #Shown when a player is forced into a specific game mmode during combat. force-switch: "Votre mode de jeu a été changé à {game_mode}." #Shown when a game mode switch is prevented during combat. no-switch: "Vous n'êtes pas autorisé à changer de mode de jeu pendant le combat." flight: #Shown when a player's ability to fly is disabled during combat. force-disabled: "Votre capacité à voler a été supprimée." #Shown when a player's attempt to fly is prevented during combat. no-flying: "Vous n'êtes pas autorisé à voler pendant le combat." elytra: #Shown when a player's ability to glide is disabled during combat. force-disabled: "Votre elytra a été désactivé." #Shown when a player's attempt to glide is prevented during combat. no-gliding: "Vous n'êtes pas autorisé à utiliser des elytres pendant le combat." teleportation: #Shown when a player tries to enter a portal and is prevented during combat. block-portal: "Vous n'êtes pas autorisé à utiliser un portail pendant le combat." #Shown when an ender pearl is prevented during combat. block-pearl: "Vous n'êtes pas autorisé à utiliser des perles d'Ender pendant le combat." #Shown when a teleport is prevented during combat. block-other: "Vous n'êtes pas autorisé à vous téléporter pendant le combat." inventory: #Shown when a player's inventory is closed by the plugin during combat. force-closed: "Votre inventaire a été fermé." #Shown when a player tries to open an inventory and is prevented during combat. no-opening: "Vous n'êtes pas autorisé à ouvrir des inventaires pendant le combat." blocks: #Shown when a player is prevented from breaking a block during combat. prevent-breaking: "Vous n'êtes pas autorisé à casser des blocs pendant le combat." #Shown when a player is prevented from breaking a block during combat. prevent-placing: "Vous n'êtes pas autorisé à placer des blocs pendant le combat." #Shown when a player is prevented from breaking a block during combat. prevent-interaction: "Vous n'êtes pas autorisé à utiliser des blocs pendant le combat." #Shown when a player is prevented from breaking a block during combat. prevent-portal-creation: "Vous n'êtes pas autorisé à créer des portails pendant le combat." items: #Shown when a player is prevented from picking up an item during combat. no-pickup: "Vous n'êtes pas autorisé à ramasser des objets pendant le combat." #Shown when a player is prevented from dropping an item during combat. no-dropping: "Vous n'êtes pas autorisé à lâcher des objets pendant le combat." buckets: #Shown when a player is prevented from emptying a bucket during combat. no-empty: "Vous ne pouvez pas vider des seaux pendant le combat." #Shown when a player is prevented from filling a bucket during combat. no-fill: "Vous ne pouvez pas remplir de seaux pendant le combat." damage-tagger: #Shown when a player is tagged for an unknown damage type. unknown-damage: "Vous avez subi des dégâts ! Ne déconnectez pas !" #These messages are shown when a player is tagged for a known damage type. #You can find a list of damage types here: #https://hub.spigotmc.org/javadocs/spigot/org/bukkit/event/entity/EntityDamageEvent.DamageCause.html damage-type: contact: "Vous avez été piqué par un cactus. Ne déconnectez pas !" suffocation: "Vous étouffez dans un mur. Ne déconnectez pas !" fall: "Vous avez subi des dégâts de chute. Ne déconnectez pas !" fire: "Vous avez marché dans le feu. Ne vous déconnectez pas !" fire-tick: "Vous brûlez. Ne déconnectez pas !" lava: "Vous faites bouillir dans de la lave. Ne déconnectez pas !" drowning: "Vous vous noiez. Ne déconnectez pas !" block-explosion: "Vous avez été endommagé par une explosion. Ne déconnectez pas !" lightning: "Tu as été frappé ! Ne te déconnectez pas !" starvation: "Vous avez trop faim. Ne déconnectez pas !" poison: "Vous avez pris des dégâts empoisonnés. Ne déconnectez pas !" magic: "Quelqu'un vous a jeté une potion. Ne vous déconnectez pas !" wither: "Vous vous dessaisissez. Ne déconnectez pas !" falling-block: "Un bloc est tombé sur vous. Ne déconnectez pas !" custom: "Vous avez subi des dégâts personnalisés. Ne déconnectez pas !" fly-into-wall: "Vous avez expérimenté l'énergie cinétique. Ne déconnectez pas !" hot-floor: "Le sol est de la lave ! Ne déconnectez pas !" cramming: "Vous êtes écrasé. Ne déconnectez pas !" newbie-helper: togglepvp: #Shown as the command output for '/togglepvp'. self: "PVP : {status}" #Shown as the command output for '/togglepvp admin on/off '. admin: "Vous avez changé le pvp de {target} à {status}." #Shown when the '/togglepvp' command is on cooldown. cooldown: "Vous devez attendre {time_left} secondes pour utiliser cette commande à nouveau." #These messages are shown when pvp is disabled for any reason. no-pvp: self: "Vous n'êtes pas autorisé à frapper ce joueur tant que votre JcJ est désactivé." other: "Ce joueur a le JcJ désactivé." protected: "Ce joueur est protégé, vous ne pouvez pas encore l'attaquer !" protection-disabled: #Shown when newbie protection is disabled due to the player attacking another player. attacker: "Vous avez attaqué quelqu'un, votre protection de débutant est maintenant désactivée." #Shown when newbie protection expires. expired: "Votre protection de débutant a expiré." #Shown for the '/togglepvp check ' command. check-format: - "Informations pour {target}:" - "Protection : {protected}" - "PvP : {pvp}" loot-protection: #Shown when an enemy dies and their loot is protected. enemy-died: "{enemy} est mort. Le butin sera protégé pendant {time} secondes." #Shown when a player tries to pick up an item that is loot protected by the plugin. protected: "Cet objet est actuellement protégé, attendez {time} secondes jusqu'à ce que vous puissiez le prendre." citizens-compatibility: #Shown when a player is prevented from joining the server due to their NPC still existing. prevent-join: "Vous n'êtes pas autorisé à rejoindre le serveur tant que votre PNJ n'est pas tué ou supprimé." disguise-compatibility: #Shown when a disguise is removed from a player during combat. remove-disguise: "Votre déguisement a été supprimé." essentials-compatibility: #Shown when a teleport request is cancelled during combat. prevent-teleport-request-self: "Vous ne pouvez pas créer de demande de téléportation pendant le combat." #Shown when a teleport request is cancelled during combat. prevent-teleport-request-other: "Vous ne pouvez pas envoyer de demande de téléportation à un joueur en combat." marriagemaster-compatibility: #Shown when a married player is prevented from teleporting to their partner during combat. prevent-teleport-self: "Vous n'êtes pas autorisé à vous téléporter à votre partenaire pendant le combat." #Shown when a married player is prevented from teleporting to their partner during combat. prevent-teleport-partner: "Vous n'êtes pas autorisé à vous téléporter à votre partenaire pendant qu'ils sont en combat." huskhomes-compatibility: prevent-teleport: "Vous n'êtes pas autorisé à vous téléporter pendant le combat." region-protection: #Shown when a player tries to enter a no-pvp area during combat. default-no-entry: "Vous n'êtes pas autorisé à entrer dans cette zone pendant le combat." factions-no-entry: Vous n'êtes pas autorisé à entrer dans cette zone pendant le combat. griefdefender-no-entry: Vous n'êtes pas autorisé à entrer dans cette zone pendant le combat. griefprevention-no-entry: Vous n'êtes pas autorisé à entrer dans cette zone pendant le combat. kingdomsx-no-entry: Vous n'êtes pas autorisé à entrer dans cette zone pendant le combat. konquest-no-entry: Vous n'êtes pas autorisé à entrer dans cette zone pendant le combat. redprotect-no-entry: Vous n'êtes pas autorisé à entrer dans cette zone pendant le combat. residence-no-entry: Vous n'êtes pas autorisé à entrer dans cette zone pendant le combat. towny-no-entry: Vous n'êtes pas autorisé à entrer dans cette zone pendant le combat. husktowns-no-entry: Vous n'êtes pas autorisé à entrer dans cette zone pendant le combat. ultimateclaims-no-entry: Vous n'êtes pas autorisé à entrer dans cette zone pendant le combat. protectionstones: prevent-area-creation: "Vous n'êtes pas autorisé à créer une zone protégée pendant le combat." no-entry: Vous n'êtes pas autorisé à entrer dans cette zone pendant le combat. preciousstones: prevent-field-creation: "Vous n'êtes pas autorisé à créer un champ de protection pendant le combat." no-entry: Vous n'êtes pas autorisé à entrer dans cette zone pendant le combat. worldguard: no-entry-mob-combat: "Vous n'êtes pas autorisé à entrer dans une zone de combat hors mob-pendant le combat." no-entry-player-combat: "Vous n'êtes pas autorisé à entrer dans une zone de combat non-joueur pendant le combat." no-entry-unknown-combat: Vous n'êtes pas autorisé à entrer dans cette zone pendant le combat. lands: no-entry: Vous n'êtes pas autorisé à entrer dans cette zone pendant le combat. war-disable-newbie-protection: "Le PvP est maintenant activé par force en raison d'une déclaration de guerre." ================================================ FILE: plugin/src/main/resources/language/hu_hu.lang.yml ================================================ language-name: hu_hu decimal-format: 0,00 prefix: [CombatLogX] broadcast: on-load: A CombatLogX sikeresen betöltődött. on-enable: A CombatLogX sikeresen engedélyezve. on-disable: A CombatLogX sikeresen letiltva. placeholder: time-left-zero: '0' unknown-enemy: Ismeretlen status: fighting: Harcol idle: Tétlen in-combat: Igen not-in-combat: Nem toggle: enabled: BE disabled: KI pvp-status: enabled: BE disabled: KI combat-timer: expire: Már nem vagy harcban. enemy-death: Már nem vagy harcban, mert az ellenséged meghalt. error: player-only: Csak a játékosok hajthatják végre ezt a parancsot. invalid-target: {target} nincs online vagy nem létezik. no-permission: 'Hiáznyzó Engedély: {permission}' target-not-in-combat: {target} nincs harcban. self-not-in-combat: Nem vagy harcban. unknown-expansion: A(z) {target} nem egy bővítmény, vagy nincs telepítve. command: combatlogx: help-message-list: - - 'CombatLogX Parancs Segítség:' - ' /combatlogx help: Megmutatja ezt a súgó oldalt.' - ' /combatlogx reload: Újra betölti a config.yml-t, language.yml-t és minden bővítmény konfigurációs fájlt.' - ' /combatlogx about \: Ellenőrzi a bővítménnyel kapcsolatos információkat.' - ' /combatlogx tag \: Kényszerít egy játékost a harcra.' - ' /combatlogx toggle bossbar/actionbar/scoreboard: Engedélyez vagy letilt egy értesítési típust.' - ' /combatlogx untag \: Kikényszerít egy játékost a harcból.' - ' /combatlogx version: Ellenőrzi a CombatLogX verzióját.' - reload-success: - Az összes konfigurációs fájlt sikeresen újra betöltötted a CombatLogX-ből. - Az összes nyelvi fájlt sikeresen újra betöltötted a CombatLogX-ből. - Az összes konfigurációs fájlt sikeresen újra betöltötted a CombatLogX bővítményekből. tag-player: Sikeresen harcba kényszerítetted {target}-t. tag-failure: {target}-t nem lehetett harcba állítani. (Talán van egy megkerülése?) untag-player: Sikeresen kikényszerítetted {target}-t a harcból. toggle-bossbar: 'Boss Sáv: {status}' toggle-actionbar: 'Action Sáv: {status}' toggle-scoreboard: 'Scoreboard: {status}' combat-timer: time-left-self: Még {time_left} másodperc van hátra. time-left-other: {target}-nek/-nak még {time_left} másodperc van hátra. tagged: unknown: Most harcban vagy! Ne jelentkezz ki. attacked: player: {enemy} megtámadott. Ne jelentkezz ki! mob: Megtámadott egy {mob_type}. Ne jelentkezz ki! attacker: player: Megtámadtad {enemy}-t. Ne jelentkezz ki! mob: Megtámadtál egy {mob_type}-t. Ne jelentkezz ki! expansion: cheat-prevention: command-blocked: A(z) {command} parancshoz nincs hozzáférésed harc közben. no-riptide: A szökőár varázslat harc közben le van tiltva. no-totem: Harc közben nem engedélyezett az életmentés toteme. no-entity-interaction: Harc közben nem engedélyezett használni ezt az élőlényt. no-chat: Harc közben nem engedélyezett chat üzeneteket küldeni. game-mode: force-switch: A játékmódod megváltozott erre {game_mode}. no-switch: Harc közben nem engedélyezett játékmódot váltani. flight: force-disabled: A repülési képességed törlésre került. no-flying: Harc közben nem engedélyezett a repülés. elytra: force-disabled: A kitinszárnyad letiltásra került. no-gliding: Harc közben nem engedélyezett kitinszárnyat használni. teleportation: block-portal: Harc közben nem engedélyezett portált használni. block-pearl: Harc közben nem engedélyezett endergyöngyöket használni. block-other: Harc közben nem engedélyezett a teleportálás. inventory: force-closed: Az eszköztárad bezárásra került. no-opening: Harc közben nem engedélyezett eszköztárakat megnyitni. blocks: prevent-breaking: Harc közben nem engedélyezett blokkokat kiütni. prevent-placing: Harc közben nem engedélyezett blokkokat lerakni. prevent-interaction: Harc közben nem engedélyezett blokkokat használni. prevent-portal-creation: Harc közben nem engedélyezett portált létrehozni. items: no-pickup: Harc közben nem engedélyezett tárgyakat felvenni. no-dropping: Harc közben nem engedélyezett tárgyakat kidobni. buckets: no-empty: Harc közben nem engedélyezett kiüríteni a vödröket. no-fill: Harc közben nem engedélyezett megtölteni a vödröket. damage-tagger: unknown-damage: Sérülést szenvedtél! Ne jelentkezz ki! damage-type: contact: Megszúrt egy kaktusz. Ne jelentkezz ki! suffocation: Beragadtál egy falba. Ne jelentkezz ki! fall: Esési sérülést szenvedtél. Ne jelentkezz ki! fire: Tűzbe sétáltál. Ne jelentkezz ki! fire-tick: Égsz. Ne jelentkezz ki! lava: Lávában forrsz. Ne jelentkezz ki! drowning: Fulladozol. Ne jelentkezz ki! block-explosion: Megsérültél egy robbanásban. Ne jelentkezz ki! lightning: Beléd csapott egy villám! Ne jelentkezz ki! starvation: Túl éhes vagy. Ne jelentkezz ki! poison: Méregkárosodást szenvedtél. Ne jelentkezz ki! magic: Valaki megdobott egy bájitallal. Ne jelentkezz ki! wither: Elsorvadsz. Ne jelentkezz ki! falling-block: Egy blokk esett rád. Ne jelentkezz ki! custom: Egyedi sérülést szenvedtél. Ne jelentkezz ki! fly-into-wall: Kinetikus energiát tapasztaltál. Ne jelentkezz ki! hot-floor: A padló láva! Ne jelentkezz ki! cramming: Téged összezsúfoltak. Ne jelentkezz ki! newbie-helper: togglepvp: self: 'PVP: {status}' admin: {target} pvp-je átállítva erre {status}. cooldown: A parancs újbóli használatához várnod kell {time_left} másodpercet. no-pvp: self: Nem ütheted meg ezt a játékost, ameddig a PvP-d le van tiltva. other: Ennek a játékosnak le van tiltva a PvP-je. protected: Ez a játékos védett, még nem engedélyezett megtámadni őt! protection-disabled: attacker: Megtámadtál valakit, az újonc védelmed letiltásra került. expired: Az újonc védelmed lejárt. check-format: - '{target} &információi :' - Védelem {protected} - 'PvP: {pvp}' loot-protection: enemy-died: {enemy} meghalt. A zsákmány {time} másodpercig védett. protected: Ez a tárgy jelenleg védett. Várj {time} másodpercet, hogy feltudd venni. citizens-compatibility: prevent-join: Addig nem csatlakozhatsz, ameddig a klónod meg nem ölték vagy el nem tűnt. disguise-compatibility: remove-disguise: Az álcád eltávolításra került. essentials-compatibility: prevent-teleport-request-self: Harc közben nem engedélyezett teleport kéréseket létrehozni. prevent-teleport-request-other: Harc közben nem engedélyezett teleport kérést küldeni egy játékosnak. region-protection: factions-no-entry: Harc közben nem engedélyezett belépni erre a területre. griefdefender-no-entry: Harc közben nem engedélyezett belépni erre a területre. griefprevention-no-entry: Harc közben nem engedélyezett belépni erre a területre. kingdomsx-no-entry: Harc közben nem engedélyezett belépni erre a területre. lands-no-entry: Harc közben nem engedélyezett belépni erre a területre. konquest-no-entry: Harc közben nem engedélyezett belépni erre a területre. redprotect-no-entry: Harc közben nem engedélyezett belépni erre a területre. residence-no-entry: Harc közben nem engedélyezett belépni erre a területre. towny-no-entry: Harc közben nem engedélyezett belépni erre a területre. ultimateclaims-no-entry: Harc közben nem engedélyezett belépni erre a területre. protectionstones: prevent-area-creation: Harc közben nem engedélyezett védett területet létrehozni. no-entry: Harc közben nem engedélyezett belépni erre a területre. preciousstones: prevent-field-creation: Harc közben nem engedélyezett védőmezőt létrehozni. no-entry: Harc közben nem engedélyezett belépni erre a területre. worldguard: no-entry-mob-combat: Harc közben nem engedélyezett belépni egy non-mob-combat területre. no-entry-player-combat: Harc közben nem engedélyezett belépni egy non-player-combat területre. no-entry-unknown-combat: Harc közben nem engedélyezett belépni erre a területre. ================================================ FILE: plugin/src/main/resources/language/it_it.lang.yml ================================================ --- ## Extra Information: ## This is the default language file for CombatLogX. ## The default language is "en_us", also known as English (United States). ## Context will be added as YAML comments above the string. ## The color scheme for messages is gold, white, and sometimes red. ## Command feedback that is successful should always be green. ## Error messages should always be red. ## Variables in messages can be gray or white. ## Messages use the MiniMessage format in non-strict mode. ## More information about MiniMessage can be found here: ## https://docs.adventure.kyori.net/minimessage/format.html #The language code for this file. language-name: "it_it" #The format for decimal numbers. #The United States uses the number and two decimal places decimal-format: "0.00" #The prefix for CombatLogX that is shown in front of all messages. #Note to translators: Do not change this message. prefix: "[CombatLogX]" broadcast: #Shown when the plugin is finished loading. on-load: "CombatLogX è stato caricato con successo." #Shown when the plugin is finished enabling. on-enable: "CombatLogX è stato abilitato." #Shown when the plugin is disabled for any reason. on-disable: "CombatLogX è stato disabilitato." placeholder: #This text is used for the {combatlogx_time_left} #This allows server configurations to change the display value of the zero to something like "Not in combat" time-left-zero: "0" #This text is used when a player does not have an enemy. #This can happen when players are tagged by a custom expansion or the tag command. unknown-enemy: "Sconosciuto" status: #Shown when the player is in combat. fighting: "In combattimento" in-combat: "Sì" #Shown when the player is not in combat idle: "Idle" not-in-combat: "No" #These placeholders are shown when a player changes a value such as whether or not their bossbar is enabled. toggle: enabled: "ON" disabled: "OFF" pvp-status: enabled: "ON" disabled: "OFF" #You can also change the location of these messages. #Example: #combat-timer: #expire: #type: ACTION_BAR #content: "" combat-timer: #Sent to a player when they escape from combat due to the timer running out. expire: "Non sei più in combattimento." #Sent to a player when they escape from combat due to their enemy being killed. enemy-death: "Non sei più in combattimento perché il tuo avversario è morto." #Sent when a player is killed during combat. self-death: "Non sei più in combattimento perché sei morto." error: #Shown when the console tries to execute a command made for players. player-only: "Questo comando può essere eseguito solo in-gioco." #Shown when a player tries to execute a command made for the server console. console-only: "Questo comando deve essere eseguito dalla console." #Shown when a command that requires a player has invalid input. invalid-target: "{target} non è online o non esiste." #Shown when a command that requires a number has invalid input. invalid-integer: "{value} non è un numero intero valido." #Shown when a player does not have access to something that requires a permission. no-permission: "Permesso mancante: {permission}" #Shown when a player executes a command in a world that is disabled in the configuration. disabled-world: "Questo comando non è disponibile in questo mondo." #Shown when a command requires a player in combat but the target player is not in combat. target-not-in-combat: "{target} non è in combattimento." #Shown when a player executes a command that requires them to be in combat. self-not-in-combat: "Non sei in combattimento." #Shown when a command that requires an expansion has invalid input. unknown-expansion: "{target} non è un'espansione o non è installato." forgive-not-enemy: "{target} non è tra i tuoi avversari." enemy-not-forgiving: "Quest'avversario non vuole perdonarti al momento." command: combatlogx: #Shown as the command output for '/combatlogx help'. help-message-list: - "" - "Guida CombatLogX Comando:" - " /combatlogx help: Visualizza la pagina di aiuto." - " /combatlogx reload: Ricarica i file di configurazione config.yml, language.yml, e tutti i file di configurazione delle espansioni." - " /combatlogx su \\: Visualizza informazioni di un'espansione." - " /combatlogx tag \\: Forza un giocatore in combattimento." - " /combatlogx toggle bossbar/actionbar/scoreboard: Abilita o disabilita un tipo di notifica." - " /combatlogx untag \\: Forza un giocatore fuori combattimento." - " /combatlogx version: Verifica la versione installata di CombatLogX." - " /combatlogx forgive request \\: Invia una richiesta all'avversario per chiedergli di uscire dal combattimento." - " /combatlogx forgive accept \\: Accetta la richiesta dell'avversario di uscire dal combattimento." - " /combatlogx forgive reject \\: Ignora la richiesta dell'avversario di uscire dal combattimento." - " /combatlogx forgive toggle: Abilita o disabilita le richieste per uscire dal combattimento." - "" #Shown as the command output for '/combatlogx reload' when reloading is successful. reload-success: - "Hai ricaricato con successo tutti i file di configurazione da CombatLogX." - "Ricaricati con successo tutti i file di lingua da CombatLogX." - "Ricaricati con successo tutti i file di configurazione dalle espansioni CombatLogX." #Shown as the command output for '/combatlogx reload' when reloading fails reload-failure: - "Si è verificato un errore durante il caricamento della configurazione." - "Controlla il log del server e correggi il file corrotto." #Shown as the command output for '/combatlogx tag ' when a player is tagged successfully. tag-player: "Giocatore {target} forzato con successo in combattimento." #Shown as the command output for '/combatlogx tag ' when the plugin failed to tag a player. tag-failure: "{target} non può essere forzato in combattimento. (Forse hanno un bypass?)" #Shown as the command output for '/combatlogx untag '. untag-player: "Giocatore {target} forzato con successo fuori combattimento." #Shown as the command output for '/combatlogx toggle bossbar'. toggle-bossbar: "Boss Bar: {status}" #Shown as the command output for '/combatlogx toggle actionbar'. toggle-actionbar: "Action Bar: {status}" #Shown as the command output for '/combatlogx toggle scoreboard'. toggle-scoreboard: "Scoreboard: {status}" #Shown as the command output for '/combatlogx about '. expansion-information: - "" - "Expansion Information for {name}:" - "Display Name: {prefix}" - "Version: {version}" - "State: {state}" - "" - "Description: {description}" - "Website: {website}" - "Authors: {authors}" forgive: toggle-disable: "Non ricevi più le richieste di perdono." toggle-enable: "Adesso ricevi le richieste di perdono." request-sent: "Hai mandato una richiesta di perdono a {target}." request-receive: - "{player} sent a forgive request to you." - "Type /clx forgive accept to accept or." - "/clx forgive reject to deny." combat-timer: #Shown as the command output for '/combat-timer'. time-left-self: "You have {time_left} seconds remaining." #Shown as the command output for '/combat-timer '. time-left-other: "{target} ha {time_left} secondi rimanenti." #These messages are shown a player is tagged into combat. #You can also change the location of these messages. #Example: #tagged: #attacked: #player: #type: ACTION_BAR #content: "" tagged: unknown: player: "Ora sei in combattimento con {enemy} per un motivo sconosciuto. Non disconnetterti!" mob: "Ora sei in combattimento con a(n) {enemy} per un motivo sconosciuto. Non disconnetterti!" mythic_mob: "Ora sei in combattimento con a(n) {mob_type} per un motivo sconosciuto. Non disconnetterti!" damage: "Ora sei in combattimento a causa di danni subiti. Non disconnetterti!" unknown: "Sei stato messo in combattimento senza un motivo. Non disconnetterti." attacked: player: "Sei stato attaccato da {enemy}. Non disconnetterti!" mob: "Sei stato attaccato da a(n) {mob_type}. Non disconnetterti!" mythic_mob: "Sei stato attaccato da a(n) {enemy}. Non disconnetterti!" damage: "Ora sei in combattimento a causa di danni subiti. Non disconnetterti!" unknown: "Sei stato attaccato da una forza sconosciuta. Non disconnetterti!" attacker: player: "Stai attaccando {enemy}. Non disconnetterti!" mob: "Stai attaccando a(n) {mob_type}. Non disconnetterti!" mythic_mob: "Stai attaccando a(n) {enemy}. Non disconnetterti!" damage: "Ora sei in combattimento a causa di danni subiti. Non disconnetterti!" unknown: "Stai attaccando una forza sconosciuta. Non disconnetterti!" expansion: angel-chest: #Shown when opening an AngelChest is prevented during combat. prevent-opening: "Non hai il permesso di aprire le casse degli angeli durante il combattimento." #Shown when breaking an AngelChest is prevented during combat. prevent-breaking: "Non ti è permesso rompere le casse degli angeli durante il combattimento." #Shown when fast looting an AngelChest is prevented during combat. prevent-fast-looting: "Non sei autorizzato a velocizzare le casse degli angeli durante il combattimento." action-bar: #Shown above the hotbar while a player is in combat. timer: "Combat \u00BB {bars} {combatlogx_time_left} secondi." #Shown above the hotbar for a brief period when combat ends. ended: "Combat \u00BB Non sei più in combattimento." boss-bar: #Shown on top of the screen while a player is in combat. timer: "Combat \u00BB {combatlogx_time_left} secondi." #Shown on top of the screen for a brief period when combat ends. ended: "Combat \u00BB Non sei più in combattimento." scoreboard: #The scoreboard title for the sidebar. #Make sure to follow the scoreboard title limits for your Spigot version. title: "CombatLogX" #The scoreboard lines for the sidebar. #Make sure to follow the scoreboard line and character limits for your Spigot version. lines: - " " - "Statistiche di battaglia:" - "\u00BB Tempo rimanente: {combatlogx_time_left}" - "\u00BB Enemies: {combatlogx_enemy_count}" - "\u00BB Status: {combatlogx_status}" - " " - "Enemies" - "\u00BB {combatlogx_specific_enemy_1_name}" - "\u00BB {combatlogx_specific_enemy_2_name}" - "\u00BB {combatlogx_specific_enemy_3_name}" - " " cheat-prevention: #Shown when a command execution is prevented during combat. command-blocked: "Non hai accesso a {command} durante il combattimento." #Shown when the riptide effect is prevented during combat. no-riptide: "L'incantesimo riptide è disabilitato durante il combattimento." #Shown when a totem of undying is prevented during combat. no-totem: "Non hai il permesso di usare i totem dell'immortalità durante il combattimento." #Shown when an entity interaction is prevented during combat. no-entity-interaction: "Non hai il permesso di usare quel mob durante il combattimento." #Shown when a chat message is prevented during combat. no-chat: "Non sei autorizzato a inviare messaggi in chat durante il combattimento." game-mode: #Shown when a player is forced into a specific game mmode during combat. force-switch: "La tua modalità di gioco è stata cambiata in {game_mode}." #Shown when a game mode switch is prevented during combat. no-switch: "Non puoi cambiare modalità di gioco durante il combattimento." flight: #Shown when a player's ability to fly is disabled during combat. force-disabled: "Fly disabilitata." #Shown when a player's attempt to fly is prevented during combat. no-flying: "Non puoi volare durante il combattimento." elytra: #Shown when a player's ability to glide is disabled during combat. force-disabled: "La tua elytra è stata disabilitata." #Shown when a player's attempt to glide is prevented during combat. no-gliding: "Non hai il permesso di usare l'elytra durante il combattimento." teleportation: #Shown when a player tries to enter a portal and is prevented during combat. block-portal: "Non hai il permesso di utilizzare un portale durante il combattimento." #Shown when an ender pearl is prevented during combat. block-pearl: "Non hai il permesso di usare perle di ender durante il combattimento." #Shown when a teleport is prevented during combat. block-other: "Non puoi teletrasportarti durante il combattimento." inventory: #Shown when a player's inventory is closed by the plugin during combat. force-closed: "Il tuo inventario è stato chiuso." #Shown when a player tries to open an inventory and is prevented during combat. no-opening: "Non puoi aprire gli inventari durante il combattimento." blocks: #Shown when a player is prevented from breaking a block during combat. prevent-breaking: "Non puoi rompere blocchi durante il combattimento." #Shown when a player is prevented from breaking a block during combat. prevent-placing: "Non puoi posizionare blocchi durante il combattimento." #Shown when a player is prevented from breaking a block during combat. prevent-interaction: "Non puoi usare blocchi durante il combattimento." #Shown when a player is prevented from breaking a block during combat. prevent-portal-creation: "Non puoi creare portali durante il combattimento." items: #Shown when a player is prevented from picking up an item during combat. no-pickup: "Non puoi raccogliere oggetti durante il combattimento." #Shown when a player is prevented from dropping an item during combat. no-dropping: "Non puoi rilasciare oggetti durante il combattimento." buckets: #Shown when a player is prevented from emptying a bucket during combat. no-empty: "You can't empty buckets during combat." #Shown when a player is prevented from filling a bucket during combat. no-fill: "You can't fill up buckets during combat." damage-tagger: #Shown when a player is tagged for an unknown damage type. unknown-damage: "Hai subito danno! Non disconnetterti!" #These messages are shown when a player is tagged for a known damage type. #You can find a list of damage types here: #https://hub.spigotmc.org/javadocs/spigot/org/bukkit/event/entity/EntityDamageEvent.DamageCause.html damage-type: block-explosion: "Sei stato danneggiato da un'esplosione. Non disconnetterti!" contact: "Sei stato danneggiato da un cactus. Non disconnetterti!" cramming: "Stai per essere schiacciato. Non disconnetterti!" custom: "Hai subito danni personalizzati. Non disconnetterti!" drowning: "Stai annegando. Non disconnetterti!" dryout: "You stayed out of water too long. Non disconnetterti!" #May be triggered by custom plugins. entity-explosion: "Hai subito danni da un cristallo dell'end. Non disconnetterti!" #Only triggered by end crystals. fall: "Hai subito danni da caduta. Non disconnetterti!" falling-block: "Un blocco è caduto su di te. Non disconnetterti!" fire: "Sei entrato nel fuoco. Non disconnetterti!" fire-tick: "Stai bruciando. Non disconnetterti!" fly-into-wall: "Hai sperimentato energia cinetica. Non disconnetterti!" freeze: "Stai congelando. Non disconnetterti!" hot-floor: "Il pavimento è lava! Non disconnetterti!" lava: "Stai bollendo nella lava. Non disconnetterti!" lightning: "Sei stato folgorato! Non disconnetterti!" magic: "Qualcuno ti ha colpito con una pozione. Non disconnetterti!" melting: "You are melting! Non disconnetterti." #May be triggered by custom plugins. poison: "Hai subito danni da avvelenamento. Non disconnetterti!" starvation: "Stai morendo di fame. Non disconnetterti!" suffocation: "Stai soffocando in un muro. Non disconnetterti!" void: "Stai cadendo nel vuoto. Non disconnetterti!" wither: "Stai rimuovendo. Non disconnetterti!" world-border: "Sei molto vicino al limite del mondo. Non disconnetterti!" newbie-helper: togglepvp: #Shown as the command output for '/togglepvp'. self: "PVP: {status}" #Shown as the command output for '/togglepvp admin on/off '. admin: "Hai cambiato il pvp di {target} a {status}." #Shown when the '/togglepvp' command is on cooldown. cooldown: "You must wait {time_left} seconds to use this command again." #These messages are shown when pvp is disabled for any reason. no-pvp: self: "Non sei autorizzato a colpire quel giocatore mentre il tuo PvP è disabilitato." other: "Quel giocatore ha PvP disabilitato." protected: "Quel giocatore è protetto, non ti è ancora permesso attaccarlo!" protection-disabled: #Shown when newbie protection is disabled due to the player attacking another player. attacker: "Hai attaccato qualcuno, la tua protezione da nabbo è ora disabilitata." #Shown when newbie protection expires. expired: "La tua protezione da nabbo è scaduta." #Shown for the '/togglepvp check ' command. check-format: - "Informazioni per {target}:" - "Protezione: {protected}" - "PvP: {pvp}" loot-protection: #Shown when an enemy dies and their loot is protected. enemy-died: "{enemy} è morto. Il bottino sarà protetto per {time} secondi." #Shown when a player tries to pick up an item that is loot protected by the plugin. protected: "Questo oggetto è attualmente protetto aspetta {time} secondi fino a quando non puoi prenderlo." citizens-compatibility: #Shown when a player is prevented from joining the server due to their NPC still existing. prevent-join: "Non puoi unirti al server finché il tuo NPC non viene ucciso o rimosso." disguise-compatibility: #Shown when a disguise is removed from a player during combat. remove-disguise: "Il tuo travestimento è stato rimosso." essentials-compatibility: #Shown when a teleport request is cancelled during combat. prevent-teleport-request-self: "Non puoi creare richieste di teletrasporto durante il combattimento." #Shown when a teleport request is cancelled during combat. prevent-teleport-request-other: "Non puoi inviare una richiesta di teletrasporto a un giocatore in combattimento." marriagemaster-compatibility: #Shown when a married player is prevented from teleporting to their partner during combat. prevent-teleport-self: "Non puoi teletrasportarti al tuo partner durante il combattimento." #Shown when a married player is prevented from teleporting to their partner during combat. prevent-teleport-partner: "Non puoi teletrasportarti al tuo partner mentre sono in combattimento." huskhomes-compatibility: prevent-teleport: "Non puoi teletrasportarti durante il combattimento." region-protection: #Shown when a player tries to enter a no-pvp area during combat. default-no-entry: "Non hai i permessi per entrare in quell'area durante il combattimento." factions-no-entry: Non hai i permessi per entrare in quell'area durante il combattimento. griefdefender-no-entry: Non hai i permessi per entrare in quell'area durante il combattimento. griefprevention-no-entry: Non hai i permessi per entrare in quell'area durante il combattimento. kingdomsx-no-entry: Non hai i permessi per entrare in quell'area durante il combattimento. konquest-no-entry: Non hai i permessi per entrare in quell'area durante il combattimento. redprotect-no-entry: Non hai i permessi per entrare in quell'area durante il combattimento. residence-no-entry: Non hai i permessi per entrare in quell'area durante il combattimento. towny-no-entry: Non hai i permessi per entrare in quell'area durante il combattimento. husktowns-no-entry: Non hai i permessi per entrare in quell'area durante il combattimento. ultimateclaims-no-entry: Non hai i permessi per entrare in quell'area durante il combattimento. protectionstones: prevent-area-creation: "Non sei autorizzato a creare un'area protetta durante il combattimento." no-entry: Non hai i permessi per entrare in quell'area durante il combattimento. preciousstones: prevent-field-creation: "Non sei autorizzato a creare un campo di protezione durante il combattimento." no-entry: Non hai i permessi per entrare in quell'area durante il combattimento. worldguard: no-entry-mob-combat: "Non hai il permesso di entrare in un'area di combattimento non-mob durante il combattimento." no-entry-player-combat: "Non hai il permesso di entrare in un'area di combattimento non giocatore-durante il combattimento." no-entry-unknown-combat: Non hai i permessi per entrare in quell'area durante il combattimento. lands: no-entry: Non hai i permessi per entrare in quell'area durante il combattimento. war-disable-newbie-protection: "Il PvP ora è la forza abilitata a causa di una dichiarazione di guerra." ================================================ FILE: plugin/src/main/resources/language/ka_ge.lang.yml ================================================ language-name: ka_ge decimal-format: '0.00' prefix: [CombatLogX] broadcast: on-load: CombatLogX წარმატებით ჩაიტვირთა. on-enable: CombatLogX წარმატებით ჩაირთო. on-disable: CombatLogX წარმატებით გამოირთო. placeholder: time-left-zero: '0' unknown-enemy: უცნობი status: fighting: იბრძვის idle: უსაქმურადაა in-combat: დიახ not-in-combat: არა toggle: enabled: ჩართვა disabled: გამორთვა pvp-status: enabled: ჩართვა disabled: გამორთვა combat-timer: expire: თქვენ აღარ იმყოფებით ბრძოლაში. enemy-death: თქვენ აღარ იმყოფებით ბრძოლაში, რადგან თქვენი მტერი მოკვდა. error: player-only: მხოლოდ მოთამაშეებს შეუძლიათ ამ ბრძანების შესრულება. invalid-target: {target} არ იმყოფება ხაზზე ან არ არსებობს. no-permission: 'დაკარგული ნებართვა: {permission}' target-not-in-combat: {target} არ იმყოფება ბრძოლაში. self-not-in-combat: თქვენ არ იმყოფებით ბრძოლაში. unknown-expansion: {target} არ არის გაფართოვება ან არ არის დაყენებული. command: combatlogx: help-message-list: - - 'CombatLogX ბრძანებათა სია:' - ' /combatlogx help: ხედავთ ამ დახმარების გვერდს.' - ' /combatlogx reload: ახორციელებს კონფიგურაციის, ენის და ყველა გაფართოვებათა კონფიგურაციის გადატვირთვას.' - ' /combatlogx about \: ამოწმებს ინფორმაციას გაფართოვების შესახებ.' - ' /combatlogx tag \: ძალით შეჰყავს მოთამაშე ბრძოლაში.' - ' /combatlogx toggle bossbar/actionbar/scoreboard: გამორთეთ ან ჩართეთ შეტყობინების ნიმუში.' - ' /combatlogx untag \: ძალით გამოჰყავს მოთამაშე ბრძოლიდან.' - ' /combatlogx version: ამოწმებს CombatLogX -ის ვერსიას.' - reload-success: - კონფიგურაცია წარმატებით გადაიტვირთა. - ენის ფაილები წარმატებით გადაიტვირთა. - გაფართოვებების კონფიგურაციათა ფაილები წარმატებით გადაიტვირთა. tag-player: მოთამაშე {target} -(ი)ს ბრძოლაში შეყვანა ძალით განხორციელდა. tag-failure: {target} ვერ დაიდგმება ბრძოლის დროს. (იქნებ მათ აქვთ შემოვლითი გზა?) untag-player: მოთამაშე {target} -(ი)ს ბრძოლიდან გამოყვანა ძალით განხორციელდა. toggle-bossbar: 'სამართავი ზოლი: {status}' toggle-actionbar: 'სამოქმედო ზოლი: {status}' toggle-scoreboard: 'საკონტროლო დაფა: {status}' combat-timer: time-left-self: თქვენ დარჩენილი გაქვთ {time_left} წამი. time-left-other: {target} -(ი)ს დარჩენილი აქვს {time_left} წამი. tagged: unknown: თქვენ უკვე ბრძოლაში იმყოფებით! არ გახვიდეთ. attacked: player: თქვენ შემოგიტიათ {enemy} -(მ)ა. არ გახვიდეთ! mob: თქვენ შემოგიტიათ {mob_type} -(მ)ა. არ გახვიდეთ! attacker: player: თქვენ უტევთ {enemy} -(ს). არ გახვიდეთ! mob: თქვენ შეუტიეთ {mob_type} -(ს). არ გახვიდეთ! expansion: angel-chest: # Shown when opening an AngelChest is prevented during combat. prevent-opening: "არ შეგიძლია ანგელოზის სკივრის გახსნა ბრძოლის დროს." # Shown when breaking an AngelChest is prevented during combat. prevent-breaking: "არ შეგიძლია ანგელოზის სკივრის მოტეხვა ბრძოლის დროს." # Shown when fast looting an AngelChest is prevented during combat. prevent-fast-looting: "არ შეგიძლია ანგელოზის სკივრის სწრაფად აღება ბრძოლის დროს." action-bar: # Shown above the hotbar while a player is in combat. timer: "ბრძოლა \u00BB {bars} {combatlogx_time_left} წამი." # Shown above the hotbar for a brief period when combat ends. ended: "ბრძოლა \u00BB აღარ ხარ ბრძოლაში." boss-bar: # Shown on top of the screen while a player is in combat. timer: "ბრძოლა \u00BB {combatlogx_time_left} წამი." # Shown on top of the screen for a brief period when combat ends. ended: "ბრძოლა \u00BB აღარ ხარ ბრძოლაში." scoreboard: # The scoreboard title for the sidebar. # Make sure to follow the scoreboard title limits for your Spigot version. title: "CombatLogX" # The scoreboard lines for the sidebar. # Make sure to follow the scoreboard line and character limits for your Spigot version. lines: - " " - "ბრძოლის სტატისტიკა:" - "\u00BB დარჩენილი დრო: {combatlogx_time_left}" - "\u00BB მტრები: {combatlogx_enemy_count}" - "\u00BB მდგომარეობა: {combatlogx_status}" - " " - "მტრები" - "\u00BB {combatlogx_specific_enemy_1_name}" - "\u00BB {combatlogx_specific_enemy_2_name}" - "\u00BB {combatlogx_specific_enemy_3_name}" - " " cheat-prevention: command-blocked: თქვენ არ შეგიძლიათ {command} ბრძანების გამოყნება ბრძოლის დროს. no-riptide: მოჯადოვებათა ტალღა გამორთულია ბრძოლის დროს. no-totem: თქვენ არ შეგიძლიათ უკვდავების ტოტემის გამოყენება ბრძოლის დროს. no-entity-interaction: თქვენ არ შეგიძლიათ იმ მობის გამოყენება ბრძოლის დროს. no-chat: თქვენ არ შეგიძლიათ ჩათში შეტყობინებების გაგზავნა ბრძოლის დროს. game-mode: force-switch: თქვენი სათამაშო-რეჟიმი შეიცვალა {game_mode} -ზე. no-switch: თქვენ არ შეგიძლიათ სათამაშო-რეჟიმის გამოცვლა ბრძოლის დროს. flight: force-disabled: თქვენი შესაძლებლობა, რომ გეფრინათ წაიშალა. no-flying: თქვენ არ შეგიძლიათ ფრენა ბრძოლის დროს. elytra: force-disabled: თქვენი ელიტრა გამოირთო. no-gliding: თქვენ არ შეგიძლიათ ელიტრის გამოყენება ბრძოლის დროს. teleportation: block-portal: თქვენ არ შეგიძლიათ პორტალის გამოყენება ბრძოლის დროს. block-pearl: თქვენ არ შეგიძლიათ ენდერის თვალის გამოყენება ბრძოლის დროს. block-other: თქვენ არ შეგიძლიათ ტელეპორტაცია ბრძოლის დროს. inventory: force-closed: თქვენი ინვენტარი დაიხურა. no-opening: თქვენ არ შეგიძლიათ ინვენტარის გახსნა ბრძოლის დროს. blocks: prevent-breaking: თქვენ არ შეგიძლიათ ბლოკების მონგრევა ბრძოლის დროს. prevent-placing: თქვენ არ შეგიძლიათ ბლოკების დადგმა ბრძოლის დროს. prevent-interaction: თქვენ არ შეგიძლიათ ბლოკების გამოყენება ბრძოლის დროს. prevent-portal-creation: თქვენ არ შეგიძლიათ პორტალების შექმნა ბრძოლის დროს. items: no-pickup: თქვენ არ შეგიძლიათ ნივთების აღება ბრძოლის დროს. no-dropping: თქვენ არ შეგიძლიათ ნივთების დაგდება ბრძოლის დროს. buckets: no-empty: თქვენ არ შეგიძლიათ სათლების დაცლა ბრძოლის დროს. no-fill: თქვენ არ შეგიძლიათ სათლების შევსება ბრძოლის დროს. damage-tagger: unknown-damage: თქვენ დაზიანება მიიღეთ! არ გახვიდეთ! damage-type: contact: თქვენ კაქტუსმა გიჩხვლიტათ. არ გახვიდეთ! suffocation: თქვენ კედელში იხრჩობით. არ გახვიდეთ! fall: თქვენ დაზიანება მიიღეთ დაცემისგან. არ გახვიდეთ! fire: თქვენ ცეცხლში გაიარეთ. არ გახვიდეთ! fire-tick: თქვენ იწვით. არ გახვიდეთ! lava: თქვენ ლავაში იხარშებით. არ გახვიდეთ! drowning: თქვენ იხრჩობით. არ გახვიდეთ! block-explosion: თქვენ აფეთქებამ დაგაზიანათ. არ გახვიდეთ! lightning: თქვენ დარტყმული იქენით! არ გახვიდეთ! starvation: თქვენ საკმაოდ მშიერი ხართ. არ გახვიდეთ! poison: თქვენ მოწამვლისგან დაზიანება მიიღეთ. არ გახვიდეთ! magic: ვიღაცამ თქვენ წამალი გესროლათ. არ გახვიდეთ! wither: თქვენ ჭკნებით. არ გახვიდეთ! falling-block: თქვენ ბლოკი დაგეცათ ზედ. არ გახვიდეთ! custom: თქვენ მიიღეთ ჩვეულებისამებრი ზიანი. არ გახვიდეთ! fly-into-wall: თქვენ გამოსცადეთ კინეტიკური ენერგია. არ გახვიდეთ! hot-floor: იატაკი ლავაა! არ გახვიდეთ! cramming: თქვენი სისხლი დაღვრილი იქნა. არ გახვიდეთ! newbie-helper: togglepvp: self: 'ბრძოლა: {status}' admin: თქვენ {target} -(ი)ს საბრძოლო სტატუსი შეცვალეთ {status} -ზე. cooldown: თქვენ უნდა დაიცადოთ {time_left} წამი, ამ ბრძანების ხელახლა გამოსაყენებლად. no-pvp: self: თქვენ არ შეგიძლიათ ამ მოთამაშეზე შეტევა, როცა თქვენი საბრძოლო სტატუსი გამორთულია. other: ამ მოთამაშეს გამორთული აქვს საბრძოლო სტატუსი. protected: ეს მოთამაშე დაცულია, თქვენ კი არ შეგიძლიათ მასზე შეტევა ჯერ-ჯერობით! protection-disabled: attacker: თქვენ სხვას დაესხით თავს, თქვენი ახალბედა დაცვა კი უკვე გამორთულია. expired: თქვენს ახალბედა დაცვას ვადა ამოეწურა. check-format: - 'ინფორმაცია {target} -(ი)სთვის:' - 'დაცვა: {protected}' - 'ბრძოლა: {pvp}' loot-protection: enemy-died: {enemy} მოკვდა. ნაძარცვი კი დაცული იქნება მომდევნო {time} წამის განმავლობაში. protected: ეს ნივთი ამჟამად დაცულია, დაიცადეთ {time} წამი, სანამ აღებას შეძლებთ. citizens-compatibility: prevent-join: თქვენ ვერ შეძლებთ სერვერზე შემოსვლას, სანამ თქვენი NPC არ იქნება მოკლული ან გამქრალი. disguise-compatibility: remove-disguise: თქვენი შენიღბვა წაიშალა. essentials-compatibility: prevent-teleport-request-self: თქვენ არ შეგიძლიათ მოითხოვოთ ტელეპორტაცია ბრძოლის დროს. prevent-teleport-request-other: თქვენ არ შეგიძლიათ გაუგზავნოთ ტელეპორტაციის მოთხოვნა მოთამაშეს, რომელიც ბრძოლაში იმყოფება. region-protection: factions-no-entry: თქვენ არ შეგიძლიათ იმ არეალში შესვლა ბრძოლის დროს. griefdefender-no-entry: თქვენ არ შეგიძლიათ იმ არეალში შესვლა ბრძოლის დროს. griefprevention-no-entry: თქვენ არ შეგიძლიათ იმ არეალში შესვლა ბრძოლის დროს. kingdomsx-no-entry: თქვენ არ შეგიძლიათ იმ არეალში შესვლა ბრძოლის დროს. lands-no-entry: თქვენ არ შეგიძლიათ იმ არეალში შესვლა ბრძოლის დროს. konquest-no-entry: თქვენ არ შეგიძლიათ იმ არეალში შესვლა ბრძოლის დროს. redprotect-no-entry: თქვენ არ შეგიძლიათ იმ არეალში შესვლა ბრძოლის დროს. residence-no-entry: თქვენ არ შეგიძლიათ იმ არეალში შესვლა ბრძოლის დროს. towny-no-entry: თქვენ არ შეგიძლიათ იმ არეალში შესვლა ბრძოლის დროს. ultimateclaims-no-entry: თქვენ არ შეგიძლიათ იმ არეალში შესვლა ბრძოლის დროს. protectionstones: prevent-area-creation: თქვენ არ შეგიძლიათ დაცული არეალის შექმნა ბრძოლის დროს. no-entry: თქვენ არ შეგიძლიათ იმ არეალში შესვლა ბრძოლის დროს. preciousstones: prevent-field-creation: თქვენ არ შეგიძლიათ დაცული მინდვრის შექმნა ბრძოლის დროს. no-entry: თქვენ არ შეგიძლიათ იმ არეალში შესვლა ბრძოლის დროს. worldguard: no-entry-mob-combat: თქვენ არ შეგიძლიათ შეხვიდეთ არა-საბრძოლო ზონაში ბრძოლის დროს. no-entry-player-combat: თქვენ არ შეგიძლიათ შეხვიდეთ არა-საბრძოლო ზონაში ბრძოლის დროს. no-entry-unknown-combat: თქვენ არ შეგიძლიათ იმ არეალში შესვლა ბრძოლის დროს. ================================================ FILE: plugin/src/main/resources/language/nl_be.yml ================================================ --- ## Extra Information: ## This is the default language file for CombatLogX. ## The default language is "en_us", also known as English (United States). ## Context will be added as YAML comments above the string. ## The color scheme for messages is gold, white, and sometimes red. ## Command feedback that is successful should always be green. ## Error messages should always be red. ## Variables in messages can be gray or white. ## Messages use the MiniMessage format in non-strict mode. ## More information about MiniMessage can be found here: ## https://docs.adventure.kyori.net/minimessage/format.html #The language code for this file. language-name: "nl_nl" #The format for decimal numbers. #The United States uses the number and two decimal places decimal-format: "0.00" #The prefix for CombatLogX. #This is shown in front of all messages and should not be changed unless necessary. prefix: "[CombatLogX]" broadcast: #Shown when the plugin is finished loading. on-load: "CombatLogX is succesvol geladen." #Shown when the plugin is finished enabling. on-enable: "CombatLogX is succesvol ingeschakeld." #Shown when the plugin is disabled for any reason. on-disable: "CombatLogX is succesvol uitgeschakeld." placeholder: #This text is used for the {combatlogx_time_left} #This allows server configurations to change the display value of the zero to something like "Not in combat" time-left-zero: "0" #This text is used when a player does not have an enemy. #This can happen when players are tagged by a custom expansion or the tag command. unknown-enemy: "Niet bekend" status: #Shown when the player is in combat. fighting: "Vechten" in-combat: "Ja" #Shown when the player is not in combat idle: "Inactief" not-in-combat: "Nee" #These placeholders are shown when a player changes a value such as whether or not their bossbar is enabled. toggle: enabled: "AAN" disabled: "KORTING" pvp-status: enabled: "AAN" disabled: "KORTING" combat-timer: #Sent to a player when they escape from combat due to the timer running out. expire: "Je bent niet meer in de strijd." #Sent to a player when they escape from combat due to their enemy being killed. enemy-death: "Je bent niet langer in gevecht omdat je vijand is gestorven." #Sent when a player is killed during combat. self-death: "Je bent niet meer in gevecht omdat je gestorven bent." error: #Shown when the console tries to execute a command made for players. player-only: "Alleen spelers kunnen deze opdracht uitvoeren" #Shown when a command that requires a player has invalid input. invalid-target: "{target} is niet online of bestaat niet." #Shown when a command that requires a number has invalid input. invalid-integer: "{value} is geen geldig geheel getal." #Shown when a player does not have access to something that requires a permission. no-permission: "Ontbrekende rechten: {permission}" #Shown when a player executes a command in a world that is disabled in the configuration. disabled-world: "Dit commando is niet beschikbaar in deze dimensie." #Shown when a command requires a player in combat but the target player is not in combat. target-not-in-combat: "{target} is niet in gevecht." #Shown when a player executes a command that requires them to be in combat. self-not-in-combat: "U bent niet in de strijd." #Shown when a command that requires an expansion has invalid input. unknown-expansion: "{target} is geen uitbreiding of is niet geïnstalleerd." command: combatlogx: #Shown as the command output for '/combatlogx help'. help-message-list: - "" - "GevechtsLogX Commando Help:" - " /combatlogx help: Bekijk deze help pagina." - " /combatlogx herladen: Herlaad de config.yml, language.yml, en alle uitbreidings configuratiebestanden." - " /combatlogx over \\: bekijk informatie over een uitbreiding." - " /combatlogx tag \\ [seconds]: Forceer een speler in de strijd." - " /combatlogx toggle bossbalk/actionbar/scoreboard: In- of uitschakelen van een meldingstype." - " /combatlogx untag \\: Forceer een speler uit zijn strijd." - " /combatlogx versie: Controleer uw versie van CombatLogX." - "" #Shown as the command output for '/combatlogx reload' when reloading is successful. reload-success: - "Alle configuratiebestanden van CombatLogX succesvol herladen." - "Alle taalbestanden van CombatLogX zijn succesvol herladen." - "Alle configuratiebestanden van CombatLogX uitbreidingen succesvol herladen." #Shown as the command output for '/combatlogx reload' when reloading fails reload-failure: - "Bij het herladen van de configuratie is een fout opgetreden." - "Controleer uw server log en repareer het beschadigde bestand." #Shown as the command output for '/combatlogx tag ' when a player is tagged successfully. tag-player: "Met succes speler {target} gedwongen te vechten." #Shown as the command output for '/combatlogx tag ' when the plugin failed to tag a player. tag-failure: "{target} kon niet in gevecht worden gezet. (Misschien hebben ze een overleving?)" #Shown as the command output for '/combatlogx untag '. untag-player: "Succesvol speler geforceerd {target} uit gevecht." #Shown as the command output for '/combatlogx toggle bossbar'. toggle-bossbar: "Baas Bar: {status}" #Shown as the command output for '/combatlogx toggle actionbar'. toggle-actionbar: "Actiebalk: {status}" #Shown as the command output for '/combatlogx toggle scoreboard'. toggle-scoreboard: "Scorebord: {status}" combat-timer: #Shown as the command output for '/combat-timer'. time-left-self: "Je hebt {time_left} seconden &een resterend." #Shown as the command output for '/combat-timer '. time-left-other: "{target} heeft {time_left} seconden resterend." #These messages are shown a player is tagged into combat. tagged: unknown: player: "Je bent nu in gevecht met {enemy} voor een onbekende reden. Log niet uit!" mob: "Je bent nu in gevecht met een (n) {enemy} om een onbekende reden. Log niet uit!" mythic_mob: "Je bent nu in gevecht met een (n) {mob_type} om een onbekende reden. Log niet uit!" damage: "Je bent nu in een gevecht als gevolg van schade. Log niet uit!" unknown: "U bent zonder reden in een gevecht geplaatst. Log niet uit." attacked: player: "Je wordt aangevallen door {enemy}. Log niet uit!" mob: "Je wordt aangevallen door a(n) {mob_type}. Log niet uit!" mythic_mob: "Je wordt aangevallen door a(n) {enemy}. Log niet uit!" damage: "Je bent nu in een gevecht als gevolg van schade. Log niet uit!" unknown: "Je wordt aangevallen door een onbekende kracht. Log niet uit!" attacker: player: "Je valt {enemy}aan. Log niet uit!" mob: "Je valt een (n) {mob_type}aan. Log niet uit!" mythic_mob: "Je valt een (n) {enemy}aan. Log niet uit!" damage: "Je bent nu in een gevecht als gevolg van schade. Log niet uit!" unknown: "Je valt een onbekende kracht aan. Log niet uit!" expansion: angel-chest: #Shown when opening an AngelChest is prevented during combat. prevent-opening: "Je mag geen engelkisten openen tijdens het gevecht." #Shown when breaking an AngelChest is prevented during combat. prevent-breaking: "Je mag geen engelkisten breken tijdens het gevecht." #Shown when fast looting an AngelChest is prevented during combat. prevent-fast-looting: "Je mag geen buit engelkisten snel maken tijdens het gevecht." action-bar: #Shown above the hotbar while a player is in combat. timer: "Gevecht \u00BB {bars} {combatlogx_time_left} seconden." #Shown above the hotbar for a brief period when combat ends. ended: "Gevecht \u00BB U bent niet meer in gevecht gegaan." boss-bar: #Shown on top of the screen while a player is in combat. timer: "Gevecht \u00BB {combatlogx_time_left} seconden." #Shown on top of the screen for a brief period when combat ends. ended: "Gevecht \u00BB U bent niet meer in gevecht gegaan." scoreboard: #The scoreboard title for the sidebar. #Make sure to follow the scoreboard title limits for your Spigot version. title: "CombatLogX" #The scoreboard lines for the sidebar. #Make sure to follow the scoreboard line and character limits for your Spigot version. lines: - " " - "Gevechtsstatistieken:" - "\u00BB Resterende tijd: {combatlogx_time_left}" - "\u00BB Enemies: {combatlogx_enemy_count}" - "\u00BB Status: {combatlogx_status}" - " " - "Enemies" - "\u00BB {combatlogx_specific_enemy_1_name}" - "\u00BB {combatlogx_specific_enemy_2_name}" - "\u00BB {combatlogx_specific_enemy_3_name}" - " " cheat-prevention: #Shown when a command execution is prevented during combat. command-blocked: "Je hebt geen toegang tot {command} tijdens je gevecht." #Shown when the riptide effect is prevented during combat. no-riptide: "De betovering van de rift is uitgeschakeld tijdens het vecht." #Shown when a totem of undying is prevented during combat. no-totem: "Je hebt geen toestemming om totems te gebruiken tijdens het gevecht om te unden." #Shown when an entity interaction is prevented during combat. no-entity-interaction: "Je hebt geen toestemming om die mob te gebruiken tijdens het vechten." #Shown when a chat message is prevented during combat. no-chat: "Je hebt geen toestemming om chatberichten te sturen tijdens het gevecht." game-mode: #Shown when a player is forced into a specific game mmode during combat. force-switch: "Je spelmodus is veranderd naar {game_mode}." #Shown when a game mode switch is prevented during combat. no-switch: "Je hebt geen toestemming om van spel te wisselen tijdens het vechten." flight: #Shown when a player's ability to fly is disabled during combat. force-disabled: "Je mogelijkheid om te vliegen is verwijderd." #Shown when a player's attempt to fly is prevented during combat. no-flying: "Je mag niet vliegen tijdens het vechten." elytra: #Shown when a player's ability to glide is disabled during combat. force-disabled: "Je elytra is uitgeschakeld." #Shown when a player's attempt to glide is prevented during combat. no-gliding: "Je mag geen elytra gebruiken tijdens het vechten." teleportation: #Shown when a player tries to enter a portal and is prevented during combat. block-portal: "Je hebt geen toestemming om een portaal te gebruiken tijdens de strijd." #Shown when an ender pearl is prevented during combat. block-pearl: "Je hebt geen toestemming om enderparels te gebruiken tijdens een gevecht." #Shown when a teleport is prevented during combat. block-other: "Je hebt geen toestemming om te teleporteren tijdens het gevecht." inventory: #Shown when a player's inventory is closed by the plugin during combat. force-closed: "Je inventaris is gesloten." #Shown when a player tries to open an inventory and is prevented during combat. no-opening: "Je mag geen inventaris openen tijdens het gevecht." blocks: #Shown when a player is prevented from breaking a block during combat. prevent-breaking: "Je mag geen blokken breken tijdens het gevecht." #Shown when a player is prevented from breaking a block during combat. prevent-placing: "Je hebt geen toestemming om blokken te plaatsen tijdens het gevecht." #Shown when a player is prevented from breaking a block during combat. prevent-interaction: "Je mag geen blokken gebruiken tijdens het vechten." #Shown when a player is prevented from breaking a block during combat. prevent-portal-creation: "U heeft geen toestemming om portalen te maken tijdens het gevecht." items: #Shown when a player is prevented from picking up an item during combat. no-pickup: "Je hebt geen toestemming om voorwerpen op te pakken tijdens het vechten." #Shown when a player is prevented from dropping an item during combat. no-dropping: "U heeft geen toestemming om voorwerpen te laten vallen tijdens het gevechten." buckets: #Shown when a player is prevented from emptying a bucket during combat. no-empty: "Je kunt tijdens het gevecht geen emmers leegmaken." #Shown when a player is prevented from filling a bucket during combat. no-fill: "Je kunt geen emmers invullen tijdens het vechten." damage-tagger: #Shown when a player is tagged for an unknown damage type. unknown-damage: "Je hebt schade gekregen! Log niet uit!" #These messages are shown when a player is tagged for a known damage type. #You can find a list of damage types here: #https://hub.spigotmc.org/javadocs/spigot/org/bukkit/event/entity/EntityDamageEvent.DamageCause.html damage-type: contact: "Je bent geprikt door een cactus. Log niet uit!" suffocation: "Je bent aan het verstikken in een muur. Log niet uit!" fall: "Je hebt valschade. Log niet uit!" fire: "Je bent in vuur gegaan. Log niet uit!" fire-tick: "Je brandt. Log niet uit!" lava: "Je bent aan het koken in de lava. Log niet uit!" drowning: "Je bent aan het verdrinken. Log niet uit!" block-explosion: "Je bent beschadigd door een explosie. Log niet uit!" lightning: "Ge hast hast! Log niet uit!" starvation: "Je hebt te honger. Log niet uit!" poison: "Je hebt gifschade gekregen. Log niet uit!" magic: "Iemand heeft een drankje naar je gegooid. Log niet uit!" wither: "Je bent afwezig. Log niet uit!" falling-block: "Er is een blok op je gevallen. Log niet uit!" custom: "Je hebt aangepaste schade aangericht. Log niet uit!" fly-into-wall: "Je hebt kinetische energie meegemaakt. Log niet uit!" hot-floor: "De vloer is lava! Log niet uit!" cramming: "Je wordt geperst. Log niet uit!" newbie-helper: togglepvp: #Shown as the command output for '/togglepvp'. self: "PVP: {status}" #Shown as the command output for '/togglepvp admin on/off '. admin: "Je hebt de pvp van {target} gewijzigd naar {status}." #Shown when the '/togglepvp' command is on cooldown. cooldown: "Je moet {time_left} seconden wachten om deze opdracht opnieuw te gebruiken." #These messages are shown when pvp is disabled for any reason. no-pvp: self: "Je mag niet op die speler drukken terwijl je PvP is uitgeschakeld." other: "Die speler heeft PvP uitgeschakeld." protected: "Die speler is beschermd, je mag hem nog niet aanvallen!" protection-disabled: #Shown when newbie protection is disabled due to the player attacking another player. attacker: "Je hebt iemand aangevallen, je nieuweling is nu uitgeschakeld." #Shown when newbie protection expires. expired: "Uw nieuweling is verlopen." #Shown for the '/togglepvp check ' command. check-format: - "Informatie voor {target}:" - "Bescherming: {protected}" - "PvP: {pvp}" loot-protection: #Shown when an enemy dies and their loot is protected. enemy-died: "{enemy} is gestorven. Schoot wordt beschermd voor {time} seconden." #Shown when a player tries to pick up an item that is loot protected by the plugin. protected: "Dit item is momenteel beveiligd, wacht {time} seconden om het op te halen." citizens-compatibility: #Shown when a player is prevented from joining the server due to their NPC still existing. prevent-join: "U mag niet toetreden tot de server totdat uw NPC is beëindigd of verwijderd." disguise-compatibility: #Shown when a disguise is removed from a player during combat. remove-disguise: "Je vermomming is verwijderd." essentials-compatibility: #Shown when a teleport request is cancelled during combat. prevent-teleport-request-self: "U kunt geen teleport verzoeken maken tijdens het gevecht." #Shown when a teleport request is cancelled during combat. prevent-teleport-request-other: "U kunt geen teleport verzoek sturen naar een speler die in gevecht is." marriagemaster-compatibility: #Shown when a married player is prevented from teleporting to their partner during combat. prevent-teleport-self: "Je mag tijdens het gevecht niet naar je partner teleporteren." #Shown when a married player is prevented from teleporting to their partner during combat. prevent-teleport-partner: "Je hebt geen toestemming om naar je partner te teleporteren tijdens de strijd." region-protection: #Shown when a player tries to enter a no-pvp area during combat. default-no-entry: "Je hebt geen toestemming om dat gebied binnen te komen tijdens het vecht." factions-no-entry: Je hebt geen toestemming om dat gebied binnen te komen tijdens het vecht. griefdefender-no-entry: Je hebt geen toestemming om dat gebied binnen te komen tijdens het vecht. griefprevention-no-entry: Je hebt geen toestemming om dat gebied binnen te komen tijdens het vecht. kingdomsx-no-entry: Je hebt geen toestemming om dat gebied binnen te komen tijdens het vecht. konquest-no-entry: Je hebt geen toestemming om dat gebied binnen te komen tijdens het vecht. redprotect-no-entry: Je hebt geen toestemming om dat gebied binnen te komen tijdens het vecht. residence-no-entry: Je hebt geen toestemming om dat gebied binnen te komen tijdens het vecht. towny-no-entry: Je hebt geen toestemming om dat gebied binnen te komen tijdens het vecht. husktowns-no-entry: Je hebt geen toestemming om dat gebied binnen te komen tijdens het vecht. ultimateclaims-no-entry: Je hebt geen toestemming om dat gebied binnen te komen tijdens het vecht. protectionstones: prevent-area-creation: "U bent niet bevoegd om een beschermd gebied te maken tijdens het gevechten." no-entry: Je hebt geen toestemming om dat gebied binnen te komen tijdens het vecht. preciousstones: prevent-field-creation: "U bent niet bevoegd om een beveiligingsveld te creëren tijdens het vechten." no-entry: Je hebt geen toestemming om dat gebied binnen te komen tijdens het vecht. worldguard: no-entry-mob-combat: "U heeft geen toestemming om een niet-mob-gevechtsgebied binnen te gaan tijdens het gevecht." no-entry-player-combat: "Je hebt geen toestemming om een niet-speler-gevechtsgebied te betreden tijdens het gevecht." no-entry-unknown-combat: Je hebt geen toestemming om dat gebied binnen te komen tijdens het vecht. lands: no-entry: Je hebt geen toestemming om dat gebied binnen te komen tijdens het vecht. war-disable-newbie-protection: "PvP is nu ingeschakeld vanwege een oorlogsverklaring." ================================================ FILE: plugin/src/main/resources/language/nl_nl.yml ================================================ --- ## Extra Information: ## This is the default language file for CombatLogX. ## The default language is "en_us", also known as English (United States). ## Context will be added as YAML comments above the string. ## The color scheme for messages is gold, white, and sometimes red. ## Command feedback that is successful should always be green. ## Error messages should always be red. ## Variables in messages can be gray or white. ## Messages use the MiniMessage format in non-strict mode. ## More information about MiniMessage can be found here: ## https://docs.adventure.kyori.net/minimessage/format.html #The language code for this file. language-name: "nl_nl" #The format for decimal numbers. #The United States uses the number and two decimal places decimal-format: "0.00" #The prefix for CombatLogX. #This is shown in front of all messages and should not be changed unless necessary. prefix: "[CombatLogX]" broadcast: #Shown when the plugin is finished loading. on-load: "CombatLogX is succesvol geladen." #Shown when the plugin is finished enabling. on-enable: "CombatLogX is succesvol ingeschakeld." #Shown when the plugin is disabled for any reason. on-disable: "CombatLogX is succesvol uitgeschakeld." placeholder: #This text is used for the {combatlogx_time_left} #This allows server configurations to change the display value of the zero to something like "Not in combat" time-left-zero: "0" #This text is used when a player does not have an enemy. #This can happen when players are tagged by a custom expansion or the tag command. unknown-enemy: "Niet bekend" status: #Shown when the player is in combat. fighting: "Vechten" in-combat: "Ja" #Shown when the player is not in combat idle: "Inactief" not-in-combat: "Nee" #These placeholders are shown when a player changes a value such as whether or not their bossbar is enabled. toggle: enabled: "AAN" disabled: "KORTING" pvp-status: enabled: "AAN" disabled: "KORTING" combat-timer: #Sent to a player when they escape from combat due to the timer running out. expire: "Je bent niet meer in de strijd." #Sent to a player when they escape from combat due to their enemy being killed. enemy-death: "Je bent niet langer in gevecht omdat je vijand is gestorven." #Sent when a player is killed during combat. self-death: "Je bent niet meer in gevecht omdat je gestorven bent." error: #Shown when the console tries to execute a command made for players. player-only: "Alleen spelers kunnen deze opdracht uitvoeren" #Shown when a command that requires a player has invalid input. invalid-target: "{target} is niet online of bestaat niet." #Shown when a command that requires a number has invalid input. invalid-integer: "{value} is geen geldig geheel getal." #Shown when a player does not have access to something that requires a permission. no-permission: "Ontbrekende rechten: {permission}" #Shown when a player executes a command in a world that is disabled in the configuration. disabled-world: "Dit commando is niet beschikbaar in deze dimensie." #Shown when a command requires a player in combat but the target player is not in combat. target-not-in-combat: "{target} is niet in gevecht." #Shown when a player executes a command that requires them to be in combat. self-not-in-combat: "U bent niet in de strijd." #Shown when a command that requires an expansion has invalid input. unknown-expansion: "{target} is geen uitbreiding of is niet geïnstalleerd." command: combatlogx: #Shown as the command output for '/combatlogx help'. help-message-list: - "" - "GevechtsLogX Commando Help:" - " /combatlogx help: Bekijk deze help pagina." - " /combatlogx herladen: Herlaad de config.yml, language.yml, en alle uitbreidings configuratiebestanden." - " /combatlogx over \\: bekijk informatie over een uitbreiding." - " /combatlogx tag \\ [seconds]: Forceer een speler in de strijd." - " /combatlogx toggle bossbalk/actionbar/scoreboard: In- of uitschakelen van een meldingstype." - " /combatlogx untag \\: Forceer een speler uit zijn strijd." - " /combatlogx versie: Controleer uw versie van CombatLogX." - "" #Shown as the command output for '/combatlogx reload' when reloading is successful. reload-success: - "Alle configuratiebestanden van CombatLogX succesvol herladen." - "Alle taalbestanden van CombatLogX zijn succesvol herladen." - "Alle configuratiebestanden van CombatLogX uitbreidingen succesvol herladen." #Shown as the command output for '/combatlogx reload' when reloading fails reload-failure: - "Bij het herladen van de configuratie is een fout opgetreden." - "Controleer uw server log en repareer het beschadigde bestand." #Shown as the command output for '/combatlogx tag ' when a player is tagged successfully. tag-player: "Met succes speler {target} gedwongen te vechten." #Shown as the command output for '/combatlogx tag ' when the plugin failed to tag a player. tag-failure: "{target} kon niet in gevecht worden gezet. (Misschien hebben ze een overleving?)" #Shown as the command output for '/combatlogx untag '. untag-player: "Succesvol speler geforceerd {target} uit gevecht." #Shown as the command output for '/combatlogx toggle bossbar'. toggle-bossbar: "Baas Bar: {status}" #Shown as the command output for '/combatlogx toggle actionbar'. toggle-actionbar: "Actiebalk: {status}" #Shown as the command output for '/combatlogx toggle scoreboard'. toggle-scoreboard: "Scorebord: {status}" combat-timer: #Shown as the command output for '/combat-timer'. time-left-self: "Je hebt {time_left} seconden &een resterend." #Shown as the command output for '/combat-timer '. time-left-other: "{target} heeft {time_left} seconden resterend." #These messages are shown a player is tagged into combat. tagged: unknown: player: "Je bent nu in gevecht met {enemy} voor een onbekende reden. Log niet uit!" mob: "Je bent nu in gevecht met een (n) {enemy} om een onbekende reden. Log niet uit!" mythic_mob: "Je bent nu in gevecht met een (n) {mob_type} om een onbekende reden. Log niet uit!" damage: "Je bent nu in een gevecht als gevolg van schade. Log niet uit!" unknown: "U bent zonder reden in een gevecht geplaatst. Log niet uit." attacked: player: "Je wordt aangevallen door {enemy}. Log niet uit!" mob: "Je wordt aangevallen door a(n) {mob_type}. Log niet uit!" mythic_mob: "Je wordt aangevallen door a(n) {enemy}. Log niet uit!" damage: "Je bent nu in een gevecht als gevolg van schade. Log niet uit!" unknown: "Je wordt aangevallen door een onbekende kracht. Log niet uit!" attacker: player: "Je valt {enemy}aan. Log niet uit!" mob: "Je valt een (n) {mob_type}aan. Log niet uit!" mythic_mob: "Je valt een (n) {enemy}aan. Log niet uit!" damage: "Je bent nu in een gevecht als gevolg van schade. Log niet uit!" unknown: "Je valt een onbekende kracht aan. Log niet uit!" expansion: angel-chest: #Shown when opening an AngelChest is prevented during combat. prevent-opening: "Je mag geen engelkisten openen tijdens het gevecht." #Shown when breaking an AngelChest is prevented during combat. prevent-breaking: "Je mag geen engelkisten breken tijdens het gevecht." #Shown when fast looting an AngelChest is prevented during combat. prevent-fast-looting: "Je mag geen buit engelkisten snel maken tijdens het gevecht." action-bar: #Shown above the hotbar while a player is in combat. timer: "Gevecht \u00BB {bars} {combatlogx_time_left} seconden." #Shown above the hotbar for a brief period when combat ends. ended: "Gevecht \u00BB U bent niet meer in gevecht gegaan." boss-bar: #Shown on top of the screen while a player is in combat. timer: "Gevecht \u00BB {combatlogx_time_left} seconden." #Shown on top of the screen for a brief period when combat ends. ended: "Gevecht \u00BB U bent niet meer in gevecht gegaan." scoreboard: #The scoreboard title for the sidebar. #Make sure to follow the scoreboard title limits for your Spigot version. title: "CombatLogX" #The scoreboard lines for the sidebar. #Make sure to follow the scoreboard line and character limits for your Spigot version. lines: - " " - "Gevechtsstatistieken:" - "\u00BB Resterende tijd: {combatlogx_time_left}" - "\u00BB Enemies: {combatlogx_enemy_count}" - "\u00BB Status: {combatlogx_status}" - " " - "Enemies" - "\u00BB {combatlogx_specific_enemy_1_name}" - "\u00BB {combatlogx_specific_enemy_2_name}" - "\u00BB {combatlogx_specific_enemy_3_name}" - " " cheat-prevention: #Shown when a command execution is prevented during combat. command-blocked: "Je hebt geen toegang tot {command} tijdens je gevecht." #Shown when the riptide effect is prevented during combat. no-riptide: "De betovering van de rift is uitgeschakeld tijdens het vecht." #Shown when a totem of undying is prevented during combat. no-totem: "Je hebt geen toestemming om totems te gebruiken tijdens het gevecht om te unden." #Shown when an entity interaction is prevented during combat. no-entity-interaction: "Je hebt geen toestemming om die mob te gebruiken tijdens het vechten." #Shown when a chat message is prevented during combat. no-chat: "Je hebt geen toestemming om chatberichten te sturen tijdens het gevecht." game-mode: #Shown when a player is forced into a specific game mmode during combat. force-switch: "Je spelmodus is veranderd naar {game_mode}." #Shown when a game mode switch is prevented during combat. no-switch: "Je hebt geen toestemming om van spel te wisselen tijdens het vechten." flight: #Shown when a player's ability to fly is disabled during combat. force-disabled: "Je mogelijkheid om te vliegen is verwijderd." #Shown when a player's attempt to fly is prevented during combat. no-flying: "Je mag niet vliegen tijdens het vechten." elytra: #Shown when a player's ability to glide is disabled during combat. force-disabled: "Je elytra is uitgeschakeld." #Shown when a player's attempt to glide is prevented during combat. no-gliding: "Je mag geen elytra gebruiken tijdens het vechten." teleportation: #Shown when a player tries to enter a portal and is prevented during combat. block-portal: "Je hebt geen toestemming om een portaal te gebruiken tijdens de strijd." #Shown when an ender pearl is prevented during combat. block-pearl: "Je hebt geen toestemming om enderparels te gebruiken tijdens een gevecht." #Shown when a teleport is prevented during combat. block-other: "Je hebt geen toestemming om te teleporteren tijdens het gevecht." inventory: #Shown when a player's inventory is closed by the plugin during combat. force-closed: "Je inventaris is gesloten." #Shown when a player tries to open an inventory and is prevented during combat. no-opening: "Je mag geen inventaris openen tijdens het gevecht." blocks: #Shown when a player is prevented from breaking a block during combat. prevent-breaking: "Je mag geen blokken breken tijdens het gevecht." #Shown when a player is prevented from breaking a block during combat. prevent-placing: "Je hebt geen toestemming om blokken te plaatsen tijdens het gevecht." #Shown when a player is prevented from breaking a block during combat. prevent-interaction: "Je mag geen blokken gebruiken tijdens het vechten." #Shown when a player is prevented from breaking a block during combat. prevent-portal-creation: "U heeft geen toestemming om portalen te maken tijdens het gevecht." items: #Shown when a player is prevented from picking up an item during combat. no-pickup: "Je hebt geen toestemming om voorwerpen op te pakken tijdens het vechten." #Shown when a player is prevented from dropping an item during combat. no-dropping: "U heeft geen toestemming om voorwerpen te laten vallen tijdens het gevechten." buckets: #Shown when a player is prevented from emptying a bucket during combat. no-empty: "Je kunt tijdens het gevecht geen emmers leegmaken." #Shown when a player is prevented from filling a bucket during combat. no-fill: "Je kunt geen emmers invullen tijdens het vechten." damage-tagger: #Shown when a player is tagged for an unknown damage type. unknown-damage: "Je hebt schade gekregen! Log niet uit!" #These messages are shown when a player is tagged for a known damage type. #You can find a list of damage types here: #https://hub.spigotmc.org/javadocs/spigot/org/bukkit/event/entity/EntityDamageEvent.DamageCause.html damage-type: contact: "Je bent geprikt door een cactus. Log niet uit!" suffocation: "Je bent aan het verstikken in een muur. Log niet uit!" fall: "Je hebt valschade. Log niet uit!" fire: "Je bent in vuur gegaan. Log niet uit!" fire-tick: "Je brandt. Log niet uit!" lava: "Je bent aan het koken in de lava. Log niet uit!" drowning: "Je bent aan het verdrinken. Log niet uit!" block-explosion: "Je bent beschadigd door een explosie. Log niet uit!" lightning: "Ge hast hast! Log niet uit!" starvation: "Je hebt te honger. Log niet uit!" poison: "Je hebt gifschade gekregen. Log niet uit!" magic: "Iemand heeft een drankje naar je gegooid. Log niet uit!" wither: "Je bent afwezig. Log niet uit!" falling-block: "Er is een blok op je gevallen. Log niet uit!" custom: "Je hebt aangepaste schade aangericht. Log niet uit!" fly-into-wall: "Je hebt kinetische energie meegemaakt. Log niet uit!" hot-floor: "De vloer is lava! Log niet uit!" cramming: "Je wordt geperst. Log niet uit!" newbie-helper: togglepvp: #Shown as the command output for '/togglepvp'. self: "PVP: {status}" #Shown as the command output for '/togglepvp admin on/off '. admin: "Je hebt de pvp van {target} gewijzigd naar {status}." #Shown when the '/togglepvp' command is on cooldown. cooldown: "Je moet {time_left} seconden wachten om deze opdracht opnieuw te gebruiken." #These messages are shown when pvp is disabled for any reason. no-pvp: self: "Je mag niet op die speler drukken terwijl je PvP is uitgeschakeld." other: "Die speler heeft PvP uitgeschakeld." protected: "Die speler is beschermd, je mag hem nog niet aanvallen!" protection-disabled: #Shown when newbie protection is disabled due to the player attacking another player. attacker: "Je hebt iemand aangevallen, je nieuweling is nu uitgeschakeld." #Shown when newbie protection expires. expired: "Uw nieuweling is verlopen." #Shown for the '/togglepvp check ' command. check-format: - "Informatie voor {target}:" - "Bescherming: {protected}" - "PvP: {pvp}" loot-protection: #Shown when an enemy dies and their loot is protected. enemy-died: "{enemy} is gestorven. Schoot wordt beschermd voor {time} seconden." #Shown when a player tries to pick up an item that is loot protected by the plugin. protected: "Dit item is momenteel beveiligd, wacht {time} seconden om het op te halen." citizens-compatibility: #Shown when a player is prevented from joining the server due to their NPC still existing. prevent-join: "U mag niet toetreden tot de server totdat uw NPC is beëindigd of verwijderd." disguise-compatibility: #Shown when a disguise is removed from a player during combat. remove-disguise: "Je vermomming is verwijderd." essentials-compatibility: #Shown when a teleport request is cancelled during combat. prevent-teleport-request-self: "U kunt geen teleport verzoeken maken tijdens het gevecht." #Shown when a teleport request is cancelled during combat. prevent-teleport-request-other: "U kunt geen teleport verzoek sturen naar een speler die in gevecht is." marriagemaster-compatibility: #Shown when a married player is prevented from teleporting to their partner during combat. prevent-teleport-self: "Je mag tijdens het gevecht niet naar je partner teleporteren." #Shown when a married player is prevented from teleporting to their partner during combat. prevent-teleport-partner: "Je hebt geen toestemming om naar je partner te teleporteren tijdens de strijd." region-protection: #Shown when a player tries to enter a no-pvp area during combat. default-no-entry: "Je hebt geen toestemming om dat gebied binnen te komen tijdens het vecht." factions-no-entry: Je hebt geen toestemming om dat gebied binnen te komen tijdens het vecht. griefdefender-no-entry: Je hebt geen toestemming om dat gebied binnen te komen tijdens het vecht. griefprevention-no-entry: Je hebt geen toestemming om dat gebied binnen te komen tijdens het vecht. kingdomsx-no-entry: Je hebt geen toestemming om dat gebied binnen te komen tijdens het vecht. konquest-no-entry: Je hebt geen toestemming om dat gebied binnen te komen tijdens het vecht. redprotect-no-entry: Je hebt geen toestemming om dat gebied binnen te komen tijdens het vecht. residence-no-entry: Je hebt geen toestemming om dat gebied binnen te komen tijdens het vecht. towny-no-entry: Je hebt geen toestemming om dat gebied binnen te komen tijdens het vecht. husktowns-no-entry: Je hebt geen toestemming om dat gebied binnen te komen tijdens het vecht. ultimateclaims-no-entry: Je hebt geen toestemming om dat gebied binnen te komen tijdens het vecht. protectionstones: prevent-area-creation: "U bent niet bevoegd om een beschermd gebied te maken tijdens het gevechten." no-entry: Je hebt geen toestemming om dat gebied binnen te komen tijdens het vecht. preciousstones: prevent-field-creation: "U bent niet bevoegd om een beveiligingsveld te creëren tijdens het vechten." no-entry: Je hebt geen toestemming om dat gebied binnen te komen tijdens het vecht. worldguard: no-entry-mob-combat: "U heeft geen toestemming om een niet-mob-gevechtsgebied binnen te gaan tijdens het gevecht." no-entry-player-combat: "Je hebt geen toestemming om een niet-speler-gevechtsgebied te betreden tijdens het gevecht." no-entry-unknown-combat: Je hebt geen toestemming om dat gebied binnen te komen tijdens het vecht. lands: no-entry: Je hebt geen toestemming om dat gebied binnen te komen tijdens het vecht. war-disable-newbie-protection: "PvP is nu ingeschakeld vanwege een oorlogsverklaring." ================================================ FILE: plugin/src/main/resources/language/nn_no.yml ================================================ --- ## Extra Information: ## This is the default language file for CombatLogX. ## The default language is "en_us", also known as English (United States). ## Context will be added as YAML comments above the string. ## The color scheme for messages is gold, white, and sometimes red. ## Command feedback that is successful should always be green. ## Error messages should always be red. ## Variables in messages can be gray or white. ## Messages use the MiniMessage format in non-strict mode. ## More information about MiniMessage can be found here: ## https://docs.adventure.kyori.net/minimessage/format.html #The language code for this file. language-name: "no_us" #The format for decimal numbers. #The United States uses the number and two decimal places decimal-format: "0.00" #The prefix for CombatLogX. #This is shown in front of all messages and should not be changed unless necessary. prefix: "[CombatLogX]" broadcast: #Shown when the plugin is finished loading. on-load: "CombatLogX ble lastet inn." #Shown when the plugin is finished enabling. on-enable: "CombatLogX ble aktivert." #Shown when the plugin is disabled for any reason. on-disable: "CombatLogX ble deaktivert vellykket." placeholder: #This text is used for the {combatlogx_time_left} #This allows server configurations to change the display value of the zero to something like "Not in combat" time-left-zero: "0" #This text is used when a player does not have an enemy. #This can happen when players are tagged by a custom expansion or the tag command. unknown-enemy: "Ukjent" status: #Shown when the player is in combat. fighting: "Fighting" in-combat: "Ja" #Shown when the player is not in combat idle: "Inaktiv" not-in-combat: "Nei" #These placeholders are shown when a player changes a value such as whether or not their bossbar is enabled. toggle: enabled: "" disabled: "AV" pvp-status: enabled: "" disabled: "AV" combat-timer: #Sent to a player when they escape from combat due to the timer running out. expire: "Du er ikke lenger i kamp." #Sent to a player when they escape from combat due to their enemy being killed. enemy-death: "Du er ikke lenger i kamp fordi fienden din døde." #Sent when a player is killed during combat. self-death: "Du er ikke lenger i kamp fordi du døde." error: #Shown when the console tries to execute a command made for players. player-only: "Kun spillere kan utføre denne kommandoen" #Shown when a command that requires a player has invalid input. invalid-target: "{target} er ikke online eller eksisterer ikke." #Shown when a command that requires a number has invalid input. invalid-integer: "{value} er ikke et gyldig heltall." #Shown when a player does not have access to something that requires a permission. no-permission: "Mangler Permission: {permission}" #Shown when a player executes a command in a world that is disabled in the configuration. disabled-world: "Den kommandoen er ikke tilgjengelig i denne dimensjonen." #Shown when a command requires a player in combat but the target player is not in combat. target-not-in-combat: "{target} er ikke i kamp." #Shown when a player executes a command that requires them to be in combat. self-not-in-combat: "Du er ikke i kamp." #Shown when a command that requires an expansion has invalid input. unknown-expansion: "{target} er ikke en utvidelse eller er ikke installert." command: combatlogx: #Shown as the command output for '/combatlogx help'. help-message-list: - "" - "KombatLogX kommandohjelp:" - " /combatlogx help: Se denne hjelpesiden." - " /combatlogx reload: Last config.yml, language.yml og alle utvidelser konfigurasjonsfiler" - " /combatlogx om \\: Se informasjon om utvidelse." - " /combatlogx tag \\ [seconds]: Tving en spiller til å tegne." - " /combatlogx toggle bossbar/actionbar/scoreboard: Aktiver eller deaktiver en meldingstype." - " /combatlogx untag \\: Tving en spiller ut av kampen." - " /combatlogx version: Sjekk din versjon av CombatLogX." - "" #Shown as the command output for '/combatlogx reload' when reloading is successful. reload-success: - "Lastet inn alle konfigurasjonsfiler fra CombatLogX." - "Vellykket reload av alle språkfiler fra CombatLogX." - "Lastet inn alle konfigurasjonsfiler fra CombatLogX utvidelser." #Shown as the command output for '/combatlogx reload' when reloading fails reload-failure: - "Det oppstod en feil ved lasting av konfigurasjonen." - "Kontroller din serverlogg og fiks den ødelagte filen." #Shown as the command output for '/combatlogx tag ' when a player is tagged successfully. tag-player: "Tvungen spiller {target} var i kamp." #Shown as the command output for '/combatlogx tag ' when the plugin failed to tag a player. tag-failure: "{target} kunne ikke settes i kamp. (Må de har en omgåelse?)" #Shown as the command output for '/combatlogx untag '. untag-player: "Tvungen spiller {target} uten kamp." #Shown as the command output for '/combatlogx toggle bossbar'. toggle-bossbar: "Boss Bar: {status}" #Shown as the command output for '/combatlogx toggle actionbar'. toggle-actionbar: "handlingslinje: {status}" #Shown as the command output for '/combatlogx toggle scoreboard'. toggle-scoreboard: "Poengtavle: {status}" combat-timer: #Shown as the command output for '/combat-timer'. time-left-self: "Du har {time_left} sekunder&a igjen." #Shown as the command output for '/combat-timer '. time-left-other: "{target} har {time_left} sekunder igjen" #These messages are shown a player is tagged into combat. tagged: unknown: player: "Du er nå i kamp med {enemy} av en ukjent grunn. Ikke logg ut!" mob: "Du er nå i kamp med a(n) {enemy} av en ukjent årsak. Ikke logg av!" mythic_mob: "Du er nå i kamp med a(n) {mob_type} av en ukjent årsak. Ikke logg av!" damage: "Du er nå i kamp på grunn av skade. Ikke logg ut!" unknown: "Du ble plassert i kamp uten en grunn. Ikke logg ut." attacked: player: "Du blir angrepet av {enemy}. Ikke logg ut!" mob: "Du blir angrepet av en(n) {mob_type}. Ikke logg ut!" mythic_mob: "Du blir angrepet av en(n) {enemy}. Ikke logg ut!" damage: "Du er nå i kamp på grunn av skade. Ikke logg ut!" unknown: "Du blir angrepet av en ukjent kraft. Ikke logg ut!" attacker: player: "Du angriper {enemy}. Ikke logg ut!" mob: "Du angriper en(n) {mob_type}. Ikke logg ut!" mythic_mob: "Du angriper en(n) {enemy}. Ikke logg ut!" damage: "Du er nå i kamp på grunn av skade. Ikke logg ut!" unknown: "Du angriper en ukjent kraft. Ikke logg ut!" expansion: angel-chest: #Shown when opening an AngelChest is prevented during combat. prevent-opening: "Du har ikke lov til å åpne engelkister under kamp." #Shown when breaking an AngelChest is prevented during combat. prevent-breaking: "Du har ikke lov til å bryte engelkister under kamp." #Shown when fast looting an AngelChest is prevented during combat. prevent-fast-looting: "Du har ikke lov til å raskt bytte ut engelskerkister under kamp." action-bar: #Shown above the hotbar while a player is in combat. timer: "Kamp \u00BB {bars} {combatlogx_time_left} sekunder." #Shown above the hotbar for a brief period when combat ends. ended: "Kamp \u00BB Du er ikke lenger i kamp." boss-bar: #Shown on top of the screen while a player is in combat. timer: "Kamp \u00BB {combatlogx_time_left} sekunder." #Shown on top of the screen for a brief period when combat ends. ended: "Kamp \u00BB Du er ikke lenger i kamp." scoreboard: #The scoreboard title for the sidebar. #Make sure to follow the scoreboard title limits for your Spigot version. title: "CombatLogX" #The scoreboard lines for the sidebar. #Make sure to follow the scoreboard line and character limits for your Spigot version. lines: - " " - "Kamp stater:" - "\u00BB Tid Igjen: {combatlogx_time_left}" - "\u00BB Enemies: {combatlogx_enemy_count}" - "\u00BB Status: {combatlogx_status}" - " " - "Enemies" - "\u00BB {combatlogx_specific_enemy_1_name}" - "\u00BB {combatlogx_specific_enemy_2_name}" - "\u00BB {combatlogx_specific_enemy_3_name}" - " " cheat-prevention: #Shown when a command execution is prevented during combat. command-blocked: "Du har ikke tilgang til {command} i kampen." #Shown when the riptide effect is prevented during combat. no-riptide: "Fortryllelsen av riptide er deaktivert i kamp." #Shown when a totem of undying is prevented during combat. no-totem: "Du har ikke tillatelse til å bruke totems of undying during combat." #Shown when an entity interaction is prevented during combat. no-entity-interaction: "Du har ikke tillatelse til å bruke mob under kampen." #Shown when a chat message is prevented during combat. no-chat: "Du har ikke tillatelse til å sende chat meldinger under kampen." game-mode: #Shown when a player is forced into a specific game mmode during combat. force-switch: "Spillmodusen din ble endret til {game_mode}." #Shown when a game mode switch is prevented during combat. no-switch: "Du har ikke lov til å bytte spillmodus under kamp." flight: #Shown when a player's ability to fly is disabled during combat. force-disabled: "Din evne til å fly ble fjernet." #Shown when a player's attempt to fly is prevented during combat. no-flying: "Du har ikke lov til å fly under kamp." elytra: #Shown when a player's ability to glide is disabled during combat. force-disabled: "elytra ble deaktivert." #Shown when a player's attempt to glide is prevented during combat. no-gliding: "Du har ikke lov til å bruke elytra under kamp." teleportation: #Shown when a player tries to enter a portal and is prevented during combat. block-portal: "Du har ikke tillatelse til å bruke en portal under kamp." #Shown when an ender pearl is prevented during combat. block-pearl: "Du har ikke tillatelse til å bruke ender perler under kamp." #Shown when a teleport is prevented during combat. block-other: "Du har ikke lov til å teleportere under kamp." inventory: #Shown when a player's inventory is closed by the plugin during combat. force-closed: "Inventaret ditt ble lukket." #Shown when a player tries to open an inventory and is prevented during combat. no-opening: "Du har ikke lov til å åpne inventar under kamp." blocks: #Shown when a player is prevented from breaking a block during combat. prevent-breaking: "Du har ikke lov til å ødelegge blokker i kamp." #Shown when a player is prevented from breaking a block during combat. prevent-placing: "Du har ikke lov å plassere blokker under tegneserie." #Shown when a player is prevented from breaking a block during combat. prevent-interaction: "Du har ikke lov til å bruke blokker under kamp." #Shown when a player is prevented from breaking a block during combat. prevent-portal-creation: "Du har ikke rettigheter til å opprette portaler i kampen." items: #Shown when a player is prevented from picking up an item during combat. no-pickup: "Du har ikke tillatelse til å plukke opp elementer under kamp." #Shown when a player is prevented from dropping an item during combat. no-dropping: "Du har ikke rettigheter til å slippe elementer i kampen." buckets: #Shown when a player is prevented from emptying a bucket during combat. no-empty: "Du kan ikke tømme bøtter når du er kamp." #Shown when a player is prevented from filling a bucket during combat. no-fill: "Du kan ikke fylle bøtter når du er kamp." damage-tagger: #Shown when a player is tagged for an unknown damage type. unknown-damage: "Du tok skade! Ikke logg ut!" #These messages are shown when a player is tagged for a known damage type. #You can find a list of damage types here: #https://hub.spigotmc.org/javadocs/spigot/org/bukkit/event/entity/EntityDamageEvent.DamageCause.html damage-type: contact: "Du ble stukket av en kaktus. Ikke logg ut!" suffocation: "Du tåler i en vegg. Ikke logg ut!" fall: "Du tok noen skader. Ikke logg ut!" fire: "Du gikk i brann. Ikke logg ut!" fire-tick: "Du brenner. Ikke logg ut!" lava: "Du starter med lava. Ikke logg ut!" drowning: "Du er druknet. Ikke logg ut!" block-explosion: "Du ble skadet av en eksplosjon. Ikke logg ut!" lightning: "Du er slått av! Ikke logg ut!" starvation: "Du er for sulten. Ikke logg ut!" poison: "Du tok gift skade. Ikke logg ut!" magic: "Noen kastet en eliksir på deg. Ikke logg ut!" wither: "Du har medført vekk. Ikke logg ut!" falling-block: "En blokk falt på deg. Ikke logg ut!" custom: "Du tok en egendefinert skade. Ikke logg ut!" fly-into-wall: "Du har opplevd kinetisk energi. Ikke logg ut!" hot-floor: "Gulvet er lava! Ikke logg ut!" cramming: "Du blir nå squed. Ikke logg ut!" newbie-helper: togglepvp: #Shown as the command output for '/togglepvp'. self: "PVP: {status}" #Shown as the command output for '/togglepvp admin on/off '. admin: "Du endret pvp av {target} til {status}." #Shown when the '/togglepvp' command is on cooldown. cooldown: "Du må vente {time_left} sekunder for å bruke denne kommandoen igjen." #These messages are shown when pvp is disabled for any reason. no-pvp: self: "Du har ikke lov til å slå denne spilleren mens PvP er deaktivert." other: "Den spilleren har PvP deaktivert." protected: "Denne spilleren er beskyttet, du får ikke lov til å angripe dem enda!" protection-disabled: #Shown when newbie protection is disabled due to the player attacking another player. attacker: "Du har angrepet noen, nyhetsbeskyttelsen din er nå deaktivert." #Shown when newbie protection expires. expired: "Din nye beskyttelse er utløpt." #Shown for the '/togglepvp check ' command. check-format: - "Informasjon om {target}:" - "Beskyttelse: {protected}" - "PvP: {pvp}" loot-protection: #Shown when an enemy dies and their loot is protected. enemy-died: "{enemy} har dødd. Lot vil være beskyttet for {time} sekunder." #Shown when a player tries to pick up an item that is loot protected by the plugin. protected: "Denne varen er for øyeblikket beskyttet, vent {time} sekunder til du kan plukke den opp." citizens-compatibility: #Shown when a player is prevented from joining the server due to their NPC still existing. prevent-join: "Du har ikke tillatelse til å bli med i serveren før din NPC er drept eller fjernet." disguise-compatibility: #Shown when a disguise is removed from a player during combat. remove-disguise: "Forkledningen din ble fjernet." essentials-compatibility: #Shown when a teleport request is cancelled during combat. prevent-teleport-request-self: "Du kan ikke opprette teleporteringsforespørsler under kampen." #Shown when a teleport request is cancelled during combat. prevent-teleport-request-other: "Du kan ikke sende en teleporteringsforespørsel til en spiller som er i kamp." marriagemaster-compatibility: #Shown when a married player is prevented from teleporting to their partner during combat. prevent-teleport-self: "Du har ikke tillatelse til å teleportere til partneren din i kamp." #Shown when a married player is prevented from teleporting to their partner during combat. prevent-teleport-partner: "Du har ikke tillatelse til å teleportere til partneren din mens de er i kamp." region-protection: #Shown when a player tries to enter a no-pvp area during combat. default-no-entry: "Du har ikke lov til å gå inn i dette området under kampen." factions-no-entry: Du har ikke lov til å gå inn i dette området under kampen. griefdefender-no-entry: Du har ikke lov til å gå inn i dette området under kampen. griefprevention-no-entry: Du har ikke lov til å gå inn i dette området under kampen. kingdomsx-no-entry: Du har ikke lov til å gå inn i dette området under kampen. konquest-no-entry: Du har ikke lov til å gå inn i dette området under kampen. redprotect-no-entry: Du har ikke lov til å gå inn i dette området under kampen. residence-no-entry: Du har ikke lov til å gå inn i dette området under kampen. towny-no-entry: Du har ikke lov til å gå inn i dette området under kampen. husktowns-no-entry: Du har ikke lov til å gå inn i dette området under kampen. ultimateclaims-no-entry: Du har ikke lov til å gå inn i dette området under kampen. protectionstones: prevent-area-creation: "Du har ikke lov til å opprette et beskyttet område under kamp." no-entry: Du har ikke lov til å gå inn i dette området under kampen. preciousstones: prevent-field-creation: "Du har ikke lov til å lage et beskyttelsesfelt under kamp." no-entry: Du har ikke lov til å gå inn i dette området under kampen. worldguard: no-entry-mob-combat: "Du har ikke lov til å gå inn i en ikke-bevegelig kamp-område under kamp." no-entry-player-combat: "Du har ikke lov til å gå inn i en ikke-spiller-kamp område under kamp." no-entry-unknown-combat: Du har ikke lov til å gå inn i dette området under kampen. lands: no-entry: Du har ikke lov til å gå inn i dette området under kampen. war-disable-newbie-protection: "PvP er nå kraftaktivert på grunn av en krigserklæring." ================================================ FILE: plugin/src/main/resources/language/no_no.yml ================================================ --- ## Extra Information: ## This is the default language file for CombatLogX. ## The default language is "en_us", also known as English (United States). ## Context will be added as YAML comments above the string. ## The color scheme for messages is gold, white, and sometimes red. ## Command feedback that is successful should always be green. ## Error messages should always be red. ## Variables in messages can be gray or white. ## Messages use the MiniMessage format in non-strict mode. ## More information about MiniMessage can be found here: ## https://docs.adventure.kyori.net/minimessage/format.html #The language code for this file. language-name: "no_us" #The format for decimal numbers. #The United States uses the number and two decimal places decimal-format: "0.00" #The prefix for CombatLogX. #This is shown in front of all messages and should not be changed unless necessary. prefix: "[CombatLogX]" broadcast: #Shown when the plugin is finished loading. on-load: "CombatLogX ble lastet inn." #Shown when the plugin is finished enabling. on-enable: "CombatLogX ble aktivert." #Shown when the plugin is disabled for any reason. on-disable: "CombatLogX ble deaktivert vellykket." placeholder: #This text is used for the {combatlogx_time_left} #This allows server configurations to change the display value of the zero to something like "Not in combat" time-left-zero: "0" #This text is used when a player does not have an enemy. #This can happen when players are tagged by a custom expansion or the tag command. unknown-enemy: "Ukjent" status: #Shown when the player is in combat. fighting: "Fighting" in-combat: "Ja" #Shown when the player is not in combat idle: "Inaktiv" not-in-combat: "Nei" #These placeholders are shown when a player changes a value such as whether or not their bossbar is enabled. toggle: enabled: "" disabled: "AV" pvp-status: enabled: "" disabled: "AV" combat-timer: #Sent to a player when they escape from combat due to the timer running out. expire: "Du er ikke lenger i kamp." #Sent to a player when they escape from combat due to their enemy being killed. enemy-death: "Du er ikke lenger i kamp fordi fienden din døde." #Sent when a player is killed during combat. self-death: "Du er ikke lenger i kamp fordi du døde." error: #Shown when the console tries to execute a command made for players. player-only: "Kun spillere kan utføre denne kommandoen" #Shown when a command that requires a player has invalid input. invalid-target: "{target} er ikke online eller eksisterer ikke." #Shown when a command that requires a number has invalid input. invalid-integer: "{value} er ikke et gyldig heltall." #Shown when a player does not have access to something that requires a permission. no-permission: "Mangler Permission: {permission}" #Shown when a player executes a command in a world that is disabled in the configuration. disabled-world: "Den kommandoen er ikke tilgjengelig i denne dimensjonen." #Shown when a command requires a player in combat but the target player is not in combat. target-not-in-combat: "{target} er ikke i kamp." #Shown when a player executes a command that requires them to be in combat. self-not-in-combat: "Du er ikke i kamp." #Shown when a command that requires an expansion has invalid input. unknown-expansion: "{target} er ikke en utvidelse eller er ikke installert." command: combatlogx: #Shown as the command output for '/combatlogx help'. help-message-list: - "" - "KombatLogX kommandohjelp:" - " /combatlogx help: Se denne hjelpesiden." - " /combatlogx reload: Last config.yml, language.yml og alle utvidelser konfigurasjonsfiler" - " /combatlogx om \\: Se informasjon om utvidelse." - " /combatlogx tag \\ [seconds]: Tving en spiller til å tegne." - " /combatlogx toggle bossbar/actionbar/scoreboard: Aktiver eller deaktiver en meldingstype." - " /combatlogx untag \\: Tving en spiller ut av kampen." - " /combatlogx version: Sjekk din versjon av CombatLogX." - "" #Shown as the command output for '/combatlogx reload' when reloading is successful. reload-success: - "Lastet inn alle konfigurasjonsfiler fra CombatLogX." - "Vellykket reload av alle språkfiler fra CombatLogX." - "Lastet inn alle konfigurasjonsfiler fra CombatLogX utvidelser." #Shown as the command output for '/combatlogx reload' when reloading fails reload-failure: - "Det oppstod en feil ved lasting av konfigurasjonen." - "Kontroller din serverlogg og fiks den ødelagte filen." #Shown as the command output for '/combatlogx tag ' when a player is tagged successfully. tag-player: "Tvungen spiller {target} var i kamp." #Shown as the command output for '/combatlogx tag ' when the plugin failed to tag a player. tag-failure: "{target} kunne ikke settes i kamp. (Må de har en omgåelse?)" #Shown as the command output for '/combatlogx untag '. untag-player: "Tvungen spiller {target} uten kamp." #Shown as the command output for '/combatlogx toggle bossbar'. toggle-bossbar: "Boss Bar: {status}" #Shown as the command output for '/combatlogx toggle actionbar'. toggle-actionbar: "handlingslinje: {status}" #Shown as the command output for '/combatlogx toggle scoreboard'. toggle-scoreboard: "Poengtavle: {status}" combat-timer: #Shown as the command output for '/combat-timer'. time-left-self: "Du har {time_left} sekunder&a igjen." #Shown as the command output for '/combat-timer '. time-left-other: "{target} har {time_left} sekunder igjen" #These messages are shown a player is tagged into combat. tagged: unknown: player: "Du er nå i kamp med {enemy} av en ukjent grunn. Ikke logg ut!" mob: "Du er nå i kamp med a(n) {enemy} av en ukjent årsak. Ikke logg av!" mythic_mob: "Du er nå i kamp med a(n) {mob_type} av en ukjent årsak. Ikke logg av!" damage: "Du er nå i kamp på grunn av skade. Ikke logg ut!" unknown: "Du ble plassert i kamp uten en grunn. Ikke logg ut." attacked: player: "Du blir angrepet av {enemy}. Ikke logg ut!" mob: "Du blir angrepet av en(n) {mob_type}. Ikke logg ut!" mythic_mob: "Du blir angrepet av en(n) {enemy}. Ikke logg ut!" damage: "Du er nå i kamp på grunn av skade. Ikke logg ut!" unknown: "Du blir angrepet av en ukjent kraft. Ikke logg ut!" attacker: player: "Du angriper {enemy}. Ikke logg ut!" mob: "Du angriper en(n) {mob_type}. Ikke logg ut!" mythic_mob: "Du angriper en(n) {enemy}. Ikke logg ut!" damage: "Du er nå i kamp på grunn av skade. Ikke logg ut!" unknown: "Du angriper en ukjent kraft. Ikke logg ut!" expansion: angel-chest: #Shown when opening an AngelChest is prevented during combat. prevent-opening: "Du har ikke lov til å åpne engelkister under kamp." #Shown when breaking an AngelChest is prevented during combat. prevent-breaking: "Du har ikke lov til å bryte engelkister under kamp." #Shown when fast looting an AngelChest is prevented during combat. prevent-fast-looting: "Du har ikke lov til å raskt bytte ut engelskerkister under kamp." action-bar: #Shown above the hotbar while a player is in combat. timer: "Kamp \u00BB {bars} {combatlogx_time_left} sekunder." #Shown above the hotbar for a brief period when combat ends. ended: "Kamp \u00BB Du er ikke lenger i kamp." boss-bar: #Shown on top of the screen while a player is in combat. timer: "Kamp \u00BB {combatlogx_time_left} sekunder." #Shown on top of the screen for a brief period when combat ends. ended: "Kamp \u00BB Du er ikke lenger i kamp." scoreboard: #The scoreboard title for the sidebar. #Make sure to follow the scoreboard title limits for your Spigot version. title: "CombatLogX" #The scoreboard lines for the sidebar. #Make sure to follow the scoreboard line and character limits for your Spigot version. lines: - " " - "Kamp stater:" - "\u00BB Tid Igjen: {combatlogx_time_left}" - "\u00BB Enemies: {combatlogx_enemy_count}" - "\u00BB Status: {combatlogx_status}" - " " - "Enemies" - "\u00BB {combatlogx_specific_enemy_1_name}" - "\u00BB {combatlogx_specific_enemy_2_name}" - "\u00BB {combatlogx_specific_enemy_3_name}" - " " cheat-prevention: #Shown when a command execution is prevented during combat. command-blocked: "Du har ikke tilgang til {command} i kampen." #Shown when the riptide effect is prevented during combat. no-riptide: "Fortryllelsen av riptide er deaktivert i kamp." #Shown when a totem of undying is prevented during combat. no-totem: "Du har ikke tillatelse til å bruke totems of undying during combat." #Shown when an entity interaction is prevented during combat. no-entity-interaction: "Du har ikke tillatelse til å bruke mob under kampen." #Shown when a chat message is prevented during combat. no-chat: "Du har ikke tillatelse til å sende chat meldinger under kampen." game-mode: #Shown when a player is forced into a specific game mmode during combat. force-switch: "Spillmodusen din ble endret til {game_mode}." #Shown when a game mode switch is prevented during combat. no-switch: "Du har ikke lov til å bytte spillmodus under kamp." flight: #Shown when a player's ability to fly is disabled during combat. force-disabled: "Din evne til å fly ble fjernet." #Shown when a player's attempt to fly is prevented during combat. no-flying: "Du har ikke lov til å fly under kamp." elytra: #Shown when a player's ability to glide is disabled during combat. force-disabled: "elytra ble deaktivert." #Shown when a player's attempt to glide is prevented during combat. no-gliding: "Du har ikke lov til å bruke elytra under kamp." teleportation: #Shown when a player tries to enter a portal and is prevented during combat. block-portal: "Du har ikke tillatelse til å bruke en portal under kamp." #Shown when an ender pearl is prevented during combat. block-pearl: "Du har ikke tillatelse til å bruke ender perler under kamp." #Shown when a teleport is prevented during combat. block-other: "Du har ikke lov til å teleportere under kamp." inventory: #Shown when a player's inventory is closed by the plugin during combat. force-closed: "Inventaret ditt ble lukket." #Shown when a player tries to open an inventory and is prevented during combat. no-opening: "Du har ikke lov til å åpne inventar under kamp." blocks: #Shown when a player is prevented from breaking a block during combat. prevent-breaking: "Du har ikke lov til å ødelegge blokker i kamp." #Shown when a player is prevented from breaking a block during combat. prevent-placing: "Du har ikke lov å plassere blokker under tegneserie." #Shown when a player is prevented from breaking a block during combat. prevent-interaction: "Du har ikke lov til å bruke blokker under kamp." #Shown when a player is prevented from breaking a block during combat. prevent-portal-creation: "Du har ikke rettigheter til å opprette portaler i kampen." items: #Shown when a player is prevented from picking up an item during combat. no-pickup: "Du har ikke tillatelse til å plukke opp elementer under kamp." #Shown when a player is prevented from dropping an item during combat. no-dropping: "Du har ikke rettigheter til å slippe elementer i kampen." buckets: #Shown when a player is prevented from emptying a bucket during combat. no-empty: "Du kan ikke tømme bøtter når du er kamp." #Shown when a player is prevented from filling a bucket during combat. no-fill: "Du kan ikke fylle bøtter når du er kamp." damage-tagger: #Shown when a player is tagged for an unknown damage type. unknown-damage: "Du tok skade! Ikke logg ut!" #These messages are shown when a player is tagged for a known damage type. #You can find a list of damage types here: #https://hub.spigotmc.org/javadocs/spigot/org/bukkit/event/entity/EntityDamageEvent.DamageCause.html damage-type: contact: "Du ble stukket av en kaktus. Ikke logg ut!" suffocation: "Du tåler i en vegg. Ikke logg ut!" fall: "Du tok noen skader. Ikke logg ut!" fire: "Du gikk i brann. Ikke logg ut!" fire-tick: "Du brenner. Ikke logg ut!" lava: "Du starter med lava. Ikke logg ut!" drowning: "Du er druknet. Ikke logg ut!" block-explosion: "Du ble skadet av en eksplosjon. Ikke logg ut!" lightning: "Du er slått av! Ikke logg ut!" starvation: "Du er for sulten. Ikke logg ut!" poison: "Du tok gift skade. Ikke logg ut!" magic: "Noen kastet en eliksir på deg. Ikke logg ut!" wither: "Du har medført vekk. Ikke logg ut!" falling-block: "En blokk falt på deg. Ikke logg ut!" custom: "Du tok en egendefinert skade. Ikke logg ut!" fly-into-wall: "Du har opplevd kinetisk energi. Ikke logg ut!" hot-floor: "Gulvet er lava! Ikke logg ut!" cramming: "Du blir nå squed. Ikke logg ut!" newbie-helper: togglepvp: #Shown as the command output for '/togglepvp'. self: "PVP: {status}" #Shown as the command output for '/togglepvp admin on/off '. admin: "Du endret pvp av {target} til {status}." #Shown when the '/togglepvp' command is on cooldown. cooldown: "Du må vente {time_left} sekunder for å bruke denne kommandoen igjen." #These messages are shown when pvp is disabled for any reason. no-pvp: self: "Du har ikke lov til å slå denne spilleren mens PvP er deaktivert." other: "Den spilleren har PvP deaktivert." protected: "Denne spilleren er beskyttet, du får ikke lov til å angripe dem enda!" protection-disabled: #Shown when newbie protection is disabled due to the player attacking another player. attacker: "Du har angrepet noen, nyhetsbeskyttelsen din er nå deaktivert." #Shown when newbie protection expires. expired: "Din nye beskyttelse er utløpt." #Shown for the '/togglepvp check ' command. check-format: - "Informasjon om {target}:" - "Beskyttelse: {protected}" - "PvP: {pvp}" loot-protection: #Shown when an enemy dies and their loot is protected. enemy-died: "{enemy} har dødd. Lot vil være beskyttet for {time} sekunder." #Shown when a player tries to pick up an item that is loot protected by the plugin. protected: "Denne varen er for øyeblikket beskyttet, vent {time} sekunder til du kan plukke den opp." citizens-compatibility: #Shown when a player is prevented from joining the server due to their NPC still existing. prevent-join: "Du har ikke tillatelse til å bli med i serveren før din NPC er drept eller fjernet." disguise-compatibility: #Shown when a disguise is removed from a player during combat. remove-disguise: "Forkledningen din ble fjernet." essentials-compatibility: #Shown when a teleport request is cancelled during combat. prevent-teleport-request-self: "Du kan ikke opprette teleporteringsforespørsler under kampen." #Shown when a teleport request is cancelled during combat. prevent-teleport-request-other: "Du kan ikke sende en teleporteringsforespørsel til en spiller som er i kamp." marriagemaster-compatibility: #Shown when a married player is prevented from teleporting to their partner during combat. prevent-teleport-self: "Du har ikke tillatelse til å teleportere til partneren din i kamp." #Shown when a married player is prevented from teleporting to their partner during combat. prevent-teleport-partner: "Du har ikke tillatelse til å teleportere til partneren din mens de er i kamp." region-protection: #Shown when a player tries to enter a no-pvp area during combat. default-no-entry: "Du har ikke lov til å gå inn i dette området under kampen." factions-no-entry: Du har ikke lov til å gå inn i dette området under kampen. griefdefender-no-entry: Du har ikke lov til å gå inn i dette området under kampen. griefprevention-no-entry: Du har ikke lov til å gå inn i dette området under kampen. kingdomsx-no-entry: Du har ikke lov til å gå inn i dette området under kampen. konquest-no-entry: Du har ikke lov til å gå inn i dette området under kampen. redprotect-no-entry: Du har ikke lov til å gå inn i dette området under kampen. residence-no-entry: Du har ikke lov til å gå inn i dette området under kampen. towny-no-entry: Du har ikke lov til å gå inn i dette området under kampen. husktowns-no-entry: Du har ikke lov til å gå inn i dette området under kampen. ultimateclaims-no-entry: Du har ikke lov til å gå inn i dette området under kampen. protectionstones: prevent-area-creation: "Du har ikke lov til å opprette et beskyttet område under kamp." no-entry: Du har ikke lov til å gå inn i dette området under kampen. preciousstones: prevent-field-creation: "Du har ikke lov til å lage et beskyttelsesfelt under kamp." no-entry: Du har ikke lov til å gå inn i dette området under kampen. worldguard: no-entry-mob-combat: "Du har ikke lov til å gå inn i en ikke-bevegelig kamp-område under kamp." no-entry-player-combat: "Du har ikke lov til å gå inn i en ikke-spiller-kamp område under kamp." no-entry-unknown-combat: Du har ikke lov til å gå inn i dette området under kampen. lands: no-entry: Du har ikke lov til å gå inn i dette området under kampen. war-disable-newbie-protection: "PvP er nå kraftaktivert på grunn av en krigserklæring." ================================================ FILE: plugin/src/main/resources/language/pl_pl.lang.yml ================================================ --- ## Extra Information: ## This is the default language file for CombatLogX. ## The default language is "en_us", also known as English (United States). ## Context will be added as YAML comments above the string. ## The color scheme for messages is gold, white, and sometimes red. ## Command feedback that is successful should always be green. ## Error messages should always be red. ## Variables in messages can be gray or white. ## Messages use the MiniMessage format in non-strict mode. ## More information about MiniMessage can be found here: ## https://docs.adventure.kyori.net/minimessage/format.html #The language code for this file. language-name: "pl_pl_nami" #The format for decimal numbers. #The United States uses the number and two decimal places decimal-format: "0.00" #The prefix for CombatLogX that is shown in front of all messages. #Note to translators: Do not change this message. prefix: "[CombatLogX]" broadcast: #Shown when the plugin is finished loading. on-load: "CombatLogX został pomyślnie załadowany." #Shown when the plugin is finished enabling. on-enable: "CombatLogX został pomyślnie włączony." #Shown when the plugin is disabled for any reason. on-disable: "CombatLogX został pomyślnie wyłączony." placeholder: #This text is used for the {combatlogx_time_left} #This allows server configurations to change the display value of the zero to something like "Not in combat" time-left-zero: "0" #This text is used when a player does not have an enemy. #This can happen when players are tagged by a custom expansion or the tag command. unknown-enemy: "Nieznany" status: #Shown when the player is in combat. fighting: "Walka" in-combat: "Tak" #Shown when the player is not in combat idle: "Bezczynny" not-in-combat: "Nie" #These placeholders are shown when a player changes a value such as whether or not their bossbar is enabled. toggle: enabled: "Włączony" disabled: "Wyłączony" pvp-status: enabled: "Włączony" disabled: "Wyłączony" #You can also change the location of these messages. #Example: #combat-timer: #expire: #type: ACTION_BAR #content: "" combat-timer: #Sent to a player when they escape from combat due to the timer running out. expire: "Nie jesteś już w walce." #Sent to a player when they escape from combat due to their enemy being killed. enemy-death: "Nie jesteś już w walce, ponieważ twój przeciwnik nie żyje." #Sent when a player is killed during combat. self-death: "Nie jesteś już w walce ponieważ zginąłeś." error: #Shown when the console tries to execute a command made for players. player-only: "Tylko gracze mogą wykonać to polecenie." #Shown when a player tries to execute a command made for the server console. console-only: "To polecenie może być wykonane tylko przez konsolę." #Shown when a command that requires a player has invalid input. invalid-target: "{target} nie jest online lub nie istnieje." #Shown when a command that requires a number has invalid input. invalid-integer: "{value} nie jest prawidłową liczbą całkowitą." #Shown when a player does not have access to something that requires a permission. no-permission: "Brak uprawnień: {permission}" #Shown when a player executes a command in a world that is disabled in the configuration. disabled-world: "Ta komenda nie jest dostępna w tym świecie." #Shown when a command requires a player in combat but the target player is not in combat. target-not-in-combat: "{target} nie jest w walce." #Shown when a player executes a command that requires them to be in combat. self-not-in-combat: "Nie jesteś w walce." #Shown when a command that requires an expansion has invalid input. unknown-expansion: "{target} nie jest rozszerzeniem lub nie jest zainstalowane." forgive-not-enemy: "{target} nie jest jednym z twoich wrogów." enemy-not-forgiving: "Ten przeciwnik nie jest w nastroju, aby ci wybaczyć." command: combatlogx: #Shown as the command output for '/combatlogx help'. help-message-list: - "" - "Menu pomocy CombatLogX:" - " /combatlogx help: Wyświetl stronę pomocy." - " /combatlogx reload: Przeładuj plik config.yml, language.yml i wszystkie pliki konfiguracyjne rozszerzeń." - " /combatlogx o \\: Sprawdź informacje o rozszerzeniu." - " /combatlogx tag \\ [seconds]: Zmuś gracza do walki." - " /combatlogx toggle bossbar/actionbar/scoreboard: Włącz lub wyłącz wybrany typ powiadomień." - " /combatlogx untag \\: Zmuś gracza do opuszczenia walki." - " /combatlogx version: Sprawdź wersję CombatLogX." - " /combatlogx forgive request \\: Wyślij prośbę do wroga, aby usunąć tagi z ciebie." - " /combatlogx forgive accept \\: Zezwól na ucieczkę na prośbę wroga." - " /combatlogx forgive reject \\: Zignoruj prośbę wroga o ucieczkę z walki." - " /combatlogx forgive toggle: Włącz lub wyłącz prośby o zaprzestanie walki." - "" #Shown as the command output for '/combatlogx reload' when reloading is successful. reload-success: - "Pomyślnie przeładowano wszystkie pliki konfiguracyjne z CombatLogX." - "Pomyślnie przeładowano wszystkie pliki językowe z CombatLogX." - "Pomyślnie przeładowano wszystkie pliki konfiguracyjne z rozszerzeń CombatLogX." #Shown as the command output for '/combatlogx reload' when reloading fails reload-failure: - "Wystąpił błąd podczas przeładowania konfiguracji." - "Sprawdź dziennik serwera i popraw uszkodzony plik." #Shown as the command output for '/combatlogx tag ' when a player is tagged successfully. tag-player: "Pomyślnie zmuszono gracza {target} do bycia w walce." #Shown as the command output for '/combatlogx tag ' when the plugin failed to tag a player. tag-failure: "{target} nie może zostać zmuszony do bycia w walce. (Może ma uprawnienie .bypass)" #Shown as the command output for '/combatlogx untag '. untag-player: "Pomyślnie zmuszono gracza {target} do bycia poza walką." #Shown as the command output for '/combatlogx toggle bossbar'. toggle-bossbar: "Boss Bar: {status}" #Shown as the command output for '/combatlogx toggle actionbar'. toggle-actionbar: "Action Bar: {status}" #Shown as the command output for '/combatlogx toggle scoreboard'. toggle-scoreboard: "Scoreboard: {status}" #Shown as the command output for '/combatlogx about '. expansion-information: - "" - "Informacje o rozszerzeniu {name}:" - "Wyświetlana nazwa: {prefix}" - "Wersja: {version}" - "Stan: {state}" - "" - "Opis: {description}" - "Strona internetowa: {website}" - "Autorzy: {authors}" forgive: toggle-disable: "Nie możesz już otrzymywać próśb o przebaczenie." toggle-enable: "Możesz teraz otrzymywać prośby o przebaczanie." request-sent: "Wysłałeś prośbę o przebaczenie do {target}." request-receive: - "{player} wysłał do Ciebie prośbę o wybaczenie." - "Wpisz /clx forgive accept aby zaakceptować lub" - "/clx forgive reject by odrzucić." combat-timer: #Shown as the command output for '/combat-timer'. time-left-self: "Pozostało Ci {time_left} sekund." #Shown as the command output for '/combat-timer '. time-left-other: "Graczowi {target} pozostało {time_left}." #These messages are shown a player is tagged into combat. #You can also change the location of these messages. #Example: #tagged: #attacked: #player: #type: ACTION_BAR #content: "" tagged: unknown: player: "Jesteś teraz w walce z {enemy} z nieznanego powodu. Nie wylogowuj się!" mob: "Jesteś teraz w walce z {enemy} z nieznanego powodu. Nie wylogowuj się!" mythic_mob: "Jesteś teraz w walce z {mob_type} z nieznanego powodu. Nie wylogowuj się!" damage: "Jesteś teraz w walce z powodu obrażeń. Nie wyloguj się!" unknown: "Zostałeś postawiony do walki bez powodu. Nie wylogowuj się." attacked: player: "Zostałeś zaatakowany przez {enemy}. Nie wylogowuj się!" mob: "Zostałeś zaatakowany przez {mob_type}. Nie wylogowuj się!" mythic_mob: "Zostałeś zaatakowany przez {enemy}. Nie wylogowuj się!" damage: "Jesteś teraz w walce z powodu obrażeń. Nie wyloguj się!" unknown: "Jesteś atakowany przez nieznaną siłę. Nie wylogowuj się!" attacker: player: "Zaatakowałeś {enemy}. Nie wylogowuj się!" mob: "Zaatakowałeś {mob_type}. Nie wylogowuj się!" mythic_mob: "Zaatakowałeś {enemy}. Nie wylogowuj się!" damage: "Jesteś teraz w walce z powodu obrażeń. Nie wyloguj się!" unknown: "Atakujesz nieznaną siłę. Nie wylogowuj się!" expansion: angel-chest: #Shown when opening an AngelChest is prevented during combat. prevent-opening: "Nie masz uprawnień do otwierania skrzyń angelowych podczas walki." #Shown when breaking an AngelChest is prevented during combat. prevent-breaking: "Nie masz uprawnień do złamania skrzyni angelli podczas walki." #Shown when fast looting an AngelChest is prevented during combat. prevent-fast-looting: "Nie masz uprawnień do szybkich skrzyń z aniołami lootów podczas walki." action-bar: #Shown above the hotbar while a player is in combat. timer: "Walka \u00BB {bars} {combatlogx_time_left} sekund." #Shown above the hotbar for a brief period when combat ends. ended: "Walka \u00BB Nie jesteś już w walce." boss-bar: #Shown on top of the screen while a player is in combat. timer: "Walka \u00BB {combatlogx_time_left} sekund." #Shown on top of the screen for a brief period when combat ends. ended: "Walka » Nie jesteś już w walce." scoreboard: #The scoreboard title for the sidebar. #Make sure to follow the scoreboard title limits for your Spigot version. title: "CombatLogX" #The scoreboard lines for the sidebar. #Make sure to follow the scoreboard line and character limits for your Spigot version. lines: - " " - "Statystyki Walki:" - "» Pozostały Czas: {time_left}" - "» W Walce: {in_combat}" - "» Status: {status}" - " " - "Statystyki Wroga" - "» Nazwa: {enemy_name}" - "» Życie: {enemy_health}" - "» Zdrowie: {enemy_health_rounded}" - " " cheat-prevention: #Shown when a command execution is prevented during combat. command-blocked: "Nie masz dostępu do {command} podczas walki." #Shown when the riptide effect is prevented during combat. no-riptide: "Zaklęcie \"Torpeda\" jest wyłączone podczas walki." #Shown when a totem of undying is prevented during combat. no-totem: "Nie możesz używać totemów nieśmiertelności podczas walki." #Shown when an entity interaction is prevented during combat. no-entity-interaction: "Nie możesz używać tego stworzenia podczas walki." #Shown when a chat message is prevented during combat. no-chat: "Nie możesz wysyłać wiadomości na czacie podczas walki." game-mode: #Shown when a player is forced into a specific game mmode during combat. force-switch: "Twój tryb gry został zmieniony na {game_mode}." #Shown when a game mode switch is prevented during combat. no-switch: "Nie możesz przełączać trybów gry podczas walki." flight: #Shown when a player's ability to fly is disabled during combat. force-disabled: "Twoja zdolność latania została usunięta." #Shown when a player's attempt to fly is prevented during combat. no-flying: "Nie możesz latać podczas walki." elytra: #Shown when a player's ability to glide is disabled during combat. force-disabled: "Twoja elytra została wyłączona." #Shown when a player's attempt to glide is prevented during combat. no-gliding: "Nie możesz używać elytry podczas walki." teleportation: #Shown when a player tries to enter a portal and is prevented during combat. block-portal: "Nie możesz używać portalu podczas walki." #Shown when an ender pearl is prevented during combat. block-pearl: "Nie możesz używać enderpereł podczas walki." #Shown when a teleport is prevented during combat. block-other: "Nie możesz się teleportować podczas walki." inventory: #Shown when a player's inventory is closed by the plugin during combat. force-closed: "Twój ekwipunek został zamknięty." #Shown when a player tries to open an inventory and is prevented during combat. no-opening: "Nie możesz otwierać ekwipunku podczas walki." blocks: #Shown when a player is prevented from breaking a block during combat. prevent-breaking: "Nie możesz niszczyć bloków podczas walki." #Shown when a player is prevented from breaking a block during combat. prevent-placing: "Nie możesz stawiać bloków podczas walki." #Shown when a player is prevented from breaking a block during combat. prevent-interaction: "Nie możesz używać bloków podczas walki." #Shown when a player is prevented from breaking a block during combat. prevent-portal-creation: "Nie możesz tworzyć portali podczas walki." items: #Shown when a player is prevented from picking up an item during combat. no-pickup: "Nie możesz podnosić przedmiotów podczas walki." #Shown when a player is prevented from dropping an item during combat. no-dropping: "Nie możesz wyrzucać przedmiotów podczas walki." buckets: #Shown when a player is prevented from emptying a bucket during combat. no-empty: "Nie możesz opróżniać wiader podczas walki." #Shown when a player is prevented from filling a bucket during combat. no-fill: "Nie możesz napełniać wiader podczas walki." damage-tagger: #Shown when a player is tagged for an unknown damage type. unknown-damage: "Otrzymałeś obrażenia! Nie wylogowuj się!" #These messages are shown when a player is tagged for a known damage type. #You can find a list of damage types here: #https://hub.spigotmc.org/javadocs/spigot/org/bukkit/event/entity/EntityDamageEvent.DamageCause.html damage-type: block-explosion: "Otrzymałeś obrażenia od wybuchu. Nie wylogowuj się!" contact: "Zostałeś ukłuty przez kaktusa. Nie wylogowuj się!" cramming: "Zostałeś zgnieciony. Nie wylogowuj się!" custom: "Otrzymałeś niestandardowe obrażenia. Nie wylogowuj się!" drowning: "Toniesz. Nie wylogowuj się!" dryout: "Zbyt długo pozostawałeś pod wodą. Nie wylogowuj się!" #May be triggered by custom plugins. entity-explosion: "Otrzymałeś obrażenia od wybuchu Kryształu Endu. Nie wylogowuj się!" #Only triggered by end crystals. fall: "Otrzymałeś obrażenia od upadku. Nie wylogowuj się!" falling-block: "Spadł na ciebie blok. Nie wylogowuj się!" fire: "Wskoczyłeś w ogień. Nie wylogowuj się!" fire-tick: "Palisz się. Nie wylogowuj się!" fly-into-wall: "Doświadczyłeś energii kinetycznej. Nie wylogowuj się!" freeze: "Zamarzasz. Nie wylogowuj się!" hot-floor: "Podłoga to lawa! Nie wyloguj się!" lava: "Gotujesz się w lawie. Nie wylogowuj się!" lightning: "Uderzył Cię piorun! Nie wylogowuj się!" magic: "Ktoś rzucił w ciebie miksturę. Nie wylogowuj się!" melting: "Palisz się! Nie wylogowuj się." #May be triggered by custom plugins. poison: "Otrzymałeś obrażenia od trucizny. Nie wylogowuj się!" starvation: "Głodujesz. Nie wylogowuj się!" suffocation: "Uderzasz się w ścianie. Nie wylogowuj się!" void: "Wpadasz w otchłań. Nie wylogowuj się!" wither: "Usychasz. Nie wylogowuj się!" world-border: "Jesteś zbyt blisko granicy świata. Nie wylogowuj się!" newbie-helper: togglepvp: #Shown as the command output for '/togglepvp'. self: "PVP: {status}" #Shown as the command output for '/togglepvp admin on/off '. admin: "Ustawiłeś status pvp gracza {target} na {status}." #Shown when the '/togglepvp' command is on cooldown. cooldown: "Musisz poczekać {time_left} sekund aby użyć tej komendy ponownie." #These messages are shown when pvp is disabled for any reason. no-pvp: self: "Nie możesz bić innych graczy, kiedy Twoje PvP jest wyłączone." other: "Ten gracz ma wyłączone PvP." protected: "Ten gracz jest chroniony, nie możesz go jeszcze zaatakować!" protection-disabled: #Shown when newbie protection is disabled due to the player attacking another player. attacker: "Zaatakowałeś kogoś, twoja ochrona dla nowych została wyłączona." #Shown when newbie protection expires. expired: "Twoja ochrona dla nowych graczy wygasła." #Shown for the '/togglepvp check ' command. check-format: - "Informacje dla {target}:" - "Ochrona: {protected}" - "PvP: {pvp}" loot-protection: #Shown when an enemy dies and their loot is protected. enemy-died: "{enemy} umarł. Łup będzie chroniony przez {time} sekund." #Shown when a player tries to pick up an item that is loot protected by the plugin. protected: "Ten przedmiot jest obecnie chroniony, poczekaj {time} sekund aby móc go podnieść." citizens-compatibility: #Shown when a player is prevented from joining the server due to their NPC still existing. prevent-join: "Nie możesz dołączyć do serwera dopóki Twój NPC nie zostanie zabity lub nie zniknie." disguise-compatibility: #Shown when a disguise is removed from a player during combat. remove-disguise: "Twoje przebranie zostało usunięte." essentials-compatibility: #Shown when a teleport request is cancelled during combat. prevent-teleport-request-self: "Nie możesz tworzyć żądań teleportacji podczas walki." #Shown when a teleport request is cancelled during combat. prevent-teleport-request-other: "Nie możesz wysłać prośby o teleportację do gracza, który jest w walce." marriagemaster-compatibility: #Shown when a married player is prevented from teleporting to their partner during combat. prevent-teleport-self: "Nie możesz teleportować się do swojego partnera podczas walki." #Shown when a married player is prevented from teleporting to their partner during combat. prevent-teleport-partner: "Nie możesz teleportować się do swojego partnera, gdy jest w walce." huskhomes-compatibility: prevent-teleport: "Nie możesz się teleportować podczas walki." region-protection: #Shown when a player tries to enter a no-pvp area during combat. default-no-entry: "Nie możesz wejść do tego obszaru podczas walki." factions-no-entry: Nie możesz wejść do tego obszaru podczas walki. griefdefender-no-entry: Nie możesz wejść do tego obszaru podczas walki. griefprevention-no-entry: Nie możesz wejść do tego obszaru podczas walki. kingdomsx-no-entry: Nie możesz wejść do tego obszaru podczas walki. konquest-no-entry: Nie możesz wejść do tego obszaru podczas walki. redprotect-no-entry: Nie możesz wejść do tego obszaru podczas walki. residence-no-entry: Nie możesz wejść do tego obszaru podczas walki. towny-no-entry: Nie możesz wejść do tego obszaru podczas walki. husktowns-no-entry: Nie możesz wejść do tego obszaru podczas walki. ultimateclaims-no-entry: Nie możesz wejść do tego obszaru podczas walki. protectionstones: prevent-area-creation: "Nie możesz tworzyć obszaru chronionego podczas walki." no-entry: Nie możesz wejść do tego obszaru podczas walki. preciousstones: prevent-field-creation: "Nie możesz tworzyć pola ochrony podczas walki." no-entry: Nie możesz wejść do tego obszaru podczas walki. worldguard: no-entry-mob-combat: "Nie możesz wejść do strefy, gdzie zostało wyłączone PvP mobów podczas walki." no-entry-player-combat: "Nie możesz wejść do strefy, gdzie zostało wyłączone PvP podczas walki." no-entry-unknown-combat: Nie możesz wejść do tego obszaru podczas walki. lands: no-entry: Nie możesz wejść do tego obszaru podczas walki. war-disable-newbie-protection: "PvP jest teraz włączone z powodu deklaracji wojennej." ================================================ FILE: plugin/src/main/resources/language/pt_br.lang.yml ================================================ --- ## Extra Information: ## This is the default language file for CombatLogX. ## The default language is "en_us", also known as English (United States). ## Context will be added as YAML comments above the string. ## The color scheme for messages is gold, white, and sometimes red. ## Command feedback that is successful should always be green. ## Error messages should always be red. ## Variables in messages can be gray or white. ## Messages use the MiniMessage format in non-strict mode. ## More information about MiniMessage can be found here: ## https://docs.adventure.kyori.net/minimessage/format.html #The language code for this file. language-name: "pt_br" #The format for decimal numbers. #The United States uses the number and two decimal places decimal-format: "0.00" #The prefix for CombatLogX. #This is shown in front of all messages and should not be changed unless necessary. prefix: "[CombatLogX]" broadcast: #Shown when the plugin is finished loading. on-load: "CombatLogX foi carregado com sucesso." #Shown when the plugin is finished enabling. on-enable: "O CombatLogX foi ativado com sucesso." #Shown when the plugin is disabled for any reason. on-disable: "O CombatLogX foi desativado com sucesso." placeholder: #This text is used for the {combatlogx_time_left} #This allows server configurations to change the display value of the zero to something like "Not in combat" time-left-zero: "0" #This text is used when a player does not have an enemy. #This can happen when players are tagged by a custom expansion or the tag command. unknown-enemy: "Desconhecido" status: #Shown when the player is in combat. fighting: "Luta" in-combat: "Sim" #Shown when the player is not in combat idle: "Inativo" not-in-combat: "Não" #These placeholders are shown when a player changes a value such as whether or not their bossbar is enabled. toggle: enabled: "LIGADO" disabled: "DESLIGADO" pvp-status: enabled: "LIGADO" disabled: "DESLIGADO" combat-timer: #Sent to a player when they escape from combat due to the timer running out. expire: "Você não está mais em combate." #Sent to a player when they escape from combat due to their enemy being killed. enemy-death: "Você não está mais em combate porque seu inimigo morreu." #Sent when a player is killed during combat. self-death: "Você não está mais em combate porque você morreu." error: #Shown when the console tries to execute a command made for players. player-only: "Somente jogadores podem executar este comando" #Shown when a command that requires a player has invalid input. invalid-target: "{target} não está online ou não existe." #Shown when a command that requires a number has invalid input. invalid-integer: "{value} não é um inteiro válido." #Shown when a player does not have access to something that requires a permission. no-permission: "Permissão faltando: {permission}" #Shown when a player executes a command in a world that is disabled in the configuration. disabled-world: "Esse comando não está disponível nesta dimensão." #Shown when a command requires a player in combat but the target player is not in combat. target-not-in-combat: "{target} não está em combate." #Shown when a player executes a command that requires them to be in combat. self-not-in-combat: "Você não está em combate." #Shown when a command that requires an expansion has invalid input. unknown-expansion: "{target} não é uma expansão ou não está instalada." command: combatlogx: #Shown as the command output for '/combatlogx help'. help-message-list: - "" - "Ajuda do Comando CombatLogX:" - " /combatlogx ajuda: Veja esta página de ajuda." - " /combatlogx reload: Recarregue o config.yml, language.yml e todos os arquivos de configuração de expansão." - " /combatlogx sobre \\: Verifique informações sobre uma expansão." - " /combatlogx tag \\ [seconds]: Força um jogador em combate." - " /combatlogx switch bossbar/actionbar/scoreboard: Ativar ou desativar um tipo de notificação." - " /combatlogx untag \\: Força um jogador a sair do combate." - " /combatlogx versão: Verifique sua versão do CombatLogX." - "" #Shown as the command output for '/combatlogx reload' when reloading is successful. reload-success: - "Recarregou com sucesso todos os arquivos de configuração do CombatLogX." - "Recarregou com sucesso todos os arquivos de idioma do CombatLogX." - "Recarregou com sucesso todos os arquivos de configuração das expansões CombatLogX." #Shown as the command output for '/combatlogx reload' when reloading fails reload-failure: - "Ocorreu um erro ao recarregar a configuração." - "Por favor, verifique o log do servidor e corrija o arquivo quebrado." #Shown as the command output for '/combatlogx tag ' when a player is tagged successfully. tag-player: "Jogador {target} forçado com sucesso em combate." #Shown as the command output for '/combatlogx tag ' when the plugin failed to tag a player. tag-failure: "{target} não pode ser colocado em combate. (Talvez eles tenham uma passagem acessível?)" #Shown as the command output for '/combatlogx untag '. untag-player: "Jogador forçado com sucesso {target} saiu de combate." #Shown as the command output for '/combatlogx toggle bossbar'. toggle-bossbar: "Barra de Chefe: {status}" #Shown as the command output for '/combatlogx toggle actionbar'. toggle-actionbar: "Barra de Ação: {status}" #Shown as the command output for '/combatlogx toggle scoreboard'. toggle-scoreboard: "Placar: {status}" combat-timer: #Shown as the command output for '/combat-timer'. time-left-self: "Você tem {time_left} segundos & a restantes." #Shown as the command output for '/combat-timer '. time-left-other: "{target} tem {time_left} segundos restantes." #These messages are shown a player is tagged into combat. tagged: unknown: player: "Agora você está em combate com {enemy} por uma razão desconhecida. Não desconecte!" mob: "Você agora está em combate com um (n) {enemy} por um motivo desconhecido. Não se desconecte!" mythic_mob: "Você agora está em combate com um (n) {mob_type} por um motivo desconhecido. Não se desconecte!" damage: "Você agora está em combate devido a tomar dano. Não se desconecte!" unknown: "Você foi colocado em combate sem um motivo. Não sair." attacked: player: "Você está sendo atacado por {enemy}. Não desconecte!" mob: "Você está sendo atacado por um (n) {mob_type}. Não desconecte!" mythic_mob: "Você está sendo atacado por um (n) {enemy}. Não desconecte!" damage: "Você agora está em combate devido a tomar dano. Não se desconecte!" unknown: "Você está sendo atacado por uma força desconhecida. Não desconecte!" attacker: player: "Você está atacando {enemy}. Não desconecte!" mob: "Você está atacando um(n) {mob_type}. Não faça loging!" mythic_mob: "Você está atacando um(n) {enemy}. Não faça loging!" damage: "Você agora está em combate devido a tomar dano. Não se desconecte!" unknown: "Você está atacando uma força desconhecida. Não desconecte!" expansion: angel-chest: #Shown when opening an AngelChest is prevented during combat. prevent-opening: "Você não tem permissão para abrir baús de anjo durante o combate." #Shown when breaking an AngelChest is prevented during combat. prevent-breaking: "Você não tem permissão para quebrar baús de anjo durante o combate." #Shown when fast looting an AngelChest is prevented during combat. prevent-fast-looting: "Você não tem permissão para saquear baús de anjos rapidamente durante o combate." action-bar: #Shown above the hotbar while a player is in combat. timer: "Combate \u00BB {bars} {combatlogx_time_left} segundos." #Shown above the hotbar for a brief period when combat ends. ended: "Combate \u00BB Você não está mais em combate." boss-bar: #Shown on top of the screen while a player is in combat. timer: "Combate \u00BB {combatlogx_time_left} segundos." #Shown on top of the screen for a brief period when combat ends. ended: "Combate \u00BB Você não está mais em combate." scoreboard: #The scoreboard title for the sidebar. #Make sure to follow the scoreboard title limits for your Spigot version. title: "CombatLogX" #The scoreboard lines for the sidebar. #Make sure to follow the scoreboard line and character limits for your Spigot version. lines: - " " - "Estatísticas de Combate:" - "\u00BB Tempo restante: {combatlogx_time_left}" - "\u00BB Enemies: {combatlogx_enemy_count}" - "\u00BB Estado: {combatlogx_status}" - " " - "Enemies" - "\u00BB {combatlogx_specific_enemy_1_name}" - "\u00BB {combatlogx_specific_enemy_2_name}" - "\u00BB {combatlogx_specific_enemy_3_name}" - " " cheat-prevention: #Shown when a command execution is prevented during combat. command-blocked: "Você não tem acesso a {command} durante o combate." #Shown when the riptide effect is prevented during combat. no-riptide: "O encantamento riptídeo está desativado durante o combate." #Shown when a totem of undying is prevented during combat. no-totem: "Você não tem permissão para usar totens de Ignora durante o combate." #Shown when an entity interaction is prevented during combat. no-entity-interaction: "Você não tem permissão para usar esse monstro durante o combate." #Shown when a chat message is prevented during combat. no-chat: "Você não tem permissão para enviar mensagens de bate-papo durante o combate." game-mode: #Shown when a player is forced into a specific game mmode during combat. force-switch: "Seu modo de jogo foi alterado para {game_mode}." #Shown when a game mode switch is prevented during combat. no-switch: "Você não tem permissão para mudar o modo de jogo durante o combate." flight: #Shown when a player's ability to fly is disabled during combat. force-disabled: "Sua habilidade de voar foi removida." #Shown when a player's attempt to fly is prevented during combat. no-flying: "Você não pode voar durante o combate." elytra: #Shown when a player's ability to glide is disabled during combat. force-disabled: "Seu elytra foi desativado." #Shown when a player's attempt to glide is prevented during combat. no-gliding: "Você não tem permissão para usar elytra durante o combate." teleportation: #Shown when a player tries to enter a portal and is prevented during combat. block-portal: "Você não tem permissão para usar um portal durante o combate." #Shown when an ender pearl is prevented during combat. block-pearl: "Você não tem permissão para usar pérolas do ender durante o combate." #Shown when a teleport is prevented during combat. block-other: "Você não tem permissão para se teleportar durante o combate." inventory: #Shown when a player's inventory is closed by the plugin during combat. force-closed: "Seu inventário foi fechado." #Shown when a player tries to open an inventory and is prevented during combat. no-opening: "Você não tem permissão para abrir inventário durante o combate." blocks: #Shown when a player is prevented from breaking a block during combat. prevent-breaking: "Você não pode quebrar blocos durante o combate." #Shown when a player is prevented from breaking a block during combat. prevent-placing: "Você não pode colocar blocos durante o combate." #Shown when a player is prevented from breaking a block during combat. prevent-interaction: "Você não tem permissão para usar blocos durante o combate." #Shown when a player is prevented from breaking a block during combat. prevent-portal-creation: "Você não pode criar portais durante o combate." items: #Shown when a player is prevented from picking up an item during combat. no-pickup: "Você não tem permissão para pegar itens durante o combate." #Shown when a player is prevented from dropping an item during combat. no-dropping: "Você não tem permissão para soltar itens durante o combate." buckets: #Shown when a player is prevented from emptying a bucket during combat. no-empty: "Você não pode esvaziar baldes durante o combate." #Shown when a player is prevented from filling a bucket during combat. no-fill: "Você não pode encher baldes durante o combate." damage-tagger: #Shown when a player is tagged for an unknown damage type. unknown-damage: "Você levou dano! Não desconecte!" #These messages are shown when a player is tagged for a known damage type. #You can find a list of damage types here: #https://hub.spigotmc.org/javadocs/spigot/org/bukkit/event/entity/EntityDamageEvent.DamageCause.html damage-type: contact: "Você foi espetado por um cacto. Não desconecte!" suffocation: "Você está sufocando em uma parede. Não desconecte!" fall: "Você sofreu dano de queda. Não se desconecte!" fire: "Você entrou em fogo. Não desconecte!" fire-tick: "Você está queimando. Não desconecte!" lava: "Você está fervendo na lava. Não desconecte!" drowning: "Você está se afogando. Não desconecte!" block-explosion: "Você foi danificado por uma explosão. Não se desconecte!" lightning: "Você foi ferido! Não saia daqui!" starvation: "Você está com muita fome. Não desconecte!" poison: "Você sofreu dano de vendimento. Não se desconecte!" magic: "Alguém lançou uma poção em você. Não se desconecte!" wither: "Você está vindo. Não desconecte!" falling-block: "Um bloco caiu em você. Não faça loging!" custom: "Você sofreu dano personalizado. Não se desconecte!" fly-into-wall: "Você experimentou energia cinética. Não se desconecte!" hot-floor: "O chão é uma lava! Não desconecte!" cramming: "Você está sendo esmagado. Não desconecte!" newbie-helper: togglepvp: #Shown as the command output for '/togglepvp'. self: "PVP: {status}" #Shown as the command output for '/togglepvp admin on/off '. admin: "Você alterou o pvp de {target} para {status}." #Shown when the '/togglepvp' command is on cooldown. cooldown: "Você deve esperar {time_left} segundos para usar este comando novamente." #These messages are shown when pvp is disabled for any reason. no-pvp: self: "Você não tem permissão para acertar este jogador enquanto seu PvP estiver desativado." other: "Este jogador está com o PvP desativado." protected: "Esse jogador está protegido, você ainda não tem permissão para atacá-lo!" protection-disabled: #Shown when newbie protection is disabled due to the player attacking another player. attacker: "Você atacou alguém, sua proteção de iniciante está desativada agora." #Shown when newbie protection expires. expired: "Sua proteção de iniciante expirou." #Shown for the '/togglepvp check ' command. check-format: - "Informações para {target}:" - "Proteção: {protected}" - "PvP: {pvp}" loot-protection: #Shown when an enemy dies and their loot is protected. enemy-died: "{enemy} morreu. Saque será protegido por {time} segundos." #Shown when a player tries to pick up an item that is loot protected by the plugin. protected: "Este item está atualmente protegido, espere {time} segundos até que você possa pegá-lo." citizens-compatibility: #Shown when a player is prevented from joining the server due to their NPC still existing. prevent-join: "Você não tem permissão para entrar no servidor até que seu NPC seja morto ou removido." disguise-compatibility: #Shown when a disguise is removed from a player during combat. remove-disguise: "Seu disfarce foi removido." essentials-compatibility: #Shown when a teleport request is cancelled during combat. prevent-teleport-request-self: "Você não pode criar solicitações de teleporte durante o combate." #Shown when a teleport request is cancelled during combat. prevent-teleport-request-other: "Você não pode enviar uma solicitação de teleporte para um jogador que está em combate." marriagemaster-compatibility: #Shown when a married player is prevented from teleporting to their partner during combat. prevent-teleport-self: "Você não tem permissão para teleportar seu parceiro durante o combate." #Shown when a married player is prevented from teleporting to their partner during combat. prevent-teleport-partner: "Você não tem permissão para teletransportar seu parceiro enquanto ele estiver em combate." region-protection: #Shown when a player tries to enter a no-pvp area during combat. default-no-entry: "Você não tem permissão para entrar nessa área durante o combate." factions-no-entry: Você não tem permissão para entrar nessa área durante o combate. griefdefender-no-entry: Você não tem permissão para entrar nessa área durante o combate. griefprevention-no-entry: Você não tem permissão para entrar nessa área durante o combate. kingdomsx-no-entry: Você não tem permissão para entrar nessa área durante o combate. konquest-no-entry: Você não tem permissão para entrar nessa área durante o combate. redprotect-no-entry: Você não tem permissão para entrar nessa área durante o combate. residence-no-entry: Você não tem permissão para entrar nessa área durante o combate. towny-no-entry: Você não tem permissão para entrar nessa área durante o combate. husktowns-no-entry: Você não tem permissão para entrar nessa área durante o combate. ultimateclaims-no-entry: Você não tem permissão para entrar nessa área durante o combate. protectionstones: prevent-area-creation: "Você não tem permissão para criar uma área protegida durante o combate." no-entry: Você não tem permissão para entrar nessa área durante o combate. preciousstones: prevent-field-creation: "Você não tem permissão para criar um campo de proteção durante o combate." no-entry: Você não tem permissão para entrar nessa área durante o combate. worldguard: no-entry-mob-combat: "Você não tem permissão para entrar em uma área de combate de mobs durante o combate." no-entry-player-combat: "Você não pode entrar em uma área de combate não-jogador durante o combate." no-entry-unknown-combat: Você não tem permissão para entrar nessa área durante o combate. lands: no-entry: Você não tem permissão para entrar nessa área durante o combate. war-disable-newbie-protection: "PvP agora é ativado em força devido a uma declaração de guerra." ================================================ FILE: plugin/src/main/resources/language/pt_pt.lang.yml ================================================ --- ## Extra Information: ## This is the default language file for CombatLogX. ## The default language is "en_us", also known as English (United States). ## Context will be added as YAML comments above the string. ## The color scheme for messages is gold, white, and sometimes red. ## Command feedback that is successful should always be green. ## Error messages should always be red. ## Variables in messages can be gray or white. ## Messages use the MiniMessage format in non-strict mode. ## More information about MiniMessage can be found here: ## https://docs.adventure.kyori.net/minimessage/format.html #The language code for this file. language-name: "pt_pt" #The format for decimal numbers. #The United States uses the number and two decimal places decimal-format: "0.00" #The prefix for CombatLogX that is shown in front of all messages. #Note to translators: Do not change this message. prefix: "[CombatLogX]" broadcast: #Shown when the plugin is finished loading. on-load: "CombatLogX foi carregado com sucesso." #Shown when the plugin is finished enabling. on-enable: "CombatLogX foi ativado com sucesso." #Shown when the plugin is disabled for any reason. on-disable: "CombatLogX foi desativado com sucesso." placeholder: #This text is used for the {combatlogx_time_left} #This allows server configurations to change the display value of the zero to something like "Not in combat" time-left-zero: "0" #This text is used when a player does not have an enemy. #This can happen when players are tagged by a custom expansion or the tag command. unknown-enemy: "Desconhecido" status: #Shown when the player is in combat. fighting: "Brigando" in-combat: "Sim" #Shown when the player is not in combat idle: "Inativo" not-in-combat: "Não" #These placeholders are shown when a player changes a value such as whether or not their bossbar is enabled. toggle: enabled: "§aLigado" disabled: "§cDesligado" pvp-status: enabled: "§aLigado" disabled: "§cDesligado" #You can also change the location of these messages. #Example: #combat-timer: #expire: #type: ACTION_BAR #content: "" combat-timer: #Sent to a player when they escape from combat due to the timer running out. expire: "Você não está mais em combate." #Sent to a player when they escape from combat due to their enemy being killed. enemy-death: "Você não está mais em combate porque seu inimigo morreu." #Sent when a player is killed during combat. self-death: "Você não está mais em combate porque você morreu." error: #Shown when the console tries to execute a command made for players. player-only: "Apenas jogadores podem executar este comando." #Shown when a player tries to execute a command made for the server console. console-only: "Este comando só pode ser executado no console do servidor." #Shown when a command that requires a player has invalid input. invalid-target: "{target} não está online ou não existe." #Shown when a command that requires a number has invalid input. invalid-integer: "{value} não é um inteiro válido." #Shown when a player does not have access to something that requires a permission. no-permission: "Permissão ausente: {permission}" #Shown when a player executes a command in a world that is disabled in the configuration. disabled-world: "Esse comando não está disponível nesta dimensão." #Shown when a command requires a player in combat but the target player is not in combat. target-not-in-combat: "{target} não está em combate." #Shown when a player executes a command that requires them to be in combat. self-not-in-combat: "Você não está em combate." #Shown when a command that requires an expansion has invalid input. unknown-expansion: "{target} não é uma expansão ou não está instalado." forgive-not-enemy: "{target} não é um dos seus inimigos." enemy-not-forgiving: "Esse inimigo não tem vontade de perdoá-lo." command: combatlogx: #Shown as the command output for '/combatlogx help'. help-message-list: - "" - "Comandos CombatalogX:" - " /combatlogx help: Veja esta página de ajuda." - " /combatlogx reload: Recarregue os arquivos config.yml, language.yml e todos os arquivos de configuração de expansão." - " /combatlogx about \\: Verifique as informações sobre uma expansão." - " /combatlogx tag \\: Força um jogador para o combate." - " /combatlogx toggle bossbar/actionbar/scoreboard: Ativar ou desativar um tipo de notificação." - " /combatlogx untag \\: Forçar um jogador a sair do combate." - " /combatlogx version: Verifique a sua versão do CombatLogX." - " /combatlogx forgive request \\: Enviar um pedido a um inimigo para remover a sua tag." - " /combatlogx forgive accept \\: Aceitar o pedido de um inimigo de escapar de combate." - " /combatlogx forgive accept \\: Ignorar o pedido de um inimigo de escapar de combate." - " /combatlogx forgive toggle: Ativar ou desativar pedidos para parar o combate." - "" #Shown as the command output for '/combatlogx reload' when reloading is successful. reload-success: - "Recarregou com sucesso todos os arquivos de configuração do CombatLogX." - "Recarregou com sucesso todos os arquivos de idioma do CombatLogX." - "Recarregou com sucesso todos os arquivos de configuração das expansões CombatLogX." #Shown as the command output for '/combatlogx reload' when reloading fails reload-failure: - "Ocorreu um erro ao recarregar a configuração." - "Por favor, verifique o log do servidor e corrija o arquivo quebrado." #Shown as the command output for '/combatlogx tag ' when a player is tagged successfully. tag-player: "Forçou com sucesso o jogador {target} para o combate." #Shown as the command output for '/combatlogx tag ' when the plugin failed to tag a player. tag-failure: "{target} não poderia ser colocado em combate. (Talvez eles tenham um bypass?)" #Shown as the command output for '/combatlogx untag '. untag-player: "Forçou com sucesso o jogador {target} para fora do combate." #Shown as the command output for '/combatlogx toggle bossbar'. toggle-bossbar: "Barra de chefe: {status}" #Shown as the command output for '/combatlogx toggle actionbar'. toggle-actionbar: "Barra de ação: {status}" #Shown as the command output for '/combatlogx toggle scoreboard'. toggle-scoreboard: "Placar: {status}" #Shown as the command output for '/combatlogx about '. expansion-information: - "" - "Informação de expansão para {name}:" - "Nome de Exibição: {prefix}" - "Versão: {version}" - "Estado: {state}" - "" - "Descrição: {description}" - "Site: {website}" - "Autores: {authors}" forgive: toggle-disable: "Não pode mais receber pedidos de perdão." toggle-enable: "Pode agora receber pedidos de perdão." request-sent: "Enviou um pedido de perdão para {target}." request-receive: - "{player} enviou um pedido de perdão." - "Escreva /clx forgive accept para aceitar ou." - "/clx forgive reject para rejeitar." combat-timer: #Shown as the command output for '/combat-timer'. time-left-self: "Tem {time_left} segundos restantes." #Shown as the command output for '/combat-timer '. time-left-other: "{target} tem {time_left} segundos restantes." #These messages are shown a player is tagged into combat. #You can also change the location of these messages. #Example: #tagged: #attacked: #player: #type: ACTION_BAR #content: "" tagged: unknown: player: "Agora você está em combate com {enemy} por uma razão desconhecida. Não desconecte!" mob: "Você agora está em combate com um (n) {enemy} por um motivo desconhecido. Não se desconecte!" mythic_mob: "Você agora está em combate com um (n) {mob_type} por um motivo desconhecido. Não se desconecte!" damage: "Você agora está em combate devido a tomar dano. Não se desconecte!" unknown: "Você foi colocado em combate sem um motivo. Não sair." attacked: player: "Você está sendo atacado por {enemy}. Não saia!" mob: "Você está sendo atacado por um {mob_type}. Não saiaout!" mythic_mob: "Você está sendo atacado por um (n) {enemy}. Não desconecte!" damage: "Você agora está em combate devido a tomar dano. Não se desconecte!" unknown: "Você está sendo atacado por uma força desconhecida. Não desconecte!" attacker: player: "Você está atacando {enemy}. Não saia!" mob: "Você está atacando um {mob_type}. Não saia!" mythic_mob: "Você está atacando um(n) {enemy}. Não faça loging!" damage: "Você agora está em combate devido a tomar dano. Não se desconecte!" unknown: "Você está atacando uma força desconhecida. Não desconecte!" expansion: angel-chest: #Shown when opening an AngelChest is prevented during combat. prevent-opening: "Você não tem permissão para abrir baús de anjo durante o combate." #Shown when breaking an AngelChest is prevented during combat. prevent-breaking: "Você não tem permissão para quebrar baús de anjo durante o combate." #Shown when fast looting an AngelChest is prevented during combat. prevent-fast-looting: "Você não tem permissão para saquear baús de anjos rapidamente durante o combate." action-bar: #Shown above the hotbar while a player is in combat. timer: "Combate \u00BB {bars} {combatlogx_time_left} segundos." #Shown above the hotbar for a brief period when combat ends. ended: "Combate \u00BB Você não está mais em combate." boss-bar: #Shown on top of the screen while a player is in combat. timer: "Combate \u00BB {combatlogx_time_left} segundos." #Shown on top of the screen for a brief period when combat ends. ended: "Combate \u00BB Você não está mais em combate." scoreboard: #The scoreboard title for the sidebar. #Make sure to follow the scoreboard title limits for your Spigot version. title: "CombatLogX" #The scoreboard lines for the sidebar. #Make sure to follow the scoreboard line and character limits for your Spigot version. lines: - " " - "Estatísticas de Combate:" - "\u00BB Tempo restante: {combatlogx_time_left}" - "\u00BB Enemies: {combatlogx_enemy_count}" - "\u00BB Estado: {combatlogx_status}" - " " - "Enemies" - "\u00BB {combatlogx_specific_enemy_1_name}" - "\u00BB {combatlogx_specific_enemy_2_name}" - "\u00BB {combatlogx_specific_enemy_3_name}" - " " cheat-prevention: #Shown when a command execution is prevented during combat. command-blocked: "Você não tem acesso a {command} durante o combate." #Shown when the riptide effect is prevented during combat. no-riptide: "O encantamento da correnteza é desativado durante o combate." #Shown when a totem of undying is prevented during combat. no-totem: "Você não tem permissão para usar totens de imortalidade durante o combate." #Shown when an entity interaction is prevented during combat. no-entity-interaction: "Você não tem permissão para usar esse mob durante o combate." #Shown when a chat message is prevented during combat. no-chat: "Você não tem permissão para enviar mensagens de bate-papo durante o combate." game-mode: #Shown when a player is forced into a specific game mmode during combat. force-switch: "Seu modo de jogo foi alterado para {game_mode}." #Shown when a game mode switch is prevented during combat. no-switch: "Você não tem permissão para mudar os modos de jogo durante o combate." flight: #Shown when a player's ability to fly is disabled during combat. force-disabled: "Sua habilidade de voar foi removida." #Shown when a player's attempt to fly is prevented during combat. no-flying: "Você não tem permissão para voar durante o combate." elytra: #Shown when a player's ability to glide is disabled during combat. force-disabled: "Seu élitros foi desativado." #Shown when a player's attempt to glide is prevented during combat. no-gliding: "Você não tem permissão para usar o élitros durante o combate." teleportation: #Shown when a player tries to enter a portal and is prevented during combat. block-portal: "Você não tem permissão para se teletransportar durante o combate." #Shown when an ender pearl is prevented during combat. block-pearl: "Você não tem permissão para usar pérolas ender durante o combate." #Shown when a teleport is prevented during combat. block-other: "Você não tem permissão para se teletransportar durante o combate." inventory: #Shown when a player's inventory is closed by the plugin during combat. force-closed: "Seu inventário foi fechado." #Shown when a player tries to open an inventory and is prevented during combat. no-opening: "Você não tem permissão para abrir inventários durante o combate." blocks: #Shown when a player is prevented from breaking a block during combat. prevent-breaking: "Você não tem permissão para quebrar blocos durante o combate." #Shown when a player is prevented from breaking a block during combat. prevent-placing: "Você não tem permissão para colocar blocos durante o combate." #Shown when a player is prevented from breaking a block during combat. prevent-interaction: "Você não tem permissão para usar blocos durante o combate." #Shown when a player is prevented from breaking a block during combat. prevent-portal-creation: "Você não tem permissão para se teletransportar durante o combate." items: #Shown when a player is prevented from picking up an item during combat. no-pickup: "Você não tem permissão para pegar itens durante o combate." #Shown when a player is prevented from dropping an item during combat. no-dropping: "Você não tem permissão para largar itens durante o combate." buckets: #Shown when a player is prevented from emptying a bucket during combat. no-empty: "Você não pode despejar baldes durante o combate." #Shown when a player is prevented from filling a bucket during combat. no-fill: "Você não pode encher baldes durante o combate." damage-tagger: #Shown when a player is tagged for an unknown damage type. unknown-damage: "Você sofreu danos! Não saia!" #These messages are shown when a player is tagged for a known damage type. #You can find a list of damage types here: #https://hub.spigotmc.org/javadocs/spigot/org/bukkit/event/entity/EntityDamageEvent.DamageCause.html damage-type: block-explosion: "Você foi danificado por uma explosão. Não saia!" contact: "Você foi picado por um cacto. Não saia!" cramming: "Você está sendo esmagado. Não saia!" custom: "Você sofreu danos personalizados. Não saia!" drowning: "Você está se afogando. Não saia!" dryout: "Você ficou sem água por muito tempo. Não desconecte" #May be triggered by custom plugins. entity-explosion: "Você recebeu dano da explosão do Cristal do Fim. Não se desconecte!" #Only triggered by end crystals. fall: "Você sofreu danos de queda. Não saia!" falling-block: "Um bloco caiu sobre você. Não saia!" fire: "Você entrou no fogo. Não saia!" fire-tick: "Você está queimando. Não saia!" fly-into-wall: "Você experimentou energia cinética. Não saia!" freeze: "Você está congelando. Não desconecte!" hot-floor: "O chão é lava! Não saia!" lava: "Você está fervendo na lava. Não saia!" lightning: "Você foi ferido! Não saia!" magic: "Alguém jogou uma poção em você. Não saia!" melting: "Você está derretendo! Não desconecte." #May be triggered by custom plugins. poison: "Você sofreu dano de veneno. Não saia!" starvation: "Você está com muita fome. Não saia!" suffocation: "Você está sufocando em uma parede. Não saia!" void: "Você está caindo no vazio. Não desconecte!" wither: "Você está murchando. Não saia!" world-border: "Você está muito perto da borda. Não desconecte!" newbie-helper: togglepvp: #Shown as the command output for '/togglepvp'. self: "PVP: {status}" #Shown as the command output for '/togglepvp admin on/off '. admin: "Você alterou o pvp de {target} para {status}." #Shown when the '/togglepvp' command is on cooldown. cooldown: "Você deve esperar {time_left} segundos para usar este comando novamente." #These messages are shown when pvp is disabled for any reason. no-pvp: self: "Você não tem permissão para acertar aquele jogador enquanto seu PvP estiver desabilitado." other: "Esse jogador tem PvP desativado." protected: "Esse jogador está protegido, você não tem permissão para atacá-lo ainda!" protection-disabled: #Shown when newbie protection is disabled due to the player attacking another player. attacker: "Você atacou alguém, sua proteção de novato agora está desativada." #Shown when newbie protection expires. expired: "Sua proteção para novatos expirou." #Shown for the '/togglepvp check ' command. check-format: - "Informação para {target}:" - "Proteção: {protected}" - "PvP: {pvp}" loot-protection: #Shown when an enemy dies and their loot is protected. enemy-died: "{enemy} está morto. Os objetos serão protegidos por {time} segundos." #Shown when a player tries to pick up an item that is loot protected by the plugin. protected: "Este item está protegido no momento, aguarde {time} segundos até que você possa pegá-lo." citizens-compatibility: #Shown when a player is prevented from joining the server due to their NPC still existing. prevent-join: "Você não tem permissão para entrar no servidor até que seu NPC seja morto ou desinvocado." disguise-compatibility: #Shown when a disguise is removed from a player during combat. remove-disguise: "Seu disfarce foi removido." essentials-compatibility: #Shown when a teleport request is cancelled during combat. prevent-teleport-request-self: "Você não pode criar solicitações de teletransporte durante o combate." #Shown when a teleport request is cancelled during combat. prevent-teleport-request-other: "Você não pode enviar uma solicitação de teletransporte para um jogador que está em combate." marriagemaster-compatibility: #Shown when a married player is prevented from teleporting to their partner during combat. prevent-teleport-self: "Você não tem permissão para teleportar seu parceiro durante o combate." #Shown when a married player is prevented from teleporting to their partner during combat. prevent-teleport-partner: "Você não tem permissão para teletransportar seu parceiro enquanto ele estiver em combate." huskhomes-compatibility: prevent-teleport: "Você não tem permissão para se teletransportar durante o combate." region-protection: #Shown when a player tries to enter a no-pvp area during combat. default-no-entry: "Você não tem permissão para entrar nessa área durante o combate." factions-no-entry: Você não tem permissão para entrar nessa área durante o combate. griefdefender-no-entry: Você não tem permissão para entrar nessa área durante o combate. griefprevention-no-entry: Você não tem permissão para entrar nessa área durante o combate. kingdomsx-no-entry: Você não tem permissão para entrar nessa área durante o combate. konquest-no-entry: Você não tem permissão para entrar nessa área durante o combate. redprotect-no-entry: Você não tem permissão para entrar nessa área durante o combate. residence-no-entry: Você não tem permissão para entrar nessa área durante o combate. towny-no-entry: Você não tem permissão para entrar nessa área durante o combate. husktowns-no-entry: Você não tem permissão para entrar nessa área durante o combate. ultimateclaims-no-entry: Você não tem permissão para entrar nessa área durante o combate. protectionstones: prevent-area-creation: "Você não pode criar um campo de proteção durante o combate." no-entry: Você não tem permissão para entrar nessa área durante o combate. preciousstones: prevent-field-creation: "Você não pode criar um campo de proteção durante o combate." no-entry: Você não tem permissão para entrar nessa área durante o combate. worldguard: no-entry-mob-combat: "Você não tem permissão para entrar em uma área de combate sem mob durante o combate." no-entry-player-combat: "Você não tem permissão para entrar em uma área de combate de não jogadores durante o combate." no-entry-unknown-combat: Você não tem permissão para entrar nessa área durante o combate. lands: no-entry: Você não tem permissão para entrar nessa área durante o combate. war-disable-newbie-protection: "PvP agora é ativado em força devido a uma declaração de guerra." ================================================ FILE: plugin/src/main/resources/language/ru_ru.lang.yml ================================================ --- ## Extra Information: ## This is the default language file for CombatLogX. ## The default language is "en_us", also known as English (United States). ## Context will be added as YAML comments above the string. ## The color scheme for messages is gold, white, and sometimes red. ## Command feedback that is successful should always be green. ## Error messages should always be red. ## Variables in messages can be gray or white. ## Messages use the MiniMessage format in non-strict mode. ## More information about MiniMessage can be found here: ## https://docs.adventure.kyori.net/minimessage/format.html #The language code for this file. language-name: "rus_RU" #The format for decimal numbers. #The United States uses the number and two decimal places decimal-format: "0,00" #The prefix for CombatLogX that is shown in front of all messages. #Note to translators: Do not change this message. prefix: "[CombatLogX]" broadcast: #Shown when the plugin is finished loading. on-load: "CombatLogX был успешно загружен." #Shown when the plugin is finished enabling. on-enable: "CombatLogX был успешно включен." #Shown when the plugin is disabled for any reason. on-disable: "CombatLogX был успешно отключен." placeholder: #This text is used for the {combatlogx_time_left} #This allows server configurations to change the display value of the zero to something like "Not in combat" time-left-zero: "0" #This text is used when a player does not have an enemy. #This can happen when players are tagged by a custom expansion or the tag command. unknown-enemy: "Неизвестно" status: #Shown when the player is in combat. fighting: "В бою" in-combat: "Да" #Shown when the player is not in combat idle: "Бездействует" not-in-combat: "Нет" #These placeholders are shown when a player changes a value such as whether or not their bossbar is enabled. toggle: enabled: "ВКЛ." disabled: "ВЫКЛ." pvp-status: enabled: "ВКЛ." disabled: "ВЫКЛ." #You can also change the location of these messages. #Example: #combat-timer: #expire: #type: ACTION_BAR #content: "" combat-timer: #Sent to a player when they escape from combat due to the timer running out. expire: "Вы вышли из боя." #Sent to a player when they escape from combat due to their enemy being killed. enemy-death: "Вы вышли из боя, потому что ваш противник погиб." #Sent when a player is killed during combat. self-death: "Вы вышли из боя, потому что умерли." error: #Shown when the console tries to execute a command made for players. player-only: "Только игроки могут использовать эту команду" #Shown when a player tries to execute a command made for the server console. console-only: "Эта команда может быть использована только в консоли." #Shown when a command that requires a player has invalid input. invalid-target: "{target} не в сети или не существует." #Shown when a command that requires a number has invalid input. invalid-integer: "{value} не является целым числом." #Shown when a player does not have access to something that requires a permission. no-permission: "Отсутствует право: {permission}" #Shown when a player executes a command in a world that is disabled in the configuration. disabled-world: "Данная команда недоступна в этом измерении." #Shown when a command requires a player in combat but the target player is not in combat. target-not-in-combat: "{target} не участвует в бое." #Shown when a player executes a command that requires them to be in combat. self-not-in-combat: "Вы не участвуете в бое." #Shown when a command that requires an expansion has invalid input. unknown-expansion: "{target} не является установленным расширением." forgive-not-enemy: "{target} не ваш противник." enemy-not-forgiving: "Этот противник не в настроении, чтобы прощать вас." command: combatlogx: #Shown as the command output for '/combatlogx help'. help-message-list: - "" - "Справка по командам CombatLogX:" - " /combatlogx help: Посмотреть эту справку." - " /combatlogx reload: Перезагрузка config.yml, language.yml, и всех конфигурационных файлов расширений." - " /combatlogx about \\<расширение>: Проверить информацию о расширении." - " /combatlogx tag \\<игрок> [секунды]: Принудить игрока вступить в бой." - " /combatlogx toggle bossbar/actionbar/scoreboard: Переключить уведомления." - " /combatlogx untag \\<игрок>: Принудительно вывести игрока из боя." - " /combatlogx version: Проверить текущую версию CombatLogX." - " /combatlogx forgive request \\<игрок>: Отправить противнику запрос на отмену боя." - " /combatlogx forgive accept \\<игрок>: Принять запрос противника на отмену боя." - " /combatlogx forgive reject \\<игрок>: Отклонить запрос противника на отмену боя." - " /combatlogx forgive toggle: Переключить прием запросов на отмену боя." - "" #Shown as the command output for '/combatlogx reload' when reloading is successful. reload-success: - "Успешно перезагружены все файлы конфигурации CombatLogX." - "Успешно перезагружены все файлы локализации CombatLogX." - "Успешно перезагружены все файлы конфигурации расширений CombatLogX." #Shown as the command output for '/combatlogx reload' when reloading fails reload-failure: - "При перезагрузке конфигурации произошла ошибка." - "Пожалуйста, проверьте журнал сервера и исправьте испорченный файл" #Shown as the command output for '/combatlogx tag ' when a player is tagged successfully. tag-player: "Принуждение игрока {target} в бой прошло успешно." #Shown as the command output for '/combatlogx tag ' when the plugin failed to tag a player. tag-failure: "{target} не может быть введен в бой. (Имеет права обхода?)" #Shown as the command output for '/combatlogx untag '. untag-player: "{target} успешно выведен из боя." #Shown as the command output for '/combatlogx toggle bossbar'. toggle-bossbar: "Боссбар: {status}" #Shown as the command output for '/combatlogx toggle actionbar'. toggle-actionbar: "Панель действий: {status}" #Shown as the command output for '/combatlogx toggle scoreboard'. toggle-scoreboard: "Скорборд: {status}" #Shown as the command output for '/combatlogx about '. expansion-information: - "" - "Информация о расширении {name}:" - "Отображаемое имя: {prefix}" - "Версия: {version}" - "Состояние: {state}" - "" - "Описание: {description}" - "Вебсайт: {website}" - "Авторы: {authors}" forgive: toggle-disable: "Вы больше не будете получать запросы на прощение." toggle-enable: "Теперь вы будете получать запросы на прощение." request-sent: "Вы отправили запрос на прощение {target}." request-receive: - "{player} отправил вам запрос на прощение." - "Введите /clx forgive accept для принятия или" - "/clx forgive reject для отказа." combat-timer: #Shown as the command output for '/combat-timer'. time-left-self: "У вас осталось {time_left} секунд." #Shown as the command output for '/combat-timer '. time-left-other: "{target} осталось {time_left} секунд." #These messages are shown a player is tagged into combat. #You can also change the location of these messages. #Example: #tagged: #attacked: #player: #type: ACTION_BAR #content: "" tagged: unknown: player: "Вы находитесь в бою с {enemy} по неизвестной причине. Не выходите из игры!" mob: "Вы находитесь в бою с {enemy} по неизвестной причине. Не выходите из игры!" mythic_mob: "Вы находитесь в бою с {mob_type} по неизвестной причине. Не выходите из игры!" damage: "Вы находитесь в бою из-за нанесенного урона. Не выходите из игры!" unknown: "Вы попали в бой без причины. Не выходите из игры." attacked: player: "Вы были атакованы {enemy}. Не выходите из игры!" mob: "Вы были атакованы {mob_type}. Не выходите из игры!" mythic_mob: "Вы были атакованы {enemy}. Не выходите из игры!" damage: "Вы находитесь в бою из-за нанесенного урона. Не выходите из игры!" unknown: "Вы были атакованы неизвестной силой. Не выходите из игры!" attacker: player: "Вы атаковали {enemy}. Не выходите из игры!" mob: "Вы атаковали {mob_type}. Не выходите из игры!" mythic_mob: "Вы атаковали {enemy}. Не выходите из игры!" damage: "Вы находитесь в бою из-за нанесенного урона. Не выходите из игры!" unknown: "Вы атакуете неизвестную силу. Не выходите из игры!" expansion: angel-chest: #Shown when opening an AngelChest is prevented during combat. prevent-opening: "Вы не можете открывать ангельские сундуки во время боя." #Shown when breaking an AngelChest is prevented during combat. prevent-breaking: "Вы не можете ломать ангельские сундуки во время боя." #Shown when fast looting an AngelChest is prevented during combat. prevent-fast-looting: "Вы не можете использовать ангельские сундуки во время боя." action-bar: #Shown above the hotbar while a player is in combat. timer: "Бой \u00BB {bars} {combatlogx_time_left} секунд." #Shown above the hotbar for a brief period when combat ends. ended: "Боя \u00BB Вы вышли из боя." boss-bar: #Shown on top of the screen while a player is in combat. timer: "Бой \u00BB {combatlogx_time_left} секунд." #Shown on top of the screen for a brief period when combat ends. ended: "Combat \u00BB Вы вышли из боя." scoreboard: #The scoreboard title for the sidebar. #Make sure to follow the scoreboard title limits for your Spigot version. title: "CombatLogX" #The scoreboard lines for the sidebar. #Make sure to follow the scoreboard line and character limits for your Spigot version. lines: - " " - "Статистика боев:" - "\u00BB Оставшееся время: {combatlogx_time_left}" - "\u00BB Противников: {combatlogx_enemy_count}" - "\u00BB Статус: {combatlogx_status}" - " " - "Противники" - "\u00BB {combatlogx_specific_enemy_1_name}" - "\u00BB {combatlogx_specific_enemy_2_name}" - "\u00BB {combatlogx_specific_enemy_3_name}" - " " cheat-prevention: #Shown when a command execution is prevented during combat. command-blocked: "У вас нет доступа к {command} во время боя." #Shown when the riptide effect is prevented during combat. no-riptide: "Зачарование \"Тягун\" недоступно во время боя." #Shown when a totem of undying is prevented during combat. no-totem: "Вы не можете использовать тотемы бессмертия во время боя." #Shown when an entity interaction is prevented during combat. no-entity-interaction: "Вы не можете использовать этого моба во время боя." #Shown when a chat message is prevented during combat. no-chat: "Вы не можете отправлять сообщения во время боя." game-mode: #Shown when a player is forced into a specific game mmode during combat. force-switch: "Ваш игровой режим был изменен на {game_mode}." #Shown when a game mode switch is prevented during combat. no-switch: "Вы не можете переключать игровой режим во время боя." flight: #Shown when a player's ability to fly is disabled during combat. force-disabled: "Ваша возможность летать снята." #Shown when a player's attempt to fly is prevented during combat. no-flying: "Вы не можете летать во время боя." elytra: #Shown when a player's ability to glide is disabled during combat. force-disabled: "Ваши элитры были отключены." #Shown when a player's attempt to glide is prevented during combat. no-gliding: "Вы не можете использовать элитры во время боя." #Shown when a player tries to use fireworks. no-fireworks: "Вы не можете запускать фейерверки во время боя." teleportation: #Shown when a player tries to enter a portal and is prevented during combat. block-portal: "Вы не можете использовать портал во время боя." #Shown when an ender pearl is prevented during combat. block-pearl: "Вы не можете использовать эндер-жемчуг во время боя." #Shown when a teleport is prevented during combat. block-other: "Вы не можете телепортироваться во время боя." inventory: #Shown when a player's inventory is closed by the plugin during combat. force-closed: "Ваш инвентарь был закрыт." #Shown when a player tries to open an inventory and is prevented during combat. no-opening: "Вы не можете открывать инвентари во время боя." blocks: #Shown when a player is prevented from breaking a block during combat. prevent-breaking: "Вы не можете ломать блоки во время боя." #Shown when a player is prevented from breaking a block during combat. prevent-placing: "Вы не можете ставить блоки во время боя." #Shown when a player is prevented from breaking a block during combat. prevent-interaction: "Вы не можете использовать блоки во время боя." #Shown when a player is prevented from breaking a block during combat. prevent-portal-creation: "Вы не можете создавать порталы во время боя." items: #Shown when a player is prevented from picking up an item during combat. no-pickup: "Вы не можете подбирать предметы во время боя." #Shown when a player is prevented from dropping an item during combat. no-dropping: "Вы не можете выбрасывать предметы во время боя." buckets: #Shown when a player is prevented from emptying a bucket during combat. no-empty: "Вы не можете опустошать вёдра во время боя." #Shown when a player is prevented from filling a bucket during combat. no-fill: "Вы не можете набирать вёдра во время боя." damage-tagger: #Shown when a player is tagged for an unknown damage type. unknown-damage: "Вы получили урон! Не выходите из игры!" #These messages are shown when a player is tagged for a known damage type. #You can find a list of damage types here: #https://hub.spigotmc.org/javadocs/spigot/org/bukkit/event/entity/EntityDamageEvent.DamageCause.html damage-type: block-explosion: "Вы получили урон от взрыва. Не выходите из игры!" contact: "Вы укололись об кактус. Не выходите из игры!" cramming: "Вас расплющивает. Не выходите из игры!" custom: "Вы получили нестандартный урон. Не выходите из игры!" drowning: "Вы тоните. Не выходите из игры!" dryout: "Вы находились вне воды слишком долго. Не выходите из игры!" #May be triggered by custom plugins. entity-explosion: "Вас задел взрыв кристалла Энда. Не выходите из игры!" #Only triggered by end crystals. fall: "Вы получили урон от падения. Не выходите из игры!" falling-block: "На вас упал блок. Не выходите из игры!" fire: "Вы вошли в огонь. Не выходите из игры!" fire-tick: "Вы горите. Не выходите из игры!" fly-into-wall: "Вы врезались о стену. Не выходите из игры!" freeze: "Вы замерзаете. Не выходите из игры!" hot-floor: "Пол это лава! Не выходите!" lava: "Вы горите в лаве. Не выходите из игры!" lightning: "Вас поразило молнией! Не выходите из игры!" magic: "Кто-то бросил в вас зелье. Не выходите из игры!" melting: "Вы таете. Не выходите из игры!" #May be triggered by custom plugins. poison: "Вы получили урон от отравления. Не выходите из игры!" starvation: "Вы слишком голодны. Не выходите из игры!" suffocation: "Вы задыхаетесь в стене. Не выходите из игры!" void: "Вы падаете в бездну. Не выходите из игры!" wither: "Вас иссыхаете. Не выходите из игры!" world-border: "Вы слишком близко от границы мира. Не выходите из игры!" newbie-helper: togglepvp: #Shown as the command output for '/togglepvp'. self: "ПвП: {status}" #Shown as the command output for '/togglepvp admin on/off '. admin: "Вы изменили возможность ПвП {target} на {status}." #Shown when the '/togglepvp' command is on cooldown. cooldown: "Вы должны подождать {time_left} секунд, прежде чем использовать эту команду снова." #These messages are shown when pvp is disabled for any reason. no-pvp: self: "Вы не можете ударить этого игрока - ваша возможность ПвП отключена." other: "У этого игрока отключена возможность ПвП." protected: "Этот игрок защищен - вы пока не можете атаковать его!" cancel: "Вы защищены - вы временно не можете атаковать других игроков!" protection-disabled: #Shown when newbie protection is disabled due to the player attacking another player. attacker: "Вы кого-то атаковали, ваша защита новичка отключилась." #Shown when newbie protection expires. expired: "Ваша защита новичка закончилась." #Shown for the '/togglepvp check ' command. check-format: - "Информация о {target}:" - "Защита: {protected}" - "ПвП: {pvp}" loot-protection: #Shown when an enemy dies and their loot is protected. enemy-died: "{enemy} погиб. Вещи будут защищены {time} секунд." #Shown when a player tries to pick up an item that is loot protected by the plugin. protected: "Этот предмет защищен - подождите {time} секунд, прежде чем поднять его." citizens-compatibility: #Shown when a player is prevented from joining the server due to their NPC still existing. prevent-join: "Вы не можете зайти на сервер, пока ваш НИП не убит или не исчез." disguise-compatibility: #Shown when a disguise is removed from a player during combat. remove-disguise: "Ваша маскировка была снята." essentials-compatibility: #Shown when a teleport request is cancelled during combat. prevent-teleport-request-self: "Вы не можете отправлять запросы на телепортацию во время боя." #Shown when a teleport request is cancelled during combat. prevent-teleport-request-other: "Вы не можете отправлять запрос на телепортацию к игроку, находящемуся в бою." marriagemaster-compatibility: #Shown when a married player is prevented from teleporting to their partner during combat. prevent-teleport-self: "Вы не можете телепортироваться к своему партнеру во время боя." #Shown when a married player is prevented from teleporting to their partner during combat. prevent-teleport-partner: "Вы не можете телепортироваться к своему партнеру, пока тот находится в бою." huskhomes-compatibility: prevent-teleport: "Вы не можете телепортироваться во время боя." region-protection: #Shown when a player tries to enter a no-pvp area during combat. default-no-entry: "Вы не можете войти в эту область во время боя." factions-no-entry: Вы не можете войти в эту область во время боя. griefdefender-no-entry: Вы не можете войти в эту область во время боя. griefprevention-no-entry: Вы не можете войти в эту область во время боя. kingdomsx-no-entry: Вы не можете войти в эту область во время боя. konquest-no-entry: Вы не можете войти в эту область во время боя. redprotect-no-entry: Вы не можете войти в эту область во время боя. residence-no-entry: Вы не можете войти в эту область во время боя. towny-no-entry: Вы не можете войти в эту область во время боя. husktowns-no-entry: Вы не можете войти в эту область во время боя. ultimateclaims-no-entry: Вы не можете войти в эту область во время боя. protectionstones: prevent-area-creation: "Вы не можете создать защищенную область во время боя." no-entry: Вы не можете войти в эту область во время боя. preciousstones: prevent-field-creation: "Вы не можете создать защитное поле во время боя." no-entry: Вы не можете войти в эту область во время боя. worldguard: no-entry-mob-combat: "Вы не можете войти в область без ПвЕ во время боя." no-entry-player-combat: "Вы не можете войти в область без ПвП во время боя." no-entry-unknown-combat: Вы не можете войти в эту область во время боя. lands: no-entry: Вы не можете войти в эту область во время боя. war-disable-newbie-protection: "ПвП было активировано из-за военной декларации." ================================================ FILE: plugin/src/main/resources/language/sv_se.lang.yml ================================================ --- ## Extra Information: ## This is the default language file for CombatLogX. ## The default language is "en_us", also known as English (United States). ## Context will be added as YAML comments above the string. ## The color scheme for messages is gold, white, and sometimes red. ## Command feedback that is successful should always be green. ## Error messages should always be red. ## Variables in messages can be gray or white. ## Messages use the MiniMessage format in non-strict mode. ## More information about MiniMessage can be found here: ## https://docs.adventure.kyori.net/minimessage/format.html #The language code for this file. language-name: "sv_SE" #The format for decimal numbers. #The United States uses the number and two decimal places decimal-format: "0.00" #The prefix for CombatLogX. #This is shown in front of all messages and should not be changed unless necessary. prefix: "[CombatLogX]" broadcast: #Shown when the plugin is finished loading. on-load: "CombatLogX laddades." #Shown when the plugin is finished enabling. on-enable: "CombatLogX aktiverades." #Shown when the plugin is disabled for any reason. on-disable: "CombatLogX har inaktiverats." placeholder: #This text is used for the {combatlogx_time_left} #This allows server configurations to change the display value of the zero to something like "Not in combat" time-left-zero: "0" #This text is used when a player does not have an enemy. #This can happen when players are tagged by a custom expansion or the tag command. unknown-enemy: "Okänd" status: #Shown when the player is in combat. fighting: "Strider" in-combat: "Ja" #Shown when the player is not in combat idle: "Idle" not-in-combat: "Nej" #These placeholders are shown when a player changes a value such as whether or not their bossbar is enabled. toggle: enabled: "" disabled: "AV" pvp-status: enabled: "" disabled: "AV" combat-timer: #Sent to a player when they escape from combat due to the timer running out. expire: "Du är inte längre i strid." #Sent to a player when they escape from combat due to their enemy being killed. enemy-death: "Du är inte längre i strid eftersom din fiende dog." #Sent when a player is killed during combat. self-death: "Du är inte längre i strid eftersom du dog." error: #Shown when the console tries to execute a command made for players. player-only: "Endast spelare kan köra detta kommando" #Shown when a command that requires a player has invalid input. invalid-target: "{target} är inte online eller finns inte." #Shown when a command that requires a number has invalid input. invalid-integer: "{value} är inte ett giltigt heltal." #Shown when a player does not have access to something that requires a permission. no-permission: "Saknad behörighet: {permission}" #Shown when a player executes a command in a world that is disabled in the configuration. disabled-world: "Det kommandot är inte tillgängligt i denna dimension." #Shown when a command requires a player in combat but the target player is not in combat. target-not-in-combat: "{target} är inte i strid." #Shown when a player executes a command that requires them to be in combat. self-not-in-combat: "Du är inte i strid." #Shown when a command that requires an expansion has invalid input. unknown-expansion: "{target} är inte en expansion eller är inte installerad." command: combatlogx: #Shown as the command output for '/combatlogx help'. help-message-list: - "" - "CombatLogX kommandohjälp:" - " /combatlogx help: Se denna hjälpsida." - " /combatlogx ladda om: Ladda om config.yml, language.yml och alla expansionskonfigurationsfiler." - " /combatlogx about \\: Kontrollera information om en expansion." - " /combatlogx tag \\ [seconds]: Tvinga en spelare i strid." - " /combatlogx växla bossbar/actionbar/resultattavla: Aktivera eller inaktivera en aviseringstyp." - " /combatlogx untag \\: Tvinga en spelare ur strid." - " /combatlogx version: Kontrollera din version av CombatLogX." - "" #Shown as the command output for '/combatlogx reload' when reloading is successful. reload-success: - "Laddade om alla konfigurationsfiler från CombatLogX." - "Laddade om alla språkfiler från CombatLogX." - "Laddade om alla konfigurationsfiler från CombatLogX-expansioner." #Shown as the command output for '/combatlogx reload' when reloading fails reload-failure: - "Ett fel uppstod vid omladdning av konfigurationen." - "Kontrollera din serverlogg och åtgärda den trasiga filen." #Shown as the command output for '/combatlogx tag ' when a player is tagged successfully. tag-player: "Framgångsrikt tvingade spelare {target} in i strid." #Shown as the command output for '/combatlogx tag ' when the plugin failed to tag a player. tag-failure: "{target} kunde inte placeras i strid. (Kanske har de en kringfart?)" #Shown as the command output for '/combatlogx untag '. untag-player: "Framgångsrikt tvingad spelare {target} ur striden." #Shown as the command output for '/combatlogx toggle bossbar'. toggle-bossbar: "Chef Bar: {status}" #Shown as the command output for '/combatlogx toggle actionbar'. toggle-actionbar: "Åtgärdsfält: {status}" #Shown as the command output for '/combatlogx toggle scoreboard'. toggle-scoreboard: "Resultattavlan: {status}" combat-timer: #Shown as the command output for '/combat-timer'. time-left-self: "Du har {time_left} sekunder&a kvar." #Shown as the command output for '/combat-timer '. time-left-other: "{target} har {time_left} sekunder kvar." #These messages are shown a player is tagged into combat. tagged: unknown: player: "Du är nu i strid med {enemy} av en okänd anledning. Logga inte ut!" mob: "Du är nu i strid med a(n) {enemy} av en okänd anledning. Logga inte ut!" mythic_mob: "Du är nu i strid med a(n) {mob_type} av en okänd anledning. Logga inte ut!" damage: "Du är nu i strid på grund av att du tar skada. Logga inte ut!" unknown: "Du placerades i strid utan anledning. Logga inte ut." attacked: player: "Du attackeras av {enemy}. Logga inte ut!" mob: "Du attackeras av a(n) {mob_type}. Logga inte ut!" mythic_mob: "Du attackeras av a(n) {enemy}. Logga inte ut!" damage: "Du är nu i strid på grund av att du tar skada. Logga inte ut!" unknown: "Du attackeras av en okänd kraft. Logga inte ut!" attacker: player: "Du attackerar {enemy}. Logga inte ut!" mob: "Du attackerar en(n) {mob_type}. Logga inte ut!" mythic_mob: "Du attackerar en(n) {enemy}. Logga inte ut!" damage: "Du är nu i strid på grund av att du tar skada. Logga inte ut!" unknown: "Du attackerar en okänd kraft. Logga inte ut!" expansion: angel-chest: #Shown when opening an AngelChest is prevented during combat. prevent-opening: "Det är inte tillåtet att öppna ängelkistor under strid." #Shown when breaking an AngelChest is prevented during combat. prevent-breaking: "Det är inte tillåtet att bryta ängelkistor under striden." #Shown when fast looting an AngelChest is prevented during combat. prevent-fast-looting: "Du har inte tillåtelse att snabbt plundra ängelkistor under strid." action-bar: #Shown above the hotbar while a player is in combat. timer: "Bekämpa \u00BB {bars} {combatlogx_time_left} sekunder." #Shown above the hotbar for a brief period when combat ends. ended: "Bekämpa \u00BB Du är inte längre i strid." boss-bar: #Shown on top of the screen while a player is in combat. timer: "Bekämpa \u00BB {combatlogx_time_left} sekunder." #Shown on top of the screen for a brief period when combat ends. ended: "Bekämpa \u00BB Du är inte längre i strid." scoreboard: #The scoreboard title for the sidebar. #Make sure to follow the scoreboard title limits for your Spigot version. title: "CombatLogX" #The scoreboard lines for the sidebar. #Make sure to follow the scoreboard line and character limits for your Spigot version. lines: - " " - "Stridsstatistik:" - "\u00BB Tid kvar: {combatlogx_time_left}" - "\u00BB Enemies: {combatlogx_enemy_count}" - "\u00BB Status: {combatlogx_status}" - " " - "Enemies" - "\u00BB {combatlogx_specific_enemy_1_name}" - "\u00BB {combatlogx_specific_enemy_2_name}" - "\u00BB {combatlogx_specific_enemy_3_name}" - " " cheat-prevention: #Shown when a command execution is prevented during combat. command-blocked: "Du har inte tillgång till {command} under strid." #Shown when the riptide effect is prevented during combat. no-riptide: "Rriptideförtrollningen är inaktiverad under strid." #Shown when a totem of undying is prevented during combat. no-totem: "Du har inte tillåtelse att använda totem av ogjort under strid." #Shown when an entity interaction is prevented during combat. no-entity-interaction: "Det är inte tillåtet att använda den mobben under strid." #Shown when a chat message is prevented during combat. no-chat: "Du får inte skicka chattmeddelanden under strid." game-mode: #Shown when a player is forced into a specific game mmode during combat. force-switch: "Ditt spelläge ändrades till {game_mode}." #Shown when a game mode switch is prevented during combat. no-switch: "Du har inte tillåtelse att byta spellägen under strid." flight: #Shown when a player's ability to fly is disabled during combat. force-disabled: "Din flygförmåga har tagits bort." #Shown when a player's attempt to fly is prevented during combat. no-flying: "Du får inte flyga under strid." elytra: #Shown when a player's ability to glide is disabled during combat. force-disabled: "Din elytra har inaktiverats." #Shown when a player's attempt to glide is prevented during combat. no-gliding: "Du får inte använda elytra under strid." teleportation: #Shown when a player tries to enter a portal and is prevented during combat. block-portal: "Du får inte använda en portal under strid." #Shown when an ender pearl is prevented during combat. block-pearl: "Du får inte använda enderpärlor under strid." #Shown when a teleport is prevented during combat. block-other: "Du får inte teleportera dig under strid." inventory: #Shown when a player's inventory is closed by the plugin during combat. force-closed: "Ditt förråd var stängt." #Shown when a player tries to open an inventory and is prevented during combat. no-opening: "Det är inte tillåtet att öppna lager under strid." blocks: #Shown when a player is prevented from breaking a block during combat. prevent-breaking: "Du får inte bryta block under strid." #Shown when a player is prevented from breaking a block during combat. prevent-placing: "Du får inte placera block under strid." #Shown when a player is prevented from breaking a block during combat. prevent-interaction: "Du har inte tillåtelse att använda block under strid." #Shown when a player is prevented from breaking a block during combat. prevent-portal-creation: "Du får inte skapa portaler under strid." items: #Shown when a player is prevented from picking up an item during combat. no-pickup: "Du får inte plocka upp föremål under strid." #Shown when a player is prevented from dropping an item during combat. no-dropping: "Du får inte släppa föremål under strid." buckets: #Shown when a player is prevented from emptying a bucket during combat. no-empty: "Du kan inte tömma hinkar under strid." #Shown when a player is prevented from filling a bucket during combat. no-fill: "Du kan inte fylla upp hinkar under strid." damage-tagger: #Shown when a player is tagged for an unknown damage type. unknown-damage: "Du tog skada! Logga inte ut!" #These messages are shown when a player is tagged for a known damage type. #You can find a list of damage types here: #https://hub.spigotmc.org/javadocs/spigot/org/bukkit/event/entity/EntityDamageEvent.DamageCause.html damage-type: contact: "Du blev prickad av en kaktus. Logga inte ut!" suffocation: "Du kvävs i en vägg. Logga inte ut!" fall: "Du tog fallskada. Logga inte ut!" fire: "Du gick in i brand. Logga inte ut!" fire-tick: "Du brinner. Logga inte ut!" lava: "Du kokar i lava. Logga inte ut!" drowning: "Du drunknar. Logga inte ut!" block-explosion: "Du skadades av en explosion. Logga inte ut!" lightning: "Du har blivit slagen! Logga inte ut!" starvation: "Du är för hungrig. Logga inte ut!" poison: "Du tog gift skada. Logga inte ut!" magic: "Någon kastade en trolldryck på dig. Logga inte ut!" wither: "Du vissnar bort. Logga inte ut!" falling-block: "Ett block föll på dig. Logga inte ut!" custom: "Du tog anpassade skador. Logga inte ut!" fly-into-wall: "Du upplevde rörelseenergi. Logga inte ut!" hot-floor: "Golvet är lava! Logga inte ut!" cramming: "Du håller på att krossas. Logga inte ut!" newbie-helper: togglepvp: #Shown as the command output for '/togglepvp'. self: "PVP: {status}" #Shown as the command output for '/togglepvp admin on/off '. admin: "Du ändrade pvp {target} till {status}." #Shown when the '/togglepvp' command is on cooldown. cooldown: "Du måste vänta {time_left} sekunder för att använda detta kommando igen." #These messages are shown when pvp is disabled for any reason. no-pvp: self: "Du får inte träffa den spelaren medan din PvP är inaktiverad." other: "Den spelaren har PvP inaktiverat." protected: "Den spelaren är skyddad, du får inte attackera dem ännu!" protection-disabled: #Shown when newbie protection is disabled due to the player attacking another player. attacker: "Du attackerade någon, ditt nybörjare skydd är nu inaktiverat." #Shown when newbie protection expires. expired: "Ditt nybörjarskydd har löpt ut." #Shown for the '/togglepvp check ' command. check-format: - "Information för {target}:" - "Skydd: {protected}" - "PvP: {pvp}" loot-protection: #Shown when an enemy dies and their loot is protected. enemy-died: "{enemy} har dött. Loot kommer att skyddas i {time} sekunder." #Shown when a player tries to pick up an item that is loot protected by the plugin. protected: "Detta objekt är för närvarande skyddat, vänta {time} sekunder tills du kan hämta det." citizens-compatibility: #Shown when a player is prevented from joining the server due to their NPC still existing. prevent-join: "Du får inte gå med i servern förrän din NPC har dödats eller tagits bort." disguise-compatibility: #Shown when a disguise is removed from a player during combat. remove-disguise: "Din förklädnad har tagits bort." essentials-compatibility: #Shown when a teleport request is cancelled during combat. prevent-teleport-request-self: "Du kan inte skapa teleporteringsförfrågningar under strid." #Shown when a teleport request is cancelled during combat. prevent-teleport-request-other: "Du kan inte skicka en teleporteringsbegäran till en spelare som är i strid." marriagemaster-compatibility: #Shown when a married player is prevented from teleporting to their partner during combat. prevent-teleport-self: "Du har inte tillåtelse att teleportera till din partner under strid." #Shown when a married player is prevented from teleporting to their partner during combat. prevent-teleport-partner: "Du har inte tillåtelse att teleportera till din partner medan de är i strid." region-protection: #Shown when a player tries to enter a no-pvp area during combat. default-no-entry: "Det är inte tillåtet att komma in i det området under strid." factions-no-entry: Det är inte tillåtet att komma in i det området under strid. griefdefender-no-entry: Det är inte tillåtet att komma in i det området under strid. griefprevention-no-entry: Det är inte tillåtet att komma in i det området under strid. kingdomsx-no-entry: Det är inte tillåtet att komma in i det området under strid. konquest-no-entry: Det är inte tillåtet att komma in i det området under strid. redprotect-no-entry: Det är inte tillåtet att komma in i det området under strid. residence-no-entry: Det är inte tillåtet att komma in i det området under strid. towny-no-entry: Det är inte tillåtet att komma in i det området under strid. husktowns-no-entry: Det är inte tillåtet att komma in i det området under strid. ultimateclaims-no-entry: Det är inte tillåtet att komma in i det området under strid. protectionstones: prevent-area-creation: "Du får inte skapa ett skyddat område under strid." no-entry: Det är inte tillåtet att komma in i det området under strid. preciousstones: prevent-field-creation: "Du får inte skapa ett skyddsfält under strid." no-entry: Det är inte tillåtet att komma in i det området under strid. worldguard: no-entry-mob-combat: "Du får inte gå in i ett icke-mob-stridsområde under strid." no-entry-player-combat: "Du får inte gå in i ett icke-spelare-stridsområde under strid." no-entry-unknown-combat: Det är inte tillåtet att komma in i det området under strid. lands: no-entry: Det är inte tillåtet att komma in i det området under strid. war-disable-newbie-protection: "PvP är nu aktiverat på grund av en krigsförklaring." ================================================ FILE: plugin/src/main/resources/language/tr_tr.lang.yml ================================================ --- ## Extra Information: ## This is the default language file for CombatLogX. ## The default language is "en_us", also known as English (United States). ## Context will be added as YAML comments above the string. ## The color scheme for messages is gold, white, and sometimes red. ## Command feedback that is successful should always be green. ## Error messages should always be red. ## Variables in messages can be gray or white. ## Messages use the MiniMessage format in non-strict mode. ## More information about MiniMessage can be found here: ## https://docs.adventure.kyori.net/minimessage/format.html #The language code for this file. language-name: "tr_TR" #The format for decimal numbers. #The United States uses the number and two decimal places decimal-format: "0. 0" #The prefix for CombatLogX that is shown in front of all messages. #Note to translators: Do not change this message. prefix: "[CombatLogX ]" broadcast: #Shown when the plugin is finished loading. on-load: "CombatLogX başarıyla yüklendi" #Shown when the plugin is finished enabling. on-enable: "CombatLogX başarıyla etkinleştirildi." #Shown when the plugin is disabled for any reason. on-disable: "CombatLogX başarıyla devre dışı bırakıldı." placeholder: #This text is used for the {combatlogx_time_left} #This allows server configurations to change the display value of the zero to something like "Not in combat" time-left-zero: "0 " #This text is used when a player does not have an enemy. #This can happen when players are tagged by a custom expansion or the tag command. unknown-enemy: "Bilinmeyenn" status: #Shown when the player is in combat. fighting: "Savaşıyor" in-combat: "Evet" #Shown when the player is not in combat idle: "Boşta" not-in-combat: "Hayır" #These placeholders are shown when a player changes a value such as whether or not their bossbar is enabled. toggle: enabled: "AÇIK" disabled: "KAPALI" pvp-status: enabled: "AÇIK" disabled: "KAPALI" #You can also change the location of these messages. #Example: #combat-timer: #expire: #type: ACTION_BAR #content: "" combat-timer: #Sent to a player when they escape from combat due to the timer running out. expire: "Artık savaşta değilsin." #Sent to a player when they escape from combat due to their enemy being killed. enemy-death: "Artık savaşta değilsin çünkü düşmanın öldü." #Sent when a player is killed during combat. self-death: "Artık savaşta değilsin çünkü düşmanın öldü" error: #Shown when the console tries to execute a command made for players. player-only: "Bu komutu sadece oyuncular kullanabilir." #Shown when a player tries to execute a command made for the server console. console-only: "Bu komut sadece konsolda çalıştırılabilir." #Shown when a command that requires a player has invalid input. invalid-target: "{target} çevrimiçi değil ya da mevcut değil." #Shown when a command that requires a number has invalid input. invalid-integer: "{value}geçerli bir tamsayı değil." #Shown when a player does not have access to something that requires a permission. no-permission: "Eksik Yetki:{permission}" #Shown when a player executes a command in a world that is disabled in the configuration. disabled-world: "Bu komut bu boyutta mevcut değil. " #Shown when a command requires a player in combat but the target player is not in combat. target-not-in-combat: "{target} savaşta değil" #Shown when a player executes a command that requires them to be in combat. self-not-in-combat: "Savaşta değilsin." #Shown when a command that requires an expansion has invalid input. unknown-expansion: "{target} bir eklenti değil ya da yüklenmedi." forgive-not-enemy: "{target} kimse düşmanın değil. " enemy-not-forgiving: "Düşmanın seni affedecek havasında değil. " command: combatlogx: #Shown as the command output for '/combatlogx help'. help-message-list: - "" - "CombatLogX Komut Yardım" - " /combatlogx help : Yardım sayfasını görüntüler" - " /combatlogx reload : config.yml, language.yml ve bütün eklentilerin konfigürasyon dosyalarını yeniden yükler" - " /combatlogx about \\: Eklentiyle ilgili bilgileri kontrol eder" - " /combatlogx tag \\[seconds]: Oyuncuyu zorla savaşa sokar" - " /combatlogx toggle bossbar/actionbar/scoreboard : Bildirim tipini etkinleştirir ya da devre dışı bırakır" - " /combatlogx untag \\: Hedef oyuncuyu savaş durumundan çıkarır" - " /combatlogx version : CombatLogX sürümünüzü kontrol eder" - " /combatlogx forgive request \\: Bir düşmana etiketini sizden kaldırması için istek gönderin." - " /combatlogx allow accept\\: Bir düşmanın savaştan kaçma isteğine izin ver." - " /combatlogxaffet reddetme \\: Bir düşmanın savaştan kaçma isteğini dikkate almayın!" - " /combatlogx forgive toggle: Savaşı durdurma isteklerini etkinleştirin veya devre dışı bırakın!" - "" #Shown as the command output for '/combatlogx reload' when reloading is successful. reload-success: - "CombatLogX konfigürasyon dosyaları başarıyla yenilendi" - "CombatLogX dil dosyaları başarıyla yenilendi." - "CombatLogX eklentilerinin konfigürasyon dosyaları başarıyla yenilendi." #Shown as the command output for '/combatlogx reload' when reloading fails reload-failure: - " Yapılandırma yeniden yüklenirken bir hata oluştu." - " Lütfen sunucu günlüğünüzü kontrol edin ve bozulan dosyayı düzeltin." #Shown as the command output for '/combatlogx tag ' when a player is tagged successfully. tag-player: "Oyuncu {target} başarıyla savaşa zorlandı" #Shown as the command output for '/combatlogx tag ' when the plugin failed to tag a player. tag-failure: "Hedef {target} savaşta yerleştiremez. (Belki bypass yetkisine sahiptir)" #Shown as the command output for '/combatlogx untag '. untag-player: "Hedef {target} başarıyla savaştan çıkarıldı" #Shown as the command output for '/combatlogx toggle bossbar'. toggle-bossbar: "Boss Bar:{status}" #Shown as the command output for '/combatlogx toggle actionbar'. toggle-actionbar: "Action Bar: {status}" #Shown as the command output for '/combatlogx toggle scoreboard'. toggle-scoreboard: "Scoreboard: {status}" #Shown as the command output for '/combatlogx about '. expansion-information: - "" - "{name} için eklenti bilgileri:" - "Görünen İsim: {prefix}" - "Versiyon: {version}" - "Durum: {state}" - "" - "Açıklama: {description}" - "Web sayfası: {website}" - "Yapımcılar: {authors}" forgive: toggle-disable: "Artık af talepleri alamazsınız " toggle-enable: "Artık af talepleri alabilirsiniz " request-sent: "{target}'e bir affetme isteği gönderdiniz! " request-receive: - "{player} size bir bağışlama isteği gönderdi! " - "allow accept>/clx affet kabul yazın veya./clx affet reddetme." combat-timer: #Shown as the command output for '/combat-timer'. time-left-self: "{time_left} saniyeniz kaldı! " #Shown as the command output for '/combat-timer '. time-left-other: "Hedef {target} kalan zamanı{time_left}" #These messages are shown a player is tagged into combat. #You can also change the location of these messages. #Example: #tagged: #attacked: #player: #type: ACTION_BAR #content: "" tagged: unknown: player: "Bilinmeyen bir nedenle şu anda{enemy} ile savaş halindesiniz! Oturumu kapatmayın!" mob: "Şu anda bir(n){enemy} ile bilinmeyen bir nedenle savaş halindesiniz. Oturumu kapatmayın! " mythic_mob: "Şu anda bilinmeyen bir nedenle bir(n) {mob_type}ile savaş halindesiniz. Oturumu kapatmayın." damage: "Artık hasar aldığınız için savaştasın. Oturumu kapatmayın\n" unknown: "Sebepsiz yere çatışmaya girdin Oturumu kapatmayın!" attacked: player: "{enemy} tarafından saldırıya uğradın. Oturumu kapatma" mob: "{mob_type}tarafından saldırıya uğradın. Oturumu kapatma" mythic_mob: "Bir(n){enemy} tarafından saldırıya uğruyorsunuz! Oturumu kapatmayın!" damage: " Artık hasar aldığınız için savaştasın. Oturumu kapatmayın!" unknown: " Bilinmeyen bir güç tarafından saldırıya uğruyorsun. Oturumu kapatmayın!" attacker: player: "{enemy} adlı oyuncuya saldırıyorsun. Oturumu kapatma!" mob: "{mob_type}adlı canlıya saldırıyorsun. Oturumu kapatma!" mythic_mob: "Bir(n){enemy}'a saldırıyorsun. Oturumu kapatmayın!" damage: "Artık hasar aldığınız için savaştasın. Oturumu kapatmayın! " unknown: "Bilinmeyen bir güce saldırıyorsun. Oturumu kapatmayın! " expansion: angel-chest: #Shown when opening an AngelChest is prevented during combat. prevent-opening: "Savaş sırasında melek sandıklarını açmanıza izin verilmiyor! " #Shown when breaking an AngelChest is prevented during combat. prevent-breaking: "Savaş sırasında melek sandıklarını kırmanıza izin verilmez!" #Shown when fast looting an AngelChest is prevented during combat. prevent-fast-looting: "Savaş sırasında hızlı bir şekilde melek sandıklarını yağmalamanıza izin verilmez!" action-bar: #Shown above the hotbar while a player is in combat. timer: "Savaş \u00BB {bars} {combatlogx_time_left}saniye." #Shown above the hotbar for a brief period when combat ends. ended: "Savaş \u00BB Artık savaşta değilsiniz!" boss-bar: #Shown on top of the screen while a player is in combat. timer: "Savaş \u00BB {combatlogx_time_left} saniye!" #Shown on top of the screen for a brief period when combat ends. ended: "Savaş \u00BB Artık savaşta değilsiniz!" scoreboard: #The scoreboard title for the sidebar. #Make sure to follow the scoreboard title limits for your Spigot version. title: "CombatLogX!" #The scoreboard lines for the sidebar. #Make sure to follow the scoreboard line and character limits for your Spigot version. lines: - " " - "Savaş İstatistikleri: " - "\u00BB Kalan Süre: {combatlogx_time_left}" - "\u00BB Enemies: {combatlogx_enemy_count}" - "\u00BB durum: {combatlogx_status}" - " " - "Düşmanlar " - "\u00BB {combatlogx_specific_enemy_1_name}" - "\u00BB {combatlogx_specific_enemy_2_name} " - "\u00BB {combatlogx_specific_enemy_3_name} " - " " cheat-prevention: #Shown when a command execution is prevented during combat. command-blocked: "Savaş sırasında {command} \nkomutuna erişemezsiniz" #Shown when the riptide effect is prevented during combat. no-riptide: "Savaş sırasında girdap büyüsü devre dışı bırakıldı" #Shown when a totem of undying is prevented during combat. no-totem: " Savaş sırasında ölmeme totemi kullanmanıza izin verilmiyor" #Shown when an entity interaction is prevented during combat. no-entity-interaction: "Savaş sırasında bu canlıyla etkileşime girmenize izin verilmiyor." #Shown when a chat message is prevented during combat. no-chat: "Savaş sırasında sohbete mesaj göndermenize izin verilmiyor. " game-mode: #Shown when a player is forced into a specific game mmode during combat. force-switch: "Oyun modunuz {game_mode} olarak değiştirildi" #Shown when a game mode switch is prevented during combat. no-switch: "Savaş sırasında oyun modunuzu değiştirmenize izin verilmiyor" flight: #Shown when a player's ability to fly is disabled during combat. force-disabled: "Uçma yeteneğiniz kaldırıldı" #Shown when a player's attempt to fly is prevented during combat. no-flying: "Savaş sırasında uçmanıza izin verilmiyor" elytra: #Shown when a player's ability to glide is disabled during combat. force-disabled: "Elytranız devre dışı bırakıldı" #Shown when a player's attempt to glide is prevented during combat. no-gliding: "Savaş sırasında elytra kullanmanıza izin verilmiyor" teleportation: #Shown when a player tries to enter a portal and is prevented during combat. block-portal: "Savaş sırasında portal kullanmanıza izin verilmiyor" #Shown when an ender pearl is prevented during combat. block-pearl: "Savaş sırasında ender pearl kullanmanıza izin verilmiyor" #Shown when a teleport is prevented during combat. block-other: "Savaş sırasında ışınlanmanıza izin verilmiyor" inventory: #Shown when a player's inventory is closed by the plugin during combat. force-closed: "Envanteriniz kapatıldı" #Shown when a player tries to open an inventory and is prevented during combat. no-opening: "Savaş sırasında envanterleri açmanıza izin verilmiyor" blocks: #Shown when a player is prevented from breaking a block during combat. prevent-breaking: "Savaş sırasında blokları kırmanıza izin verilmiyor" #Shown when a player is prevented from breaking a block during combat. prevent-placing: "Savaş sırasında blokları yerleştirmenize izin verilmiyor" #Shown when a player is prevented from breaking a block during combat. prevent-interaction: "Savaş sırasında blokları kullanmanıza izin verilmiyor" #Shown when a player is prevented from breaking a block during combat. prevent-portal-creation: "Savaş sırasında portal oluşturmanıza izin verilmiyor" items: #Shown when a player is prevented from picking up an item during combat. no-pickup: "Savaş sırasında eşyaları almanıza izin verilmiyor" #Shown when a player is prevented from dropping an item during combat. no-dropping: "Savaş sırasında eşyaları atmanıza izin verilmiyor" buckets: #Shown when a player is prevented from emptying a bucket during combat. no-empty: "Savaş sırasında kovaları boşaltmanıza izin verilmiyor" #Shown when a player is prevented from filling a bucket during combat. no-fill: "Savaş sırasında kovaları doldurmanıza izin verilmiyori" damage-tagger: #Shown when a player is tagged for an unknown damage type. unknown-damage: "Hasar aldın! Oturumu kapatma" #These messages are shown when a player is tagged for a known damage type. #You can find a list of damage types here: #https://hub.spigotmc.org/javadocs/spigot/org/bukkit/event/entity/EntityDamageEvent.DamageCause.html damage-type: block-explosion: "Patlama tarafından hasar aldın. Oturumu kapatma" contact: "Kaktüs tarafından delindin. Oturumu kapatma" cramming: "Eziliyorsun. Oturumu kapatma" custom: "Bilinmeyen bir hasar aldın. Oturumu kapatma" drowning: "Boğuluyorsun. Oturumu kapatma" dryout: "Suyun dışında çok fazla durdun. Sunucudan çıkma!" #May be triggered by custom plugins. entity-explosion: "Bir End Crystal patlaması sonucu hasar gördünüz. Çıkış yapmayın!" #Only triggered by end crystals. fall: "Düşme hasarı aldın. Oturumu kapatma" falling-block: "Kafana bir blok düştü. Oturumu kapatma" fire: "Ateşe yürüdün. Oturumu kapatma" fire-tick: "Yanıyorsun. Oturumu kapatma" fly-into-wall: "Kinetik enerjiyi tecrübe ettin. Oturumu kapatma" freeze: "Donuyorsun. Sunucudan çıkma!" hot-floor: "Zemin lavdan! Oturumu kapatmayın" lava: "Lavda eriyorsun. Oturumu kapatma" lightning: "Başına şimşek düştü! Oturumu kapatma" magic: "Birileri sana bir iksir fırlattı. Oturumu kapatma" melting: "Eriyorsun! Sunucudan çıkma." #May be triggered by custom plugins. poison: "Zehir hasarı aldın. Oturumu kapatma" starvation: "Çok açsın. Oturumu kapatma" suffocation: "Duvarda sıkıştın. Oturumu kapatma" void: "Boşluğa düşüyorsun. Sunucudan çıkma!" wither: "Soluyorsun. Oturumu kapatma" world-border: "Sınıra çok yakınsın. Sunucudan çıkma!" newbie-helper: togglepvp: #Shown as the command output for '/togglepvp'. self: "PVP:{status}" #Shown as the command output for '/togglepvp admin on/off '. admin: "Hedef oyuncu {target} pvp'sini {status} olarak değiştirdiniz" #Shown when the '/togglepvp' command is on cooldown. cooldown: "Bu komutu tekrar kullanmadan önce {time_left} saniye beklemelisin" #These messages are shown when pvp is disabled for any reason. no-pvp: self: "PvP'niz kapalıyken oyunculara vurmanıza izin verilmiyor" other: "Hedef oyuncunun PvP'si devre dışı" protected: "Hedef oyuncu korunuyor, ona şu an dokunamazsın" protection-disabled: #Shown when newbie protection is disabled due to the player attacking another player. attacker: "Birilerine saldırdın, yeni oyuncu koruman devre dışı bırakıldı" #Shown when newbie protection expires. expired: "Yeni oyuncu korumanızın süresi doldu" #Shown for the '/togglepvp check ' command. check-format: - "Bilgilendirme {target}" - "Koruma:{protected}" - "PvP:{pvp}" loot-protection: #Shown when an enemy dies and their loot is protected. enemy-died: "{enemy} öldü. Ganimetler {time} saniye boyunca korunacaktır" #Shown when a player tries to pick up an item that is loot protected by the plugin. protected: "Bu eşya şu anda korunuyor, lütfen eşyayı almadan önce {time} saniye bekleyin" citizens-compatibility: #Shown when a player is prevented from joining the server due to their NPC still existing. prevent-join: "NPC'niz ölüyken ya da geri çağırılmışken sunucuya katılmanıza izin verilmiyor" disguise-compatibility: #Shown when a disguise is removed from a player during combat. remove-disguise: "Kamuflajınız kaldırıldı" essentials-compatibility: #Shown when a teleport request is cancelled during combat. prevent-teleport-request-self: "Savaş sırasında ışınlanma isteği oluşturamazsınız" #Shown when a teleport request is cancelled during combat. prevent-teleport-request-other: "Savaş sırasında bir oyuncuya ışınlanma isteği gönderemezsiniz" marriagemaster-compatibility: #Shown when a married player is prevented from teleporting to their partner during combat. prevent-teleport-self: "Savaş sırasında partnerinize ışınlanmanıza izin verilmiyor!" #Shown when a married player is prevented from teleporting to their partner during combat. prevent-teleport-partner: "Ortağınız savaş halindeyken ona ışınlanmanıza izin verilmez. " huskhomes-compatibility: prevent-teleport: "Savaş sırasında ışınlanmanıza izin verilmiyor" region-protection: #Shown when a player tries to enter a no-pvp area during combat. default-no-entry: "Savaş sırasında o bölgeye girmenize izin verilmiyor. " factions-no-entry: Savaş sırasında bu alana girmenize izin verilmiyor griefdefender-no-entry: Savaş sırasında bu alana girmenize izin verilmiyor griefprevention-no-entry: Savaş sırasında bu alana girmenize izin verilmiyor kingdomsx-no-entry: Savaş sırasında bu alana girmenize izin verilmiyor konquest-no-entry: Savaş sırasında bu alana girmenize izin verilmiyor. redprotect-no-entry: Savaş sırasında bu alana girmenize izin verilmiyor. residence-no-entry: Savaş sırasında bu alana girmenize izin verilmiyor. towny-no-entry: Savaş sırasında bu alana girmenize izin verilmiyor. husktowns-no-entry: Savaş sırasında o bölgeye girmenize izin verilmiyor. ultimateclaims-no-entry: Savaş sırasında bu alana girmenize izin verilmiyor. protectionstones: prevent-area-creation: "Savaş sırasında bu alana girmenize izin verilmiyor." no-entry: Savaş sırasında bu alana girmenize izin verilmiyor. preciousstones: prevent-field-creation: "Savaş sırasında koruma alanı oluşturmanıza izin verilmiyor." no-entry: Savaş sırasında bu alana girmenize izin verilmiyor. worldguard: no-entry-mob-combat: "Savaş sırasında non-mob-combat alanına girmenize izin verilmiyor." no-entry-player-combat: "Savaş sırasında non-player-combat alanına girmenize izin verilmiyor." no-entry-unknown-combat: Savaş sırasında bu alanına girmenize izin verilmiyor. lands: no-entry: Savaş sırasında o bölgeye girmenize izin verilmiyor. war-disable-newbie-protection: "Bir savaş ilanı nedeniyle PvP artık zorla etkinleştirildi." ================================================ FILE: plugin/src/main/resources/language/uk_ua.lang.yml ================================================ --- ## Extra Information: ## This is the default language file for CombatLogX. ## The default language is "en_us", also known as English (United States). ## Context will be added as YAML comments above the string. ## The color scheme for messages is gold, white, and sometimes red. ## Command feedback that is successful should always be green. ## Error messages should always be red. ## Variables in messages can be gray or white. ## Messages use the MiniMessage format in non-strict mode. ## More information about MiniMessage can be found here: ## https://docs.adventure.kyori.net/minimessage/format.html #The language code for this file. language-name: "uk_ua" #The format for decimal numbers. #The United States uses the number and two decimal places decimal-format: "0.00" #The prefix for CombatLogX that is shown in front of all messages. #Note to translators: Do not change this message. prefix: "[CombatLogX]" broadcast: #Shown when the plugin is finished loading. on-load: "CombatLogX успішно завантажено." #Shown when the plugin is finished enabling. on-enable: "CombatLogX успішно увімкнено." #Shown when the plugin is disabled for any reason. on-disable: "CombatLogX успішно відключено." placeholder: #This text is used for the {combatlogx_time_left} #This allows server configurations to change the display value of the zero to something like "Not in combat" time-left-zero: "0" #This text is used when a player does not have an enemy. #This can happen when players are tagged by a custom expansion or the tag command. unknown-enemy: "Невідомий" status: #Shown when the player is in combat. fighting: "Боротьба" in-combat: "Так" #Shown when the player is not in combat idle: "Бездіяльний" not-in-combat: "Ні" #These placeholders are shown when a player changes a value such as whether or not their bossbar is enabled. toggle: enabled: "УВІМКНЕНО" disabled: "ВИМКНЕНО" pvp-status: enabled: "УВІМКНЕНО" disabled: "ВИМКНЕНО" #You can also change the location of these messages. #Example: #combat-timer: #expire: #type: ACTION_BAR #content: "" combat-timer: #Sent to a player when they escape from combat due to the timer running out. expire: "Ви більше не в бою." #Sent to a player when they escape from combat due to their enemy being killed. enemy-death: "Ви більше не в бою, тому що ваш ворог загинув." #Sent when a player is killed during combat. self-death: "Ви більше не в битві, оскільки ви померли." error: #Shown when the console tries to execute a command made for players. player-only: "Цю команду можуть виконувати лише гравці." #Shown when a player tries to execute a command made for the server console. console-only: "Цю команду можна виконати тільки в консолі сервера." #Shown when a command that requires a player has invalid input. invalid-target: "{target} не в мережі або не існує." #Shown when a command that requires a number has invalid input. invalid-integer: "{value} не є дійсним цілим числом." #Shown when a player does not have access to something that requires a permission. no-permission: "Немає дозволу: {permission}" #Shown when a player executes a command in a world that is disabled in the configuration. disabled-world: "Ця команда недоступна в цьому вимірі." #Shown when a command requires a player in combat but the target player is not in combat. target-not-in-combat: "{target} не в бою." #Shown when a player executes a command that requires them to be in combat. self-not-in-combat: "Ви не в бою." #Shown when a command that requires an expansion has invalid input. unknown-expansion: "{target} не є розширенням або не встановлено." forgive-not-enemy: "{target} не є одним з ваших ворогів." enemy-not-forgiving: "Цей ворог не налаштований пробачати вас." command: combatlogx: #Shown as the command output for '/combatlogx help'. help-message-list: - "" - "CombatLogX Команди:" - " /combatlogx help: Переглянути цю сторінку довідки." - " /combatlogx reload: Перезавантажте config.yml, language.yml та всі файли конфігурації розширення." - " /combatlogx about \\: Перевірте інформацію про розширення." - " /combatlogx tag \\: Примусити гравця вступити в бій." - " /combatlogx toggle bossbar/actionbar/scoreboard: Увімкнути або вимкнути тип сповіщення." - " /combatlogx untag \\: Вимусити гравця вийти з бою." - " /combatlogx version: Перевірте свою версію CombatLogX." - " /combatlogx forgive request \\: Надішліть ворогу запит, щоб він зняв з вас свою мітку." - " /combatlogx forgive accept \\: Задовольнити прохання ворога про втечу з бою." - " /combatlogx forgive reject \\: Ігноруйте прохання ворога вийти з бою." - " /combatlogx forgive toggle: Увімкнути або вимкнути запити на припинення бою." - "" #Shown as the command output for '/combatlogx reload' when reloading is successful. reload-success: - "Успішно перезавантажено всі файли конфігурації з CombatLogX." - "Успішно перезавантажено всі мовні файли з CombatLogX." - "Успішно перезавантажено всі файли конфігурації з розширень CombatLogX." #Shown as the command output for '/combatlogx reload' when reloading fails reload-failure: - "Помилка під час завантаження конфігурації" - "Будь ласка, перевірте журнал сервера і полагодьте зламаний файл." #Shown as the command output for '/combatlogx tag ' when a player is tagged successfully. tag-player: "Успішно змусив гравця {target} вступити в бій." #Shown as the command output for '/combatlogx tag ' when the plugin failed to tag a player. tag-failure: "{target} не вдалося ввести в бій. (Може, у них обхід?)" #Shown as the command output for '/combatlogx untag '. untag-player: "Гравець {target} успішно виведений з бою." #Shown as the command output for '/combatlogx toggle bossbar'. toggle-bossbar: "Бос Бар: {status}" #Shown as the command output for '/combatlogx toggle actionbar'. toggle-actionbar: "Панель дій: {status}" #Shown as the command output for '/combatlogx toggle scoreboard'. toggle-scoreboard: "Табло: {status}" #Shown as the command output for '/combatlogx about '. expansion-information: - "" - "Інформація про розширення для {name}:" - "Показувана назва: {prefix}" - "Версія: {version}" - "Держава: {state}" - "" - "Опис: {description}" - "Вебсайт: {website}" - "Автори: {authors}" forgive: toggle-disable: "Ви більше не можете отримувати прохання про прощення." toggle-enable: "Тепер ви можете отримувати прохання про прощення." request-sent: "Ви надіслали прохання про прощення {target}." request-receive: - "{player} надіслав вам прохання про вибачення." - "Тип /clx пробачити прийняти прийняти або." - "/clx forgive reject щоб заперечувати." combat-timer: #Shown as the command output for '/combat-timer'. time-left-self: "У вас залишилося {time_left} секунд." #Shown as the command output for '/combat-timer '. time-left-other: "У {target} залишилося {time_left} секунд." #These messages are shown a player is tagged into combat. #You can also change the location of these messages. #Example: #tagged: #attacked: #player: #type: ACTION_BAR #content: "" tagged: unknown: player: "Ви зараз в битві з {enemy} з невідомою причиною. Не виходьте!" mob: "Ви тепер у бою з a(n) {enemy} з невідомої причини. Не виходьте!" mythic_mob: "Ви тепер у бою з a(n) {mob_type} з невідомої причини. Не виходьте!" damage: "Тепер ви виконуєте боротьбу через пошкодження чи ні. Не виходите!" unknown: "Ви були поставлені у битву без причини. Не виходити з ладу." attacked: player: "На вас нападає {enemy}. Не виходьте!" mob: "На вас нападає {mob_type}. Не виходьте!" mythic_mob: "На вас атакує a(n) {enemy}. Не виходьте з системи!" damage: "Тепер ви виконуєте боротьбу через пошкодження чи ні. Не виходите!" unknown: "Вас атакує невідома сила. Не вийдіть!" attacker: player: "Ви атакуєте {enemy}. Не виходьте!" mob: "Ви атакуєте {mob_type}. Не виходьте!" mythic_mob: "Ви атакуєте a(n) {enemy}. Не виходьте з системи!" damage: "Тепер ви виконуєте боротьбу через пошкодження чи ні. Не виходите!" unknown: "Ви атакуєте невідому силу. Не виходите!" expansion: angel-chest: #Shown when opening an AngelChest is prevented during combat. prevent-opening: "Вам не дозволяється відкрити ангел-скрині під час бою." #Shown when breaking an AngelChest is prevented during combat. prevent-breaking: "У вас немає права порушувати ангели скрині під час бою." #Shown when fast looting an AngelChest is prevented during combat. prevent-fast-looting: "У вас не дозволяється швидко ходити ангеловими скринями під час бою." action-bar: #Shown above the hotbar while a player is in combat. timer: "Боротьба » {bars} {time_left_decimal} секунд." #Shown above the hotbar for a brief period when combat ends. ended: "Боротьба » Ти більше не в бою." boss-bar: #Shown on top of the screen while a player is in combat. timer: "Боротьба » {time_left_decimal} секунд." #Shown on top of the screen for a brief period when combat ends. ended: "Боротьба » Ти більше не в бою." scoreboard: #The scoreboard title for the sidebar. #Make sure to follow the scoreboard title limits for your Spigot version. title: "CombatLogX" #The scoreboard lines for the sidebar. #Make sure to follow the scoreboard line and character limits for your Spigot version. lines: - " " - "Бойова статистика:" - "» Залишився час: {time_left}" - "» В бою: {in_combat}" - "» Статус: {status}" - " " - "Статистика ворога" - "» Назва: {enemy_name}" - "» Здоров'я: {enemy_health}" - "» Здоров'я округлене: {enemy_health_rounded}" - " " cheat-prevention: #Shown when a command execution is prevented during combat. command-blocked: "Ви не маєте доступу до {command} під час бою." #Shown when the riptide effect is prevented during combat. no-riptide: "Зачарування тягун вимикається під час бою." #Shown when a totem of undying is prevented during combat. no-totem: "Під час бою не дозволяється використовувати тотеми безсмертя." #Shown when an entity interaction is prevented during combat. no-entity-interaction: "Вам заборонено використовувати цей моб під час бою." #Shown when a chat message is prevented during combat. no-chat: "Під час бою не дозволяється надсилати повідомлення чату." game-mode: #Shown when a player is forced into a specific game mmode during combat. force-switch: "Ваш режим гри був змінений на {game_mode}." #Shown when a game mode switch is prevented during combat. no-switch: "Під час бою не дозволяється змінювати режими гри." flight: #Shown when a player's ability to fly is disabled during combat. force-disabled: "Ваша здатність літати була видалена." #Shown when a player's attempt to fly is prevented during combat. no-flying: "Під час бою вам заборонено літати." elytra: #Shown when a player's ability to glide is disabled during combat. force-disabled: "Ваші крила були вимкнені." #Shown when a player's attempt to glide is prevented during combat. no-gliding: "Під час бою заборонено використовувати крила." #Shown when a player tries to use fireworks. no-fireworks: "Під час бою заборонено запускати феєрверки." teleportation: #Shown when a player tries to enter a portal and is prevented during combat. block-portal: "Вам було заборонено користуватися порталом під час бою." #Shown when an ender pearl is prevented during combat. block-pearl: "Під час бою заборонено використовувати перлину ендера." #Shown when a teleport is prevented during combat. block-other: "Вам заборонено телепортуватися під час бою." inventory: #Shown when a player's inventory is closed by the plugin during combat. force-closed: "Ваш інвентар закрили." #Shown when a player tries to open an inventory and is prevented during combat. no-opening: "Не дозволяється відкривати запаси під час бою." blocks: #Shown when a player is prevented from breaking a block during combat. prevent-breaking: "Під час бою не дозволяється розбивати блоки." #Shown when a player is prevented from breaking a block during combat. prevent-placing: "Під час бою заборонено розміщувати блоки." #Shown when a player is prevented from breaking a block during combat. prevent-interaction: "Під час бою заборонено використовувати блоки." #Shown when a player is prevented from breaking a block during combat. prevent-portal-creation: "Не дозволяється створювати портали під час бою." items: #Shown when a player is prevented from picking up an item during combat. no-pickup: "Під час бою заборонено брати речі." #Shown when a player is prevented from dropping an item during combat. no-dropping: "Під час бою заборонено кидати предмети." buckets: #Shown when a player is prevented from emptying a bucket during combat. no-empty: "Під час бою не можна спорожняти відра." #Shown when a player is prevented from filling a bucket during combat. no-fill: "Під час бою не можна наповнювати відра." damage-tagger: #Shown when a player is tagged for an unknown damage type. unknown-damage: "Ви отримали шкоду! Не виходьте!" #These messages are shown when a player is tagged for a known damage type. #You can find a list of damage types here: #https://hub.spigotmc.org/javadocs/spigot/org/bukkit/event/entity/EntityDamageEvent.DamageCause.html damage-type: block-explosion: "Ви були пошкоджені вибухом. Не виходьте!" contact: "Вас уколов кактус. Не виходьте!" cramming: "Вас розчавлюють. Не виходьте!" custom: "Ви взяли нестандартну шкоду. Не виходьте!" drowning: "Ви тонете. Не виходьте!" dryout: "Ви занадто довго не були у воді. Не виходьте з системи!" #May be triggered by custom plugins. entity-explosion: "Вас було пошкоджено вибухом Кінцевого Кристала. Не виходьте з системи!" #Only triggered by end crystals. fall: "Ви отримали пошкодження при падінні. Не виходьте!" falling-block: "На вас упав блок. Не виходьте!" fire: "Ви увійшли в вогонь. Не виходьте!" fire-tick: "Ви горите. Не виходьте!" fly-into-wall: "Ви відчули кінетичну енергію. Не виходьте!" freeze: "Ти замерзаєш. Не виходь з системи!" hot-floor: "Підлога - це лава! Не виходьте!" lava: "Ви кипите в лаве. Не виходьте!" lightning: "Вас вразило! Не виходьте!" magic: "Хтось кинув у вас зілля. Не виходьте!" melting: "Ти танеш! Не виходьте з системи." #May be triggered by custom plugins. poison: "Ви отримали пошкодження від отрути. Не виходьте!" starvation: "Ви надто голодні. Не виходьте!" suffocation: "Ви задихаєтесь у стіні. Не виходьте!" void: "You are falling into the void. Do not log out!" wither: "Ви відмираєте. Не виходьте!" world-border: "Ви знаходитесь занадто близько до кордону. Не виходьте з системи!" newbie-helper: togglepvp: #Shown as the command output for '/togglepvp'. self: "PVP: {status}" #Shown as the command output for '/togglepvp admin on/off '. admin: "Ви змінили pvp {target} на {status}." #Shown when the '/togglepvp' command is on cooldown. cooldown: "Щоб знову використати цю команду, потрібно почекати {time_left} секунд." #These messages are shown when pvp is disabled for any reason. no-pvp: self: "Ви не можете вдарити цього гравця, коли ваш PvP вимкнено." other: "У цього гравця відключено PvP." protected: "Цей гравець захищений, вам поки заборонено атакувати його!" cancel: "Ви захищені, вам не можна атакувати інших гравців!" protection-disabled: #Shown when newbie protection is disabled due to the player attacking another player. attacker: "Ви напали на когось, ваш захист новачка відключено." #Shown when newbie protection expires. expired: "Термін дії вашого захисту новачка закінчився." #Shown for the '/togglepvp check ' command. check-format: - "Інформація для {target}:" - "Захист: {protected}" - "PvP: {pvp}" loot-protection: #Shown when an enemy dies and their loot is protected. enemy-died: "{enemy} помер. Здобуток буде захищений протягом {time} секунд." #Shown when a player tries to pick up an item that is loot protected by the plugin. protected: "Наразі цей предмет захищено, зачекайте {time} секунд, поки ви зможете його забрати." citizens-compatibility: #Shown when a player is prevented from joining the server due to their NPC still existing. prevent-join: "Вам заборонено під'єднуваться до сервера, поки ваш NPC не буде вбитий або не знищиться." disguise-compatibility: #Shown when a disguise is removed from a player during combat. remove-disguise: "Вашу маску видалили." essentials-compatibility: #Shown when a teleport request is cancelled during combat. prevent-teleport-request-self: "Ви не можете створювати запити телепорту під час бою." #Shown when a teleport request is cancelled during combat. prevent-teleport-request-other: "Ви не можете надсилати запит на телепорт гравцеві, який перебуває в бою." marriagemaster-compatibility: #Shown when a married player is prevented from teleporting to their partner during combat. prevent-teleport-self: "Вам не дозволено телепортуватися до вашого партнера під час бою." #Shown when a married player is prevented from teleporting to their partner during combat. prevent-teleport-partner: "Вам не дозволяється переміщуватися до вашого партнера, поки вони знаходяться в бою." huskhomes-compatibility: prevent-teleport: "Вам заборонено телепортуватися під час бою." region-protection: #Shown when a player tries to enter a no-pvp area during combat. default-no-entry: "Вам не дозволено вводити цю область під час бою." factions-no-entry: Вам заборонено входити в цю зону під час бою. griefdefender-no-entry: Вам заборонено входити в цю зону під час бою. griefprevention-no-entry: Вам заборонено входити в цю зону під час бою. kingdomsx-no-entry: Вам заборонено входити в цю зону під час бою. konquest-no-entry: Вам заборонено входити в цю зону під час бою. redprotect-no-entry: Вам заборонено входити в цю зону під час бою. residence-no-entry: Вам заборонено входити в цю зону під час бою. towny-no-entry: Вам заборонено входити в цю зону під час бою. husktowns-no-entry: Вам не дозволено вводити цю область під час бою. ultimateclaims-no-entry: Вам заборонено входити в цю зону під час бою. protectionstones: prevent-area-creation: "Під час бою не дозволяється створювати захищену територію." no-entry: Вам заборонено входити в цю зону під час бою. preciousstones: prevent-field-creation: "Вам заборонено створювати захисне поле під час бою." no-entry: Вам заборонено входити в цю зону під час бою. worldguard: no-entry-mob-combat: "Ви не можете увійти в зону, де заборонений PvE, під час бою." no-entry-player-combat: "Ви не можете увійти в зону, де заборонений PvP, під час бою." no-entry-unknown-combat: Вам заборонено входити в цю зону під час бою. lands: no-entry: Вам не дозволено вводити цю область під час бою. war-disable-newbie-protection: "PvP тепер примусово увімкнуто через оголошення війни." ================================================ FILE: plugin/src/main/resources/language/zh_cn.lang.yml ================================================ --- ## Extra Information: ## This is the default language file for CombatLogX. ## The default language is "en_us", also known as English (United States). ## Context will be added as YAML comments above the string. ## The color scheme for messages is gold, white, and sometimes red. ## Command feedback that is successful should always be green. ## Error messages should always be red. ## Variables in messages can be gray or white. ## Messages use the MiniMessage format in non-strict mode. ## More information about MiniMessage can be found here: ## https://docs.adventure.kyori.net/minimessage/format.html #The language code for this file. language-name: "zh_cn" #The format for decimal numbers. #The United States uses the number and two decimal places decimal-format: "0.00" #The prefix for CombatLogX that is shown in front of all messages. #Note to translators: Do not change this message. prefix: "[CombatLogX]" broadcast: #Shown when the plugin is finished loading. on-load: "CombatLogX 已成功加载。" #Shown when the plugin is finished enabling. on-enable: "CombatLogX 已成功启用。" #Shown when the plugin is disabled for any reason. on-disable: "CombatLogX 已成功禁用。" placeholder: #This text is used for the {combatlogx_time_left} #This allows server configurations to change the display value of the zero to something like "Not in combat" time-left-zero: "0" #This text is used when a player does not have an enemy. #This can happen when players are tagged by a custom expansion or the tag command. unknown-enemy: "未知" status: #Shown when the player is in combat. fighting: "战斗中" in-combat: "" #Shown when the player is not in combat idle: "空闲中" not-in-combat: "" #These placeholders are shown when a player changes a value such as whether or not their bossbar is enabled. toggle: enabled: "开启" disabled: "关闭" pvp-status: enabled: "开启" disabled: "关闭" #You can also change the location of these messages. #Example: #combat-timer: #expire: #type: ACTION_BAR #content: "" combat-timer: #Sent to a player when they escape from combat due to the timer running out. expire: "你不再处于战斗状态。" #Sent to a player when they escape from combat due to their enemy being killed. enemy-death: "你不再处于战斗状态,因为你的敌人已死亡。" #Sent when a player is killed during combat. self-death: "你不再处于战斗中,因为你已死亡。" error: #Shown when the console tries to execute a command made for players. player-only: "仅玩家可以使用此命令。" #Shown when a player tries to execute a command made for the server console. console-only: "仅控制台可以执行此命令!" #Shown when a command that requires a player has invalid input. invalid-target: "{target}不在线或不存在。" #Shown when a command that requires a number has invalid input. invalid-integer: "{value} 不是一个有效的整数。" #Shown when a player does not have access to something that requires a permission. no-permission: "缺少权限: {permission}" #Shown when a player executes a command in a world that is disabled in the configuration. disabled-world: "该命令在此维度中不可用。" #Shown when a command requires a player in combat but the target player is not in combat. target-not-in-combat: "{target}未处于战斗状态。" #Shown when a player executes a command that requires them to be in combat. self-not-in-combat: "你未处于战斗状态。" #Shown when a command that requires an expansion has invalid input. unknown-expansion: "{target} 不是一个扩展或未被安装。" forgive-not-enemy: "{target}不是你的敌人。" enemy-not-forgiving: "那个敌人不想原谅你。" command: combatlogx: #Shown as the command output for '/combatlogx help'. help-message-list: - "" - "CombatLogX 命令帮助:" - " /combatlogx help: 查看帮助页面。" - " /combatlogx reload: 重新载入config.yml、language.yml以及扩展配置文件。" - " /combatlogx about \\: 检查扩展信息。" - " /combatlogx tag \\ [seconds]: 强迫玩家进入战斗状态。" - " /combatlogx toggle bossbar/actionbar/scoreboard: 启用或禁用一种通知类型。" - " /combatlogx tag \\ [seconds]: 强迫玩家进入战斗状态。" - " /combatlogx version: 检查 CombatLogX 版本。" - " /combatlogx forgive request \\: 向敌人发送请求,要求移除你所导致的战斗状态。" - " /combatlogx forgive accept \\: 允许敌人要求避免战斗。" - " /combatlogx forgive reject \\: 忽略敌人避免战斗的请求。" - " /combatlogx forgive toggle: 启用或禁用停止战斗的请求。" - "" #Shown as the command output for '/combatlogx reload' when reloading is successful. reload-success: - "成功重载 CombatLogX 中所有的配置文件。" - "成功重载 CombatLogX 中所有的语言文件。" - "成功重载 CombatLogX 中所有的扩展配置文件。" #Shown as the command output for '/combatlogx reload' when reloading fails reload-failure: - "重载配置时出错。" - "请检查服务器日志并修复损坏的文件。" #Shown as the command output for '/combatlogx tag ' when a player is tagged successfully. tag-player: "成功强迫玩家{target}进入战斗状态。" #Shown as the command output for '/combatlogx tag ' when the plugin failed to tag a player. tag-failure: "{target}无法进入战斗状态。(或许他们拥有某种绕过权限?)" #Shown as the command output for '/combatlogx untag '. untag-player: "成功强迫玩家{target}退出战斗状态。" #Shown as the command output for '/combatlogx toggle bossbar'. toggle-bossbar: "Boss条: {status}" #Shown as the command output for '/combatlogx toggle actionbar'. toggle-actionbar: "底部信息栏: {status}" #Shown as the command output for '/combatlogx toggle scoreboard'. toggle-scoreboard: "计分板: {status}" #Shown as the command output for '/combatlogx about '. expansion-information: - "" - "关于 {name}的扩展信息:" - "显示名称: {prefix}" - "版本: {version}" - "状态: {state}" - "" - "描述: {description}" - "网站: {website}" - "作者: {authors}" forgive: toggle-disable: "你不再接收宽恕请求。" toggle-enable: "你现在可以接收宽恕请求。" request-sent: "你向{target}发送了宽恕请求。" request-receive: - "{player}向你发送了宽恕请求。" - "输入 /clx forgive accept 以接受。" - "/clx forgive reject 以拒绝。" combat-timer: #Shown as the command output for '/combat-timer'. time-left-self: "你还剩下{time_left}秒。" #Shown as the command output for '/combat-timer '. time-left-other: "{target}还剩下{time_left}秒" #These messages are shown a player is tagged into combat. #You can also change the location of these messages. #Example: #tagged: #attacked: #player: #type: ACTION_BAR #content: "" tagged: unknown: player: "你正在与{enemy}作战,原因不详。请不要登出!" mob: "你正在与{enemy}作战,原因不详。请不要登出!" mythic_mob: "你正在与{mob_type}作战,原因不详。请不要登出!" damage: "你因受到伤害而处于战斗状态中。请不要登出!" unknown: "你被无理由置于战斗状态中。请不要登出。" attacked: player: "你正在被{enemy}攻击。不要登出!" mob: "你正在被{mob_type}攻击。不要登出!" mythic_mob: "你正在被{enemy}攻击。不要登出!" damage: "你因受到伤害而处于战斗状态中。请不要登出!" unknown: "你正在受到未知力量的攻击。请不要登出!" attacker: player: "你正在攻击{enemy}。不要登出!" mob: "你正在攻击{mob_type}。不要登出!" mythic_mob: "你正在攻击{enemy}。不要登出!" damage: "你因受到伤害而处于战斗状态中。请不要登出!" unknown: "你正在攻击一个未知的力量。请不要登出!" expansion: angel-chest: #Shown when opening an AngelChest is prevented during combat. prevent-opening: "你不能在战斗中打开天使箱。" #Shown when breaking an AngelChest is prevented during combat. prevent-breaking: "你不能战斗中破坏天使箱。" #Shown when fast looting an AngelChest is prevented during combat. prevent-fast-looting: "&c你不能在战斗中快速掠夺天使箱。" action-bar: #Shown above the hotbar while a player is in combat. timer: "战斗中 \u00BB {bars} {combatlogx_time_left}" #Shown above the hotbar for a brief period when combat ends. ended: "战斗中 \u00BB 你不再处于战斗中" boss-bar: #Shown on top of the screen while a player is in combat. timer: "战斗中 \u00BB {combatlogx_time_left}" #Shown on top of the screen for a brief period when combat ends. ended: "战斗中 \u00BB 你不再处于战斗中" scoreboard: #The scoreboard title for the sidebar. #Make sure to follow the scoreboard title limits for your Spigot version. title: "CombatLogX" #The scoreboard lines for the sidebar. #Make sure to follow the scoreboard line and character limits for your Spigot version. lines: - " " - "战斗状态:" - "\u00BB 剩余时间: {combatlogx_time_left}" - "\u00BB 敌人: {combatlogx_enemy_count}" - "\u00BB 状态: {combatlogx_status}" - " " - "敌人" - "\u00BB {combatlogx_specific_enemy_1_name}" - "\u00BB {combatlogx_specific_enemy_2_name}" - "\u00BB {combatlogx_specific_enemy_3_name}" - " " cheat-prevention: #Shown when a command execution is prevented during combat. command-blocked: "你不能在战斗中使用 {command}" #Shown when the riptide effect is prevented during combat. no-riptide: "战斗期间禁用激流附魔。" #Shown when a totem of undying is prevented during combat. no-totem: "你不能在战斗中使用不死图腾。" #Shown when an entity interaction is prevented during combat. no-entity-interaction: "你不能在战斗中与那个实体交互。" #Shown when a chat message is prevented during combat. no-chat: "你不能在战斗中发送聊天消息。" game-mode: #Shown when a player is forced into a specific game mmode during combat. force-switch: "你的游戏模式已被设置为{game_mode}" #Shown when a game mode switch is prevented during combat. no-switch: "你不能在战斗中更改游戏模式。" flight: #Shown when a player's ability to fly is disabled during combat. force-disabled: "你的飞行能力已被移除。" #Shown when a player's attempt to fly is prevented during combat. no-flying: "你不能在战斗中飞行。" elytra: #Shown when a player's ability to glide is disabled during combat. force-disabled: "你的鞘翅已被禁用。" #Shown when a player's attempt to glide is prevented during combat. no-gliding: "你不能在战斗中使用鞘翅。" #Shown when a player tries to use fireworks. no-fireworks: "你不能在战斗中发射烟花火箭。" teleportation: #Shown when a player tries to enter a portal and is prevented during combat. block-portal: "你不能在战斗中使用传送门。" #Shown when an ender pearl is prevented during combat. block-pearl: "你不能在战斗中使用末影珍珠。" #Shown when a teleport is prevented during combat. block-other: "你不能在战斗中进行传送。" inventory: #Shown when a player's inventory is closed by the plugin during combat. force-closed: "你的物品栏已被关闭。" #Shown when a player tries to open an inventory and is prevented during combat. no-opening: "你不能在战斗中打开物品栏。" blocks: #Shown when a player is prevented from breaking a block during combat. prevent-breaking: "你不能在战斗中破坏方块。" #Shown when a player is prevented from breaking a block during combat. prevent-placing: "你不能在战斗中放置方块。" #Shown when a player is prevented from breaking a block during combat. prevent-interaction: "你不能在战斗中使用方块。" #Shown when a player is prevented from breaking a block during combat. prevent-portal-creation: "你不能在战斗中创建传送门。" items: #Shown when a player is prevented from picking up an item during combat. no-pickup: "你不能在战斗中捡起物品。" #Shown when a player is prevented from dropping an item during combat. no-dropping: "你不能在战斗中丢弃物品。" buckets: #Shown when a player is prevented from emptying a bucket during combat. no-empty: "你不能在战斗中将桶倒空。" #Shown when a player is prevented from filling a bucket during combat. no-fill: "你不能在战斗中将桶装满。" damage-tagger: #Shown when a player is tagged for an unknown damage type. unknown-damage: "你受到了伤害!不要登出!" #These messages are shown when a player is tagged for a known damage type. #You can find a list of damage types here: #https://hub.spigotmc.org/javadocs/spigot/org/bukkit/event/entity/EntityDamageEvent.DamageCause.html damage-type: block-explosion: "你受到了爆炸伤害。不要登出!" contact: "你被仙人掌扎伤了。不要登出!" cramming: "你正在被压扁。不要登出!" custom: "你受到了自定义伤害。不要登出!" drowning: "你正在溺水。不要登出!" dryout: "你停留在水外太长。不要登出!" #May be triggered by custom plugins. entity-explosion: "你受到了末地水晶的爆炸伤害。不要登出!" #Only triggered by end crystals. fall: "你受到了坠落伤害!不要登出!" falling-block: "一个方块砸到你身上了。不要登出!" fire: "你走到了火里。不要登出!" fire-tick: "你正在燃烧。不要登出!" fly-into-wall: "你感受到了动能。不要登出!" freeze: "你正在被冻结。不要登出!" hot-floor: "地板是岩浆做的!不要登出!" lava: "你正在岩浆里游泳。不要登出!" lightning: "你被闪电劈了!不要登出!" magic: "有人向你扔药水。不要登出!" melting: "你正在熔化!不要登出。" #May be triggered by custom plugins. poison: "你受到了药水伤害。不要登出!" starvation: "你太饿了。不要登出!" suffocation: "你正在墙里窒息。不要登出!" void: "你掉出了这个世界。不要登出!" wither: "你正在凋零。不要登出!" world-border: "你太靠近世界边界了。不要登出!" newbie-helper: togglepvp: #Shown as the command output for '/togglepvp'. self: "PVP: {status}" #Shown as the command output for '/togglepvp admin on/off '. admin: "你将 {target} 的PVP状态更改为 {status}" #Shown when the '/togglepvp' command is on cooldown. cooldown: "你必须等待{time_left}秒才能再次使用此命令。" #These messages are shown when pvp is disabled for any reason. no-pvp: self: "你不能在自身PvP被禁用时攻击该玩家。" other: "该玩家已禁用PvP。" protected: "那个玩家受到保护,你无法攻击!" cancel: "由于你受到保护,暂时无法攻击其他玩家!" protection-disabled: #Shown when newbie protection is disabled due to the player attacking another player. attacker: "你攻击了他人,你的新手保护已被禁用。" #Shown when newbie protection expires. expired: "你的新手保护已过期。" #Shown for the '/togglepvp check ' command. check-format: - "{target}的信息:" - "保护: {protected}" - "PvP: {pvp}" loot-protection: #Shown when an enemy dies and their loot is protected. enemy-died: "{enemy}已经死亡。战利品将在{time}秒内受到保护。" #Shown when a player tries to pick up an item that is loot protected by the plugin. protected: "该物品目前受到保护,请等待{time}秒再来捡起它。" citizens-compatibility: #Shown when a player is prevented from joining the server due to their NPC still existing. prevent-join: "你不能加入服务器,直到你的NPC被杀死或被清除为止。" disguise-compatibility: #Shown when a disguise is removed from a player during combat. remove-disguise: "你的伪装已被移除。" essentials-compatibility: #Shown when a teleport request is cancelled during combat. prevent-teleport-request-self: "你不能在战斗中创建传送请求。" #Shown when a teleport request is cancelled during combat. prevent-teleport-request-other: "你不能向战斗中的玩家发送传送请求。" marriagemaster-compatibility: #Shown when a married player is prevented from teleporting to their partner during combat. prevent-teleport-self: "你不能在战斗中传送到你的伙伴。" #Shown when a married player is prevented from teleporting to their partner during combat. prevent-teleport-partner: "你不能传送至正在战斗中的伙伴。" huskhomes-compatibility: prevent-teleport: "你不能在战斗中进行传送。" region-protection: #Shown when a player tries to enter a no-pvp area during combat. default-no-entry: "你不能在战斗中进入那片区域。" factions-no-entry: 你不能在战斗中进入那片区域。 griefdefender-no-entry: 你不能在战斗中进入那片区域。 griefprevention-no-entry: 你不能在战斗中进入那片区域。 kingdomsx-no-entry: 你不能在战斗中进入那片区域。 konquest-no-entry: 你不能在战斗中进入那片区域。 redprotect-no-entry: 你不能在战斗中进入那片区域。 residence-no-entry: 你不能在战斗中进入那片区域。 towny-no-entry: 你不能在战斗中进入那片区域。 husktowns-no-entry: 你不能在战斗中进入那片区域。 ultimateclaims-no-entry: 你不能在战斗中进入那片区域。 protectionstones: prevent-area-creation: "你不能在战斗中创建保护区域。" no-entry: 你不能在战斗中进入那片区域。 preciousstones: prevent-field-creation: "你不能在战斗中创建保护区域。" no-entry: 你不能在战斗中进入那片区域。 worldguard: no-entry-mob-combat: "你不能在战斗中进入非怪物战斗区域。" no-entry-player-combat: "你不能在战斗中进入非玩家战斗区域。" no-entry-unknown-combat: 你不能在战斗中进入那片区域。 lands: no-entry: 你不能在战斗中进入那片区域。 war-disable-newbie-protection: "由于宣战PvP已被启用。" ================================================ FILE: plugin/src/main/resources/language.yml ================================================ # CombatLogX Language Configuration # This plugin supports per-player language messages in 1.12.2+ # Force all players to use the 'default-locale', even when they have set a different language in their client. # This option also makes the 'console-locale' option useless. enforce-default-locale: false # This is the default language that will be shown to players when their language is not detected. # Player language can fail to detect if the file does not exist or if your Spigot jar does not support locales. default-locale: "en_us" # This is the language that will be used for messages sent to the server console. console-locale: "en_us" # Set this to true if you want language messages to include PlaceholderAPI placeholders. # The placeholder will be replaced relative to the player that the message is sent to. # If the message is sent to a non-player, the placeholders will not be replaced. use-placeholder-api: false ================================================ FILE: plugin/src/main/resources/punish.yml ================================================ # Should CombatLogX punish players when they log out during combat? # It is not recommended to disable this option unless you are testing something. # Default: true on-disconnect: true # Should CombatLogX punish players when they are kicked from the game? # Getting kicked from the game is usually not the fault of the player. # Default: false on-kick: false # Should CombatLogX punish players when their timer expires? # This option is not recommended unless you are testing something. # Default: false on-expire: false # Which kick reasons should not punish players? # This option is only used when the 'on-kick' option is set to true. # Default: ["troll", "kicked by SirBlobman"] kick-ignore-list: - "troll" - "kicked by SirBlobman" # Should the kick ignore list be converted into a kick requirement list? # Default: false kick-ignore-list-inverted: false # When should CombatLogX kill the player? # QUIT: CombatLogX will kill the player the moment they log out. # JOIN: CombatLogX will kill the player as soon as they log back in. # NEVER: CombatLogX will never kill the player. # Default: QUIT kill-time: QUIT # This is a list of custom death messages that CombatLogX will use when killing a player. # A message will be selected from this list randomly. # # Valid Placeholders: # {combatlogx_player} - The name of the player that died. # {combatlogx_current_enemy_name} - The name of the last enemy that tagged the player. The enemy can be unknown. # # If you don't want any custom messages, set this to an empty list # custom-death-message-list: [] custom-death-message-list: - "{combatlogx_player} was killed for logging out during combat." - "{combatlogx_player} instantly died due to logging out during combat." # Should CombatLogX keep track of the amount of times each player was punished? # Default: true enable-punishment-counter: true ## If you are searching for the punishment commands, check the 'commands.yml' file. ================================================ FILE: settings.gradle.kts ================================================ rootProject.name = "CombatLogX" // CombatLogX API include("api") // Base Spigot Plugin include("plugin") // CombatLogX Expansions include("expansion") // Normal Expansions include("expansion:action-bar") include("expansion:boss-bar") include("expansion:damage-tagger") include("expansion:damage-effects") include("expansion:death-effects") include("expansion:force-field") include("expansion:glowing") include("expansion:logger") include("expansion:loot-protection") include("expansion:mob-tagger") include("expansion:newbie-helper") include("expansion:rewards") include("expansion:scoreboard") // Cheat Prevention include("expansion:cheat-prevention:abstract") include("expansion:cheat-prevention:legacy") include("expansion:cheat-prevention:modern") include("expansion:cheat-prevention:paper") include("expansion:cheat-prevention") // End Crystals include("expansion:end-crystal:legacy") include("expansion:end-crystal:modern") include("expansion:end-crystal") // Compatibility expansions include("expansion:compatibility") include("expansion:compatibility:AngelChest") include("expansion:compatibility:ASkyBlock") include("expansion:compatibility:BSkyBlock") include("expansion:compatibility:Citizens") include("expansion:compatibility:CMI") include("expansion:compatibility:CrackShot") include("expansion:compatibility:CrashClaim") include("expansion:compatibility:EssentialsX") include("expansion:compatibility:FabledSkyBlock") include("expansion:compatibility:Factions") include("expansion:compatibility:FeatherBoard") include("expansion:compatibility:GriefDefender") include("expansion:compatibility:GriefPrevention") include("expansion:compatibility:HuskHomes") include("expansion:compatibility:HuskSync") include("expansion:compatibility:HuskTowns") include("expansion:compatibility:iDisguise") include("expansion:compatibility:IridiumSkyblock") include("expansion:compatibility:KingdomsX") include("expansion:compatibility:Konquest") include("expansion:compatibility:Lands") include("expansion:compatibility:LibsDisguises") include("expansion:compatibility:LuckPerms") include("expansion:compatibility:MarriageMaster") include("expansion:compatibility:MCPets") include("expansion:compatibility:MythicMobs") include("expansion:compatibility:PlaceholderAPI") include("expansion:compatibility:PlayerParticles") include("expansion:compatibility:PreciousStones") include("expansion:compatibility:ProtectionStones") include("expansion:compatibility:RedProtect") include("expansion:compatibility:Residence") include("expansion:compatibility:SuperiorSkyblock") include("expansion:compatibility:SuperVanish") include("expansion:compatibility:Towny") include("expansion:compatibility:UltimateClaims") include("expansion:compatibility:uSkyBlock") include("expansion:compatibility:VanishNoPacket") include("expansion:compatibility:WorldGuard") // include("expansion:compatibility:ZNPCsPlus") // Final ZIP Builder include("builder") ================================================ FILE: spigot.documentation.bbcode ================================================ This page provides a list of the features for CombatLogX and all bundled expansions. [SIZE=6][B]CombatLogX[/B][/SIZE] [LIST] [*]Tag players into combat with other players. [*]Check for updates. [*]Kill players for logging out during combat. [*]Run commands when players are tagged, untagged, and punished. [*]Link pets, projectiles, tnt, and fishing rods. [*]Use a global or permission-based combat timer. [/LIST] [SIZE=5][B]Commands:[/B][/SIZE] [B]/combatlogx:[/B] [INDENT] [B]Aliases:[/B] [ICODE]/clx[/ICODE], [ICODE]/ctx[/ICODE], [ICODE]/combatlog[/ICODE], [ICODE]/combattagx[/ICODE], [ICODE]/combattag[/ICODE] [ICODE]/combatlogx help[/ICODE] View the list of sub-commands for CombatLogX. [ICODE]/combatlogx about [/ICODE] View information about an expansion. [ICODE]/combatlogx reload[/ICODE] Reload the configuration files for the plugin and expansions. [ICODE]/combatlogx toggle [/ICODE] Toggle the action bar, boss bar, and scoreboard for yourself. [ICODE]/combatlogx tag [/ICODE] Force a player to be tagged into combat. [ICODE]/combatlogx untag [/ICODE] Force a player to be untagged from combat. [ICODE]/combatlogx version[/ICODE] View version information and a list of enabled expansions. [/INDENT] [B]/combat-timer:[/B] [INDENT] [B]Aliases:[/B] [ICODE]/combattimer[/ICODE], [ICODE]/combattime[/ICODE], [ICODE]/ctime[/ICODE], [ICODE]/clt[/ICODE], [ICODE]/ct[/ICODE] [ICODE]/combat-timer[/ICODE] Check how much time you have left in combat. [ICODE]/combat-timer [/ICODE] Check how much time a player has left in combat. [/INDENT] [SIZE=5][B]Permissions:[/B][/SIZE] [LIST] [*][ICODE]combatlogx.bypass[/ICODE] Default bypass permission, can be changed in the config.yml file. [*][ICODE]combatlogx.bypass.force.field[/ICODE] Default bypass permission for the force field, can be changed in the configuration file for the force field expansion. [*][ICODE]combatlogx.command.combat-timer[/ICODE] Gives access to the /combat-timer command. [*][ICODE]combatlogx.command.togglepvp[/ICODE] Gives access to the /togglepvp command from the NewbieHelper expansion. [*][ICODE]combatlogx.command.togglepvp.admin[/ICODE] Gives access to the admin features of the /togglepvp command. [*][ICODE]combatlogx.command.combatlogx[/ICODE] Gives access to the base /combatlogx command, but not the sub-commands. [*][ICODE]combatlogx.command.combatlogx.toggle[/ICODE] Gives access to /combatlogx toggle command to toggle boss bar, action bar, and scoreboard. [*][ICODE]combatlogx.command.combatlogx.about[/ICODE] Gives access to information about expansions with /combatlogx about. [*][ICODE]combatlogx.command.combatlogx.help[/ICODE] Gives access to information about CombatLogX commands with /combatlogx help. [*][ICODE]combatlogx.command.combatlogx.reload[/ICODE] Gives access to reload configurations with /combatlogx reload. [*][ICODE]combatlogx.command.combatlogx.version[/ICODE] Gives access to version information with /combatlogx version. [*][ICODE]combatlogx.command.combatlogx.tag[/ICODE] Gives access to force tag players with /combatlogx tag. [*][ICODE]combatlogx.command.combatlogx.untag[/ICODE] Gives access to force players out of combat with /combatlogx untag. [/LIST] [SIZE=6][B]Expansions[/B][/SIZE] [SIZE=5][B]Normal Expansions[/B][/SIZE] [SIZE=4][B]Action Bar[/B][/SIZE] [LIST] [*]Display a message above a player's hot bar during combat that shows the amount of time remaining. [*]Customizable bar feature with unicode characters. [/LIST] [SIZE=4][B]Boss Bar[/B][/SIZE] [LIST] [*]Display a message as a fake boss progress bar on top of the screen. [*]Customizable boss bar colors and type (requires Spigot 1.9+) [/LIST] [SIZE=4][B]Cheat Prevention[/B][/SIZE] Cheat Prevention can be used to prevent players from escaping during combat. This expansion is [U]not[/U] a hacking prevention tool. [B]Features:[/B] [LIST] [*]Prevent players from breaking, placing, and interaction for blocks. [*]Prevent players from creating nether and end portals. (requires 1.14+) [*]Prevent players from emptying and filling buckets. [*]Prevent players from typing in chat. [*]Prevent players from typing commands. [*]Prevent players from interacting with entities. [*]Prevent players from flying or keep them tagged while flying. [*]Prevent players from using elytra or keep them tagged while gliding. [*]Prevent players from switching game modes, or untag players when their game mode changes. [*]Force players into a specific game mode when tagged. [*]Force close inventories and prevent players from opening new ones. [*]Prevent players from dropping and picking up items. [*]Prevent players from using the riptide enchantment. [*]Prevent players from using totems of undying. [*]Prevent players from entering combat with potion effects. [*]Prevent players from teleporting away or untag them when they've been teleported. [*]Renew a player's combat tag when they use an ender pearl. [/LIST] [SIZE=4][B]Damage Effects[/B][/SIZE] [LIST] [*]Add blood effect every time a player is attacked. [/LIST] [SIZE=4][B]Damage Tagger[/B][/SIZE] Damage Tagger can tag players when they are damaged by the environment. [B]Known Damage Types:[/B] [LIST] [*]BLOCK_EXPLOSION: Explosions created by plugins. [*]CONTACT: Touching a cactus or a berry bush. [*]CRAMMING: Standing in an enclosed space with too many other mobs. [*]CUSTOM: Custom damage created by plugins. [*]DROWNING: Staying under water for too long. [*]FALL: Falling from a high place. [*]FALLING_BLOCK: Damage from a falling block, such as an anvil. [*]FIRE: Touching a fire block. [*]FIRE_TICK: Being on fire after touching a source of heat. [*]FLY_INTO_WALL: Damage caused by lack of elytra training. [*]HOT_FLOOR: Standing on magma blocks. [*]LAVA: Touching or swimming in lava. [*]MAGIC: Damage from the Instant Damage potion [*]POISON: Damage from a Poison potion due to witches or plugins. [*]STARVATION: Running out of food. [*]SUFFOCATION: Buried in sand or teleported into a wall. [*]WITHER: Wither effect caused by wither skeletons, roses, and bosses. [/LIST] [SIZE=4][B]Death Effects[/B][/SIZE] [LIST] [*]Spawn a lightning bolt effect when a player is killed. [*]Create a blood effect with redstone particles when a player is killed. [/LIST] [SIZE=4][B]End Crystal Helper[/B][/SIZE] End Crystal Helper requires Spigot 1.9 or higher. [LIST] [*]Links placed 'End Crystal' entities to players during combat. [/LIST] [SIZE=4][B]Force Field[/B][/SIZE] Force Field requires the ProtocolLib plugin and at least one of the Region Compatibility expansions listed below. [B]Features:[/B] [LIST] [*]Create a force field of blocks around non-pvp areas. [*]Customizable block type and radius. [/LIST] [B]Disclaimers:[/B] [LIST] [*]The force field is a nice visual effect that shows players the areas they cannot enter. [*]The force field should not be used as entry prevention, as players can just ignore the fake block packets that are sent to them. [*]For the actual entry prevention options, please check the configuration for your region expansion. [*]If your server has weak hardware, or if you have a lot of players online, we recommend disabling the force field effect. [*]You can try to enable unsafe mode and see if performance improves, but the recommended option is to disable the force field. [/LIST] [SIZE=4][B]Glowing[/B][/SIZE] Glowing requires Spigot 1.9 or higher. [LIST] [*]Make a player glow when tagged into combat. [*]The glow effect will be removed when the player is removed from combat. [/LIST] [SIZE=4][B]Logger[/B][/SIZE] [LIST] [*]Save details about different combat events to files. [*]Change the name and format of the log files. [*]Configurable log message and date format. [*]Option to log every CombatLogX event and the EntityDamageByEntityEvent. [/LIST] [SIZE=4][B]Loot Protection[/B][/SIZE] [LIST] [*]Protect dropped items from players logging out during combat. [*]Prevent players from stealing items from players that they did not kill. [*]Restore dropped items to the enemy if the player dies in the void. [*]Configurable amount of time to protect the loot. [/LIST] [SIZE=4][B]Mob Tagger[/B][/SIZE] [LIST] [*]Allow mobs to tag players into combat. [*]Configurable list of mobs that can tag players. [*]Prevent certain types of mobs from tagging players. [*]Prevent mobs spawned for certain reasons from tagging players. (e.g. spawners) [/LIST] [SIZE=4][B]Newbie Helper[/B][/SIZE] Newbie Helper can be used to protect new players from pvp. [LIST] [*]Prevent new players from being attacked for a configurable amount of time. [*]Remove protection from newbies when they attack someone. [*]Toggle your own ability to PVP. [*](Admin Only) Force a certain player to have pvp enabled/disabled. [*]Adds a command '/togglepvp' to enable and disable PVP. [/LIST] [SIZE=4][B]Rewards[/B][/SIZE] Rewards can be used to execute commands whenever a player kills a mob or another player. [LIST] [*]Customizable rewards. [*]Enabled/Disabled worlds per reward. [*]Specific entity types per reward. [*]Chance based rewards. [*]Rewards with custom requirements: [LIST] [*]Vault Economy balance. [*]Experience Points. [*]More coming soon... [/LIST] [/LIST] [SIZE=4][B]Scoreboard[/B][/SIZE] [LIST] [*]Display messages about the player's combat tag on the side bar. [*]Customizable title and lines with no flickering. [/LIST] [SIZE=5][B]Compatibility Expansions[/B][/SIZE] [SIZE=4][B]Region Compatibility Expansions[/B][/SIZE] The following expansions link into a region plugin and can be used to prevent entry into non-pvp areas. [LIST] [*]CrashClaim Compatibility [*]Factions Compatibility [*]GriefDefender Compatibility [*]GriefPrevention Compatibility [*]HuskTowns Compatibility [*]KingdomsX Compatibility [*]Konquest Compatibility [*]Lands Compatibility [*]PreciousStones Compatibility [*]ProtectionStones Compatibility [*]RedProtect Compatibility [*]Residence Compatibility [*]Towny Compatibility [*]UltimateClaims Compatibility [*]WorldGuard Compatibility [/LIST] [SIZE=4][B]WorldGuard Compatibility[/B][/SIZE] The WorldGuard compatibility has the following custom flags [LIST] [*][ICODE]no-tagging: TRUE[/ICODE]: CombatLogX will not tag players that are within the region. [*][ICODE]damage-combat: DENY[/ICODE]: Prevent entry for players that were tagged by generic damage. [*][ICODE]mob-combat: DENY[/ICODE]: Prevent entry for players in combat with mobs. [*][ICODE]mythic-mob-combat: DENY[/ICODE]: Prevent entry for players in combat with a Mythic mob. [*][ICODE]player-combat: DENY[/ICODE]: Prevent entry for players in combat with other players. [*][ICODE]unknown-combat: DENY[/ICODE]: Prevent entry for players in combat for an unknown reason. [*][ICODE]prevent-leaving: custom_id[/ICODE]: Prevents players from leaving a region during combat. Regions with the same id will allow players to move between them. [/LIST] [SIZE=4][B]SkyBlock Compatibility Expansions[/B][/SIZE] The following expansions link into a SkyBlock plugin and prevent teams from tagging each other. [LIST] [*]ASkyBlock Compatibility [*]BSkyBlock Compatibility [*]FabledSkyBlock Compatibility [*]IridiumSkyblock Compatibility [*]SuperiorSkyblock Compatibility [*]uSkyBlock Compatibility [/LIST] [SIZE=4][B]Vanish Compatibility Expansions[/B][/SIZE] The following expansions link into a vanish plugin and prevent vanished players from tagging other players and getting tagged. [LIST] [*]CMI Compatibility [*]EssentialsX Compatibility [*]SuperVanish Compatibility [*]VanishNoPacket Compatibility [/LIST] [SIZE=4][B]Disguise Compatibility Expansions[/B][/SIZE] The following expansions link into a disguise plugin and remove disguises when player are tagged. [LIST] [*]iDisguise Compatibility [*]LibsDisguises Compatibility [/LIST] [SIZE=4][B]AngelChest Compatibility[/B][/SIZE] [LIST] [*]Prevent players from opening angel chests during combat. [*]Prevent players from breaking angel chests during combat. [*]Prevent players from fast looting angel chests during combat. [/LIST] [SIZE=4][B]Citizens Compatibility[/B][/SIZE] [LIST] [*]Create an NPC instead of running the normal player punishments. [*]Store last location, health, and inventory items. [*]Support for Sentinel to make NPCs attack players. [*]Prevent players from logging in until their NPC is removed. [/LIST] [SIZE=4][B]CrackShot Compatibility[/B][/SIZE] [LIST] [*]Link CrackShot weapons to their shooter for tagging. [/LIST] [SIZE=4][B]EssentialsX Compatibility[/B][/SIZE] [LIST] [*]Vanish compatibility support. [*]Prevent players from creating teleport requests during combat. [/LIST] [SIZE=4][B]FeatherBoard Compatibility[/B][/SIZE] [LIST] [*]Sends trigger for FeatherBoard when players are tagged and untagged. [/LIST] [SIZE=4][B]HuskSync Compatibility[/B][/SIZE] [LIST] [*]Fixes some bugs caused when using CombatLogX and HuskSync together. [/LIST] [SIZE=4][B]HuskHomes Compatibility[/B][/SIZE] [LIST] [*]Prevents players from teleporting to their home during combat. [/LIST] [SIZE=4][B]LuckPerms Compatibility[/B][/SIZE] [LIST] [*]Adds custom contexts for LuckPerms permissions. [*]You can find context details [URL='https://github.com/SirBlobman/CombatLogX/blob/main/expansion/compatibility/LuckPerms/README.MD']here[/URL] [/LIST] [SIZE=4][B]MarriageMaster Compatibility[/B][/SIZE] [LIST] [*]Prevent partners from teleporting to each other during combat. [/LIST] [SIZE=4][B]MythicMobs Compatibility[/B][/SIZE] [LIST] [*]Prevent some mythic mobs from tagging players. [*]Force some mythic mobs to always tag players. [/LIST] [SIZE=4][B]PlaceholderAPI Compatibility[/B][/SIZE] [LIST] [*]Add support for placeholders from CombatLogX. [*]You can find a list of placeholders [URL='https://github.com/SirBlobman/CombatLogX/blob/main/expansion/compatibility/PlaceholderAPI/README.MD']here[/URL]. [/LIST] [SIZE=4][B]PlayerParticles Compatibility[/B][/SIZE] [LIST] [*]Disable a player's particle effects when tagged. [*]Enable a player's particle effects when combat ends. [/LIST] ================================================ FILE: spigot.overview.bbcode ================================================ [SIZE=5][B]Version Information:[/B][/SIZE] Only the following versions are officially supported: 1.19.4, 1.20.6, 1.21.1 Other versions may work, but you are on your own. [SIZE=5][B]Dependencies[/B][/SIZE] [LIST] [*][URL='https://www.spigotmc.org/resources/83189/']BlueSlimeCore[/URL] [/LIST] [SIZE=5][B]Description[/B][/SIZE] CombatLogX is a pvp-based plugin that punishes players for logging out during combat. There are many configuration options, such as punishment type and commands. CombatLogX also has a lot of expansions that are used to add extra features and keep the main plugin lightweight. [SIZE=5][B]Expansions[/B][/SIZE] CombatLogX uses expansions. Expansions add features to the main plugin. Please visit the documentation page to learn about the expansions before installing the plugin. [URL='https://www.spigotmc.org/resources/31689/field?field=documentation']CombatLogX Expansion Documentation[/URL] [SIZE=5][B]Installation Guide[/B][/SIZE] CombatLogX has different installation steps than other plugins. Please read this guide before trying to add CombatLogX to your server! [LIST=1] [*]Download the [U]CombatLogX.zip[/U] file from Jenkins or SpigotMC. [*]Extract the contents of the [U]CombatLogX.zip[/U] to your PC. [*]Click the stop button on the panel. If your server doesn't use a panel, type [ICODE]stop[/ICODE] into the console. [*]Upload [U]CombatLogX.jar[/U] and [U]BlueSlimeCore.jar[/U] to your server [U]/plugins/[/U] folder. [*]Upload the contents of [U]CombatLogX/expansions[/U] to your server [U]/plugins/CombatLogX/expansions[/U] folder. [*]If the files were uploaded and extracted correctly, your server should have the following files: [LIST] [*]File: [ICODE]/plugins/CombatLogX.jar[/ICODE] [*]File [ICODE]/plugins/BlueSlimeCore.jar[/ICODE] [*]Folder: [ICODE]/plugins/CombatLogX/[/ICODE] [*]Folder: [ICODE]/plugins/CombatLogX/expansions/[/ICODE] [*]Multiple Files: [ICODE]/plugins/CombatLogX/expansions/*.jar[/ICODE] [/LIST] [*]Delete the CombatLogX.zip file. [*]Restart your server using the panel or your startup script. [*]Edit the configuration files for the main plugin, languages, and expansions. [*]Type the command [ICODE]/clx reload[/ICODE] to reload the configuration files. [*]If you want to remove an expansion, delete the jar file from [U]/plugins/CombatLogX/expansions[/U]. [/LIST] [SIZE=5][B]Developers[/B][/SIZE] CombatLogX is an open source project licensed with GPL-3.0. You can find the source on [URL='https://github.com/SirBlobman/CombatLogX/']GitHub[/URL]. There is also information about the [URL='https://github.com/SirBlobman/CombatLogX/blob/main/api/README.MD']API[/URL] on GitHub. My [URL='https://jenkins.sirblobman.xyz/job/SirBlobman/job/CombatLogX/job/main/']Jenkins CI[/URL] has developer builds of CombatLogX for testing new features. [SIZE=5][B]Help and Support[/B][/SIZE] When you are having problems with CombatLogX, make sure you followed the installation guide and read through all configurations. If you are still having issues, please create a new "Bug Report" on my [URL="https://github.com/SirBlobman/CombatLogX/issues/new/choose"]GitHub page[/URL]. If you want to discuss the issue before reporting it, you can join our [URL='https://discord.gg/XMq2agT']Discord[/URL] community. [URL='https://discord.gg/XMq2agT'][IMG]https://discordapp.com/assets/fc0b01fe10a0b8c602fb0106d8189d9b.png[/IMG][/URL] You can also post on the Discussion tab or send me a private message, but you will receive a slow response since I do not check those pages often. [SIZE=5][B]Sponsorships[/B][/SIZE] My projects are sponsored by Alien Host. Click the banner to check them out! [URL='https://alienhost.net'][IMG]https://sirblobman.xyz/image/banner_base.png[/IMG][/URL] [SIZE=5][B]Extra Information[/B][/SIZE] Please do not use a review to leave bug reports or errors. I am not able to help you through a review. If you need help please use the contact methods provided above.